diff options
author | root <root@artemis.panaceas.org> | 2015-12-25 04:40:36 +0000 |
---|---|---|
committer | root <root@artemis.panaceas.org> | 2015-12-25 04:40:36 +0000 |
commit | 849369d6c66d3054688672f97d31fceb8e8230fb (patch) | |
tree | 6135abc790ca67dedbe07c39806591e70eda81ce /arch/arm/mach-at91 | |
download | linux-3.0.35-kobo-849369d6c66d3054688672f97d31fceb8e8230fb.tar.gz linux-3.0.35-kobo-849369d6c66d3054688672f97d31fceb8e8230fb.tar.bz2 linux-3.0.35-kobo-849369d6c66d3054688672f97d31fceb8e8230fb.zip |
initial_commit
Diffstat (limited to 'arch/arm/mach-at91')
126 files changed, 30568 insertions, 0 deletions
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig new file mode 100644 index 00000000..22484670 --- /dev/null +++ b/arch/arm/mach-at91/Kconfig @@ -0,0 +1,524 @@ +if ARCH_AT91 + +config HAVE_AT91_DATAFLASH_CARD + bool + +config HAVE_AT91_USART3 + bool + +config HAVE_AT91_USART4 + bool + +config HAVE_AT91_USART5 + bool + +menu "Atmel AT91 System-on-Chip" + +choice + prompt "Atmel AT91 Processor" + +config ARCH_AT91RM9200 + bool "AT91RM9200" + select CPU_ARM920T + select GENERIC_CLOCKEVENTS + select HAVE_AT91_USART3 + +config ARCH_AT91SAM9260 + bool "AT91SAM9260 or AT91SAM9XE" + select CPU_ARM926T + select GENERIC_CLOCKEVENTS + select HAVE_AT91_USART3 + select HAVE_AT91_USART4 + select HAVE_AT91_USART5 + select HAVE_NET_MACB + +config ARCH_AT91SAM9261 + bool "AT91SAM9261" + select CPU_ARM926T + select GENERIC_CLOCKEVENTS + select HAVE_FB_ATMEL + +config ARCH_AT91SAM9G10 + bool "AT91SAM9G10" + select CPU_ARM926T + select GENERIC_CLOCKEVENTS + select HAVE_FB_ATMEL + +config ARCH_AT91SAM9263 + bool "AT91SAM9263" + select CPU_ARM926T + select GENERIC_CLOCKEVENTS + select HAVE_FB_ATMEL + select HAVE_NET_MACB + +config ARCH_AT91SAM9RL + bool "AT91SAM9RL" + select CPU_ARM926T + select GENERIC_CLOCKEVENTS + select HAVE_AT91_USART3 + select HAVE_FB_ATMEL + +config ARCH_AT91SAM9G20 + bool "AT91SAM9G20" + select CPU_ARM926T + select GENERIC_CLOCKEVENTS + select HAVE_AT91_USART3 + select HAVE_AT91_USART4 + select HAVE_AT91_USART5 + select HAVE_NET_MACB + +config ARCH_AT91SAM9G45 + bool "AT91SAM9G45" + select CPU_ARM926T + select GENERIC_CLOCKEVENTS + select HAVE_AT91_USART3 + select HAVE_FB_ATMEL + select HAVE_NET_MACB + +config ARCH_AT91CAP9 + bool "AT91CAP9" + select CPU_ARM926T + select GENERIC_CLOCKEVENTS + select HAVE_FB_ATMEL + select HAVE_NET_MACB + +config ARCH_AT91X40 + bool "AT91x40" + select ARCH_USES_GETTIMEOFFSET + +endchoice + +config AT91_PMC_UNIT + bool + default !ARCH_AT91X40 + +# ---------------------------------------------------------- + +if ARCH_AT91RM9200 + +comment "AT91RM9200 Board Type" + +config MACH_ONEARM + bool "Ajeco 1ARM Single Board Computer" + help + Select this if you are using Ajeco's 1ARM Single Board Computer. + <http://www.ajeco.fi/> + +config ARCH_AT91RM9200DK + bool "Atmel AT91RM9200-DK Development board" + select HAVE_AT91_DATAFLASH_CARD + help + Select this if you are using Atmel's AT91RM9200-DK Development board. + (Discontinued) + +config MACH_AT91RM9200EK + bool "Atmel AT91RM9200-EK Evaluation Kit" + select HAVE_AT91_DATAFLASH_CARD + help + Select this if you are using Atmel's AT91RM9200-EK Evaluation Kit. + <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3507> + +config MACH_CSB337 + bool "Cogent CSB337" + help + Select this if you are using Cogent's CSB337 board. + <http://www.cogcomp.com/csb_csb337.htm> + +config MACH_CSB637 + bool "Cogent CSB637" + help + Select this if you are using Cogent's CSB637 board. + <http://www.cogcomp.com/csb_csb637.htm> + +config MACH_CARMEVA + bool "Conitec ARM&EVA" + help + Select this if you are using Conitec's AT91RM9200-MCU-Module. + <http://www.conitec.net/english/linuxboard.php> + +config MACH_ATEB9200 + bool "Embest ATEB9200" + help + Select this if you are using Embest's ATEB9200 board. + <http://www.embedinfo.com/english/product/ATEB9200.asp> + +config MACH_KB9200 + bool "KwikByte KB920x" + help + Select this if you are using KwikByte's KB920x board. + <http://www.kwikbyte.com/KB9202.html> + +config MACH_PICOTUX2XX + bool "picotux 200" + help + Select this if you are using a picotux 200. + <http://www.picotux.com/> + +config MACH_KAFA + bool "Sperry-Sun KAFA board" + help + Select this if you are using Sperry-Sun's KAFA board. + +config MACH_ECBAT91 + bool "emQbit ECB_AT91 SBC" + select HAVE_AT91_DATAFLASH_CARD + help + Select this if you are using emQbit's ECB_AT91 board. + <http://wiki.emqbit.com/free-ecb-at91> + +config MACH_YL9200 + bool "ucDragon YL-9200" + help + Select this if you are using the ucDragon YL-9200 board. + +config MACH_CPUAT91 + bool "Eukrea CPUAT91" + help + Select this if you are using the Eukrea Electromatique's + CPUAT91 board <http://www.eukrea.com/>. + +config MACH_ECO920 + bool "eco920" + help + Select this if you are using the eco920 board + +endif + +# ---------------------------------------------------------- + +if ARCH_AT91SAM9260 + +comment "AT91SAM9260 Variants" + +config ARCH_AT91SAM9260_SAM9XE + bool "AT91SAM9XE" + help + Select this if you are using Atmel's AT91SAM9XE System-on-Chip. + They are basically AT91SAM9260s with various sizes of embedded Flash. + +comment "AT91SAM9260 / AT91SAM9XE Board Type" + +config MACH_AT91SAM9260EK + bool "Atmel AT91SAM9260-EK / AT91SAM9XE Evaluation Kit" + select HAVE_AT91_DATAFLASH_CARD + help + Select this if you are using Atmel's AT91SAM9260-EK or AT91SAM9XE Evaluation Kit + <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3933> + +config MACH_CAM60 + bool "KwikByte KB9260 (CAM60) board" + help + Select this if you are using KwikByte's KB9260 (CAM60) board based on the Atmel AT91SAM9260. + <http://www.kwikbyte.com/KB9260.html> + +config MACH_SAM9_L9260 + bool "Olimex SAM9-L9260 board" + select HAVE_AT91_DATAFLASH_CARD + help + Select this if you are using Olimex's SAM9-L9260 board based on the Atmel AT91SAM9260. + <http://www.olimex.com/dev/sam9-L9260.html> + +config MACH_AFEB9260 + bool "Custom afeb9260 board v1" + help + Select this if you are using custom afeb9260 board based on + open hardware design. Select this for revision 1 of the board. + <svn://194.85.238.22/home/users/george/svn/arm9eb> + <http://groups.google.com/group/arm9fpga-evolution-board> + +config MACH_USB_A9260 + bool "CALAO USB-A9260" + help + Select this if you are using a Calao Systems USB-A9260. + <http://www.calao-systems.com> + +config MACH_QIL_A9260 + bool "CALAO QIL-A9260 board" + help + Select this if you are using a Calao Systems QIL-A9260 Board. + <http://www.calao-systems.com> + +config MACH_CPU9260 + bool "Eukrea CPU9260 board" + help + Select this if you are using a Eukrea Electromatique's + CPU9260 Board <http://www.eukrea.com/> + +config MACH_FLEXIBITY + bool "Flexibity Connect board" + help + Select this if you are using Flexibity Connect board + <http://www.flexibity.com> + +endif + +# ---------------------------------------------------------- + +if ARCH_AT91SAM9261 + +comment "AT91SAM9261 Board Type" + +config MACH_AT91SAM9261EK + bool "Atmel AT91SAM9261-EK Evaluation Kit" + select HAVE_AT91_DATAFLASH_CARD + help + Select this if you are using Atmel's AT91SAM9261-EK Evaluation Kit. + <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3820> + +endif + +# ---------------------------------------------------------- + +if ARCH_AT91SAM9G10 + +comment "AT91SAM9G10 Board Type" + +config MACH_AT91SAM9G10EK + bool "Atmel AT91SAM9G10-EK Evaluation Kit" + select HAVE_AT91_DATAFLASH_CARD + help + Select this if you are using Atmel's AT91SAM9G10-EK Evaluation Kit. + <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4588> + +endif + +# ---------------------------------------------------------- + +if ARCH_AT91SAM9263 + +comment "AT91SAM9263 Board Type" + +config MACH_AT91SAM9263EK + bool "Atmel AT91SAM9263-EK Evaluation Kit" + select HAVE_AT91_DATAFLASH_CARD + help + Select this if you are using Atmel's AT91SAM9263-EK Evaluation Kit. + <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4057> + +config MACH_USB_A9263 + bool "CALAO USB-A9263" + help + Select this if you are using a Calao Systems USB-A9263. + <http://www.calao-systems.com> + +config MACH_NEOCORE926 + bool "Adeneo NEOCORE926" + select HAVE_AT91_DATAFLASH_CARD + help + Select this if you are using the Adeneo Neocore 926 board. + +endif + +# ---------------------------------------------------------- + +if ARCH_AT91SAM9RL + +comment "AT91SAM9RL Board Type" + +config MACH_AT91SAM9RLEK + bool "Atmel AT91SAM9RL-EK Evaluation Kit" + help + Select this if you are using Atmel's AT91SAM9RL-EK Evaluation Kit. + +endif + +# ---------------------------------------------------------- + +if ARCH_AT91SAM9G20 + +comment "AT91SAM9G20 Board Type" + +config MACH_AT91SAM9G20EK + bool "Atmel AT91SAM9G20-EK Evaluation Kit" + select HAVE_AT91_DATAFLASH_CARD + help + Select this if you are using Atmel's AT91SAM9G20-EK Evaluation Kit + that embeds only one SD/MMC slot. + +config MACH_AT91SAM9G20EK_2MMC + depends on MACH_AT91SAM9G20EK + bool "Atmel AT91SAM9G20-EK Evaluation Kit with 2 SD/MMC Slots" + help + Select this if you are using an Atmel AT91SAM9G20-EK Evaluation Kit + with 2 SD/MMC Slots. This is the case for AT91SAM9G20-EK rev. C and + onwards. + +config MACH_CPU9G20 + bool "Eukrea CPU9G20 board" + help + Select this if you are using a Eukrea Electromatique's + CPU9G20 Board <http://www.eukrea.com/> + +config MACH_ACMENETUSFOXG20 + bool "Acme Systems srl FOX Board G20" + help + Select this if you are using Acme Systems + FOX Board G20 <http://www.acmesystems.it> + +config MACH_PORTUXG20 + bool "taskit PortuxG20" + help + Select this if you are using taskit's PortuxG20. + <http://www.taskit.de/en/> + +config MACH_STAMP9G20 + bool "taskit Stamp9G20 CPU module" + help + Select this if you are using taskit's Stamp9G20 CPU module on its + evaluation board. + <http://www.taskit.de/en/> + +config MACH_PCONTROL_G20 + bool "PControl G20 CPU module" + help + Select this if you are using taskit's Stamp9G20 CPU module on this + carrier board, beeing the decentralized unit of a building automation + system; featuring nvram, eth-switch, iso-rs485, display, io + +config MACH_GSIA18S + bool "GS_IA18_S board" + help + This enables support for the GS_IA18_S board + produced by GeoSIG Ltd company. This is an internet accelerograph. + <http://www.geosig.com> +endif + +if (ARCH_AT91SAM9260 || ARCH_AT91SAM9G20) +comment "AT91SAM9260/AT91SAM9G20 boards" + +config MACH_SNAPPER_9260 + bool "Bluewater Systems Snapper 9260/9G20 module" + help + Select this if you are using the Bluewater Systems Snapper 9260 or + Snapper 9G20 modules. + <http://www.bluewatersys.com/> +endif + +# ---------------------------------------------------------- + +if ARCH_AT91SAM9G45 + +comment "AT91SAM9G45 Board Type" + +config MACH_AT91SAM9M10G45EK + bool "Atmel AT91SAM9M10G45-EK Evaluation Kits" + help + Select this if you are using Atmel's AT91SAM9G45-EKES Evaluation Kit. + "ES" at the end of the name means that this board is an + Engineering Sample. + +endif + +# ---------------------------------------------------------- + +if ARCH_AT91CAP9 + +comment "AT91CAP9 Board Type" + +config MACH_AT91CAP9ADK + bool "Atmel AT91CAP9A-DK Evaluation Kit" + select HAVE_AT91_DATAFLASH_CARD + help + Select this if you are using Atmel's AT91CAP9A-DK Evaluation Kit. + <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4138> + +endif + +# ---------------------------------------------------------- + +if ARCH_AT91X40 + +comment "AT91X40 Board Type" + +config MACH_AT91EB01 + bool "Atmel AT91EB01 Evaluation Kit" + help + Select this if you are using Atmel's AT91EB01 Evaluation Kit. + It is also a popular target for simulators such as GDB's + ARM simulator (commonly known as the ARMulator) and the + Skyeye simulator. + +endif + +# ---------------------------------------------------------- + +comment "AT91 Board Options" + +config MTD_AT91_DATAFLASH_CARD + bool "Enable DataFlash Card support" + depends on HAVE_AT91_DATAFLASH_CARD + help + Enable support for the DataFlash card. + +# ---------------------------------------------------------- + +comment "AT91 Feature Selections" + +config AT91_PROGRAMMABLE_CLOCKS + bool "Programmable Clocks" + help + Select this if you need to program one or more of the PCK0..PCK3 + programmable clock outputs. + +config AT91_SLOW_CLOCK + bool "Suspend-to-RAM disables main oscillator" + depends on SUSPEND + help + Select this if you want Suspend-to-RAM to save the most power + possible (without powering off the CPU) by disabling the PLLs + and main oscillator so that only the 32 KiHz clock is available. + + When only that slow-clock is available, some peripherals lose + functionality. Many can't issue wakeup events unless faster + clocks are available. Some lose their operating state and + need to be completely re-initialized. + +config AT91_TIMER_HZ + int "Kernel HZ (jiffies per second)" + range 32 1024 + depends on ARCH_AT91 + default "128" if ARCH_AT91RM9200 + default "100" + help + On AT91rm9200 chips where you're using a system clock derived + from the 32768 Hz hardware clock, this tick rate should divide + it exactly: use a power-of-two value, such as 128 or 256, to + reduce timing errors caused by rounding. + + On AT91sam926x chips, or otherwise when using a higher precision + system clock (of at least several MHz), rounding is less of a + problem so it can be safer to use a decimal values like 100. + +choice + prompt "Select a UART for early kernel messages" + +config AT91_EARLY_DBGU + bool "DBGU" + +config AT91_EARLY_USART0 + bool "USART0" + +config AT91_EARLY_USART1 + bool "USART1" + +config AT91_EARLY_USART2 + bool "USART2" + depends on ! ARCH_AT91X40 + +config AT91_EARLY_USART3 + bool "USART3" + depends on HAVE_AT91_USART3 + +config AT91_EARLY_USART4 + bool "USART4" + depends on HAVE_AT91_USART4 + +config AT91_EARLY_USART5 + bool "USART5" + depends on HAVE_AT91_USART5 + +endchoice + +endmenu + +endif diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile new file mode 100644 index 00000000..96966231 --- /dev/null +++ b/arch/arm/mach-at91/Makefile @@ -0,0 +1,93 @@ +# +# Makefile for the linux kernel. +# + +obj-y := irq.o gpio.o +obj-m := +obj-n := +obj- := + +obj-$(CONFIG_AT91_PMC_UNIT) += clock.o + +# CPU-specific support +obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devices.o +obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o at91sam9_alt_reset.o +obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o at91sam9_alt_reset.o +obj-$(CONFIG_ARCH_AT91SAM9G10) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o at91sam9_alt_reset.o +obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o sam9_smc.o at91sam9_alt_reset.o +obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o at91sam9_alt_reset.o +obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o at91sam9_alt_reset.o +obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o +obj-$(CONFIG_ARCH_AT91CAP9) += at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o +obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o + +# AT91RM9200 board-specific support +obj-$(CONFIG_MACH_ONEARM) += board-1arm.o +obj-$(CONFIG_ARCH_AT91RM9200DK) += board-rm9200dk.o +obj-$(CONFIG_MACH_AT91RM9200EK) += board-rm9200ek.o +obj-$(CONFIG_MACH_CSB337) += board-csb337.o +obj-$(CONFIG_MACH_CSB637) += board-csb637.o +obj-$(CONFIG_MACH_CARMEVA) += board-carmeva.o +obj-$(CONFIG_MACH_KB9200) += board-kb9202.o +obj-$(CONFIG_MACH_ATEB9200) += board-eb9200.o +obj-$(CONFIG_MACH_KAFA) += board-kafa.o +obj-$(CONFIG_MACH_PICOTUX2XX) += board-picotux200.o +obj-$(CONFIG_MACH_ECBAT91) += board-ecbat91.o +obj-$(CONFIG_MACH_YL9200) += board-yl-9200.o +obj-$(CONFIG_MACH_CPUAT91) += board-cpuat91.o +obj-$(CONFIG_MACH_ECO920) += board-eco920.o + +# AT91SAM9260 board-specific support +obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o +obj-$(CONFIG_MACH_CAM60) += board-cam60.o +obj-$(CONFIG_MACH_SAM9_L9260) += board-sam9-l9260.o +obj-$(CONFIG_MACH_USB_A9260) += board-usb-a9260.o +obj-$(CONFIG_MACH_QIL_A9260) += board-qil-a9260.o +obj-$(CONFIG_MACH_AFEB9260) += board-afeb-9260v1.o +obj-$(CONFIG_MACH_CPU9260) += board-cpu9krea.o +obj-$(CONFIG_MACH_FLEXIBITY) += board-flexibity.o + +# AT91SAM9261 board-specific support +obj-$(CONFIG_MACH_AT91SAM9261EK) += board-sam9261ek.o +obj-$(CONFIG_MACH_AT91SAM9G10EK) += board-sam9261ek.o + +# AT91SAM9263 board-specific support +obj-$(CONFIG_MACH_AT91SAM9263EK) += board-sam9263ek.o +obj-$(CONFIG_MACH_USB_A9263) += board-usb-a9263.o +obj-$(CONFIG_MACH_NEOCORE926) += board-neocore926.o + +# AT91SAM9RL board-specific support +obj-$(CONFIG_MACH_AT91SAM9RLEK) += board-sam9rlek.o + +# AT91SAM9G20 board-specific support +obj-$(CONFIG_MACH_AT91SAM9G20EK) += board-sam9g20ek.o +obj-$(CONFIG_MACH_CPU9G20) += board-cpu9krea.o +obj-$(CONFIG_MACH_ACMENETUSFOXG20) += board-foxg20.o +obj-$(CONFIG_MACH_STAMP9G20) += board-stamp9g20.o +obj-$(CONFIG_MACH_PORTUXG20) += board-stamp9g20.o +obj-$(CONFIG_MACH_PCONTROL_G20) += board-pcontrol-g20.o board-stamp9g20.o +obj-$(CONFIG_MACH_GSIA18S) += board-gsia18s.o board-stamp9g20.o + +# AT91SAM9260/AT91SAM9G20 board-specific support +obj-$(CONFIG_MACH_SNAPPER_9260) += board-snapper9260.o + +# AT91SAM9G45 board-specific support +obj-$(CONFIG_MACH_AT91SAM9M10G45EK) += board-sam9m10g45ek.o + +# AT91CAP9 board-specific support +obj-$(CONFIG_MACH_AT91CAP9ADK) += board-cap9adk.o + +# AT91X40 board-specific support +obj-$(CONFIG_MACH_AT91EB01) += board-eb01.o + +# Drivers +obj-y += leds.o + +# Power Management +obj-$(CONFIG_PM) += pm.o +obj-$(CONFIG_AT91_SLOW_CLOCK) += pm_slowclock.o +obj-$(CONFIG_CPU_IDLE) += cpuidle.o + +ifeq ($(CONFIG_PM_DEBUG),y) +CFLAGS_pm.o += -DDEBUG +endif diff --git a/arch/arm/mach-at91/Makefile.boot b/arch/arm/mach-at91/Makefile.boot new file mode 100644 index 00000000..3462b815 --- /dev/null +++ b/arch/arm/mach-at91/Makefile.boot @@ -0,0 +1,18 @@ +# Note: the following conditions must always be true: +# ZRELADDR == virt_to_phys(TEXTADDR) +# PARAMS_PHYS must be within 4MB of ZRELADDR +# INITRD_PHYS must be in RAM + +ifeq ($(CONFIG_ARCH_AT91CAP9),y) + zreladdr-y := 0x70008000 +params_phys-y := 0x70000100 +initrd_phys-y := 0x70410000 +else ifeq ($(CONFIG_ARCH_AT91SAM9G45),y) + zreladdr-y := 0x70008000 +params_phys-y := 0x70000100 +initrd_phys-y := 0x70410000 +else + zreladdr-y := 0x20008000 +params_phys-y := 0x20000100 +initrd_phys-y := 0x20410000 +endif diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c new file mode 100644 index 00000000..f1013d08 --- /dev/null +++ b/arch/arm/mach-at91/at91cap9.c @@ -0,0 +1,422 @@ +/* + * arch/arm/mach-at91/at91cap9.c + * + * Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com> + * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com> + * Copyright (C) 2007 Atmel Corporation. + * + * 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. + * + */ + +#include <linux/module.h> +#include <linux/pm.h> + +#include <asm/irq.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <mach/cpu.h> +#include <mach/at91cap9.h> +#include <mach/at91_pmc.h> +#include <mach/at91_rstc.h> +#include <mach/at91_shdwc.h> + +#include "generic.h" +#include "clock.h" + +static struct map_desc at91cap9_io_desc[] __initdata = { + { + .virtual = AT91_VA_BASE_SYS, + .pfn = __phys_to_pfn(AT91_BASE_SYS), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = AT91_IO_VIRT_BASE - AT91CAP9_SRAM_SIZE, + .pfn = __phys_to_pfn(AT91CAP9_SRAM_BASE), + .length = AT91CAP9_SRAM_SIZE, + .type = MT_DEVICE, + }, +}; + +/* -------------------------------------------------------------------- + * Clocks + * -------------------------------------------------------------------- */ + +/* + * The peripheral clocks. + */ +static struct clk pioABCD_clk = { + .name = "pioABCD_clk", + .pmc_mask = 1 << AT91CAP9_ID_PIOABCD, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk mpb0_clk = { + .name = "mpb0_clk", + .pmc_mask = 1 << AT91CAP9_ID_MPB0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk mpb1_clk = { + .name = "mpb1_clk", + .pmc_mask = 1 << AT91CAP9_ID_MPB1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk mpb2_clk = { + .name = "mpb2_clk", + .pmc_mask = 1 << AT91CAP9_ID_MPB2, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk mpb3_clk = { + .name = "mpb3_clk", + .pmc_mask = 1 << AT91CAP9_ID_MPB3, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk mpb4_clk = { + .name = "mpb4_clk", + .pmc_mask = 1 << AT91CAP9_ID_MPB4, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart0_clk = { + .name = "usart0_clk", + .pmc_mask = 1 << AT91CAP9_ID_US0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart1_clk = { + .name = "usart1_clk", + .pmc_mask = 1 << AT91CAP9_ID_US1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart2_clk = { + .name = "usart2_clk", + .pmc_mask = 1 << AT91CAP9_ID_US2, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk mmc0_clk = { + .name = "mci0_clk", + .pmc_mask = 1 << AT91CAP9_ID_MCI0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk mmc1_clk = { + .name = "mci1_clk", + .pmc_mask = 1 << AT91CAP9_ID_MCI1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk can_clk = { + .name = "can_clk", + .pmc_mask = 1 << AT91CAP9_ID_CAN, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk twi_clk = { + .name = "twi_clk", + .pmc_mask = 1 << AT91CAP9_ID_TWI, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk spi0_clk = { + .name = "spi0_clk", + .pmc_mask = 1 << AT91CAP9_ID_SPI0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk spi1_clk = { + .name = "spi1_clk", + .pmc_mask = 1 << AT91CAP9_ID_SPI1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ssc0_clk = { + .name = "ssc0_clk", + .pmc_mask = 1 << AT91CAP9_ID_SSC0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ssc1_clk = { + .name = "ssc1_clk", + .pmc_mask = 1 << AT91CAP9_ID_SSC1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ac97_clk = { + .name = "ac97_clk", + .pmc_mask = 1 << AT91CAP9_ID_AC97C, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk tcb_clk = { + .name = "tcb_clk", + .pmc_mask = 1 << AT91CAP9_ID_TCB, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pwm_clk = { + .name = "pwm_clk", + .pmc_mask = 1 << AT91CAP9_ID_PWMC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk macb_clk = { + .name = "macb_clk", + .pmc_mask = 1 << AT91CAP9_ID_EMAC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk aestdes_clk = { + .name = "aestdes_clk", + .pmc_mask = 1 << AT91CAP9_ID_AESTDES, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk adc_clk = { + .name = "adc_clk", + .pmc_mask = 1 << AT91CAP9_ID_ADC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk isi_clk = { + .name = "isi_clk", + .pmc_mask = 1 << AT91CAP9_ID_ISI, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk lcdc_clk = { + .name = "lcdc_clk", + .pmc_mask = 1 << AT91CAP9_ID_LCDC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk dma_clk = { + .name = "dma_clk", + .pmc_mask = 1 << AT91CAP9_ID_DMA, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk udphs_clk = { + .name = "udphs_clk", + .pmc_mask = 1 << AT91CAP9_ID_UDPHS, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ohci_clk = { + .name = "ohci_clk", + .pmc_mask = 1 << AT91CAP9_ID_UHP, + .type = CLK_TYPE_PERIPHERAL, +}; + +static struct clk *periph_clocks[] __initdata = { + &pioABCD_clk, + &mpb0_clk, + &mpb1_clk, + &mpb2_clk, + &mpb3_clk, + &mpb4_clk, + &usart0_clk, + &usart1_clk, + &usart2_clk, + &mmc0_clk, + &mmc1_clk, + &can_clk, + &twi_clk, + &spi0_clk, + &spi1_clk, + &ssc0_clk, + &ssc1_clk, + &ac97_clk, + &tcb_clk, + &pwm_clk, + &macb_clk, + &aestdes_clk, + &adc_clk, + &isi_clk, + &lcdc_clk, + &dma_clk, + &udphs_clk, + &ohci_clk, + // irq0 .. irq1 +}; + +static struct clk_lookup periph_clocks_lookups[] = { + CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk), + CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk), + CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.0", &mmc0_clk), + CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.1", &mmc1_clk), + CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), + CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), + CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb_clk), + CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), + CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), +}; + +static struct clk_lookup usart_clocks_lookups[] = { + CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck), + CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk), + CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk), + CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk), +}; + +/* + * The four programmable clocks. + * You must configure pin multiplexing to bring these signals out. + */ +static struct clk pck0 = { + .name = "pck0", + .pmc_mask = AT91_PMC_PCK0, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 0, +}; +static struct clk pck1 = { + .name = "pck1", + .pmc_mask = AT91_PMC_PCK1, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 1, +}; +static struct clk pck2 = { + .name = "pck2", + .pmc_mask = AT91_PMC_PCK2, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 2, +}; +static struct clk pck3 = { + .name = "pck3", + .pmc_mask = AT91_PMC_PCK3, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 3, +}; + +static void __init at91cap9_register_clocks(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) + clk_register(periph_clocks[i]); + + clkdev_add_table(periph_clocks_lookups, + ARRAY_SIZE(periph_clocks_lookups)); + clkdev_add_table(usart_clocks_lookups, + ARRAY_SIZE(usart_clocks_lookups)); + + clk_register(&pck0); + clk_register(&pck1); + clk_register(&pck2); + clk_register(&pck3); +} + +static struct clk_lookup console_clock_lookup; + +void __init at91cap9_set_console_clock(int id) +{ + if (id >= ARRAY_SIZE(usart_clocks_lookups)) + return; + + console_clock_lookup.con_id = "usart"; + console_clock_lookup.clk = usart_clocks_lookups[id].clk; + clkdev_add(&console_clock_lookup); +} + +/* -------------------------------------------------------------------- + * GPIO + * -------------------------------------------------------------------- */ + +static struct at91_gpio_bank at91cap9_gpio[] = { + { + .id = AT91CAP9_ID_PIOABCD, + .offset = AT91_PIOA, + .clock = &pioABCD_clk, + }, { + .id = AT91CAP9_ID_PIOABCD, + .offset = AT91_PIOB, + .clock = &pioABCD_clk, + }, { + .id = AT91CAP9_ID_PIOABCD, + .offset = AT91_PIOC, + .clock = &pioABCD_clk, + }, { + .id = AT91CAP9_ID_PIOABCD, + .offset = AT91_PIOD, + .clock = &pioABCD_clk, + } +}; + +static void at91cap9_reset(void) +{ + at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST); +} + +static void at91cap9_poweroff(void) +{ + at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW); +} + + +/* -------------------------------------------------------------------- + * AT91CAP9 processor initialization + * -------------------------------------------------------------------- */ + +void __init at91cap9_map_io(void) +{ + /* Map peripherals */ + iotable_init(at91cap9_io_desc, ARRAY_SIZE(at91cap9_io_desc)); +} + +void __init at91cap9_initialize(unsigned long main_clock) +{ + at91_arch_reset = at91cap9_reset; + pm_power_off = at91cap9_poweroff; + at91_extern_irq = (1 << AT91CAP9_ID_IRQ0) | (1 << AT91CAP9_ID_IRQ1); + + /* Init clock subsystem */ + at91_clock_init(main_clock); + + /* Register the processor-specific clocks */ + at91cap9_register_clocks(); + + /* Register GPIO subsystem */ + at91_gpio_init(at91cap9_gpio, 4); + + /* Remember the silicon revision */ + if (cpu_is_at91cap9_revB()) + system_rev = 0xB; + else if (cpu_is_at91cap9_revC()) + system_rev = 0xC; +} + +/* -------------------------------------------------------------------- + * Interrupt initialization + * -------------------------------------------------------------------- */ + +/* + * The default interrupt priority levels (0 = lowest, 7 = highest). + */ +static unsigned int at91cap9_default_irq_priority[NR_AIC_IRQS] __initdata = { + 7, /* Advanced Interrupt Controller (FIQ) */ + 7, /* System Peripherals */ + 1, /* Parallel IO Controller A, B, C and D */ + 0, /* MP Block Peripheral 0 */ + 0, /* MP Block Peripheral 1 */ + 0, /* MP Block Peripheral 2 */ + 0, /* MP Block Peripheral 3 */ + 0, /* MP Block Peripheral 4 */ + 5, /* USART 0 */ + 5, /* USART 1 */ + 5, /* USART 2 */ + 0, /* Multimedia Card Interface 0 */ + 0, /* Multimedia Card Interface 1 */ + 3, /* CAN */ + 6, /* Two-Wire Interface */ + 5, /* Serial Peripheral Interface 0 */ + 5, /* Serial Peripheral Interface 1 */ + 4, /* Serial Synchronous Controller 0 */ + 4, /* Serial Synchronous Controller 1 */ + 5, /* AC97 Controller */ + 0, /* Timer Counter 0, 1 and 2 */ + 0, /* Pulse Width Modulation Controller */ + 3, /* Ethernet */ + 0, /* Advanced Encryption Standard, Triple DES*/ + 0, /* Analog-to-Digital Converter */ + 0, /* Image Sensor Interface */ + 3, /* LCD Controller */ + 0, /* DMA Controller */ + 2, /* USB Device Port */ + 2, /* USB Host port */ + 0, /* Advanced Interrupt Controller (IRQ0) */ + 0, /* Advanced Interrupt Controller (IRQ1) */ +}; + +void __init at91cap9_init_interrupts(unsigned int priority[NR_AIC_IRQS]) +{ + if (!priority) + priority = at91cap9_default_irq_priority; + + /* Initialize the AIC interrupt controller */ + at91_aic_init(priority); + + /* Enable GPIO interrupts */ + at91_gpio_irq_setup(); +} diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c new file mode 100644 index 00000000..dba0d8d8 --- /dev/null +++ b/arch/arm/mach-at91/at91cap9_devices.c @@ -0,0 +1,1259 @@ +/* + * arch/arm/mach-at91/at91cap9_devices.c + * + * Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com> + * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com> + * Copyright (C) 2007 Atmel Corporation. + * + * 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. + * + */ +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <linux/dma-mapping.h> +#include <linux/platform_device.h> +#include <linux/i2c-gpio.h> + +#include <video/atmel_lcdc.h> + +#include <mach/board.h> +#include <mach/cpu.h> +#include <mach/gpio.h> +#include <mach/at91cap9.h> +#include <mach/at91cap9_matrix.h> +#include <mach/at91sam9_smc.h> + +#include "generic.h" + + +/* -------------------------------------------------------------------- + * USB Host + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) +static u64 ohci_dmamask = DMA_BIT_MASK(32); +static struct at91_usbh_data usbh_data; + +static struct resource usbh_resources[] = { + [0] = { + .start = AT91CAP9_UHP_BASE, + .end = AT91CAP9_UHP_BASE + SZ_1M - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91CAP9_ID_UHP, + .end = AT91CAP9_ID_UHP, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91_usbh_device = { + .name = "at91_ohci", + .id = -1, + .dev = { + .dma_mask = &ohci_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &usbh_data, + }, + .resource = usbh_resources, + .num_resources = ARRAY_SIZE(usbh_resources), +}; + +void __init at91_add_device_usbh(struct at91_usbh_data *data) +{ + int i; + + if (!data) + return; + + if (cpu_is_at91cap9_revB()) + irq_set_irq_type(AT91CAP9_ID_UHP, IRQ_TYPE_LEVEL_HIGH); + + /* Enable VBus control for UHP ports */ + for (i = 0; i < data->ports; i++) { + if (data->vbus_pin[i]) + at91_set_gpio_output(data->vbus_pin[i], 0); + } + + usbh_data = *data; + platform_device_register(&at91_usbh_device); +} +#else +void __init at91_add_device_usbh(struct at91_usbh_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * USB HS Device (Gadget) + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_USB_GADGET_ATMEL_USBA) || defined(CONFIG_USB_GADGET_ATMEL_USBA_MODULE) + +static struct resource usba_udc_resources[] = { + [0] = { + .start = AT91CAP9_UDPHS_FIFO, + .end = AT91CAP9_UDPHS_FIFO + SZ_512K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91CAP9_BASE_UDPHS, + .end = AT91CAP9_BASE_UDPHS + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = AT91CAP9_ID_UDPHS, + .end = AT91CAP9_ID_UDPHS, + .flags = IORESOURCE_IRQ, + }, +}; + +#define EP(nam, idx, maxpkt, maxbk, dma, isoc) \ + [idx] = { \ + .name = nam, \ + .index = idx, \ + .fifo_size = maxpkt, \ + .nr_banks = maxbk, \ + .can_dma = dma, \ + .can_isoc = isoc, \ + } + +static struct usba_ep_data usba_udc_ep[] = { + EP("ep0", 0, 64, 1, 0, 0), + EP("ep1", 1, 1024, 3, 1, 1), + EP("ep2", 2, 1024, 3, 1, 1), + EP("ep3", 3, 1024, 2, 1, 1), + EP("ep4", 4, 1024, 2, 1, 1), + EP("ep5", 5, 1024, 2, 1, 0), + EP("ep6", 6, 1024, 2, 1, 0), + EP("ep7", 7, 1024, 2, 0, 0), +}; + +#undef EP + +/* + * pdata doesn't have room for any endpoints, so we need to + * append room for the ones we need right after it. + */ +static struct { + struct usba_platform_data pdata; + struct usba_ep_data ep[8]; +} usba_udc_data; + +static struct platform_device at91_usba_udc_device = { + .name = "atmel_usba_udc", + .id = -1, + .dev = { + .platform_data = &usba_udc_data.pdata, + }, + .resource = usba_udc_resources, + .num_resources = ARRAY_SIZE(usba_udc_resources), +}; + +void __init at91_add_device_usba(struct usba_platform_data *data) +{ + if (cpu_is_at91cap9_revB()) { + irq_set_irq_type(AT91CAP9_ID_UDPHS, IRQ_TYPE_LEVEL_HIGH); + at91_sys_write(AT91_MATRIX_UDPHS, AT91_MATRIX_SELECT_UDPHS | + AT91_MATRIX_UDPHS_BYPASS_LOCK); + } + else + at91_sys_write(AT91_MATRIX_UDPHS, AT91_MATRIX_SELECT_UDPHS); + + /* + * Invalid pins are 0 on AT91, but the usba driver is shared + * with AVR32, which use negative values instead. Once/if + * gpio_is_valid() is ported to AT91, revisit this code. + */ + usba_udc_data.pdata.vbus_pin = -EINVAL; + usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep); + memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep)); + + if (data && data->vbus_pin > 0) { + at91_set_gpio_input(data->vbus_pin, 0); + at91_set_deglitch(data->vbus_pin, 1); + usba_udc_data.pdata.vbus_pin = data->vbus_pin; + } + + /* Pullup pin is handled internally by USB device peripheral */ + + platform_device_register(&at91_usba_udc_device); +} +#else +void __init at91_add_device_usba(struct usba_platform_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * Ethernet + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) +static u64 eth_dmamask = DMA_BIT_MASK(32); +static struct at91_eth_data eth_data; + +static struct resource eth_resources[] = { + [0] = { + .start = AT91CAP9_BASE_EMAC, + .end = AT91CAP9_BASE_EMAC + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91CAP9_ID_EMAC, + .end = AT91CAP9_ID_EMAC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91cap9_eth_device = { + .name = "macb", + .id = -1, + .dev = { + .dma_mask = ð_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = ð_data, + }, + .resource = eth_resources, + .num_resources = ARRAY_SIZE(eth_resources), +}; + +void __init at91_add_device_eth(struct at91_eth_data *data) +{ + if (!data) + return; + + if (data->phy_irq_pin) { + at91_set_gpio_input(data->phy_irq_pin, 0); + at91_set_deglitch(data->phy_irq_pin, 1); + } + + /* Pins used for MII and RMII */ + at91_set_A_periph(AT91_PIN_PB21, 0); /* ETXCK_EREFCK */ + at91_set_A_periph(AT91_PIN_PB22, 0); /* ERXDV */ + at91_set_A_periph(AT91_PIN_PB25, 0); /* ERX0 */ + at91_set_A_periph(AT91_PIN_PB26, 0); /* ERX1 */ + at91_set_A_periph(AT91_PIN_PB27, 0); /* ERXER */ + at91_set_A_periph(AT91_PIN_PB28, 0); /* ETXEN */ + at91_set_A_periph(AT91_PIN_PB23, 0); /* ETX0 */ + at91_set_A_periph(AT91_PIN_PB24, 0); /* ETX1 */ + at91_set_A_periph(AT91_PIN_PB30, 0); /* EMDIO */ + at91_set_A_periph(AT91_PIN_PB29, 0); /* EMDC */ + + if (!data->is_rmii) { + at91_set_B_periph(AT91_PIN_PC25, 0); /* ECRS */ + at91_set_B_periph(AT91_PIN_PC26, 0); /* ECOL */ + at91_set_B_periph(AT91_PIN_PC22, 0); /* ERX2 */ + at91_set_B_periph(AT91_PIN_PC23, 0); /* ERX3 */ + at91_set_B_periph(AT91_PIN_PC27, 0); /* ERXCK */ + at91_set_B_periph(AT91_PIN_PC20, 0); /* ETX2 */ + at91_set_B_periph(AT91_PIN_PC21, 0); /* ETX3 */ + at91_set_B_periph(AT91_PIN_PC24, 0); /* ETXER */ + } + + eth_data = *data; + platform_device_register(&at91cap9_eth_device); +} +#else +void __init at91_add_device_eth(struct at91_eth_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * MMC / SD + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) +static u64 mmc_dmamask = DMA_BIT_MASK(32); +static struct at91_mmc_data mmc0_data, mmc1_data; + +static struct resource mmc0_resources[] = { + [0] = { + .start = AT91CAP9_BASE_MCI0, + .end = AT91CAP9_BASE_MCI0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91CAP9_ID_MCI0, + .end = AT91CAP9_ID_MCI0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91cap9_mmc0_device = { + .name = "at91_mci", + .id = 0, + .dev = { + .dma_mask = &mmc_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &mmc0_data, + }, + .resource = mmc0_resources, + .num_resources = ARRAY_SIZE(mmc0_resources), +}; + +static struct resource mmc1_resources[] = { + [0] = { + .start = AT91CAP9_BASE_MCI1, + .end = AT91CAP9_BASE_MCI1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91CAP9_ID_MCI1, + .end = AT91CAP9_ID_MCI1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91cap9_mmc1_device = { + .name = "at91_mci", + .id = 1, + .dev = { + .dma_mask = &mmc_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &mmc1_data, + }, + .resource = mmc1_resources, + .num_resources = ARRAY_SIZE(mmc1_resources), +}; + +void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) +{ + if (!data) + return; + + /* input/irq */ + if (data->det_pin) { + at91_set_gpio_input(data->det_pin, 1); + at91_set_deglitch(data->det_pin, 1); + } + if (data->wp_pin) + at91_set_gpio_input(data->wp_pin, 1); + if (data->vcc_pin) + at91_set_gpio_output(data->vcc_pin, 0); + + if (mmc_id == 0) { /* MCI0 */ + /* CLK */ + at91_set_A_periph(AT91_PIN_PA2, 0); + + /* CMD */ + at91_set_A_periph(AT91_PIN_PA1, 1); + + /* DAT0, maybe DAT1..DAT3 */ + at91_set_A_periph(AT91_PIN_PA0, 1); + if (data->wire4) { + at91_set_A_periph(AT91_PIN_PA3, 1); + at91_set_A_periph(AT91_PIN_PA4, 1); + at91_set_A_periph(AT91_PIN_PA5, 1); + } + + mmc0_data = *data; + platform_device_register(&at91cap9_mmc0_device); + } else { /* MCI1 */ + /* CLK */ + at91_set_A_periph(AT91_PIN_PA16, 0); + + /* CMD */ + at91_set_A_periph(AT91_PIN_PA17, 1); + + /* DAT0, maybe DAT1..DAT3 */ + at91_set_A_periph(AT91_PIN_PA18, 1); + if (data->wire4) { + at91_set_A_periph(AT91_PIN_PA19, 1); + at91_set_A_periph(AT91_PIN_PA20, 1); + at91_set_A_periph(AT91_PIN_PA21, 1); + } + + mmc1_data = *data; + platform_device_register(&at91cap9_mmc1_device); + } +} +#else +void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * NAND / SmartMedia + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE) +static struct atmel_nand_data nand_data; + +#define NAND_BASE AT91_CHIPSELECT_3 + +static struct resource nand_resources[] = { + [0] = { + .start = NAND_BASE, + .end = NAND_BASE + SZ_256M - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91_BASE_SYS + AT91_ECC, + .end = AT91_BASE_SYS + AT91_ECC + SZ_512 - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device at91cap9_nand_device = { + .name = "atmel_nand", + .id = -1, + .dev = { + .platform_data = &nand_data, + }, + .resource = nand_resources, + .num_resources = ARRAY_SIZE(nand_resources), +}; + +void __init at91_add_device_nand(struct atmel_nand_data *data) +{ + unsigned long csa; + + if (!data) + return; + + csa = at91_sys_read(AT91_MATRIX_EBICSA); + at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA); + + /* enable pin */ + if (data->enable_pin) + at91_set_gpio_output(data->enable_pin, 1); + + /* ready/busy pin */ + if (data->rdy_pin) + at91_set_gpio_input(data->rdy_pin, 1); + + /* card detect pin */ + if (data->det_pin) + at91_set_gpio_input(data->det_pin, 1); + + nand_data = *data; + platform_device_register(&at91cap9_nand_device); +} +#else +void __init at91_add_device_nand(struct atmel_nand_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * TWI (i2c) + * -------------------------------------------------------------------- */ + +/* + * Prefer the GPIO code since the TWI controller isn't robust + * (gets overruns and underruns under load) and can only issue + * repeated STARTs in one scenario (the driver doesn't yet handle them). + */ +#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) + +static struct i2c_gpio_platform_data pdata = { + .sda_pin = AT91_PIN_PB4, + .sda_is_open_drain = 1, + .scl_pin = AT91_PIN_PB5, + .scl_is_open_drain = 1, + .udelay = 2, /* ~100 kHz */ +}; + +static struct platform_device at91cap9_twi_device = { + .name = "i2c-gpio", + .id = -1, + .dev.platform_data = &pdata, +}; + +void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) +{ + at91_set_GPIO_periph(AT91_PIN_PB4, 1); /* TWD (SDA) */ + at91_set_multi_drive(AT91_PIN_PB4, 1); + + at91_set_GPIO_periph(AT91_PIN_PB5, 1); /* TWCK (SCL) */ + at91_set_multi_drive(AT91_PIN_PB5, 1); + + i2c_register_board_info(0, devices, nr_devices); + platform_device_register(&at91cap9_twi_device); +} + +#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) + +static struct resource twi_resources[] = { + [0] = { + .start = AT91CAP9_BASE_TWI, + .end = AT91CAP9_BASE_TWI + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91CAP9_ID_TWI, + .end = AT91CAP9_ID_TWI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91cap9_twi_device = { + .name = "at91_i2c", + .id = -1, + .resource = twi_resources, + .num_resources = ARRAY_SIZE(twi_resources), +}; + +void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) +{ + /* pins used for TWI interface */ + at91_set_B_periph(AT91_PIN_PB4, 0); /* TWD */ + at91_set_multi_drive(AT91_PIN_PB4, 1); + + at91_set_B_periph(AT91_PIN_PB5, 0); /* TWCK */ + at91_set_multi_drive(AT91_PIN_PB5, 1); + + i2c_register_board_info(0, devices, nr_devices); + platform_device_register(&at91cap9_twi_device); +} +#else +void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {} +#endif + +/* -------------------------------------------------------------------- + * SPI + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) +static u64 spi_dmamask = DMA_BIT_MASK(32); + +static struct resource spi0_resources[] = { + [0] = { + .start = AT91CAP9_BASE_SPI0, + .end = AT91CAP9_BASE_SPI0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91CAP9_ID_SPI0, + .end = AT91CAP9_ID_SPI0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91cap9_spi0_device = { + .name = "atmel_spi", + .id = 0, + .dev = { + .dma_mask = &spi_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = spi0_resources, + .num_resources = ARRAY_SIZE(spi0_resources), +}; + +static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA5, AT91_PIN_PA3, AT91_PIN_PD0, AT91_PIN_PD1 }; + +static struct resource spi1_resources[] = { + [0] = { + .start = AT91CAP9_BASE_SPI1, + .end = AT91CAP9_BASE_SPI1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91CAP9_ID_SPI1, + .end = AT91CAP9_ID_SPI1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91cap9_spi1_device = { + .name = "atmel_spi", + .id = 1, + .dev = { + .dma_mask = &spi_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = spi1_resources, + .num_resources = ARRAY_SIZE(spi1_resources), +}; + +static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB15, AT91_PIN_PB16, AT91_PIN_PB17, AT91_PIN_PB18 }; + +void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) +{ + int i; + unsigned long cs_pin; + short enable_spi0 = 0; + short enable_spi1 = 0; + + /* Choose SPI chip-selects */ + for (i = 0; i < nr_devices; i++) { + if (devices[i].controller_data) + cs_pin = (unsigned long) devices[i].controller_data; + else if (devices[i].bus_num == 0) + cs_pin = spi0_standard_cs[devices[i].chip_select]; + else + cs_pin = spi1_standard_cs[devices[i].chip_select]; + + if (devices[i].bus_num == 0) + enable_spi0 = 1; + else + enable_spi1 = 1; + + /* enable chip-select pin */ + at91_set_gpio_output(cs_pin, 1); + + /* pass chip-select pin to driver */ + devices[i].controller_data = (void *) cs_pin; + } + + spi_register_board_info(devices, nr_devices); + + /* Configure SPI bus(es) */ + if (enable_spi0) { + at91_set_B_periph(AT91_PIN_PA0, 0); /* SPI0_MISO */ + at91_set_B_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */ + at91_set_B_periph(AT91_PIN_PA2, 0); /* SPI0_SPCK */ + + platform_device_register(&at91cap9_spi0_device); + } + if (enable_spi1) { + at91_set_A_periph(AT91_PIN_PB12, 0); /* SPI1_MISO */ + at91_set_A_periph(AT91_PIN_PB13, 0); /* SPI1_MOSI */ + at91_set_A_periph(AT91_PIN_PB14, 0); /* SPI1_SPCK */ + + platform_device_register(&at91cap9_spi1_device); + } +} +#else +void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {} +#endif + + +/* -------------------------------------------------------------------- + * Timer/Counter block + * -------------------------------------------------------------------- */ + +#ifdef CONFIG_ATMEL_TCLIB + +static struct resource tcb_resources[] = { + [0] = { + .start = AT91CAP9_BASE_TCB0, + .end = AT91CAP9_BASE_TCB0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91CAP9_ID_TCB, + .end = AT91CAP9_ID_TCB, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91cap9_tcb_device = { + .name = "atmel_tcb", + .id = 0, + .resource = tcb_resources, + .num_resources = ARRAY_SIZE(tcb_resources), +}; + +static void __init at91_add_device_tc(void) +{ + platform_device_register(&at91cap9_tcb_device); +} +#else +static void __init at91_add_device_tc(void) { } +#endif + + +/* -------------------------------------------------------------------- + * RTT + * -------------------------------------------------------------------- */ + +static struct resource rtt_resources[] = { + { + .start = AT91_BASE_SYS + AT91_RTT, + .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device at91cap9_rtt_device = { + .name = "at91_rtt", + .id = 0, + .resource = rtt_resources, + .num_resources = ARRAY_SIZE(rtt_resources), +}; + +static void __init at91_add_device_rtt(void) +{ + platform_device_register(&at91cap9_rtt_device); +} + + +/* -------------------------------------------------------------------- + * Watchdog + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) +static struct platform_device at91cap9_wdt_device = { + .name = "at91_wdt", + .id = -1, + .num_resources = 0, +}; + +static void __init at91_add_device_watchdog(void) +{ + platform_device_register(&at91cap9_wdt_device); +} +#else +static void __init at91_add_device_watchdog(void) {} +#endif + + +/* -------------------------------------------------------------------- + * PWM + * --------------------------------------------------------------------*/ + +#if defined(CONFIG_ATMEL_PWM) +static u32 pwm_mask; + +static struct resource pwm_resources[] = { + [0] = { + .start = AT91CAP9_BASE_PWMC, + .end = AT91CAP9_BASE_PWMC + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91CAP9_ID_PWMC, + .end = AT91CAP9_ID_PWMC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91cap9_pwm0_device = { + .name = "atmel_pwm", + .id = -1, + .dev = { + .platform_data = &pwm_mask, + }, + .resource = pwm_resources, + .num_resources = ARRAY_SIZE(pwm_resources), +}; + +void __init at91_add_device_pwm(u32 mask) +{ + if (mask & (1 << AT91_PWM0)) + at91_set_A_periph(AT91_PIN_PB19, 1); /* enable PWM0 */ + + if (mask & (1 << AT91_PWM1)) + at91_set_B_periph(AT91_PIN_PB8, 1); /* enable PWM1 */ + + if (mask & (1 << AT91_PWM2)) + at91_set_B_periph(AT91_PIN_PC29, 1); /* enable PWM2 */ + + if (mask & (1 << AT91_PWM3)) + at91_set_B_periph(AT91_PIN_PA11, 1); /* enable PWM3 */ + + pwm_mask = mask; + + platform_device_register(&at91cap9_pwm0_device); +} +#else +void __init at91_add_device_pwm(u32 mask) {} +#endif + + + +/* -------------------------------------------------------------------- + * AC97 + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_SND_ATMEL_AC97C) || defined(CONFIG_SND_ATMEL_AC97C_MODULE) +static u64 ac97_dmamask = DMA_BIT_MASK(32); +static struct ac97c_platform_data ac97_data; + +static struct resource ac97_resources[] = { + [0] = { + .start = AT91CAP9_BASE_AC97C, + .end = AT91CAP9_BASE_AC97C + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91CAP9_ID_AC97C, + .end = AT91CAP9_ID_AC97C, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91cap9_ac97_device = { + .name = "atmel_ac97c", + .id = 1, + .dev = { + .dma_mask = &ac97_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &ac97_data, + }, + .resource = ac97_resources, + .num_resources = ARRAY_SIZE(ac97_resources), +}; + +void __init at91_add_device_ac97(struct ac97c_platform_data *data) +{ + if (!data) + return; + + at91_set_A_periph(AT91_PIN_PA6, 0); /* AC97FS */ + at91_set_A_periph(AT91_PIN_PA7, 0); /* AC97CK */ + at91_set_A_periph(AT91_PIN_PA8, 0); /* AC97TX */ + at91_set_A_periph(AT91_PIN_PA9, 0); /* AC97RX */ + + /* reset */ + if (data->reset_pin) + at91_set_gpio_output(data->reset_pin, 0); + + ac97_data = *data; + platform_device_register(&at91cap9_ac97_device); +} +#else +void __init at91_add_device_ac97(struct ac97c_platform_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * LCD Controller + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) +static u64 lcdc_dmamask = DMA_BIT_MASK(32); +static struct atmel_lcdfb_info lcdc_data; + +static struct resource lcdc_resources[] = { + [0] = { + .start = AT91CAP9_LCDC_BASE, + .end = AT91CAP9_LCDC_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91CAP9_ID_LCDC, + .end = AT91CAP9_ID_LCDC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91_lcdc_device = { + .name = "atmel_lcdfb", + .id = 0, + .dev = { + .dma_mask = &lcdc_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &lcdc_data, + }, + .resource = lcdc_resources, + .num_resources = ARRAY_SIZE(lcdc_resources), +}; + +void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) +{ + if (!data) + return; + + if (cpu_is_at91cap9_revB()) + irq_set_irq_type(AT91CAP9_ID_LCDC, IRQ_TYPE_LEVEL_HIGH); + + at91_set_A_periph(AT91_PIN_PC1, 0); /* LCDHSYNC */ + at91_set_A_periph(AT91_PIN_PC2, 0); /* LCDDOTCK */ + at91_set_A_periph(AT91_PIN_PC3, 0); /* LCDDEN */ + at91_set_B_periph(AT91_PIN_PB9, 0); /* LCDCC */ + at91_set_A_periph(AT91_PIN_PC6, 0); /* LCDD2 */ + at91_set_A_periph(AT91_PIN_PC7, 0); /* LCDD3 */ + at91_set_A_periph(AT91_PIN_PC8, 0); /* LCDD4 */ + at91_set_A_periph(AT91_PIN_PC9, 0); /* LCDD5 */ + at91_set_A_periph(AT91_PIN_PC10, 0); /* LCDD6 */ + at91_set_A_periph(AT91_PIN_PC11, 0); /* LCDD7 */ + at91_set_A_periph(AT91_PIN_PC14, 0); /* LCDD10 */ + at91_set_A_periph(AT91_PIN_PC15, 0); /* LCDD11 */ + at91_set_A_periph(AT91_PIN_PC16, 0); /* LCDD12 */ + at91_set_A_periph(AT91_PIN_PC17, 0); /* LCDD13 */ + at91_set_A_periph(AT91_PIN_PC18, 0); /* LCDD14 */ + at91_set_A_periph(AT91_PIN_PC19, 0); /* LCDD15 */ + at91_set_A_periph(AT91_PIN_PC22, 0); /* LCDD18 */ + at91_set_A_periph(AT91_PIN_PC23, 0); /* LCDD19 */ + at91_set_A_periph(AT91_PIN_PC24, 0); /* LCDD20 */ + at91_set_A_periph(AT91_PIN_PC25, 0); /* LCDD21 */ + at91_set_A_periph(AT91_PIN_PC26, 0); /* LCDD22 */ + at91_set_A_periph(AT91_PIN_PC27, 0); /* LCDD23 */ + + lcdc_data = *data; + platform_device_register(&at91_lcdc_device); +} +#else +void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {} +#endif + + +/* -------------------------------------------------------------------- + * SSC -- Synchronous Serial Controller + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE) +static u64 ssc0_dmamask = DMA_BIT_MASK(32); + +static struct resource ssc0_resources[] = { + [0] = { + .start = AT91CAP9_BASE_SSC0, + .end = AT91CAP9_BASE_SSC0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91CAP9_ID_SSC0, + .end = AT91CAP9_ID_SSC0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91cap9_ssc0_device = { + .name = "ssc", + .id = 0, + .dev = { + .dma_mask = &ssc0_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = ssc0_resources, + .num_resources = ARRAY_SIZE(ssc0_resources), +}; + +static inline void configure_ssc0_pins(unsigned pins) +{ + if (pins & ATMEL_SSC_TF) + at91_set_A_periph(AT91_PIN_PB0, 1); + if (pins & ATMEL_SSC_TK) + at91_set_A_periph(AT91_PIN_PB1, 1); + if (pins & ATMEL_SSC_TD) + at91_set_A_periph(AT91_PIN_PB2, 1); + if (pins & ATMEL_SSC_RD) + at91_set_A_periph(AT91_PIN_PB3, 1); + if (pins & ATMEL_SSC_RK) + at91_set_A_periph(AT91_PIN_PB4, 1); + if (pins & ATMEL_SSC_RF) + at91_set_A_periph(AT91_PIN_PB5, 1); +} + +static u64 ssc1_dmamask = DMA_BIT_MASK(32); + +static struct resource ssc1_resources[] = { + [0] = { + .start = AT91CAP9_BASE_SSC1, + .end = AT91CAP9_BASE_SSC1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91CAP9_ID_SSC1, + .end = AT91CAP9_ID_SSC1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91cap9_ssc1_device = { + .name = "ssc", + .id = 1, + .dev = { + .dma_mask = &ssc1_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = ssc1_resources, + .num_resources = ARRAY_SIZE(ssc1_resources), +}; + +static inline void configure_ssc1_pins(unsigned pins) +{ + if (pins & ATMEL_SSC_TF) + at91_set_A_periph(AT91_PIN_PB6, 1); + if (pins & ATMEL_SSC_TK) + at91_set_A_periph(AT91_PIN_PB7, 1); + if (pins & ATMEL_SSC_TD) + at91_set_A_periph(AT91_PIN_PB8, 1); + if (pins & ATMEL_SSC_RD) + at91_set_A_periph(AT91_PIN_PB9, 1); + if (pins & ATMEL_SSC_RK) + at91_set_A_periph(AT91_PIN_PB10, 1); + if (pins & ATMEL_SSC_RF) + at91_set_A_periph(AT91_PIN_PB11, 1); +} + +/* + * SSC controllers are accessed through library code, instead of any + * kind of all-singing/all-dancing driver. For example one could be + * used by a particular I2S audio codec's driver, while another one + * on the same system might be used by a custom data capture driver. + */ +void __init at91_add_device_ssc(unsigned id, unsigned pins) +{ + struct platform_device *pdev; + + /* + * NOTE: caller is responsible for passing information matching + * "pins" to whatever will be using each particular controller. + */ + switch (id) { + case AT91CAP9_ID_SSC0: + pdev = &at91cap9_ssc0_device; + configure_ssc0_pins(pins); + break; + case AT91CAP9_ID_SSC1: + pdev = &at91cap9_ssc1_device; + configure_ssc1_pins(pins); + break; + default: + return; + } + + platform_device_register(pdev); +} + +#else +void __init at91_add_device_ssc(unsigned id, unsigned pins) {} +#endif + + +/* -------------------------------------------------------------------- + * UART + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_SERIAL_ATMEL) +static struct resource dbgu_resources[] = { + [0] = { + .start = AT91_VA_BASE_SYS + AT91_DBGU, + .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91_ID_SYS, + .end = AT91_ID_SYS, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data dbgu_data = { + .use_dma_tx = 0, + .use_dma_rx = 0, /* DBGU not capable of receive DMA */ + .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), +}; + +static u64 dbgu_dmamask = DMA_BIT_MASK(32); + +static struct platform_device at91cap9_dbgu_device = { + .name = "atmel_usart", + .id = 0, + .dev = { + .dma_mask = &dbgu_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &dbgu_data, + }, + .resource = dbgu_resources, + .num_resources = ARRAY_SIZE(dbgu_resources), +}; + +static inline void configure_dbgu_pins(void) +{ + at91_set_A_periph(AT91_PIN_PC30, 0); /* DRXD */ + at91_set_A_periph(AT91_PIN_PC31, 1); /* DTXD */ +} + +static struct resource uart0_resources[] = { + [0] = { + .start = AT91CAP9_BASE_US0, + .end = AT91CAP9_BASE_US0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91CAP9_ID_US0, + .end = AT91CAP9_ID_US0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart0_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static u64 uart0_dmamask = DMA_BIT_MASK(32); + +static struct platform_device at91cap9_uart0_device = { + .name = "atmel_usart", + .id = 1, + .dev = { + .dma_mask = &uart0_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &uart0_data, + }, + .resource = uart0_resources, + .num_resources = ARRAY_SIZE(uart0_resources), +}; + +static inline void configure_usart0_pins(unsigned pins) +{ + at91_set_A_periph(AT91_PIN_PA22, 1); /* TXD0 */ + at91_set_A_periph(AT91_PIN_PA23, 0); /* RXD0 */ + + if (pins & ATMEL_UART_RTS) + at91_set_A_periph(AT91_PIN_PA24, 0); /* RTS0 */ + if (pins & ATMEL_UART_CTS) + at91_set_A_periph(AT91_PIN_PA25, 0); /* CTS0 */ +} + +static struct resource uart1_resources[] = { + [0] = { + .start = AT91CAP9_BASE_US1, + .end = AT91CAP9_BASE_US1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91CAP9_ID_US1, + .end = AT91CAP9_ID_US1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart1_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static u64 uart1_dmamask = DMA_BIT_MASK(32); + +static struct platform_device at91cap9_uart1_device = { + .name = "atmel_usart", + .id = 2, + .dev = { + .dma_mask = &uart1_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &uart1_data, + }, + .resource = uart1_resources, + .num_resources = ARRAY_SIZE(uart1_resources), +}; + +static inline void configure_usart1_pins(unsigned pins) +{ + at91_set_A_periph(AT91_PIN_PD0, 1); /* TXD1 */ + at91_set_A_periph(AT91_PIN_PD1, 0); /* RXD1 */ + + if (pins & ATMEL_UART_RTS) + at91_set_B_periph(AT91_PIN_PD7, 0); /* RTS1 */ + if (pins & ATMEL_UART_CTS) + at91_set_B_periph(AT91_PIN_PD8, 0); /* CTS1 */ +} + +static struct resource uart2_resources[] = { + [0] = { + .start = AT91CAP9_BASE_US2, + .end = AT91CAP9_BASE_US2 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91CAP9_ID_US2, + .end = AT91CAP9_ID_US2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart2_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static u64 uart2_dmamask = DMA_BIT_MASK(32); + +static struct platform_device at91cap9_uart2_device = { + .name = "atmel_usart", + .id = 3, + .dev = { + .dma_mask = &uart2_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &uart2_data, + }, + .resource = uart2_resources, + .num_resources = ARRAY_SIZE(uart2_resources), +}; + +static inline void configure_usart2_pins(unsigned pins) +{ + at91_set_A_periph(AT91_PIN_PD2, 1); /* TXD2 */ + at91_set_A_periph(AT91_PIN_PD3, 0); /* RXD2 */ + + if (pins & ATMEL_UART_RTS) + at91_set_B_periph(AT91_PIN_PD5, 0); /* RTS2 */ + if (pins & ATMEL_UART_CTS) + at91_set_B_periph(AT91_PIN_PD6, 0); /* CTS2 */ +} + +static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ +struct platform_device *atmel_default_console_device; /* the serial console device */ + +void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) +{ + struct platform_device *pdev; + struct atmel_uart_data *pdata; + + switch (id) { + case 0: /* DBGU */ + pdev = &at91cap9_dbgu_device; + configure_dbgu_pins(); + break; + case AT91CAP9_ID_US0: + pdev = &at91cap9_uart0_device; + configure_usart0_pins(pins); + break; + case AT91CAP9_ID_US1: + pdev = &at91cap9_uart1_device; + configure_usart1_pins(pins); + break; + case AT91CAP9_ID_US2: + pdev = &at91cap9_uart2_device; + configure_usart2_pins(pins); + break; + default: + return; + } + pdata = pdev->dev.platform_data; + pdata->num = portnr; /* update to mapped ID */ + + if (portnr < ATMEL_MAX_UART) + at91_uarts[portnr] = pdev; +} + +void __init at91_set_serial_console(unsigned portnr) +{ + if (portnr < ATMEL_MAX_UART) { + atmel_default_console_device = at91_uarts[portnr]; + at91cap9_set_console_clock(at91_uarts[portnr]->id); + } +} + +void __init at91_add_device_serial(void) +{ + int i; + + for (i = 0; i < ATMEL_MAX_UART; i++) { + if (at91_uarts[i]) + platform_device_register(at91_uarts[i]); + } + + if (!atmel_default_console_device) + printk(KERN_INFO "AT91: No default serial console defined.\n"); +} +#else +void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} +void __init at91_set_serial_console(unsigned portnr) {} +void __init at91_add_device_serial(void) {} +#endif + + +/* -------------------------------------------------------------------- */ +/* + * These devices are always present and don't need any board-specific + * setup. + */ +static int __init at91_add_standard_devices(void) +{ + at91_add_device_rtt(); + at91_add_device_watchdog(); + at91_add_device_tc(); + return 0; +} + +arch_initcall(at91_add_standard_devices); diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c new file mode 100644 index 00000000..83a1a3fe --- /dev/null +++ b/arch/arm/mach-at91/at91rm9200.c @@ -0,0 +1,396 @@ +/* + * arch/arm/mach-at91/at91rm9200.c + * + * Copyright (C) 2005 SAN People + * + * 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. + * + */ + +#include <linux/module.h> + +#include <asm/irq.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <mach/at91rm9200.h> +#include <mach/at91_pmc.h> +#include <mach/at91_st.h> +#include <mach/cpu.h> + +#include "generic.h" +#include "clock.h" + +static struct map_desc at91rm9200_io_desc[] __initdata = { + { + .virtual = AT91_VA_BASE_SYS, + .pfn = __phys_to_pfn(AT91_BASE_SYS), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = AT91_VA_BASE_EMAC, + .pfn = __phys_to_pfn(AT91RM9200_BASE_EMAC), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = AT91_IO_VIRT_BASE - AT91RM9200_SRAM_SIZE, + .pfn = __phys_to_pfn(AT91RM9200_SRAM_BASE), + .length = AT91RM9200_SRAM_SIZE, + .type = MT_DEVICE, + }, +}; + +/* -------------------------------------------------------------------- + * Clocks + * -------------------------------------------------------------------- */ + +/* + * The peripheral clocks. + */ +static struct clk udc_clk = { + .name = "udc_clk", + .pmc_mask = 1 << AT91RM9200_ID_UDP, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ohci_clk = { + .name = "ohci_clk", + .pmc_mask = 1 << AT91RM9200_ID_UHP, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ether_clk = { + .name = "ether_clk", + .pmc_mask = 1 << AT91RM9200_ID_EMAC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk mmc_clk = { + .name = "mci_clk", + .pmc_mask = 1 << AT91RM9200_ID_MCI, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk twi_clk = { + .name = "twi_clk", + .pmc_mask = 1 << AT91RM9200_ID_TWI, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart0_clk = { + .name = "usart0_clk", + .pmc_mask = 1 << AT91RM9200_ID_US0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart1_clk = { + .name = "usart1_clk", + .pmc_mask = 1 << AT91RM9200_ID_US1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart2_clk = { + .name = "usart2_clk", + .pmc_mask = 1 << AT91RM9200_ID_US2, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart3_clk = { + .name = "usart3_clk", + .pmc_mask = 1 << AT91RM9200_ID_US3, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk spi_clk = { + .name = "spi_clk", + .pmc_mask = 1 << AT91RM9200_ID_SPI, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioA_clk = { + .name = "pioA_clk", + .pmc_mask = 1 << AT91RM9200_ID_PIOA, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioB_clk = { + .name = "pioB_clk", + .pmc_mask = 1 << AT91RM9200_ID_PIOB, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioC_clk = { + .name = "pioC_clk", + .pmc_mask = 1 << AT91RM9200_ID_PIOC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioD_clk = { + .name = "pioD_clk", + .pmc_mask = 1 << AT91RM9200_ID_PIOD, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ssc0_clk = { + .name = "ssc0_clk", + .pmc_mask = 1 << AT91RM9200_ID_SSC0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ssc1_clk = { + .name = "ssc1_clk", + .pmc_mask = 1 << AT91RM9200_ID_SSC1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ssc2_clk = { + .name = "ssc2_clk", + .pmc_mask = 1 << AT91RM9200_ID_SSC2, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk tc0_clk = { + .name = "tc0_clk", + .pmc_mask = 1 << AT91RM9200_ID_TC0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk tc1_clk = { + .name = "tc1_clk", + .pmc_mask = 1 << AT91RM9200_ID_TC1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk tc2_clk = { + .name = "tc2_clk", + .pmc_mask = 1 << AT91RM9200_ID_TC2, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk tc3_clk = { + .name = "tc3_clk", + .pmc_mask = 1 << AT91RM9200_ID_TC3, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk tc4_clk = { + .name = "tc4_clk", + .pmc_mask = 1 << AT91RM9200_ID_TC4, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk tc5_clk = { + .name = "tc5_clk", + .pmc_mask = 1 << AT91RM9200_ID_TC5, + .type = CLK_TYPE_PERIPHERAL, +}; + +static struct clk *periph_clocks[] __initdata = { + &pioA_clk, + &pioB_clk, + &pioC_clk, + &pioD_clk, + &usart0_clk, + &usart1_clk, + &usart2_clk, + &usart3_clk, + &mmc_clk, + &udc_clk, + &twi_clk, + &spi_clk, + &ssc0_clk, + &ssc1_clk, + &ssc2_clk, + &tc0_clk, + &tc1_clk, + &tc2_clk, + &tc3_clk, + &tc4_clk, + &tc5_clk, + &ohci_clk, + ðer_clk, + // irq0 .. irq6 +}; + +static struct clk_lookup periph_clocks_lookups[] = { + CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), + CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk), + CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk), + CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tc3_clk), + CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.1", &tc4_clk), + CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.1", &tc5_clk), + CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), + CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), + CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk), +}; + +static struct clk_lookup usart_clocks_lookups[] = { + CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck), + CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk), + CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk), + CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk), + CLKDEV_CON_DEV_ID("usart", "atmel_usart.4", &usart3_clk), +}; + +/* + * The four programmable clocks. + * You must configure pin multiplexing to bring these signals out. + */ +static struct clk pck0 = { + .name = "pck0", + .pmc_mask = AT91_PMC_PCK0, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 0, +}; +static struct clk pck1 = { + .name = "pck1", + .pmc_mask = AT91_PMC_PCK1, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 1, +}; +static struct clk pck2 = { + .name = "pck2", + .pmc_mask = AT91_PMC_PCK2, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 2, +}; +static struct clk pck3 = { + .name = "pck3", + .pmc_mask = AT91_PMC_PCK3, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 3, +}; + +static void __init at91rm9200_register_clocks(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) + clk_register(periph_clocks[i]); + + clkdev_add_table(periph_clocks_lookups, + ARRAY_SIZE(periph_clocks_lookups)); + clkdev_add_table(usart_clocks_lookups, + ARRAY_SIZE(usart_clocks_lookups)); + + clk_register(&pck0); + clk_register(&pck1); + clk_register(&pck2); + clk_register(&pck3); +} + +static struct clk_lookup console_clock_lookup; + +void __init at91rm9200_set_console_clock(int id) +{ + if (id >= ARRAY_SIZE(usart_clocks_lookups)) + return; + + console_clock_lookup.con_id = "usart"; + console_clock_lookup.clk = usart_clocks_lookups[id].clk; + clkdev_add(&console_clock_lookup); +} + +/* -------------------------------------------------------------------- + * GPIO + * -------------------------------------------------------------------- */ + +static struct at91_gpio_bank at91rm9200_gpio[] = { + { + .id = AT91RM9200_ID_PIOA, + .offset = AT91_PIOA, + .clock = &pioA_clk, + }, { + .id = AT91RM9200_ID_PIOB, + .offset = AT91_PIOB, + .clock = &pioB_clk, + }, { + .id = AT91RM9200_ID_PIOC, + .offset = AT91_PIOC, + .clock = &pioC_clk, + }, { + .id = AT91RM9200_ID_PIOD, + .offset = AT91_PIOD, + .clock = &pioD_clk, + } +}; + +static void at91rm9200_reset(void) +{ + /* + * Perform a hardware reset with the use of the Watchdog timer. + */ + at91_sys_write(AT91_ST_WDMR, AT91_ST_RSTEN | AT91_ST_EXTEN | 1); + at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); +} + +int rm9200_type; +EXPORT_SYMBOL(rm9200_type); + +void __init at91rm9200_set_type(int type) +{ + rm9200_type = type; +} + +/* -------------------------------------------------------------------- + * AT91RM9200 processor initialization + * -------------------------------------------------------------------- */ +void __init at91rm9200_map_io(void) +{ + /* Map peripherals */ + iotable_init(at91rm9200_io_desc, ARRAY_SIZE(at91rm9200_io_desc)); +} + +void __init at91rm9200_initialize(unsigned long main_clock) +{ + at91_arch_reset = at91rm9200_reset; + at91_extern_irq = (1 << AT91RM9200_ID_IRQ0) | (1 << AT91RM9200_ID_IRQ1) + | (1 << AT91RM9200_ID_IRQ2) | (1 << AT91RM9200_ID_IRQ3) + | (1 << AT91RM9200_ID_IRQ4) | (1 << AT91RM9200_ID_IRQ5) + | (1 << AT91RM9200_ID_IRQ6); + + /* Init clock subsystem */ + at91_clock_init(main_clock); + + /* Register the processor-specific clocks */ + at91rm9200_register_clocks(); + + /* Initialize GPIO subsystem */ + at91_gpio_init(at91rm9200_gpio, + cpu_is_at91rm9200_bga() ? AT91RM9200_BGA : AT91RM9200_PQFP); +} + + +/* -------------------------------------------------------------------- + * Interrupt initialization + * -------------------------------------------------------------------- */ + +/* + * The default interrupt priority levels (0 = lowest, 7 = highest). + */ +static unsigned int at91rm9200_default_irq_priority[NR_AIC_IRQS] __initdata = { + 7, /* Advanced Interrupt Controller (FIQ) */ + 7, /* System Peripherals */ + 1, /* Parallel IO Controller A */ + 1, /* Parallel IO Controller B */ + 1, /* Parallel IO Controller C */ + 1, /* Parallel IO Controller D */ + 5, /* USART 0 */ + 5, /* USART 1 */ + 5, /* USART 2 */ + 5, /* USART 3 */ + 0, /* Multimedia Card Interface */ + 2, /* USB Device Port */ + 6, /* Two-Wire Interface */ + 5, /* Serial Peripheral Interface */ + 4, /* Serial Synchronous Controller 0 */ + 4, /* Serial Synchronous Controller 1 */ + 4, /* Serial Synchronous Controller 2 */ + 0, /* Timer Counter 0 */ + 0, /* Timer Counter 1 */ + 0, /* Timer Counter 2 */ + 0, /* Timer Counter 3 */ + 0, /* Timer Counter 4 */ + 0, /* Timer Counter 5 */ + 2, /* USB Host port */ + 3, /* Ethernet MAC */ + 0, /* Advanced Interrupt Controller (IRQ0) */ + 0, /* Advanced Interrupt Controller (IRQ1) */ + 0, /* Advanced Interrupt Controller (IRQ2) */ + 0, /* Advanced Interrupt Controller (IRQ3) */ + 0, /* Advanced Interrupt Controller (IRQ4) */ + 0, /* Advanced Interrupt Controller (IRQ5) */ + 0 /* Advanced Interrupt Controller (IRQ6) */ +}; + +void __init at91rm9200_init_interrupts(unsigned int priority[NR_AIC_IRQS]) +{ + if (!priority) + priority = at91rm9200_default_irq_priority; + + /* Initialize the AIC interrupt controller */ + at91_aic_init(priority); + + /* Enable GPIO interrupts */ + at91_gpio_irq_setup(); +} diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c new file mode 100644 index 00000000..7227755f --- /dev/null +++ b/arch/arm/mach-at91/at91rm9200_devices.c @@ -0,0 +1,1176 @@ +/* + * arch/arm/mach-at91/at91rm9200_devices.c + * + * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org> + * Copyright (C) 2005 David Brownell + * + * 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. + * + */ +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <linux/dma-mapping.h> +#include <linux/platform_device.h> +#include <linux/i2c-gpio.h> + +#include <mach/board.h> +#include <mach/gpio.h> +#include <mach/at91rm9200.h> +#include <mach/at91rm9200_mc.h> + +#include "generic.h" + + +/* -------------------------------------------------------------------- + * USB Host + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) +static u64 ohci_dmamask = DMA_BIT_MASK(32); +static struct at91_usbh_data usbh_data; + +static struct resource usbh_resources[] = { + [0] = { + .start = AT91RM9200_UHP_BASE, + .end = AT91RM9200_UHP_BASE + SZ_1M - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_UHP, + .end = AT91RM9200_ID_UHP, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91rm9200_usbh_device = { + .name = "at91_ohci", + .id = -1, + .dev = { + .dma_mask = &ohci_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &usbh_data, + }, + .resource = usbh_resources, + .num_resources = ARRAY_SIZE(usbh_resources), +}; + +void __init at91_add_device_usbh(struct at91_usbh_data *data) +{ + if (!data) + return; + + usbh_data = *data; + platform_device_register(&at91rm9200_usbh_device); +} +#else +void __init at91_add_device_usbh(struct at91_usbh_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * USB Device (Gadget) + * -------------------------------------------------------------------- */ + +#ifdef CONFIG_USB_GADGET_AT91 +static struct at91_udc_data udc_data; + +static struct resource udc_resources[] = { + [0] = { + .start = AT91RM9200_BASE_UDP, + .end = AT91RM9200_BASE_UDP + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_UDP, + .end = AT91RM9200_ID_UDP, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91rm9200_udc_device = { + .name = "at91_udc", + .id = -1, + .dev = { + .platform_data = &udc_data, + }, + .resource = udc_resources, + .num_resources = ARRAY_SIZE(udc_resources), +}; + +void __init at91_add_device_udc(struct at91_udc_data *data) +{ + if (!data) + return; + + if (data->vbus_pin) { + at91_set_gpio_input(data->vbus_pin, 0); + at91_set_deglitch(data->vbus_pin, 1); + } + if (data->pullup_pin) + at91_set_gpio_output(data->pullup_pin, 0); + + udc_data = *data; + platform_device_register(&at91rm9200_udc_device); +} +#else +void __init at91_add_device_udc(struct at91_udc_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * Ethernet + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_ARM_AT91_ETHER) || defined(CONFIG_ARM_AT91_ETHER_MODULE) +static u64 eth_dmamask = DMA_BIT_MASK(32); +static struct at91_eth_data eth_data; + +static struct resource eth_resources[] = { + [0] = { + .start = AT91_VA_BASE_EMAC, + .end = AT91_VA_BASE_EMAC + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_EMAC, + .end = AT91RM9200_ID_EMAC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91rm9200_eth_device = { + .name = "at91_ether", + .id = -1, + .dev = { + .dma_mask = ð_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = ð_data, + }, + .resource = eth_resources, + .num_resources = ARRAY_SIZE(eth_resources), +}; + +void __init at91_add_device_eth(struct at91_eth_data *data) +{ + if (!data) + return; + + if (data->phy_irq_pin) { + at91_set_gpio_input(data->phy_irq_pin, 0); + at91_set_deglitch(data->phy_irq_pin, 1); + } + + /* Pins used for MII and RMII */ + at91_set_A_periph(AT91_PIN_PA16, 0); /* EMDIO */ + at91_set_A_periph(AT91_PIN_PA15, 0); /* EMDC */ + at91_set_A_periph(AT91_PIN_PA14, 0); /* ERXER */ + at91_set_A_periph(AT91_PIN_PA13, 0); /* ERX1 */ + at91_set_A_periph(AT91_PIN_PA12, 0); /* ERX0 */ + at91_set_A_periph(AT91_PIN_PA11, 0); /* ECRS_ECRSDV */ + at91_set_A_periph(AT91_PIN_PA10, 0); /* ETX1 */ + at91_set_A_periph(AT91_PIN_PA9, 0); /* ETX0 */ + at91_set_A_periph(AT91_PIN_PA8, 0); /* ETXEN */ + at91_set_A_periph(AT91_PIN_PA7, 0); /* ETXCK_EREFCK */ + + if (!data->is_rmii) { + at91_set_B_periph(AT91_PIN_PB19, 0); /* ERXCK */ + at91_set_B_periph(AT91_PIN_PB18, 0); /* ECOL */ + at91_set_B_periph(AT91_PIN_PB17, 0); /* ERXDV */ + at91_set_B_periph(AT91_PIN_PB16, 0); /* ERX3 */ + at91_set_B_periph(AT91_PIN_PB15, 0); /* ERX2 */ + at91_set_B_periph(AT91_PIN_PB14, 0); /* ETXER */ + at91_set_B_periph(AT91_PIN_PB13, 0); /* ETX3 */ + at91_set_B_periph(AT91_PIN_PB12, 0); /* ETX2 */ + } + + eth_data = *data; + platform_device_register(&at91rm9200_eth_device); +} +#else +void __init at91_add_device_eth(struct at91_eth_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * Compact Flash / PCMCIA + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE) +static struct at91_cf_data cf_data; + +#define CF_BASE AT91_CHIPSELECT_4 + +static struct resource cf_resources[] = { + [0] = { + .start = CF_BASE, + /* ties up CS4, CS5 and CS6 */ + .end = CF_BASE + (0x30000000 - 1), + .flags = IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT, + }, +}; + +static struct platform_device at91rm9200_cf_device = { + .name = "at91_cf", + .id = -1, + .dev = { + .platform_data = &cf_data, + }, + .resource = cf_resources, + .num_resources = ARRAY_SIZE(cf_resources), +}; + +void __init at91_add_device_cf(struct at91_cf_data *data) +{ + unsigned int csa; + + if (!data) + return; + + data->chipselect = 4; /* can only use EBI ChipSelect 4 */ + + /* CF takes over CS4, CS5, CS6 */ + csa = at91_sys_read(AT91_EBI_CSA); + at91_sys_write(AT91_EBI_CSA, csa | AT91_EBI_CS4A_SMC_COMPACTFLASH); + + /* + * Static memory controller timing adjustments. + * REVISIT: these timings are in terms of MCK cycles, so + * when MCK changes (cpufreq etc) so must these values... + */ + at91_sys_write(AT91_SMC_CSR(4), + AT91_SMC_ACSS_STD + | AT91_SMC_DBW_16 + | AT91_SMC_BAT + | AT91_SMC_WSEN + | AT91_SMC_NWS_(32) /* wait states */ + | AT91_SMC_RWSETUP_(6) /* setup time */ + | AT91_SMC_RWHOLD_(4) /* hold time */ + ); + + /* input/irq */ + if (data->irq_pin) { + at91_set_gpio_input(data->irq_pin, 1); + at91_set_deglitch(data->irq_pin, 1); + } + at91_set_gpio_input(data->det_pin, 1); + at91_set_deglitch(data->det_pin, 1); + + /* outputs, initially off */ + if (data->vcc_pin) + at91_set_gpio_output(data->vcc_pin, 0); + at91_set_gpio_output(data->rst_pin, 0); + + /* force poweron defaults for these pins ... */ + at91_set_A_periph(AT91_PIN_PC9, 0); /* A25/CFRNW */ + at91_set_A_periph(AT91_PIN_PC10, 0); /* NCS4/CFCS */ + at91_set_A_periph(AT91_PIN_PC11, 0); /* NCS5/CFCE1 */ + at91_set_A_periph(AT91_PIN_PC12, 0); /* NCS6/CFCE2 */ + + /* nWAIT is _not_ a default setting */ + at91_set_A_periph(AT91_PIN_PC6, 1); /* nWAIT */ + + cf_data = *data; + platform_device_register(&at91rm9200_cf_device); +} +#else +void __init at91_add_device_cf(struct at91_cf_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * MMC / SD + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) +static u64 mmc_dmamask = DMA_BIT_MASK(32); +static struct at91_mmc_data mmc_data; + +static struct resource mmc_resources[] = { + [0] = { + .start = AT91RM9200_BASE_MCI, + .end = AT91RM9200_BASE_MCI + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_MCI, + .end = AT91RM9200_ID_MCI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91rm9200_mmc_device = { + .name = "at91_mci", + .id = -1, + .dev = { + .dma_mask = &mmc_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &mmc_data, + }, + .resource = mmc_resources, + .num_resources = ARRAY_SIZE(mmc_resources), +}; + +void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) +{ + if (!data) + return; + + /* input/irq */ + if (data->det_pin) { + at91_set_gpio_input(data->det_pin, 1); + at91_set_deglitch(data->det_pin, 1); + } + if (data->wp_pin) + at91_set_gpio_input(data->wp_pin, 1); + if (data->vcc_pin) + at91_set_gpio_output(data->vcc_pin, 0); + + /* CLK */ + at91_set_A_periph(AT91_PIN_PA27, 0); + + if (data->slot_b) { + /* CMD */ + at91_set_B_periph(AT91_PIN_PA8, 1); + + /* DAT0, maybe DAT1..DAT3 */ + at91_set_B_periph(AT91_PIN_PA9, 1); + if (data->wire4) { + at91_set_B_periph(AT91_PIN_PA10, 1); + at91_set_B_periph(AT91_PIN_PA11, 1); + at91_set_B_periph(AT91_PIN_PA12, 1); + } + } else { + /* CMD */ + at91_set_A_periph(AT91_PIN_PA28, 1); + + /* DAT0, maybe DAT1..DAT3 */ + at91_set_A_periph(AT91_PIN_PA29, 1); + if (data->wire4) { + at91_set_B_periph(AT91_PIN_PB3, 1); + at91_set_B_periph(AT91_PIN_PB4, 1); + at91_set_B_periph(AT91_PIN_PB5, 1); + } + } + + mmc_data = *data; + platform_device_register(&at91rm9200_mmc_device); +} +#else +void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * NAND / SmartMedia + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE) +static struct atmel_nand_data nand_data; + +#define NAND_BASE AT91_CHIPSELECT_3 + +static struct resource nand_resources[] = { + { + .start = NAND_BASE, + .end = NAND_BASE + SZ_256M - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device at91rm9200_nand_device = { + .name = "atmel_nand", + .id = -1, + .dev = { + .platform_data = &nand_data, + }, + .resource = nand_resources, + .num_resources = ARRAY_SIZE(nand_resources), +}; + +void __init at91_add_device_nand(struct atmel_nand_data *data) +{ + unsigned int csa; + + if (!data) + return; + + /* enable the address range of CS3 */ + csa = at91_sys_read(AT91_EBI_CSA); + at91_sys_write(AT91_EBI_CSA, csa | AT91_EBI_CS3A_SMC_SMARTMEDIA); + + /* set the bus interface characteristics */ + at91_sys_write(AT91_SMC_CSR(3), AT91_SMC_ACSS_STD | AT91_SMC_DBW_8 | AT91_SMC_WSEN + | AT91_SMC_NWS_(5) + | AT91_SMC_TDF_(1) + | AT91_SMC_RWSETUP_(0) /* tDS Data Set up Time 30 - ns */ + | AT91_SMC_RWHOLD_(1) /* tDH Data Hold Time 20 - ns */ + ); + + /* enable pin */ + if (data->enable_pin) + at91_set_gpio_output(data->enable_pin, 1); + + /* ready/busy pin */ + if (data->rdy_pin) + at91_set_gpio_input(data->rdy_pin, 1); + + /* card detect pin */ + if (data->det_pin) + at91_set_gpio_input(data->det_pin, 1); + + at91_set_A_periph(AT91_PIN_PC1, 0); /* SMOE */ + at91_set_A_periph(AT91_PIN_PC3, 0); /* SMWE */ + + nand_data = *data; + platform_device_register(&at91rm9200_nand_device); +} +#else +void __init at91_add_device_nand(struct atmel_nand_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * TWI (i2c) + * -------------------------------------------------------------------- */ + +/* + * Prefer the GPIO code since the TWI controller isn't robust + * (gets overruns and underruns under load) and can only issue + * repeated STARTs in one scenario (the driver doesn't yet handle them). + */ +#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) + +static struct i2c_gpio_platform_data pdata = { + .sda_pin = AT91_PIN_PA25, + .sda_is_open_drain = 1, + .scl_pin = AT91_PIN_PA26, + .scl_is_open_drain = 1, + .udelay = 2, /* ~100 kHz */ +}; + +static struct platform_device at91rm9200_twi_device = { + .name = "i2c-gpio", + .id = -1, + .dev.platform_data = &pdata, +}; + +void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) +{ + at91_set_GPIO_periph(AT91_PIN_PA25, 1); /* TWD (SDA) */ + at91_set_multi_drive(AT91_PIN_PA25, 1); + + at91_set_GPIO_periph(AT91_PIN_PA26, 1); /* TWCK (SCL) */ + at91_set_multi_drive(AT91_PIN_PA26, 1); + + i2c_register_board_info(0, devices, nr_devices); + platform_device_register(&at91rm9200_twi_device); +} + +#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) + +static struct resource twi_resources[] = { + [0] = { + .start = AT91RM9200_BASE_TWI, + .end = AT91RM9200_BASE_TWI + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_TWI, + .end = AT91RM9200_ID_TWI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91rm9200_twi_device = { + .name = "at91_i2c", + .id = -1, + .resource = twi_resources, + .num_resources = ARRAY_SIZE(twi_resources), +}; + +void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) +{ + /* pins used for TWI interface */ + at91_set_A_periph(AT91_PIN_PA25, 0); /* TWD */ + at91_set_multi_drive(AT91_PIN_PA25, 1); + + at91_set_A_periph(AT91_PIN_PA26, 0); /* TWCK */ + at91_set_multi_drive(AT91_PIN_PA26, 1); + + i2c_register_board_info(0, devices, nr_devices); + platform_device_register(&at91rm9200_twi_device); +} +#else +void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {} +#endif + + +/* -------------------------------------------------------------------- + * SPI + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) +static u64 spi_dmamask = DMA_BIT_MASK(32); + +static struct resource spi_resources[] = { + [0] = { + .start = AT91RM9200_BASE_SPI, + .end = AT91RM9200_BASE_SPI + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_SPI, + .end = AT91RM9200_ID_SPI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91rm9200_spi_device = { + .name = "atmel_spi", + .id = 0, + .dev = { + .dma_mask = &spi_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = spi_resources, + .num_resources = ARRAY_SIZE(spi_resources), +}; + +static const unsigned spi_standard_cs[4] = { AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PA5, AT91_PIN_PA6 }; + +void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) +{ + int i; + unsigned long cs_pin; + + at91_set_A_periph(AT91_PIN_PA0, 0); /* MISO */ + at91_set_A_periph(AT91_PIN_PA1, 0); /* MOSI */ + at91_set_A_periph(AT91_PIN_PA2, 0); /* SPCK */ + + /* Enable SPI chip-selects */ + for (i = 0; i < nr_devices; i++) { + if (devices[i].controller_data) + cs_pin = (unsigned long) devices[i].controller_data; + else + cs_pin = spi_standard_cs[devices[i].chip_select]; + + if (devices[i].chip_select == 0) /* for CS0 errata */ + at91_set_A_periph(cs_pin, 0); + else + at91_set_gpio_output(cs_pin, 1); + + + /* pass chip-select pin to driver */ + devices[i].controller_data = (void *) cs_pin; + } + + spi_register_board_info(devices, nr_devices); + platform_device_register(&at91rm9200_spi_device); +} +#else +void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {} +#endif + + +/* -------------------------------------------------------------------- + * Timer/Counter blocks + * -------------------------------------------------------------------- */ + +#ifdef CONFIG_ATMEL_TCLIB + +static struct resource tcb0_resources[] = { + [0] = { + .start = AT91RM9200_BASE_TCB0, + .end = AT91RM9200_BASE_TCB0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_TC0, + .end = AT91RM9200_ID_TC0, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = AT91RM9200_ID_TC1, + .end = AT91RM9200_ID_TC1, + .flags = IORESOURCE_IRQ, + }, + [3] = { + .start = AT91RM9200_ID_TC2, + .end = AT91RM9200_ID_TC2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91rm9200_tcb0_device = { + .name = "atmel_tcb", + .id = 0, + .resource = tcb0_resources, + .num_resources = ARRAY_SIZE(tcb0_resources), +}; + +static struct resource tcb1_resources[] = { + [0] = { + .start = AT91RM9200_BASE_TCB1, + .end = AT91RM9200_BASE_TCB1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_TC3, + .end = AT91RM9200_ID_TC3, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = AT91RM9200_ID_TC4, + .end = AT91RM9200_ID_TC4, + .flags = IORESOURCE_IRQ, + }, + [3] = { + .start = AT91RM9200_ID_TC5, + .end = AT91RM9200_ID_TC5, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91rm9200_tcb1_device = { + .name = "atmel_tcb", + .id = 1, + .resource = tcb1_resources, + .num_resources = ARRAY_SIZE(tcb1_resources), +}; + +static void __init at91_add_device_tc(void) +{ + platform_device_register(&at91rm9200_tcb0_device); + platform_device_register(&at91rm9200_tcb1_device); +} +#else +static void __init at91_add_device_tc(void) { } +#endif + + +/* -------------------------------------------------------------------- + * RTC + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE) +static struct platform_device at91rm9200_rtc_device = { + .name = "at91_rtc", + .id = -1, + .num_resources = 0, +}; + +static void __init at91_add_device_rtc(void) +{ + platform_device_register(&at91rm9200_rtc_device); +} +#else +static void __init at91_add_device_rtc(void) {} +#endif + + +/* -------------------------------------------------------------------- + * Watchdog + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_AT91RM9200_WATCHDOG) || defined(CONFIG_AT91RM9200_WATCHDOG_MODULE) +static struct platform_device at91rm9200_wdt_device = { + .name = "at91_wdt", + .id = -1, + .num_resources = 0, +}; + +static void __init at91_add_device_watchdog(void) +{ + platform_device_register(&at91rm9200_wdt_device); +} +#else +static void __init at91_add_device_watchdog(void) {} +#endif + + +/* -------------------------------------------------------------------- + * SSC -- Synchronous Serial Controller + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE) +static u64 ssc0_dmamask = DMA_BIT_MASK(32); + +static struct resource ssc0_resources[] = { + [0] = { + .start = AT91RM9200_BASE_SSC0, + .end = AT91RM9200_BASE_SSC0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_SSC0, + .end = AT91RM9200_ID_SSC0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91rm9200_ssc0_device = { + .name = "ssc", + .id = 0, + .dev = { + .dma_mask = &ssc0_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = ssc0_resources, + .num_resources = ARRAY_SIZE(ssc0_resources), +}; + +static inline void configure_ssc0_pins(unsigned pins) +{ + if (pins & ATMEL_SSC_TF) + at91_set_A_periph(AT91_PIN_PB0, 1); + if (pins & ATMEL_SSC_TK) + at91_set_A_periph(AT91_PIN_PB1, 1); + if (pins & ATMEL_SSC_TD) + at91_set_A_periph(AT91_PIN_PB2, 1); + if (pins & ATMEL_SSC_RD) + at91_set_A_periph(AT91_PIN_PB3, 1); + if (pins & ATMEL_SSC_RK) + at91_set_A_periph(AT91_PIN_PB4, 1); + if (pins & ATMEL_SSC_RF) + at91_set_A_periph(AT91_PIN_PB5, 1); +} + +static u64 ssc1_dmamask = DMA_BIT_MASK(32); + +static struct resource ssc1_resources[] = { + [0] = { + .start = AT91RM9200_BASE_SSC1, + .end = AT91RM9200_BASE_SSC1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_SSC1, + .end = AT91RM9200_ID_SSC1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91rm9200_ssc1_device = { + .name = "ssc", + .id = 1, + .dev = { + .dma_mask = &ssc1_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = ssc1_resources, + .num_resources = ARRAY_SIZE(ssc1_resources), +}; + +static inline void configure_ssc1_pins(unsigned pins) +{ + if (pins & ATMEL_SSC_TF) + at91_set_A_periph(AT91_PIN_PB6, 1); + if (pins & ATMEL_SSC_TK) + at91_set_A_periph(AT91_PIN_PB7, 1); + if (pins & ATMEL_SSC_TD) + at91_set_A_periph(AT91_PIN_PB8, 1); + if (pins & ATMEL_SSC_RD) + at91_set_A_periph(AT91_PIN_PB9, 1); + if (pins & ATMEL_SSC_RK) + at91_set_A_periph(AT91_PIN_PB10, 1); + if (pins & ATMEL_SSC_RF) + at91_set_A_periph(AT91_PIN_PB11, 1); +} + +static u64 ssc2_dmamask = DMA_BIT_MASK(32); + +static struct resource ssc2_resources[] = { + [0] = { + .start = AT91RM9200_BASE_SSC2, + .end = AT91RM9200_BASE_SSC2 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_SSC2, + .end = AT91RM9200_ID_SSC2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91rm9200_ssc2_device = { + .name = "ssc", + .id = 2, + .dev = { + .dma_mask = &ssc2_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = ssc2_resources, + .num_resources = ARRAY_SIZE(ssc2_resources), +}; + +static inline void configure_ssc2_pins(unsigned pins) +{ + if (pins & ATMEL_SSC_TF) + at91_set_A_periph(AT91_PIN_PB12, 1); + if (pins & ATMEL_SSC_TK) + at91_set_A_periph(AT91_PIN_PB13, 1); + if (pins & ATMEL_SSC_TD) + at91_set_A_periph(AT91_PIN_PB14, 1); + if (pins & ATMEL_SSC_RD) + at91_set_A_periph(AT91_PIN_PB15, 1); + if (pins & ATMEL_SSC_RK) + at91_set_A_periph(AT91_PIN_PB16, 1); + if (pins & ATMEL_SSC_RF) + at91_set_A_periph(AT91_PIN_PB17, 1); +} + +/* + * SSC controllers are accessed through library code, instead of any + * kind of all-singing/all-dancing driver. For example one could be + * used by a particular I2S audio codec's driver, while another one + * on the same system might be used by a custom data capture driver. + */ +void __init at91_add_device_ssc(unsigned id, unsigned pins) +{ + struct platform_device *pdev; + + /* + * NOTE: caller is responsible for passing information matching + * "pins" to whatever will be using each particular controller. + */ + switch (id) { + case AT91RM9200_ID_SSC0: + pdev = &at91rm9200_ssc0_device; + configure_ssc0_pins(pins); + break; + case AT91RM9200_ID_SSC1: + pdev = &at91rm9200_ssc1_device; + configure_ssc1_pins(pins); + break; + case AT91RM9200_ID_SSC2: + pdev = &at91rm9200_ssc2_device; + configure_ssc2_pins(pins); + break; + default: + return; + } + + platform_device_register(pdev); +} + +#else +void __init at91_add_device_ssc(unsigned id, unsigned pins) {} +#endif + + +/* -------------------------------------------------------------------- + * UART + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_SERIAL_ATMEL) +static struct resource dbgu_resources[] = { + [0] = { + .start = AT91_VA_BASE_SYS + AT91_DBGU, + .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91_ID_SYS, + .end = AT91_ID_SYS, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data dbgu_data = { + .use_dma_tx = 0, + .use_dma_rx = 0, /* DBGU not capable of receive DMA */ + .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), +}; + +static u64 dbgu_dmamask = DMA_BIT_MASK(32); + +static struct platform_device at91rm9200_dbgu_device = { + .name = "atmel_usart", + .id = 0, + .dev = { + .dma_mask = &dbgu_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &dbgu_data, + }, + .resource = dbgu_resources, + .num_resources = ARRAY_SIZE(dbgu_resources), +}; + +static inline void configure_dbgu_pins(void) +{ + at91_set_A_periph(AT91_PIN_PA30, 0); /* DRXD */ + at91_set_A_periph(AT91_PIN_PA31, 1); /* DTXD */ +} + +static struct resource uart0_resources[] = { + [0] = { + .start = AT91RM9200_BASE_US0, + .end = AT91RM9200_BASE_US0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_US0, + .end = AT91RM9200_ID_US0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart0_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static u64 uart0_dmamask = DMA_BIT_MASK(32); + +static struct platform_device at91rm9200_uart0_device = { + .name = "atmel_usart", + .id = 1, + .dev = { + .dma_mask = &uart0_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &uart0_data, + }, + .resource = uart0_resources, + .num_resources = ARRAY_SIZE(uart0_resources), +}; + +static inline void configure_usart0_pins(unsigned pins) +{ + at91_set_A_periph(AT91_PIN_PA17, 1); /* TXD0 */ + at91_set_A_periph(AT91_PIN_PA18, 0); /* RXD0 */ + + if (pins & ATMEL_UART_CTS) + at91_set_A_periph(AT91_PIN_PA20, 0); /* CTS0 */ + + if (pins & ATMEL_UART_RTS) { + /* + * AT91RM9200 Errata #39 - RTS0 is not internally connected to PA21. + * We need to drive the pin manually. Default is off (RTS is active low). + */ + at91_set_gpio_output(AT91_PIN_PA21, 1); + } +} + +static struct resource uart1_resources[] = { + [0] = { + .start = AT91RM9200_BASE_US1, + .end = AT91RM9200_BASE_US1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_US1, + .end = AT91RM9200_ID_US1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart1_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static u64 uart1_dmamask = DMA_BIT_MASK(32); + +static struct platform_device at91rm9200_uart1_device = { + .name = "atmel_usart", + .id = 2, + .dev = { + .dma_mask = &uart1_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &uart1_data, + }, + .resource = uart1_resources, + .num_resources = ARRAY_SIZE(uart1_resources), +}; + +static inline void configure_usart1_pins(unsigned pins) +{ + at91_set_A_periph(AT91_PIN_PB20, 1); /* TXD1 */ + at91_set_A_periph(AT91_PIN_PB21, 0); /* RXD1 */ + + if (pins & ATMEL_UART_RI) + at91_set_A_periph(AT91_PIN_PB18, 0); /* RI1 */ + if (pins & ATMEL_UART_DTR) + at91_set_A_periph(AT91_PIN_PB19, 0); /* DTR1 */ + if (pins & ATMEL_UART_DCD) + at91_set_A_periph(AT91_PIN_PB23, 0); /* DCD1 */ + if (pins & ATMEL_UART_CTS) + at91_set_A_periph(AT91_PIN_PB24, 0); /* CTS1 */ + if (pins & ATMEL_UART_DSR) + at91_set_A_periph(AT91_PIN_PB25, 0); /* DSR1 */ + if (pins & ATMEL_UART_RTS) + at91_set_A_periph(AT91_PIN_PB26, 0); /* RTS1 */ +} + +static struct resource uart2_resources[] = { + [0] = { + .start = AT91RM9200_BASE_US2, + .end = AT91RM9200_BASE_US2 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_US2, + .end = AT91RM9200_ID_US2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart2_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static u64 uart2_dmamask = DMA_BIT_MASK(32); + +static struct platform_device at91rm9200_uart2_device = { + .name = "atmel_usart", + .id = 3, + .dev = { + .dma_mask = &uart2_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &uart2_data, + }, + .resource = uart2_resources, + .num_resources = ARRAY_SIZE(uart2_resources), +}; + +static inline void configure_usart2_pins(unsigned pins) +{ + at91_set_A_periph(AT91_PIN_PA22, 0); /* RXD2 */ + at91_set_A_periph(AT91_PIN_PA23, 1); /* TXD2 */ + + if (pins & ATMEL_UART_CTS) + at91_set_B_periph(AT91_PIN_PA30, 0); /* CTS2 */ + if (pins & ATMEL_UART_RTS) + at91_set_B_periph(AT91_PIN_PA31, 0); /* RTS2 */ +} + +static struct resource uart3_resources[] = { + [0] = { + .start = AT91RM9200_BASE_US3, + .end = AT91RM9200_BASE_US3 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_US3, + .end = AT91RM9200_ID_US3, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart3_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static u64 uart3_dmamask = DMA_BIT_MASK(32); + +static struct platform_device at91rm9200_uart3_device = { + .name = "atmel_usart", + .id = 4, + .dev = { + .dma_mask = &uart3_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &uart3_data, + }, + .resource = uart3_resources, + .num_resources = ARRAY_SIZE(uart3_resources), +}; + +static inline void configure_usart3_pins(unsigned pins) +{ + at91_set_B_periph(AT91_PIN_PA5, 1); /* TXD3 */ + at91_set_B_periph(AT91_PIN_PA6, 0); /* RXD3 */ + + if (pins & ATMEL_UART_CTS) + at91_set_B_periph(AT91_PIN_PB1, 0); /* CTS3 */ + if (pins & ATMEL_UART_RTS) + at91_set_B_periph(AT91_PIN_PB0, 0); /* RTS3 */ +} + +static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ +struct platform_device *atmel_default_console_device; /* the serial console device */ + +void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) +{ + struct platform_device *pdev; + struct atmel_uart_data *pdata; + + switch (id) { + case 0: /* DBGU */ + pdev = &at91rm9200_dbgu_device; + configure_dbgu_pins(); + break; + case AT91RM9200_ID_US0: + pdev = &at91rm9200_uart0_device; + configure_usart0_pins(pins); + break; + case AT91RM9200_ID_US1: + pdev = &at91rm9200_uart1_device; + configure_usart1_pins(pins); + break; + case AT91RM9200_ID_US2: + pdev = &at91rm9200_uart2_device; + configure_usart2_pins(pins); + break; + case AT91RM9200_ID_US3: + pdev = &at91rm9200_uart3_device; + configure_usart3_pins(pins); + break; + default: + return; + } + pdata = pdev->dev.platform_data; + pdata->num = portnr; /* update to mapped ID */ + + if (portnr < ATMEL_MAX_UART) + at91_uarts[portnr] = pdev; +} + +void __init at91_set_serial_console(unsigned portnr) +{ + if (portnr < ATMEL_MAX_UART) { + atmel_default_console_device = at91_uarts[portnr]; + at91rm9200_set_console_clock(at91_uarts[portnr]->id); + } +} + +void __init at91_add_device_serial(void) +{ + int i; + + for (i = 0; i < ATMEL_MAX_UART; i++) { + if (at91_uarts[i]) + platform_device_register(at91_uarts[i]); + } + + if (!atmel_default_console_device) + printk(KERN_INFO "AT91: No default serial console defined.\n"); +} +#else +void __init __deprecated at91_init_serial(struct at91_uart_config *config) {} +void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} +void __init at91_set_serial_console(unsigned portnr) {} +void __init at91_add_device_serial(void) {} +#endif + + +/* -------------------------------------------------------------------- */ + +/* + * These devices are always present and don't need any board-specific + * setup. + */ +static int __init at91_add_standard_devices(void) +{ + at91_add_device_rtc(); + at91_add_device_watchdog(); + at91_add_device_tc(); + return 0; +} + +arch_initcall(at91_add_standard_devices); diff --git a/arch/arm/mach-at91/at91rm9200_time.c b/arch/arm/mach-at91/at91rm9200_time.c new file mode 100644 index 00000000..1dd69c85 --- /dev/null +++ b/arch/arm/mach-at91/at91rm9200_time.c @@ -0,0 +1,209 @@ +/* + * linux/arch/arm/mach-at91/at91rm9200_time.c + * + * Copyright (C) 2003 SAN People + * Copyright (C) 2003 ATMEL + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/clockchips.h> + +#include <asm/mach/time.h> + +#include <mach/at91_st.h> + +static unsigned long last_crtr; +static u32 irqmask; +static struct clock_event_device clkevt; + +/* + * The ST_CRTR is updated asynchronously to the master clock ... but + * the updates as seen by the CPU don't seem to be strictly monotonic. + * Waiting until we read the same value twice avoids glitching. + */ +static inline unsigned long read_CRTR(void) +{ + unsigned long x1, x2; + + x1 = at91_sys_read(AT91_ST_CRTR); + do { + x2 = at91_sys_read(AT91_ST_CRTR); + if (x1 == x2) + break; + x1 = x2; + } while (1); + return x1; +} + +/* + * IRQ handler for the timer. + */ +static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id) +{ + u32 sr = at91_sys_read(AT91_ST_SR) & irqmask; + + /* + * irqs should be disabled here, but as the irq is shared they are only + * guaranteed to be off if the timer irq is registered first. + */ + WARN_ON_ONCE(!irqs_disabled()); + + /* simulate "oneshot" timer with alarm */ + if (sr & AT91_ST_ALMS) { + clkevt.event_handler(&clkevt); + return IRQ_HANDLED; + } + + /* periodic mode should handle delayed ticks */ + if (sr & AT91_ST_PITS) { + u32 crtr = read_CRTR(); + + while (((crtr - last_crtr) & AT91_ST_CRTV) >= LATCH) { + last_crtr += LATCH; + clkevt.event_handler(&clkevt); + } + return IRQ_HANDLED; + } + + /* this irq is shared ... */ + return IRQ_NONE; +} + +static struct irqaction at91rm9200_timer_irq = { + .name = "at91_tick", + .flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .handler = at91rm9200_timer_interrupt +}; + +static cycle_t read_clk32k(struct clocksource *cs) +{ + return read_CRTR(); +} + +static struct clocksource clk32k = { + .name = "32k_counter", + .rating = 150, + .read = read_clk32k, + .mask = CLOCKSOURCE_MASK(20), + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +static void +clkevt32k_mode(enum clock_event_mode mode, struct clock_event_device *dev) +{ + /* Disable and flush pending timer interrupts */ + at91_sys_write(AT91_ST_IDR, AT91_ST_PITS | AT91_ST_ALMS); + (void) at91_sys_read(AT91_ST_SR); + + last_crtr = read_CRTR(); + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + /* PIT for periodic irqs; fixed rate of 1/HZ */ + irqmask = AT91_ST_PITS; + at91_sys_write(AT91_ST_PIMR, LATCH); + break; + case CLOCK_EVT_MODE_ONESHOT: + /* ALM for oneshot irqs, set by next_event() + * before 32 seconds have passed + */ + irqmask = AT91_ST_ALMS; + at91_sys_write(AT91_ST_RTAR, last_crtr); + break; + case CLOCK_EVT_MODE_SHUTDOWN: + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_RESUME: + irqmask = 0; + break; + } + at91_sys_write(AT91_ST_IER, irqmask); +} + +static int +clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev) +{ + u32 alm; + int status = 0; + + BUG_ON(delta < 2); + + /* The alarm IRQ uses absolute time (now+delta), not the relative + * time (delta) in our calling convention. Like all clockevents + * using such "match" hardware, we have a race to defend against. + * + * Our defense here is to have set up the clockevent device so the + * delta is at least two. That way we never end up writing RTAR + * with the value then held in CRTR ... which would mean the match + * wouldn't trigger until 32 seconds later, after CRTR wraps. + */ + alm = read_CRTR(); + + /* Cancel any pending alarm; flush any pending IRQ */ + at91_sys_write(AT91_ST_RTAR, alm); + (void) at91_sys_read(AT91_ST_SR); + + /* Schedule alarm by writing RTAR. */ + alm += delta; + at91_sys_write(AT91_ST_RTAR, alm); + + return status; +} + +static struct clock_event_device clkevt = { + .name = "at91_tick", + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .shift = 32, + .rating = 150, + .set_next_event = clkevt32k_next_event, + .set_mode = clkevt32k_mode, +}; + +/* + * ST (system timer) module supports both clockevents and clocksource. + */ +void __init at91rm9200_timer_init(void) +{ + /* Disable all timer interrupts, and clear any pending ones */ + at91_sys_write(AT91_ST_IDR, + AT91_ST_PITS | AT91_ST_WDOVF | AT91_ST_RTTINC | AT91_ST_ALMS); + (void) at91_sys_read(AT91_ST_SR); + + /* Make IRQs happen for the system timer */ + setup_irq(AT91_ID_SYS, &at91rm9200_timer_irq); + + /* The 32KiHz "Slow Clock" (tick every 30517.58 nanoseconds) is used + * directly for the clocksource and all clockevents, after adjusting + * its prescaler from the 1 Hz default. + */ + at91_sys_write(AT91_ST_RTMR, 1); + + /* Setup timer clockevent, with minimum of two ticks (important!!) */ + clkevt.mult = div_sc(AT91_SLOW_CLOCK, NSEC_PER_SEC, clkevt.shift); + clkevt.max_delta_ns = clockevent_delta2ns(AT91_ST_ALMV, &clkevt); + clkevt.min_delta_ns = clockevent_delta2ns(2, &clkevt) + 1; + clkevt.cpumask = cpumask_of(0); + clockevents_register_device(&clkevt); + + /* register clocksource */ + clocksource_register_hz(&clk32k, AT91_SLOW_CLOCK); +} + +struct sys_timer at91rm9200_timer = { + .init = at91rm9200_timer_init, +}; + diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c new file mode 100644 index 00000000..eeb94785 --- /dev/null +++ b/arch/arm/mach-at91/at91sam9260.c @@ -0,0 +1,434 @@ +/* + * arch/arm/mach-at91/at91sam9260.c + * + * Copyright (C) 2006 SAN People + * + * 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. + * + */ + +#include <linux/module.h> +#include <linux/pm.h> + +#include <asm/irq.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <mach/cpu.h> +#include <mach/at91sam9260.h> +#include <mach/at91_pmc.h> +#include <mach/at91_rstc.h> +#include <mach/at91_shdwc.h> + +#include "generic.h" +#include "clock.h" + +static struct map_desc at91sam9260_io_desc[] __initdata = { + { + .virtual = AT91_VA_BASE_SYS, + .pfn = __phys_to_pfn(AT91_BASE_SYS), + .length = SZ_16K, + .type = MT_DEVICE, + } +}; + +static struct map_desc at91sam9260_sram_desc[] __initdata = { + { + .virtual = AT91_IO_VIRT_BASE - AT91SAM9260_SRAM0_SIZE, + .pfn = __phys_to_pfn(AT91SAM9260_SRAM0_BASE), + .length = AT91SAM9260_SRAM0_SIZE, + .type = MT_DEVICE, + }, { + .virtual = AT91_IO_VIRT_BASE - AT91SAM9260_SRAM0_SIZE - AT91SAM9260_SRAM1_SIZE, + .pfn = __phys_to_pfn(AT91SAM9260_SRAM1_BASE), + .length = AT91SAM9260_SRAM1_SIZE, + .type = MT_DEVICE, + } +}; + +static struct map_desc at91sam9g20_sram_desc[] __initdata = { + { + .virtual = AT91_IO_VIRT_BASE - AT91SAM9G20_SRAM0_SIZE, + .pfn = __phys_to_pfn(AT91SAM9G20_SRAM0_BASE), + .length = AT91SAM9G20_SRAM0_SIZE, + .type = MT_DEVICE, + }, { + .virtual = AT91_IO_VIRT_BASE - AT91SAM9G20_SRAM0_SIZE - AT91SAM9G20_SRAM1_SIZE, + .pfn = __phys_to_pfn(AT91SAM9G20_SRAM1_BASE), + .length = AT91SAM9G20_SRAM1_SIZE, + .type = MT_DEVICE, + } +}; + +static struct map_desc at91sam9xe_sram_desc[] __initdata = { + { + .pfn = __phys_to_pfn(AT91SAM9XE_SRAM_BASE), + .type = MT_DEVICE, + } +}; + +/* -------------------------------------------------------------------- + * Clocks + * -------------------------------------------------------------------- */ + +/* + * The peripheral clocks. + */ +static struct clk pioA_clk = { + .name = "pioA_clk", + .pmc_mask = 1 << AT91SAM9260_ID_PIOA, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioB_clk = { + .name = "pioB_clk", + .pmc_mask = 1 << AT91SAM9260_ID_PIOB, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioC_clk = { + .name = "pioC_clk", + .pmc_mask = 1 << AT91SAM9260_ID_PIOC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk adc_clk = { + .name = "adc_clk", + .pmc_mask = 1 << AT91SAM9260_ID_ADC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart0_clk = { + .name = "usart0_clk", + .pmc_mask = 1 << AT91SAM9260_ID_US0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart1_clk = { + .name = "usart1_clk", + .pmc_mask = 1 << AT91SAM9260_ID_US1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart2_clk = { + .name = "usart2_clk", + .pmc_mask = 1 << AT91SAM9260_ID_US2, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk mmc_clk = { + .name = "mci_clk", + .pmc_mask = 1 << AT91SAM9260_ID_MCI, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk udc_clk = { + .name = "udc_clk", + .pmc_mask = 1 << AT91SAM9260_ID_UDP, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk twi_clk = { + .name = "twi_clk", + .pmc_mask = 1 << AT91SAM9260_ID_TWI, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk spi0_clk = { + .name = "spi0_clk", + .pmc_mask = 1 << AT91SAM9260_ID_SPI0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk spi1_clk = { + .name = "spi1_clk", + .pmc_mask = 1 << AT91SAM9260_ID_SPI1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ssc_clk = { + .name = "ssc_clk", + .pmc_mask = 1 << AT91SAM9260_ID_SSC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk tc0_clk = { + .name = "tc0_clk", + .pmc_mask = 1 << AT91SAM9260_ID_TC0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk tc1_clk = { + .name = "tc1_clk", + .pmc_mask = 1 << AT91SAM9260_ID_TC1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk tc2_clk = { + .name = "tc2_clk", + .pmc_mask = 1 << AT91SAM9260_ID_TC2, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ohci_clk = { + .name = "ohci_clk", + .pmc_mask = 1 << AT91SAM9260_ID_UHP, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk macb_clk = { + .name = "macb_clk", + .pmc_mask = 1 << AT91SAM9260_ID_EMAC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk isi_clk = { + .name = "isi_clk", + .pmc_mask = 1 << AT91SAM9260_ID_ISI, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart3_clk = { + .name = "usart3_clk", + .pmc_mask = 1 << AT91SAM9260_ID_US3, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart4_clk = { + .name = "usart4_clk", + .pmc_mask = 1 << AT91SAM9260_ID_US4, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart5_clk = { + .name = "usart5_clk", + .pmc_mask = 1 << AT91SAM9260_ID_US5, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk tc3_clk = { + .name = "tc3_clk", + .pmc_mask = 1 << AT91SAM9260_ID_TC3, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk tc4_clk = { + .name = "tc4_clk", + .pmc_mask = 1 << AT91SAM9260_ID_TC4, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk tc5_clk = { + .name = "tc5_clk", + .pmc_mask = 1 << AT91SAM9260_ID_TC5, + .type = CLK_TYPE_PERIPHERAL, +}; + +static struct clk *periph_clocks[] __initdata = { + &pioA_clk, + &pioB_clk, + &pioC_clk, + &adc_clk, + &usart0_clk, + &usart1_clk, + &usart2_clk, + &mmc_clk, + &udc_clk, + &twi_clk, + &spi0_clk, + &spi1_clk, + &ssc_clk, + &tc0_clk, + &tc1_clk, + &tc2_clk, + &ohci_clk, + &macb_clk, + &isi_clk, + &usart3_clk, + &usart4_clk, + &usart5_clk, + &tc3_clk, + &tc4_clk, + &tc5_clk, + // irq0 .. irq2 +}; + +static struct clk_lookup periph_clocks_lookups[] = { + CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), + CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), + CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), + CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk), + CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk), + CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tc3_clk), + CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.1", &tc4_clk), + CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.1", &tc5_clk), + CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc_clk), +}; + +static struct clk_lookup usart_clocks_lookups[] = { + CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck), + CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk), + CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk), + CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk), + CLKDEV_CON_DEV_ID("usart", "atmel_usart.4", &usart3_clk), + CLKDEV_CON_DEV_ID("usart", "atmel_usart.5", &usart4_clk), + CLKDEV_CON_DEV_ID("usart", "atmel_usart.6", &usart5_clk), +}; + +/* + * The two programmable clocks. + * You must configure pin multiplexing to bring these signals out. + */ +static struct clk pck0 = { + .name = "pck0", + .pmc_mask = AT91_PMC_PCK0, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 0, +}; +static struct clk pck1 = { + .name = "pck1", + .pmc_mask = AT91_PMC_PCK1, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 1, +}; + +static void __init at91sam9260_register_clocks(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) + clk_register(periph_clocks[i]); + + clkdev_add_table(periph_clocks_lookups, + ARRAY_SIZE(periph_clocks_lookups)); + clkdev_add_table(usart_clocks_lookups, + ARRAY_SIZE(usart_clocks_lookups)); + + clk_register(&pck0); + clk_register(&pck1); +} + +static struct clk_lookup console_clock_lookup; + +void __init at91sam9260_set_console_clock(int id) +{ + if (id >= ARRAY_SIZE(usart_clocks_lookups)) + return; + + console_clock_lookup.con_id = "usart"; + console_clock_lookup.clk = usart_clocks_lookups[id].clk; + clkdev_add(&console_clock_lookup); +} + +/* -------------------------------------------------------------------- + * GPIO + * -------------------------------------------------------------------- */ + +static struct at91_gpio_bank at91sam9260_gpio[] = { + { + .id = AT91SAM9260_ID_PIOA, + .offset = AT91_PIOA, + .clock = &pioA_clk, + }, { + .id = AT91SAM9260_ID_PIOB, + .offset = AT91_PIOB, + .clock = &pioB_clk, + }, { + .id = AT91SAM9260_ID_PIOC, + .offset = AT91_PIOC, + .clock = &pioC_clk, + } +}; + +static void at91sam9260_poweroff(void) +{ + at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW); +} + + +/* -------------------------------------------------------------------- + * AT91SAM9260 processor initialization + * -------------------------------------------------------------------- */ + +static void __init at91sam9xe_map_io(void) +{ + unsigned long cidr, sram_size; + + cidr = at91_sys_read(AT91_DBGU_CIDR); + + switch (cidr & AT91_CIDR_SRAMSIZ) { + case AT91_CIDR_SRAMSIZ_32K: + sram_size = 2 * SZ_16K; + break; + case AT91_CIDR_SRAMSIZ_16K: + default: + sram_size = SZ_16K; + } + + at91sam9xe_sram_desc->virtual = AT91_IO_VIRT_BASE - sram_size; + at91sam9xe_sram_desc->length = sram_size; + + iotable_init(at91sam9xe_sram_desc, ARRAY_SIZE(at91sam9xe_sram_desc)); +} + +void __init at91sam9260_map_io(void) +{ + /* Map peripherals */ + iotable_init(at91sam9260_io_desc, ARRAY_SIZE(at91sam9260_io_desc)); + + if (cpu_is_at91sam9xe()) + at91sam9xe_map_io(); + else if (cpu_is_at91sam9g20()) + iotable_init(at91sam9g20_sram_desc, ARRAY_SIZE(at91sam9g20_sram_desc)); + else + iotable_init(at91sam9260_sram_desc, ARRAY_SIZE(at91sam9260_sram_desc)); +} + +void __init at91sam9260_initialize(unsigned long main_clock) +{ + at91_arch_reset = at91sam9_alt_reset; + pm_power_off = at91sam9260_poweroff; + at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1) + | (1 << AT91SAM9260_ID_IRQ2); + + /* Init clock subsystem */ + at91_clock_init(main_clock); + + /* Register the processor-specific clocks */ + at91sam9260_register_clocks(); + + /* Register GPIO subsystem */ + at91_gpio_init(at91sam9260_gpio, 3); +} + +/* -------------------------------------------------------------------- + * Interrupt initialization + * -------------------------------------------------------------------- */ + +/* + * The default interrupt priority levels (0 = lowest, 7 = highest). + */ +static unsigned int at91sam9260_default_irq_priority[NR_AIC_IRQS] __initdata = { + 7, /* Advanced Interrupt Controller */ + 7, /* System Peripherals */ + 1, /* Parallel IO Controller A */ + 1, /* Parallel IO Controller B */ + 1, /* Parallel IO Controller C */ + 0, /* Analog-to-Digital Converter */ + 5, /* USART 0 */ + 5, /* USART 1 */ + 5, /* USART 2 */ + 0, /* Multimedia Card Interface */ + 2, /* USB Device Port */ + 6, /* Two-Wire Interface */ + 5, /* Serial Peripheral Interface 0 */ + 5, /* Serial Peripheral Interface 1 */ + 5, /* Serial Synchronous Controller */ + 0, + 0, + 0, /* Timer Counter 0 */ + 0, /* Timer Counter 1 */ + 0, /* Timer Counter 2 */ + 2, /* USB Host port */ + 3, /* Ethernet */ + 0, /* Image Sensor Interface */ + 5, /* USART 3 */ + 5, /* USART 4 */ + 5, /* USART 5 */ + 0, /* Timer Counter 3 */ + 0, /* Timer Counter 4 */ + 0, /* Timer Counter 5 */ + 0, /* Advanced Interrupt Controller */ + 0, /* Advanced Interrupt Controller */ + 0, /* Advanced Interrupt Controller */ +}; + +void __init at91sam9260_init_interrupts(unsigned int priority[NR_AIC_IRQS]) +{ + if (!priority) + priority = at91sam9260_default_irq_priority; + + /* Initialize the AIC interrupt controller */ + at91_aic_init(priority); + + /* Enable GPIO interrupts */ + at91_gpio_irq_setup(); +} diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c new file mode 100644 index 00000000..39f81f47 --- /dev/null +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -0,0 +1,1328 @@ +/* + * arch/arm/mach-at91/at91sam9260_devices.c + * + * Copyright (C) 2006 Atmel + * + * 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. + * + */ +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <linux/dma-mapping.h> +#include <linux/platform_device.h> +#include <linux/i2c-gpio.h> + +#include <mach/board.h> +#include <mach/gpio.h> +#include <mach/cpu.h> +#include <mach/at91sam9260.h> +#include <mach/at91sam9260_matrix.h> +#include <mach/at91sam9_smc.h> + +#include "generic.h" + + +/* -------------------------------------------------------------------- + * USB Host + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) +static u64 ohci_dmamask = DMA_BIT_MASK(32); +static struct at91_usbh_data usbh_data; + +static struct resource usbh_resources[] = { + [0] = { + .start = AT91SAM9260_UHP_BASE, + .end = AT91SAM9260_UHP_BASE + SZ_1M - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_UHP, + .end = AT91SAM9260_ID_UHP, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91_usbh_device = { + .name = "at91_ohci", + .id = -1, + .dev = { + .dma_mask = &ohci_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &usbh_data, + }, + .resource = usbh_resources, + .num_resources = ARRAY_SIZE(usbh_resources), +}; + +void __init at91_add_device_usbh(struct at91_usbh_data *data) +{ + if (!data) + return; + + usbh_data = *data; + platform_device_register(&at91_usbh_device); +} +#else +void __init at91_add_device_usbh(struct at91_usbh_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * USB Device (Gadget) + * -------------------------------------------------------------------- */ + +#ifdef CONFIG_USB_GADGET_AT91 +static struct at91_udc_data udc_data; + +static struct resource udc_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_UDP, + .end = AT91SAM9260_BASE_UDP + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_UDP, + .end = AT91SAM9260_ID_UDP, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91_udc_device = { + .name = "at91_udc", + .id = -1, + .dev = { + .platform_data = &udc_data, + }, + .resource = udc_resources, + .num_resources = ARRAY_SIZE(udc_resources), +}; + +void __init at91_add_device_udc(struct at91_udc_data *data) +{ + if (!data) + return; + + if (data->vbus_pin) { + at91_set_gpio_input(data->vbus_pin, 0); + at91_set_deglitch(data->vbus_pin, 1); + } + + /* Pullup pin is handled internally by USB device peripheral */ + + udc_data = *data; + platform_device_register(&at91_udc_device); +} +#else +void __init at91_add_device_udc(struct at91_udc_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * Ethernet + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) +static u64 eth_dmamask = DMA_BIT_MASK(32); +static struct at91_eth_data eth_data; + +static struct resource eth_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_EMAC, + .end = AT91SAM9260_BASE_EMAC + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_EMAC, + .end = AT91SAM9260_ID_EMAC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9260_eth_device = { + .name = "macb", + .id = -1, + .dev = { + .dma_mask = ð_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = ð_data, + }, + .resource = eth_resources, + .num_resources = ARRAY_SIZE(eth_resources), +}; + +void __init at91_add_device_eth(struct at91_eth_data *data) +{ + if (!data) + return; + + if (data->phy_irq_pin) { + at91_set_gpio_input(data->phy_irq_pin, 0); + at91_set_deglitch(data->phy_irq_pin, 1); + } + + /* Pins used for MII and RMII */ + at91_set_A_periph(AT91_PIN_PA19, 0); /* ETXCK_EREFCK */ + at91_set_A_periph(AT91_PIN_PA17, 0); /* ERXDV */ + at91_set_A_periph(AT91_PIN_PA14, 0); /* ERX0 */ + at91_set_A_periph(AT91_PIN_PA15, 0); /* ERX1 */ + at91_set_A_periph(AT91_PIN_PA18, 0); /* ERXER */ + at91_set_A_periph(AT91_PIN_PA16, 0); /* ETXEN */ + at91_set_A_periph(AT91_PIN_PA12, 0); /* ETX0 */ + at91_set_A_periph(AT91_PIN_PA13, 0); /* ETX1 */ + at91_set_A_periph(AT91_PIN_PA21, 0); /* EMDIO */ + at91_set_A_periph(AT91_PIN_PA20, 0); /* EMDC */ + + if (!data->is_rmii) { + at91_set_B_periph(AT91_PIN_PA28, 0); /* ECRS */ + at91_set_B_periph(AT91_PIN_PA29, 0); /* ECOL */ + at91_set_B_periph(AT91_PIN_PA25, 0); /* ERX2 */ + at91_set_B_periph(AT91_PIN_PA26, 0); /* ERX3 */ + at91_set_B_periph(AT91_PIN_PA27, 0); /* ERXCK */ + at91_set_B_periph(AT91_PIN_PA23, 0); /* ETX2 */ + at91_set_B_periph(AT91_PIN_PA24, 0); /* ETX3 */ + at91_set_B_periph(AT91_PIN_PA22, 0); /* ETXER */ + } + + eth_data = *data; + platform_device_register(&at91sam9260_eth_device); +} +#else +void __init at91_add_device_eth(struct at91_eth_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * MMC / SD + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) +static u64 mmc_dmamask = DMA_BIT_MASK(32); +static struct at91_mmc_data mmc_data; + +static struct resource mmc_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_MCI, + .end = AT91SAM9260_BASE_MCI + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_MCI, + .end = AT91SAM9260_ID_MCI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9260_mmc_device = { + .name = "at91_mci", + .id = -1, + .dev = { + .dma_mask = &mmc_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &mmc_data, + }, + .resource = mmc_resources, + .num_resources = ARRAY_SIZE(mmc_resources), +}; + +void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) +{ + if (!data) + return; + + /* input/irq */ + if (data->det_pin) { + at91_set_gpio_input(data->det_pin, 1); + at91_set_deglitch(data->det_pin, 1); + } + if (data->wp_pin) + at91_set_gpio_input(data->wp_pin, 1); + if (data->vcc_pin) + at91_set_gpio_output(data->vcc_pin, 0); + + /* CLK */ + at91_set_A_periph(AT91_PIN_PA8, 0); + + if (data->slot_b) { + /* CMD */ + at91_set_B_periph(AT91_PIN_PA1, 1); + + /* DAT0, maybe DAT1..DAT3 */ + at91_set_B_periph(AT91_PIN_PA0, 1); + if (data->wire4) { + at91_set_B_periph(AT91_PIN_PA5, 1); + at91_set_B_periph(AT91_PIN_PA4, 1); + at91_set_B_periph(AT91_PIN_PA3, 1); + } + } else { + /* CMD */ + at91_set_A_periph(AT91_PIN_PA7, 1); + + /* DAT0, maybe DAT1..DAT3 */ + at91_set_A_periph(AT91_PIN_PA6, 1); + if (data->wire4) { + at91_set_A_periph(AT91_PIN_PA9, 1); + at91_set_A_periph(AT91_PIN_PA10, 1); + at91_set_A_periph(AT91_PIN_PA11, 1); + } + } + + mmc_data = *data; + platform_device_register(&at91sam9260_mmc_device); +} +#else +void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} +#endif + +/* -------------------------------------------------------------------- + * MMC / SD Slot for Atmel MCI Driver + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE) +static u64 mmc_dmamask = DMA_BIT_MASK(32); +static struct mci_platform_data mmc_data; + +static struct resource mmc_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_MCI, + .end = AT91SAM9260_BASE_MCI + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_MCI, + .end = AT91SAM9260_ID_MCI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9260_mmc_device = { + .name = "atmel_mci", + .id = -1, + .dev = { + .dma_mask = &mmc_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &mmc_data, + }, + .resource = mmc_resources, + .num_resources = ARRAY_SIZE(mmc_resources), +}; + +void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) +{ + unsigned int i; + unsigned int slot_count = 0; + + if (!data) + return; + + for (i = 0; i < ATMEL_MCI_MAX_NR_SLOTS; i++) { + if (data->slot[i].bus_width) { + /* input/irq */ + if (data->slot[i].detect_pin) { + at91_set_gpio_input(data->slot[i].detect_pin, 1); + at91_set_deglitch(data->slot[i].detect_pin, 1); + } + if (data->slot[i].wp_pin) + at91_set_gpio_input(data->slot[i].wp_pin, 1); + + switch (i) { + case 0: + /* CMD */ + at91_set_A_periph(AT91_PIN_PA7, 1); + /* DAT0, maybe DAT1..DAT3 */ + at91_set_A_periph(AT91_PIN_PA6, 1); + if (data->slot[i].bus_width == 4) { + at91_set_A_periph(AT91_PIN_PA9, 1); + at91_set_A_periph(AT91_PIN_PA10, 1); + at91_set_A_periph(AT91_PIN_PA11, 1); + } + slot_count++; + break; + case 1: + /* CMD */ + at91_set_B_periph(AT91_PIN_PA1, 1); + /* DAT0, maybe DAT1..DAT3 */ + at91_set_B_periph(AT91_PIN_PA0, 1); + if (data->slot[i].bus_width == 4) { + at91_set_B_periph(AT91_PIN_PA5, 1); + at91_set_B_periph(AT91_PIN_PA4, 1); + at91_set_B_periph(AT91_PIN_PA3, 1); + } + slot_count++; + break; + default: + printk(KERN_ERR + "AT91: SD/MMC slot %d not available\n", i); + break; + } + } + } + + if (slot_count) { + /* CLK */ + at91_set_A_periph(AT91_PIN_PA8, 0); + + mmc_data = *data; + platform_device_register(&at91sam9260_mmc_device); + } +} +#else +void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * NAND / SmartMedia + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE) +static struct atmel_nand_data nand_data; + +#define NAND_BASE AT91_CHIPSELECT_3 + +static struct resource nand_resources[] = { + [0] = { + .start = NAND_BASE, + .end = NAND_BASE + SZ_256M - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91_BASE_SYS + AT91_ECC, + .end = AT91_BASE_SYS + AT91_ECC + SZ_512 - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device at91sam9260_nand_device = { + .name = "atmel_nand", + .id = -1, + .dev = { + .platform_data = &nand_data, + }, + .resource = nand_resources, + .num_resources = ARRAY_SIZE(nand_resources), +}; + +void __init at91_add_device_nand(struct atmel_nand_data *data) +{ + unsigned long csa; + + if (!data) + return; + + csa = at91_sys_read(AT91_MATRIX_EBICSA); + at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); + + /* enable pin */ + if (data->enable_pin) + at91_set_gpio_output(data->enable_pin, 1); + + /* ready/busy pin */ + if (data->rdy_pin) + at91_set_gpio_input(data->rdy_pin, 1); + + /* card detect pin */ + if (data->det_pin) + at91_set_gpio_input(data->det_pin, 1); + + nand_data = *data; + platform_device_register(&at91sam9260_nand_device); +} +#else +void __init at91_add_device_nand(struct atmel_nand_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * TWI (i2c) + * -------------------------------------------------------------------- */ + +/* + * Prefer the GPIO code since the TWI controller isn't robust + * (gets overruns and underruns under load) and can only issue + * repeated STARTs in one scenario (the driver doesn't yet handle them). + */ + +#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) + +static struct i2c_gpio_platform_data pdata = { + .sda_pin = AT91_PIN_PA23, + .sda_is_open_drain = 1, + .scl_pin = AT91_PIN_PA24, + .scl_is_open_drain = 1, + .udelay = 2, /* ~100 kHz */ +}; + +static struct platform_device at91sam9260_twi_device = { + .name = "i2c-gpio", + .id = -1, + .dev.platform_data = &pdata, +}; + +void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) +{ + at91_set_GPIO_periph(AT91_PIN_PA23, 1); /* TWD (SDA) */ + at91_set_multi_drive(AT91_PIN_PA23, 1); + + at91_set_GPIO_periph(AT91_PIN_PA24, 1); /* TWCK (SCL) */ + at91_set_multi_drive(AT91_PIN_PA24, 1); + + i2c_register_board_info(0, devices, nr_devices); + platform_device_register(&at91sam9260_twi_device); +} + +#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) + +static struct resource twi_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_TWI, + .end = AT91SAM9260_BASE_TWI + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_TWI, + .end = AT91SAM9260_ID_TWI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9260_twi_device = { + .name = "at91_i2c", + .id = -1, + .resource = twi_resources, + .num_resources = ARRAY_SIZE(twi_resources), +}; + +void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) +{ + /* pins used for TWI interface */ + at91_set_A_periph(AT91_PIN_PA23, 0); /* TWD */ + at91_set_multi_drive(AT91_PIN_PA23, 1); + + at91_set_A_periph(AT91_PIN_PA24, 0); /* TWCK */ + at91_set_multi_drive(AT91_PIN_PA24, 1); + + i2c_register_board_info(0, devices, nr_devices); + platform_device_register(&at91sam9260_twi_device); +} +#else +void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {} +#endif + + +/* -------------------------------------------------------------------- + * SPI + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) +static u64 spi_dmamask = DMA_BIT_MASK(32); + +static struct resource spi0_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_SPI0, + .end = AT91SAM9260_BASE_SPI0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_SPI0, + .end = AT91SAM9260_ID_SPI0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9260_spi0_device = { + .name = "atmel_spi", + .id = 0, + .dev = { + .dma_mask = &spi_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = spi0_resources, + .num_resources = ARRAY_SIZE(spi0_resources), +}; + +static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA3, AT91_PIN_PC11, AT91_PIN_PC16, AT91_PIN_PC17 }; + +static struct resource spi1_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_SPI1, + .end = AT91SAM9260_BASE_SPI1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_SPI1, + .end = AT91SAM9260_ID_SPI1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9260_spi1_device = { + .name = "atmel_spi", + .id = 1, + .dev = { + .dma_mask = &spi_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = spi1_resources, + .num_resources = ARRAY_SIZE(spi1_resources), +}; + +static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB3, AT91_PIN_PC5, AT91_PIN_PC4, AT91_PIN_PC3 }; + +void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) +{ + int i; + unsigned long cs_pin; + short enable_spi0 = 0; + short enable_spi1 = 0; + + /* Choose SPI chip-selects */ + for (i = 0; i < nr_devices; i++) { + if (devices[i].controller_data) + cs_pin = (unsigned long) devices[i].controller_data; + else if (devices[i].bus_num == 0) + cs_pin = spi0_standard_cs[devices[i].chip_select]; + else + cs_pin = spi1_standard_cs[devices[i].chip_select]; + + if (devices[i].bus_num == 0) + enable_spi0 = 1; + else + enable_spi1 = 1; + + /* enable chip-select pin */ + at91_set_gpio_output(cs_pin, 1); + + /* pass chip-select pin to driver */ + devices[i].controller_data = (void *) cs_pin; + } + + spi_register_board_info(devices, nr_devices); + + /* Configure SPI bus(es) */ + if (enable_spi0) { + at91_set_A_periph(AT91_PIN_PA0, 0); /* SPI0_MISO */ + at91_set_A_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */ + at91_set_A_periph(AT91_PIN_PA2, 0); /* SPI1_SPCK */ + + platform_device_register(&at91sam9260_spi0_device); + } + if (enable_spi1) { + at91_set_A_periph(AT91_PIN_PB0, 0); /* SPI1_MISO */ + at91_set_A_periph(AT91_PIN_PB1, 0); /* SPI1_MOSI */ + at91_set_A_periph(AT91_PIN_PB2, 0); /* SPI1_SPCK */ + + platform_device_register(&at91sam9260_spi1_device); + } +} +#else +void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {} +#endif + + +/* -------------------------------------------------------------------- + * Timer/Counter blocks + * -------------------------------------------------------------------- */ + +#ifdef CONFIG_ATMEL_TCLIB + +static struct resource tcb0_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_TCB0, + .end = AT91SAM9260_BASE_TCB0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_TC0, + .end = AT91SAM9260_ID_TC0, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = AT91SAM9260_ID_TC1, + .end = AT91SAM9260_ID_TC1, + .flags = IORESOURCE_IRQ, + }, + [3] = { + .start = AT91SAM9260_ID_TC2, + .end = AT91SAM9260_ID_TC2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9260_tcb0_device = { + .name = "atmel_tcb", + .id = 0, + .resource = tcb0_resources, + .num_resources = ARRAY_SIZE(tcb0_resources), +}; + +static struct resource tcb1_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_TCB1, + .end = AT91SAM9260_BASE_TCB1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_TC3, + .end = AT91SAM9260_ID_TC3, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = AT91SAM9260_ID_TC4, + .end = AT91SAM9260_ID_TC4, + .flags = IORESOURCE_IRQ, + }, + [3] = { + .start = AT91SAM9260_ID_TC5, + .end = AT91SAM9260_ID_TC5, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9260_tcb1_device = { + .name = "atmel_tcb", + .id = 1, + .resource = tcb1_resources, + .num_resources = ARRAY_SIZE(tcb1_resources), +}; + +static void __init at91_add_device_tc(void) +{ + platform_device_register(&at91sam9260_tcb0_device); + platform_device_register(&at91sam9260_tcb1_device); +} +#else +static void __init at91_add_device_tc(void) { } +#endif + + +/* -------------------------------------------------------------------- + * RTT + * -------------------------------------------------------------------- */ + +static struct resource rtt_resources[] = { + { + .start = AT91_BASE_SYS + AT91_RTT, + .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device at91sam9260_rtt_device = { + .name = "at91_rtt", + .id = 0, + .resource = rtt_resources, + .num_resources = ARRAY_SIZE(rtt_resources), +}; + +static void __init at91_add_device_rtt(void) +{ + platform_device_register(&at91sam9260_rtt_device); +} + + +/* -------------------------------------------------------------------- + * Watchdog + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) +static struct platform_device at91sam9260_wdt_device = { + .name = "at91_wdt", + .id = -1, + .num_resources = 0, +}; + +static void __init at91_add_device_watchdog(void) +{ + platform_device_register(&at91sam9260_wdt_device); +} +#else +static void __init at91_add_device_watchdog(void) {} +#endif + + +/* -------------------------------------------------------------------- + * SSC -- Synchronous Serial Controller + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE) +static u64 ssc_dmamask = DMA_BIT_MASK(32); + +static struct resource ssc_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_SSC, + .end = AT91SAM9260_BASE_SSC + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_SSC, + .end = AT91SAM9260_ID_SSC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9260_ssc_device = { + .name = "ssc", + .id = 0, + .dev = { + .dma_mask = &ssc_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = ssc_resources, + .num_resources = ARRAY_SIZE(ssc_resources), +}; + +static inline void configure_ssc_pins(unsigned pins) +{ + if (pins & ATMEL_SSC_TF) + at91_set_A_periph(AT91_PIN_PB17, 1); + if (pins & ATMEL_SSC_TK) + at91_set_A_periph(AT91_PIN_PB16, 1); + if (pins & ATMEL_SSC_TD) + at91_set_A_periph(AT91_PIN_PB18, 1); + if (pins & ATMEL_SSC_RD) + at91_set_A_periph(AT91_PIN_PB19, 1); + if (pins & ATMEL_SSC_RK) + at91_set_A_periph(AT91_PIN_PB20, 1); + if (pins & ATMEL_SSC_RF) + at91_set_A_periph(AT91_PIN_PB21, 1); +} + +/* + * SSC controllers are accessed through library code, instead of any + * kind of all-singing/all-dancing driver. For example one could be + * used by a particular I2S audio codec's driver, while another one + * on the same system might be used by a custom data capture driver. + */ +void __init at91_add_device_ssc(unsigned id, unsigned pins) +{ + struct platform_device *pdev; + + /* + * NOTE: caller is responsible for passing information matching + * "pins" to whatever will be using each particular controller. + */ + switch (id) { + case AT91SAM9260_ID_SSC: + pdev = &at91sam9260_ssc_device; + configure_ssc_pins(pins); + break; + default: + return; + } + + platform_device_register(pdev); +} + +#else +void __init at91_add_device_ssc(unsigned id, unsigned pins) {} +#endif + + +/* -------------------------------------------------------------------- + * UART + * -------------------------------------------------------------------- */ +#if defined(CONFIG_SERIAL_ATMEL) +static struct resource dbgu_resources[] = { + [0] = { + .start = AT91_VA_BASE_SYS + AT91_DBGU, + .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91_ID_SYS, + .end = AT91_ID_SYS, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data dbgu_data = { + .use_dma_tx = 0, + .use_dma_rx = 0, /* DBGU not capable of receive DMA */ + .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), +}; + +static u64 dbgu_dmamask = DMA_BIT_MASK(32); + +static struct platform_device at91sam9260_dbgu_device = { + .name = "atmel_usart", + .id = 0, + .dev = { + .dma_mask = &dbgu_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &dbgu_data, + }, + .resource = dbgu_resources, + .num_resources = ARRAY_SIZE(dbgu_resources), +}; + +static inline void configure_dbgu_pins(void) +{ + at91_set_A_periph(AT91_PIN_PB14, 0); /* DRXD */ + at91_set_A_periph(AT91_PIN_PB15, 1); /* DTXD */ +} + +static struct resource uart0_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_US0, + .end = AT91SAM9260_BASE_US0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_US0, + .end = AT91SAM9260_ID_US0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart0_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static u64 uart0_dmamask = DMA_BIT_MASK(32); + +static struct platform_device at91sam9260_uart0_device = { + .name = "atmel_usart", + .id = 1, + .dev = { + .dma_mask = &uart0_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &uart0_data, + }, + .resource = uart0_resources, + .num_resources = ARRAY_SIZE(uart0_resources), +}; + +static inline void configure_usart0_pins(unsigned pins) +{ + at91_set_A_periph(AT91_PIN_PB4, 1); /* TXD0 */ + at91_set_A_periph(AT91_PIN_PB5, 0); /* RXD0 */ + + if (pins & ATMEL_UART_RTS) + at91_set_A_periph(AT91_PIN_PB26, 0); /* RTS0 */ + if (pins & ATMEL_UART_CTS) + at91_set_A_periph(AT91_PIN_PB27, 0); /* CTS0 */ + if (pins & ATMEL_UART_DTR) + at91_set_A_periph(AT91_PIN_PB24, 0); /* DTR0 */ + if (pins & ATMEL_UART_DSR) + at91_set_A_periph(AT91_PIN_PB22, 0); /* DSR0 */ + if (pins & ATMEL_UART_DCD) + at91_set_A_periph(AT91_PIN_PB23, 0); /* DCD0 */ + if (pins & ATMEL_UART_RI) + at91_set_A_periph(AT91_PIN_PB25, 0); /* RI0 */ +} + +static struct resource uart1_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_US1, + .end = AT91SAM9260_BASE_US1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_US1, + .end = AT91SAM9260_ID_US1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart1_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static u64 uart1_dmamask = DMA_BIT_MASK(32); + +static struct platform_device at91sam9260_uart1_device = { + .name = "atmel_usart", + .id = 2, + .dev = { + .dma_mask = &uart1_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &uart1_data, + }, + .resource = uart1_resources, + .num_resources = ARRAY_SIZE(uart1_resources), +}; + +static inline void configure_usart1_pins(unsigned pins) +{ + at91_set_A_periph(AT91_PIN_PB6, 1); /* TXD1 */ + at91_set_A_periph(AT91_PIN_PB7, 0); /* RXD1 */ + + if (pins & ATMEL_UART_RTS) + at91_set_A_periph(AT91_PIN_PB28, 0); /* RTS1 */ + if (pins & ATMEL_UART_CTS) + at91_set_A_periph(AT91_PIN_PB29, 0); /* CTS1 */ +} + +static struct resource uart2_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_US2, + .end = AT91SAM9260_BASE_US2 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_US2, + .end = AT91SAM9260_ID_US2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart2_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static u64 uart2_dmamask = DMA_BIT_MASK(32); + +static struct platform_device at91sam9260_uart2_device = { + .name = "atmel_usart", + .id = 3, + .dev = { + .dma_mask = &uart2_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &uart2_data, + }, + .resource = uart2_resources, + .num_resources = ARRAY_SIZE(uart2_resources), +}; + +static inline void configure_usart2_pins(unsigned pins) +{ + at91_set_A_periph(AT91_PIN_PB8, 1); /* TXD2 */ + at91_set_A_periph(AT91_PIN_PB9, 0); /* RXD2 */ + + if (pins & ATMEL_UART_RTS) + at91_set_A_periph(AT91_PIN_PA4, 0); /* RTS2 */ + if (pins & ATMEL_UART_CTS) + at91_set_A_periph(AT91_PIN_PA5, 0); /* CTS2 */ +} + +static struct resource uart3_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_US3, + .end = AT91SAM9260_BASE_US3 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_US3, + .end = AT91SAM9260_ID_US3, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart3_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static u64 uart3_dmamask = DMA_BIT_MASK(32); + +static struct platform_device at91sam9260_uart3_device = { + .name = "atmel_usart", + .id = 4, + .dev = { + .dma_mask = &uart3_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &uart3_data, + }, + .resource = uart3_resources, + .num_resources = ARRAY_SIZE(uart3_resources), +}; + +static inline void configure_usart3_pins(unsigned pins) +{ + at91_set_A_periph(AT91_PIN_PB10, 1); /* TXD3 */ + at91_set_A_periph(AT91_PIN_PB11, 0); /* RXD3 */ + + if (pins & ATMEL_UART_RTS) + at91_set_B_periph(AT91_PIN_PC8, 0); /* RTS3 */ + if (pins & ATMEL_UART_CTS) + at91_set_B_periph(AT91_PIN_PC10, 0); /* CTS3 */ +} + +static struct resource uart4_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_US4, + .end = AT91SAM9260_BASE_US4 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_US4, + .end = AT91SAM9260_ID_US4, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart4_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static u64 uart4_dmamask = DMA_BIT_MASK(32); + +static struct platform_device at91sam9260_uart4_device = { + .name = "atmel_usart", + .id = 5, + .dev = { + .dma_mask = &uart4_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &uart4_data, + }, + .resource = uart4_resources, + .num_resources = ARRAY_SIZE(uart4_resources), +}; + +static inline void configure_usart4_pins(void) +{ + at91_set_B_periph(AT91_PIN_PA31, 1); /* TXD4 */ + at91_set_B_periph(AT91_PIN_PA30, 0); /* RXD4 */ +} + +static struct resource uart5_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_US5, + .end = AT91SAM9260_BASE_US5 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_US5, + .end = AT91SAM9260_ID_US5, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart5_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static u64 uart5_dmamask = DMA_BIT_MASK(32); + +static struct platform_device at91sam9260_uart5_device = { + .name = "atmel_usart", + .id = 6, + .dev = { + .dma_mask = &uart5_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &uart5_data, + }, + .resource = uart5_resources, + .num_resources = ARRAY_SIZE(uart5_resources), +}; + +static inline void configure_usart5_pins(void) +{ + at91_set_A_periph(AT91_PIN_PB12, 1); /* TXD5 */ + at91_set_A_periph(AT91_PIN_PB13, 0); /* RXD5 */ +} + +static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ +struct platform_device *atmel_default_console_device; /* the serial console device */ + +void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) +{ + struct platform_device *pdev; + struct atmel_uart_data *pdata; + + switch (id) { + case 0: /* DBGU */ + pdev = &at91sam9260_dbgu_device; + configure_dbgu_pins(); + break; + case AT91SAM9260_ID_US0: + pdev = &at91sam9260_uart0_device; + configure_usart0_pins(pins); + break; + case AT91SAM9260_ID_US1: + pdev = &at91sam9260_uart1_device; + configure_usart1_pins(pins); + break; + case AT91SAM9260_ID_US2: + pdev = &at91sam9260_uart2_device; + configure_usart2_pins(pins); + break; + case AT91SAM9260_ID_US3: + pdev = &at91sam9260_uart3_device; + configure_usart3_pins(pins); + break; + case AT91SAM9260_ID_US4: + pdev = &at91sam9260_uart4_device; + configure_usart4_pins(); + break; + case AT91SAM9260_ID_US5: + pdev = &at91sam9260_uart5_device; + configure_usart5_pins(); + break; + default: + return; + } + pdata = pdev->dev.platform_data; + pdata->num = portnr; /* update to mapped ID */ + + if (portnr < ATMEL_MAX_UART) + at91_uarts[portnr] = pdev; +} + +void __init at91_set_serial_console(unsigned portnr) +{ + if (portnr < ATMEL_MAX_UART) { + atmel_default_console_device = at91_uarts[portnr]; + at91sam9260_set_console_clock(at91_uarts[portnr]->id); + } +} + +void __init at91_add_device_serial(void) +{ + int i; + + for (i = 0; i < ATMEL_MAX_UART; i++) { + if (at91_uarts[i]) + platform_device_register(at91_uarts[i]); + } + + if (!atmel_default_console_device) + printk(KERN_INFO "AT91: No default serial console defined.\n"); +} +#else +void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} +void __init at91_set_serial_console(unsigned portnr) {} +void __init at91_add_device_serial(void) {} +#endif + +/* -------------------------------------------------------------------- + * CF/IDE + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_BLK_DEV_IDE_AT91) || defined(CONFIG_BLK_DEV_IDE_AT91_MODULE) || \ + defined(CONFIG_PATA_AT91) || defined(CONFIG_PATA_AT91_MODULE) || \ + defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE) + +static struct at91_cf_data cf0_data; + +static struct resource cf0_resources[] = { + [0] = { + .start = AT91_CHIPSELECT_4, + .end = AT91_CHIPSELECT_4 + SZ_256M - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device cf0_device = { + .id = 0, + .dev = { + .platform_data = &cf0_data, + }, + .resource = cf0_resources, + .num_resources = ARRAY_SIZE(cf0_resources), +}; + +static struct at91_cf_data cf1_data; + +static struct resource cf1_resources[] = { + [0] = { + .start = AT91_CHIPSELECT_5, + .end = AT91_CHIPSELECT_5 + SZ_256M - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device cf1_device = { + .id = 1, + .dev = { + .platform_data = &cf1_data, + }, + .resource = cf1_resources, + .num_resources = ARRAY_SIZE(cf1_resources), +}; + +void __init at91_add_device_cf(struct at91_cf_data *data) +{ + struct platform_device *pdev; + unsigned long csa; + + if (!data) + return; + + csa = at91_sys_read(AT91_MATRIX_EBICSA); + + switch (data->chipselect) { + case 4: + at91_set_multi_drive(AT91_PIN_PC8, 0); + at91_set_A_periph(AT91_PIN_PC8, 0); + csa |= AT91_MATRIX_CS4A_SMC_CF1; + cf0_data = *data; + pdev = &cf0_device; + break; + case 5: + at91_set_multi_drive(AT91_PIN_PC9, 0); + at91_set_A_periph(AT91_PIN_PC9, 0); + csa |= AT91_MATRIX_CS5A_SMC_CF2; + cf1_data = *data; + pdev = &cf1_device; + break; + default: + printk(KERN_ERR "AT91 CF: bad chip-select requested (%u)\n", + data->chipselect); + return; + } + + at91_sys_write(AT91_MATRIX_EBICSA, csa); + + if (data->rst_pin) { + at91_set_multi_drive(data->rst_pin, 0); + at91_set_gpio_output(data->rst_pin, 1); + } + + if (data->irq_pin) { + at91_set_gpio_input(data->irq_pin, 0); + at91_set_deglitch(data->irq_pin, 1); + } + + if (data->det_pin) { + at91_set_gpio_input(data->det_pin, 0); + at91_set_deglitch(data->det_pin, 1); + } + + at91_set_B_periph(AT91_PIN_PC6, 0); /* CFCE1 */ + at91_set_B_periph(AT91_PIN_PC7, 0); /* CFCE2 */ + at91_set_A_periph(AT91_PIN_PC10, 0); /* CFRNW */ + at91_set_A_periph(AT91_PIN_PC15, 1); /* NWAIT */ + + if (data->flags & AT91_CF_TRUE_IDE) +#if defined(CONFIG_PATA_AT91) || defined(CONFIG_PATA_AT91_MODULE) + pdev->name = "pata_at91"; +#elif defined(CONFIG_BLK_DEV_IDE_AT91) || defined(CONFIG_BLK_DEV_IDE_AT91_MODULE) + pdev->name = "at91_ide"; +#else +#warning "board requires AT91_CF_TRUE_IDE: enable either at91_ide or pata_at91" +#endif + else + pdev->name = "at91_cf"; + + platform_device_register(pdev); +} + +#else +void __init at91_add_device_cf(struct at91_cf_data * data) {} +#endif + +/* -------------------------------------------------------------------- */ +/* + * These devices are always present and don't need any board-specific + * setup. + */ +static int __init at91_add_standard_devices(void) +{ + at91_add_device_rtt(); + at91_add_device_watchdog(); + at91_add_device_tc(); + return 0; +} + +arch_initcall(at91_add_standard_devices); diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c new file mode 100644 index 00000000..c1483168 --- /dev/null +++ b/arch/arm/mach-at91/at91sam9261.c @@ -0,0 +1,385 @@ +/* + * arch/arm/mach-at91/at91sam9261.c + * + * Copyright (C) 2005 SAN People + * + * 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. + * + */ + +#include <linux/module.h> +#include <linux/pm.h> + +#include <asm/irq.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <mach/cpu.h> +#include <mach/at91sam9261.h> +#include <mach/at91_pmc.h> +#include <mach/at91_rstc.h> +#include <mach/at91_shdwc.h> + +#include "generic.h" +#include "clock.h" + +static struct map_desc at91sam9261_io_desc[] __initdata = { + { + .virtual = AT91_VA_BASE_SYS, + .pfn = __phys_to_pfn(AT91_BASE_SYS), + .length = SZ_16K, + .type = MT_DEVICE, + }, +}; + +static struct map_desc at91sam9261_sram_desc[] __initdata = { + { + .virtual = AT91_IO_VIRT_BASE - AT91SAM9261_SRAM_SIZE, + .pfn = __phys_to_pfn(AT91SAM9261_SRAM_BASE), + .length = AT91SAM9261_SRAM_SIZE, + .type = MT_DEVICE, + }, +}; + +static struct map_desc at91sam9g10_sram_desc[] __initdata = { + { + .virtual = AT91_IO_VIRT_BASE - AT91SAM9G10_SRAM_SIZE, + .pfn = __phys_to_pfn(AT91SAM9G10_SRAM_BASE), + .length = AT91SAM9G10_SRAM_SIZE, + .type = MT_DEVICE, + }, +}; + +/* -------------------------------------------------------------------- + * Clocks + * -------------------------------------------------------------------- */ + +/* + * The peripheral clocks. + */ +static struct clk pioA_clk = { + .name = "pioA_clk", + .pmc_mask = 1 << AT91SAM9261_ID_PIOA, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioB_clk = { + .name = "pioB_clk", + .pmc_mask = 1 << AT91SAM9261_ID_PIOB, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioC_clk = { + .name = "pioC_clk", + .pmc_mask = 1 << AT91SAM9261_ID_PIOC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart0_clk = { + .name = "usart0_clk", + .pmc_mask = 1 << AT91SAM9261_ID_US0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart1_clk = { + .name = "usart1_clk", + .pmc_mask = 1 << AT91SAM9261_ID_US1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart2_clk = { + .name = "usart2_clk", + .pmc_mask = 1 << AT91SAM9261_ID_US2, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk mmc_clk = { + .name = "mci_clk", + .pmc_mask = 1 << AT91SAM9261_ID_MCI, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk udc_clk = { + .name = "udc_clk", + .pmc_mask = 1 << AT91SAM9261_ID_UDP, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk twi_clk = { + .name = "twi_clk", + .pmc_mask = 1 << AT91SAM9261_ID_TWI, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk spi0_clk = { + .name = "spi0_clk", + .pmc_mask = 1 << AT91SAM9261_ID_SPI0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk spi1_clk = { + .name = "spi1_clk", + .pmc_mask = 1 << AT91SAM9261_ID_SPI1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ssc0_clk = { + .name = "ssc0_clk", + .pmc_mask = 1 << AT91SAM9261_ID_SSC0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ssc1_clk = { + .name = "ssc1_clk", + .pmc_mask = 1 << AT91SAM9261_ID_SSC1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ssc2_clk = { + .name = "ssc2_clk", + .pmc_mask = 1 << AT91SAM9261_ID_SSC2, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk tc0_clk = { + .name = "tc0_clk", + .pmc_mask = 1 << AT91SAM9261_ID_TC0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk tc1_clk = { + .name = "tc1_clk", + .pmc_mask = 1 << AT91SAM9261_ID_TC1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk tc2_clk = { + .name = "tc2_clk", + .pmc_mask = 1 << AT91SAM9261_ID_TC2, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ohci_clk = { + .name = "ohci_clk", + .pmc_mask = 1 << AT91SAM9261_ID_UHP, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk lcdc_clk = { + .name = "lcdc_clk", + .pmc_mask = 1 << AT91SAM9261_ID_LCDC, + .type = CLK_TYPE_PERIPHERAL, +}; + +static struct clk *periph_clocks[] __initdata = { + &pioA_clk, + &pioB_clk, + &pioC_clk, + &usart0_clk, + &usart1_clk, + &usart2_clk, + &mmc_clk, + &udc_clk, + &twi_clk, + &spi0_clk, + &spi1_clk, + &ssc0_clk, + &ssc1_clk, + &ssc2_clk, + &tc0_clk, + &tc1_clk, + &tc2_clk, + &ohci_clk, + &lcdc_clk, + // irq0 .. irq2 +}; + +static struct clk_lookup periph_clocks_lookups[] = { + CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), + CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), + CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), + CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk), + CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc1_clk), + CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), + CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), + CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk), +}; + +static struct clk_lookup usart_clocks_lookups[] = { + CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck), + CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk), + CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk), + CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk), +}; + +/* + * The four programmable clocks. + * You must configure pin multiplexing to bring these signals out. + */ +static struct clk pck0 = { + .name = "pck0", + .pmc_mask = AT91_PMC_PCK0, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 0, +}; +static struct clk pck1 = { + .name = "pck1", + .pmc_mask = AT91_PMC_PCK1, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 1, +}; +static struct clk pck2 = { + .name = "pck2", + .pmc_mask = AT91_PMC_PCK2, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 2, +}; +static struct clk pck3 = { + .name = "pck3", + .pmc_mask = AT91_PMC_PCK3, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 3, +}; + +/* HClocks */ +static struct clk hck0 = { + .name = "hck0", + .pmc_mask = AT91_PMC_HCK0, + .type = CLK_TYPE_SYSTEM, + .id = 0, +}; +static struct clk hck1 = { + .name = "hck1", + .pmc_mask = AT91_PMC_HCK1, + .type = CLK_TYPE_SYSTEM, + .id = 1, +}; + +static void __init at91sam9261_register_clocks(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) + clk_register(periph_clocks[i]); + + clkdev_add_table(periph_clocks_lookups, + ARRAY_SIZE(periph_clocks_lookups)); + clkdev_add_table(usart_clocks_lookups, + ARRAY_SIZE(usart_clocks_lookups)); + + clk_register(&pck0); + clk_register(&pck1); + clk_register(&pck2); + clk_register(&pck3); + + clk_register(&hck0); + clk_register(&hck1); +} + +static struct clk_lookup console_clock_lookup; + +void __init at91sam9261_set_console_clock(int id) +{ + if (id >= ARRAY_SIZE(usart_clocks_lookups)) + return; + + console_clock_lookup.con_id = "usart"; + console_clock_lookup.clk = usart_clocks_lookups[id].clk; + clkdev_add(&console_clock_lookup); +} + +/* -------------------------------------------------------------------- + * GPIO + * -------------------------------------------------------------------- */ + +static struct at91_gpio_bank at91sam9261_gpio[] = { + { + .id = AT91SAM9261_ID_PIOA, + .offset = AT91_PIOA, + .clock = &pioA_clk, + }, { + .id = AT91SAM9261_ID_PIOB, + .offset = AT91_PIOB, + .clock = &pioB_clk, + }, { + .id = AT91SAM9261_ID_PIOC, + .offset = AT91_PIOC, + .clock = &pioC_clk, + } +}; + +static void at91sam9261_poweroff(void) +{ + at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW); +} + + +/* -------------------------------------------------------------------- + * AT91SAM9261 processor initialization + * -------------------------------------------------------------------- */ + +void __init at91sam9261_map_io(void) +{ + /* Map peripherals */ + iotable_init(at91sam9261_io_desc, ARRAY_SIZE(at91sam9261_io_desc)); + + if (cpu_is_at91sam9g10()) + iotable_init(at91sam9g10_sram_desc, ARRAY_SIZE(at91sam9g10_sram_desc)); + else + iotable_init(at91sam9261_sram_desc, ARRAY_SIZE(at91sam9261_sram_desc)); +} + +void __init at91sam9261_initialize(unsigned long main_clock) +{ + at91_arch_reset = at91sam9_alt_reset; + pm_power_off = at91sam9261_poweroff; + at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1) + | (1 << AT91SAM9261_ID_IRQ2); + + /* Init clock subsystem */ + at91_clock_init(main_clock); + + /* Register the processor-specific clocks */ + at91sam9261_register_clocks(); + + /* Register GPIO subsystem */ + at91_gpio_init(at91sam9261_gpio, 3); +} + +/* -------------------------------------------------------------------- + * Interrupt initialization + * -------------------------------------------------------------------- */ + +/* + * The default interrupt priority levels (0 = lowest, 7 = highest). + */ +static unsigned int at91sam9261_default_irq_priority[NR_AIC_IRQS] __initdata = { + 7, /* Advanced Interrupt Controller */ + 7, /* System Peripherals */ + 1, /* Parallel IO Controller A */ + 1, /* Parallel IO Controller B */ + 1, /* Parallel IO Controller C */ + 0, + 5, /* USART 0 */ + 5, /* USART 1 */ + 5, /* USART 2 */ + 0, /* Multimedia Card Interface */ + 2, /* USB Device Port */ + 6, /* Two-Wire Interface */ + 5, /* Serial Peripheral Interface 0 */ + 5, /* Serial Peripheral Interface 1 */ + 4, /* Serial Synchronous Controller 0 */ + 4, /* Serial Synchronous Controller 1 */ + 4, /* Serial Synchronous Controller 2 */ + 0, /* Timer Counter 0 */ + 0, /* Timer Counter 1 */ + 0, /* Timer Counter 2 */ + 2, /* USB Host port */ + 3, /* LCD Controller */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, /* Advanced Interrupt Controller */ + 0, /* Advanced Interrupt Controller */ + 0, /* Advanced Interrupt Controller */ +}; + +void __init at91sam9261_init_interrupts(unsigned int priority[NR_AIC_IRQS]) +{ + if (!priority) + priority = at91sam9261_default_irq_priority; + + /* Initialize the AIC interrupt controller */ + at91_aic_init(priority); + + /* Enable GPIO interrupts */ + at91_gpio_irq_setup(); +} diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c new file mode 100644 index 00000000..5004bf0a --- /dev/null +++ b/arch/arm/mach-at91/at91sam9261_devices.c @@ -0,0 +1,1053 @@ +/* + * arch/arm/mach-at91/at91sam9261_devices.c + * + * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org> + * Copyright (C) 2005 David Brownell + * + * 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. + * + */ +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <linux/dma-mapping.h> +#include <linux/platform_device.h> +#include <linux/i2c-gpio.h> + +#include <linux/fb.h> +#include <video/atmel_lcdc.h> + +#include <mach/board.h> +#include <mach/gpio.h> +#include <mach/at91sam9261.h> +#include <mach/at91sam9261_matrix.h> +#include <mach/at91sam9_smc.h> + +#include "generic.h" + + +/* -------------------------------------------------------------------- + * USB Host + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) +static u64 ohci_dmamask = DMA_BIT_MASK(32); +static struct at91_usbh_data usbh_data; + +static struct resource usbh_resources[] = { + [0] = { + .start = AT91SAM9261_UHP_BASE, + .end = AT91SAM9261_UHP_BASE + SZ_1M - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_ID_UHP, + .end = AT91SAM9261_ID_UHP, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9261_usbh_device = { + .name = "at91_ohci", + .id = -1, + .dev = { + .dma_mask = &ohci_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &usbh_data, + }, + .resource = usbh_resources, + .num_resources = ARRAY_SIZE(usbh_resources), +}; + +void __init at91_add_device_usbh(struct at91_usbh_data *data) +{ + if (!data) + return; + + usbh_data = *data; + platform_device_register(&at91sam9261_usbh_device); +} +#else +void __init at91_add_device_usbh(struct at91_usbh_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * USB Device (Gadget) + * -------------------------------------------------------------------- */ + +#ifdef CONFIG_USB_GADGET_AT91 +static struct at91_udc_data udc_data; + +static struct resource udc_resources[] = { + [0] = { + .start = AT91SAM9261_BASE_UDP, + .end = AT91SAM9261_BASE_UDP + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_ID_UDP, + .end = AT91SAM9261_ID_UDP, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9261_udc_device = { + .name = "at91_udc", + .id = -1, + .dev = { + .platform_data = &udc_data, + }, + .resource = udc_resources, + .num_resources = ARRAY_SIZE(udc_resources), +}; + +void __init at91_add_device_udc(struct at91_udc_data *data) +{ + if (!data) + return; + + if (data->vbus_pin) { + at91_set_gpio_input(data->vbus_pin, 0); + at91_set_deglitch(data->vbus_pin, 1); + } + + /* Pullup pin is handled internally by USB device peripheral */ + + udc_data = *data; + platform_device_register(&at91sam9261_udc_device); +} +#else +void __init at91_add_device_udc(struct at91_udc_data *data) {} +#endif + +/* -------------------------------------------------------------------- + * MMC / SD + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) +static u64 mmc_dmamask = DMA_BIT_MASK(32); +static struct at91_mmc_data mmc_data; + +static struct resource mmc_resources[] = { + [0] = { + .start = AT91SAM9261_BASE_MCI, + .end = AT91SAM9261_BASE_MCI + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_ID_MCI, + .end = AT91SAM9261_ID_MCI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9261_mmc_device = { + .name = "at91_mci", + .id = -1, + .dev = { + .dma_mask = &mmc_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &mmc_data, + }, + .resource = mmc_resources, + .num_resources = ARRAY_SIZE(mmc_resources), +}; + +void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) +{ + if (!data) + return; + + /* input/irq */ + if (data->det_pin) { + at91_set_gpio_input(data->det_pin, 1); + at91_set_deglitch(data->det_pin, 1); + } + if (data->wp_pin) + at91_set_gpio_input(data->wp_pin, 1); + if (data->vcc_pin) + at91_set_gpio_output(data->vcc_pin, 0); + + /* CLK */ + at91_set_B_periph(AT91_PIN_PA2, 0); + + /* CMD */ + at91_set_B_periph(AT91_PIN_PA1, 1); + + /* DAT0, maybe DAT1..DAT3 */ + at91_set_B_periph(AT91_PIN_PA0, 1); + if (data->wire4) { + at91_set_B_periph(AT91_PIN_PA4, 1); + at91_set_B_periph(AT91_PIN_PA5, 1); + at91_set_B_periph(AT91_PIN_PA6, 1); + } + + mmc_data = *data; + platform_device_register(&at91sam9261_mmc_device); +} +#else +void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * NAND / SmartMedia + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE) +static struct atmel_nand_data nand_data; + +#define NAND_BASE AT91_CHIPSELECT_3 + +static struct resource nand_resources[] = { + { + .start = NAND_BASE, + .end = NAND_BASE + SZ_256M - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device atmel_nand_device = { + .name = "atmel_nand", + .id = -1, + .dev = { + .platform_data = &nand_data, + }, + .resource = nand_resources, + .num_resources = ARRAY_SIZE(nand_resources), +}; + +void __init at91_add_device_nand(struct atmel_nand_data *data) +{ + unsigned long csa; + + if (!data) + return; + + csa = at91_sys_read(AT91_MATRIX_EBICSA); + at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); + + /* enable pin */ + if (data->enable_pin) + at91_set_gpio_output(data->enable_pin, 1); + + /* ready/busy pin */ + if (data->rdy_pin) + at91_set_gpio_input(data->rdy_pin, 1); + + /* card detect pin */ + if (data->det_pin) + at91_set_gpio_input(data->det_pin, 1); + + at91_set_A_periph(AT91_PIN_PC0, 0); /* NANDOE */ + at91_set_A_periph(AT91_PIN_PC1, 0); /* NANDWE */ + + nand_data = *data; + platform_device_register(&atmel_nand_device); +} + +#else +void __init at91_add_device_nand(struct atmel_nand_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * TWI (i2c) + * -------------------------------------------------------------------- */ + +/* + * Prefer the GPIO code since the TWI controller isn't robust + * (gets overruns and underruns under load) and can only issue + * repeated STARTs in one scenario (the driver doesn't yet handle them). + */ +#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) + +static struct i2c_gpio_platform_data pdata = { + .sda_pin = AT91_PIN_PA7, + .sda_is_open_drain = 1, + .scl_pin = AT91_PIN_PA8, + .scl_is_open_drain = 1, + .udelay = 2, /* ~100 kHz */ +}; + +static struct platform_device at91sam9261_twi_device = { + .name = "i2c-gpio", + .id = -1, + .dev.platform_data = &pdata, +}; + +void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) +{ + at91_set_GPIO_periph(AT91_PIN_PA7, 1); /* TWD (SDA) */ + at91_set_multi_drive(AT91_PIN_PA7, 1); + + at91_set_GPIO_periph(AT91_PIN_PA8, 1); /* TWCK (SCL) */ + at91_set_multi_drive(AT91_PIN_PA8, 1); + + i2c_register_board_info(0, devices, nr_devices); + platform_device_register(&at91sam9261_twi_device); +} + +#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) + +static struct resource twi_resources[] = { + [0] = { + .start = AT91SAM9261_BASE_TWI, + .end = AT91SAM9261_BASE_TWI + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_ID_TWI, + .end = AT91SAM9261_ID_TWI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9261_twi_device = { + .name = "at91_i2c", + .id = -1, + .resource = twi_resources, + .num_resources = ARRAY_SIZE(twi_resources), +}; + +void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) +{ + /* pins used for TWI interface */ + at91_set_A_periph(AT91_PIN_PA7, 0); /* TWD */ + at91_set_multi_drive(AT91_PIN_PA7, 1); + + at91_set_A_periph(AT91_PIN_PA8, 0); /* TWCK */ + at91_set_multi_drive(AT91_PIN_PA8, 1); + + i2c_register_board_info(0, devices, nr_devices); + platform_device_register(&at91sam9261_twi_device); +} +#else +void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {} +#endif + + +/* -------------------------------------------------------------------- + * SPI + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) +static u64 spi_dmamask = DMA_BIT_MASK(32); + +static struct resource spi0_resources[] = { + [0] = { + .start = AT91SAM9261_BASE_SPI0, + .end = AT91SAM9261_BASE_SPI0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_ID_SPI0, + .end = AT91SAM9261_ID_SPI0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9261_spi0_device = { + .name = "atmel_spi", + .id = 0, + .dev = { + .dma_mask = &spi_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = spi0_resources, + .num_resources = ARRAY_SIZE(spi0_resources), +}; + +static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PA5, AT91_PIN_PA6 }; + +static struct resource spi1_resources[] = { + [0] = { + .start = AT91SAM9261_BASE_SPI1, + .end = AT91SAM9261_BASE_SPI1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_ID_SPI1, + .end = AT91SAM9261_ID_SPI1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9261_spi1_device = { + .name = "atmel_spi", + .id = 1, + .dev = { + .dma_mask = &spi_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = spi1_resources, + .num_resources = ARRAY_SIZE(spi1_resources), +}; + +static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB28, AT91_PIN_PA24, AT91_PIN_PA25, AT91_PIN_PA26 }; + +void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) +{ + int i; + unsigned long cs_pin; + short enable_spi0 = 0; + short enable_spi1 = 0; + + /* Choose SPI chip-selects */ + for (i = 0; i < nr_devices; i++) { + if (devices[i].controller_data) + cs_pin = (unsigned long) devices[i].controller_data; + else if (devices[i].bus_num == 0) + cs_pin = spi0_standard_cs[devices[i].chip_select]; + else + cs_pin = spi1_standard_cs[devices[i].chip_select]; + + if (devices[i].bus_num == 0) + enable_spi0 = 1; + else + enable_spi1 = 1; + + /* enable chip-select pin */ + at91_set_gpio_output(cs_pin, 1); + + /* pass chip-select pin to driver */ + devices[i].controller_data = (void *) cs_pin; + } + + spi_register_board_info(devices, nr_devices); + + /* Configure SPI bus(es) */ + if (enable_spi0) { + at91_set_A_periph(AT91_PIN_PA0, 0); /* SPI0_MISO */ + at91_set_A_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */ + at91_set_A_periph(AT91_PIN_PA2, 0); /* SPI0_SPCK */ + + platform_device_register(&at91sam9261_spi0_device); + } + if (enable_spi1) { + at91_set_A_periph(AT91_PIN_PB30, 0); /* SPI1_MISO */ + at91_set_A_periph(AT91_PIN_PB31, 0); /* SPI1_MOSI */ + at91_set_A_periph(AT91_PIN_PB29, 0); /* SPI1_SPCK */ + + platform_device_register(&at91sam9261_spi1_device); + } +} +#else +void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {} +#endif + + +/* -------------------------------------------------------------------- + * LCD Controller + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) +static u64 lcdc_dmamask = DMA_BIT_MASK(32); +static struct atmel_lcdfb_info lcdc_data; + +static struct resource lcdc_resources[] = { + [0] = { + .start = AT91SAM9261_LCDC_BASE, + .end = AT91SAM9261_LCDC_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_ID_LCDC, + .end = AT91SAM9261_ID_LCDC, + .flags = IORESOURCE_IRQ, + }, +#if defined(CONFIG_FB_INTSRAM) + [2] = { + .start = AT91SAM9261_SRAM_BASE, + .end = AT91SAM9261_SRAM_BASE + AT91SAM9261_SRAM_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +#endif +}; + +static struct platform_device at91_lcdc_device = { + .name = "atmel_lcdfb", + .id = 0, + .dev = { + .dma_mask = &lcdc_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &lcdc_data, + }, + .resource = lcdc_resources, + .num_resources = ARRAY_SIZE(lcdc_resources), +}; + +void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) +{ + if (!data) { + return; + } + +#if defined(CONFIG_FB_ATMEL_STN) + at91_set_A_periph(AT91_PIN_PB0, 0); /* LCDVSYNC */ + at91_set_A_periph(AT91_PIN_PB1, 0); /* LCDHSYNC */ + at91_set_A_periph(AT91_PIN_PB2, 0); /* LCDDOTCK */ + at91_set_A_periph(AT91_PIN_PB3, 0); /* LCDDEN */ + at91_set_A_periph(AT91_PIN_PB4, 0); /* LCDCC */ + at91_set_A_periph(AT91_PIN_PB5, 0); /* LCDD0 */ + at91_set_A_periph(AT91_PIN_PB6, 0); /* LCDD1 */ + at91_set_A_periph(AT91_PIN_PB7, 0); /* LCDD2 */ + at91_set_A_periph(AT91_PIN_PB8, 0); /* LCDD3 */ +#else + at91_set_A_periph(AT91_PIN_PB1, 0); /* LCDHSYNC */ + at91_set_A_periph(AT91_PIN_PB2, 0); /* LCDDOTCK */ + at91_set_A_periph(AT91_PIN_PB3, 0); /* LCDDEN */ + at91_set_A_periph(AT91_PIN_PB4, 0); /* LCDCC */ + at91_set_A_periph(AT91_PIN_PB7, 0); /* LCDD2 */ + at91_set_A_periph(AT91_PIN_PB8, 0); /* LCDD3 */ + at91_set_A_periph(AT91_PIN_PB9, 0); /* LCDD4 */ + at91_set_A_periph(AT91_PIN_PB10, 0); /* LCDD5 */ + at91_set_A_periph(AT91_PIN_PB11, 0); /* LCDD6 */ + at91_set_A_periph(AT91_PIN_PB12, 0); /* LCDD7 */ + at91_set_A_periph(AT91_PIN_PB15, 0); /* LCDD10 */ + at91_set_A_periph(AT91_PIN_PB16, 0); /* LCDD11 */ + at91_set_A_periph(AT91_PIN_PB17, 0); /* LCDD12 */ + at91_set_A_periph(AT91_PIN_PB18, 0); /* LCDD13 */ + at91_set_A_periph(AT91_PIN_PB19, 0); /* LCDD14 */ + at91_set_A_periph(AT91_PIN_PB20, 0); /* LCDD15 */ + at91_set_B_periph(AT91_PIN_PB23, 0); /* LCDD18 */ + at91_set_B_periph(AT91_PIN_PB24, 0); /* LCDD19 */ + at91_set_B_periph(AT91_PIN_PB25, 0); /* LCDD20 */ + at91_set_B_periph(AT91_PIN_PB26, 0); /* LCDD21 */ + at91_set_B_periph(AT91_PIN_PB27, 0); /* LCDD22 */ + at91_set_B_periph(AT91_PIN_PB28, 0); /* LCDD23 */ +#endif + + if (ARRAY_SIZE(lcdc_resources) > 2) { + void __iomem *fb; + struct resource *fb_res = &lcdc_resources[2]; + size_t fb_len = fb_res->end - fb_res->start + 1; + + fb = ioremap(fb_res->start, fb_len); + if (fb) { + memset(fb, 0, fb_len); + iounmap(fb); + } + } + lcdc_data = *data; + platform_device_register(&at91_lcdc_device); +} +#else +void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {} +#endif + + +/* -------------------------------------------------------------------- + * Timer/Counter block + * -------------------------------------------------------------------- */ + +#ifdef CONFIG_ATMEL_TCLIB + +static struct resource tcb_resources[] = { + [0] = { + .start = AT91SAM9261_BASE_TCB0, + .end = AT91SAM9261_BASE_TCB0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_ID_TC0, + .end = AT91SAM9261_ID_TC0, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = AT91SAM9261_ID_TC1, + .end = AT91SAM9261_ID_TC1, + .flags = IORESOURCE_IRQ, + }, + [3] = { + .start = AT91SAM9261_ID_TC2, + .end = AT91SAM9261_ID_TC2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9261_tcb_device = { + .name = "atmel_tcb", + .id = 0, + .resource = tcb_resources, + .num_resources = ARRAY_SIZE(tcb_resources), +}; + +static void __init at91_add_device_tc(void) +{ + platform_device_register(&at91sam9261_tcb_device); +} +#else +static void __init at91_add_device_tc(void) { } +#endif + + +/* -------------------------------------------------------------------- + * RTT + * -------------------------------------------------------------------- */ + +static struct resource rtt_resources[] = { + { + .start = AT91_BASE_SYS + AT91_RTT, + .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device at91sam9261_rtt_device = { + .name = "at91_rtt", + .id = 0, + .resource = rtt_resources, + .num_resources = ARRAY_SIZE(rtt_resources), +}; + +static void __init at91_add_device_rtt(void) +{ + platform_device_register(&at91sam9261_rtt_device); +} + + +/* -------------------------------------------------------------------- + * Watchdog + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) +static struct platform_device at91sam9261_wdt_device = { + .name = "at91_wdt", + .id = -1, + .num_resources = 0, +}; + +static void __init at91_add_device_watchdog(void) +{ + platform_device_register(&at91sam9261_wdt_device); +} +#else +static void __init at91_add_device_watchdog(void) {} +#endif + + +/* -------------------------------------------------------------------- + * SSC -- Synchronous Serial Controller + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE) +static u64 ssc0_dmamask = DMA_BIT_MASK(32); + +static struct resource ssc0_resources[] = { + [0] = { + .start = AT91SAM9261_BASE_SSC0, + .end = AT91SAM9261_BASE_SSC0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_ID_SSC0, + .end = AT91SAM9261_ID_SSC0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9261_ssc0_device = { + .name = "ssc", + .id = 0, + .dev = { + .dma_mask = &ssc0_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = ssc0_resources, + .num_resources = ARRAY_SIZE(ssc0_resources), +}; + +static inline void configure_ssc0_pins(unsigned pins) +{ + if (pins & ATMEL_SSC_TF) + at91_set_A_periph(AT91_PIN_PB21, 1); + if (pins & ATMEL_SSC_TK) + at91_set_A_periph(AT91_PIN_PB22, 1); + if (pins & ATMEL_SSC_TD) + at91_set_A_periph(AT91_PIN_PB23, 1); + if (pins & ATMEL_SSC_RD) + at91_set_A_periph(AT91_PIN_PB24, 1); + if (pins & ATMEL_SSC_RK) + at91_set_A_periph(AT91_PIN_PB25, 1); + if (pins & ATMEL_SSC_RF) + at91_set_A_periph(AT91_PIN_PB26, 1); +} + +static u64 ssc1_dmamask = DMA_BIT_MASK(32); + +static struct resource ssc1_resources[] = { + [0] = { + .start = AT91SAM9261_BASE_SSC1, + .end = AT91SAM9261_BASE_SSC1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_ID_SSC1, + .end = AT91SAM9261_ID_SSC1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9261_ssc1_device = { + .name = "ssc", + .id = 1, + .dev = { + .dma_mask = &ssc1_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = ssc1_resources, + .num_resources = ARRAY_SIZE(ssc1_resources), +}; + +static inline void configure_ssc1_pins(unsigned pins) +{ + if (pins & ATMEL_SSC_TF) + at91_set_B_periph(AT91_PIN_PA17, 1); + if (pins & ATMEL_SSC_TK) + at91_set_B_periph(AT91_PIN_PA18, 1); + if (pins & ATMEL_SSC_TD) + at91_set_B_periph(AT91_PIN_PA19, 1); + if (pins & ATMEL_SSC_RD) + at91_set_B_periph(AT91_PIN_PA20, 1); + if (pins & ATMEL_SSC_RK) + at91_set_B_periph(AT91_PIN_PA21, 1); + if (pins & ATMEL_SSC_RF) + at91_set_B_periph(AT91_PIN_PA22, 1); +} + +static u64 ssc2_dmamask = DMA_BIT_MASK(32); + +static struct resource ssc2_resources[] = { + [0] = { + .start = AT91SAM9261_BASE_SSC2, + .end = AT91SAM9261_BASE_SSC2 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_ID_SSC2, + .end = AT91SAM9261_ID_SSC2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9261_ssc2_device = { + .name = "ssc", + .id = 2, + .dev = { + .dma_mask = &ssc2_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = ssc2_resources, + .num_resources = ARRAY_SIZE(ssc2_resources), +}; + +static inline void configure_ssc2_pins(unsigned pins) +{ + if (pins & ATMEL_SSC_TF) + at91_set_B_periph(AT91_PIN_PC25, 1); + if (pins & ATMEL_SSC_TK) + at91_set_B_periph(AT91_PIN_PC26, 1); + if (pins & ATMEL_SSC_TD) + at91_set_B_periph(AT91_PIN_PC27, 1); + if (pins & ATMEL_SSC_RD) + at91_set_B_periph(AT91_PIN_PC28, 1); + if (pins & ATMEL_SSC_RK) + at91_set_B_periph(AT91_PIN_PC29, 1); + if (pins & ATMEL_SSC_RF) + at91_set_B_periph(AT91_PIN_PC30, 1); +} + +/* + * SSC controllers are accessed through library code, instead of any + * kind of all-singing/all-dancing driver. For example one could be + * used by a particular I2S audio codec's driver, while another one + * on the same system might be used by a custom data capture driver. + */ +void __init at91_add_device_ssc(unsigned id, unsigned pins) +{ + struct platform_device *pdev; + + /* + * NOTE: caller is responsible for passing information matching + * "pins" to whatever will be using each particular controller. + */ + switch (id) { + case AT91SAM9261_ID_SSC0: + pdev = &at91sam9261_ssc0_device; + configure_ssc0_pins(pins); + break; + case AT91SAM9261_ID_SSC1: + pdev = &at91sam9261_ssc1_device; + configure_ssc1_pins(pins); + break; + case AT91SAM9261_ID_SSC2: + pdev = &at91sam9261_ssc2_device; + configure_ssc2_pins(pins); + break; + default: + return; + } + + platform_device_register(pdev); +} + +#else +void __init at91_add_device_ssc(unsigned id, unsigned pins) {} +#endif + + +/* -------------------------------------------------------------------- + * UART + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_SERIAL_ATMEL) +static struct resource dbgu_resources[] = { + [0] = { + .start = AT91_VA_BASE_SYS + AT91_DBGU, + .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91_ID_SYS, + .end = AT91_ID_SYS, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data dbgu_data = { + .use_dma_tx = 0, + .use_dma_rx = 0, /* DBGU not capable of receive DMA */ + .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), +}; + +static u64 dbgu_dmamask = DMA_BIT_MASK(32); + +static struct platform_device at91sam9261_dbgu_device = { + .name = "atmel_usart", + .id = 0, + .dev = { + .dma_mask = &dbgu_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &dbgu_data, + }, + .resource = dbgu_resources, + .num_resources = ARRAY_SIZE(dbgu_resources), +}; + +static inline void configure_dbgu_pins(void) +{ + at91_set_A_periph(AT91_PIN_PA9, 0); /* DRXD */ + at91_set_A_periph(AT91_PIN_PA10, 1); /* DTXD */ +} + +static struct resource uart0_resources[] = { + [0] = { + .start = AT91SAM9261_BASE_US0, + .end = AT91SAM9261_BASE_US0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_ID_US0, + .end = AT91SAM9261_ID_US0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart0_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static u64 uart0_dmamask = DMA_BIT_MASK(32); + +static struct platform_device at91sam9261_uart0_device = { + .name = "atmel_usart", + .id = 1, + .dev = { + .dma_mask = &uart0_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &uart0_data, + }, + .resource = uart0_resources, + .num_resources = ARRAY_SIZE(uart0_resources), +}; + +static inline void configure_usart0_pins(unsigned pins) +{ + at91_set_A_periph(AT91_PIN_PC8, 1); /* TXD0 */ + at91_set_A_periph(AT91_PIN_PC9, 0); /* RXD0 */ + + if (pins & ATMEL_UART_RTS) + at91_set_A_periph(AT91_PIN_PC10, 0); /* RTS0 */ + if (pins & ATMEL_UART_CTS) + at91_set_A_periph(AT91_PIN_PC11, 0); /* CTS0 */ +} + +static struct resource uart1_resources[] = { + [0] = { + .start = AT91SAM9261_BASE_US1, + .end = AT91SAM9261_BASE_US1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_ID_US1, + .end = AT91SAM9261_ID_US1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart1_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static u64 uart1_dmamask = DMA_BIT_MASK(32); + +static struct platform_device at91sam9261_uart1_device = { + .name = "atmel_usart", + .id = 2, + .dev = { + .dma_mask = &uart1_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &uart1_data, + }, + .resource = uart1_resources, + .num_resources = ARRAY_SIZE(uart1_resources), +}; + +static inline void configure_usart1_pins(unsigned pins) +{ + at91_set_A_periph(AT91_PIN_PC12, 1); /* TXD1 */ + at91_set_A_periph(AT91_PIN_PC13, 0); /* RXD1 */ + + if (pins & ATMEL_UART_RTS) + at91_set_B_periph(AT91_PIN_PA12, 0); /* RTS1 */ + if (pins & ATMEL_UART_CTS) + at91_set_B_periph(AT91_PIN_PA13, 0); /* CTS1 */ +} + +static struct resource uart2_resources[] = { + [0] = { + .start = AT91SAM9261_BASE_US2, + .end = AT91SAM9261_BASE_US2 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_ID_US2, + .end = AT91SAM9261_ID_US2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart2_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static u64 uart2_dmamask = DMA_BIT_MASK(32); + +static struct platform_device at91sam9261_uart2_device = { + .name = "atmel_usart", + .id = 3, + .dev = { + .dma_mask = &uart2_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &uart2_data, + }, + .resource = uart2_resources, + .num_resources = ARRAY_SIZE(uart2_resources), +}; + +static inline void configure_usart2_pins(unsigned pins) +{ + at91_set_A_periph(AT91_PIN_PC15, 0); /* RXD2 */ + at91_set_A_periph(AT91_PIN_PC14, 1); /* TXD2 */ + + if (pins & ATMEL_UART_RTS) + at91_set_B_periph(AT91_PIN_PA15, 0); /* RTS2*/ + if (pins & ATMEL_UART_CTS) + at91_set_B_periph(AT91_PIN_PA16, 0); /* CTS2 */ +} + +static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ +struct platform_device *atmel_default_console_device; /* the serial console device */ + +void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) +{ + struct platform_device *pdev; + struct atmel_uart_data *pdata; + + switch (id) { + case 0: /* DBGU */ + pdev = &at91sam9261_dbgu_device; + configure_dbgu_pins(); + break; + case AT91SAM9261_ID_US0: + pdev = &at91sam9261_uart0_device; + configure_usart0_pins(pins); + break; + case AT91SAM9261_ID_US1: + pdev = &at91sam9261_uart1_device; + configure_usart1_pins(pins); + break; + case AT91SAM9261_ID_US2: + pdev = &at91sam9261_uart2_device; + configure_usart2_pins(pins); + break; + default: + return; + } + pdata = pdev->dev.platform_data; + pdata->num = portnr; /* update to mapped ID */ + + if (portnr < ATMEL_MAX_UART) + at91_uarts[portnr] = pdev; +} + +void __init at91_set_serial_console(unsigned portnr) +{ + if (portnr < ATMEL_MAX_UART) { + atmel_default_console_device = at91_uarts[portnr]; + at91sam9261_set_console_clock(at91_uarts[portnr]->id); + } +} + +void __init at91_add_device_serial(void) +{ + int i; + + for (i = 0; i < ATMEL_MAX_UART; i++) { + if (at91_uarts[i]) + platform_device_register(at91_uarts[i]); + } + + if (!atmel_default_console_device) + printk(KERN_INFO "AT91: No default serial console defined.\n"); +} +#else +void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} +void __init at91_set_serial_console(unsigned portnr) {} +void __init at91_add_device_serial(void) {} +#endif + + +/* -------------------------------------------------------------------- */ + +/* + * These devices are always present and don't need any board-specific + * setup. + */ +static int __init at91_add_standard_devices(void) +{ + at91_add_device_rtt(); + at91_add_device_watchdog(); + at91_add_device_tc(); + return 0; +} + +arch_initcall(at91_add_standard_devices); diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c new file mode 100644 index 00000000..dc28477d --- /dev/null +++ b/arch/arm/mach-at91/at91sam9263.c @@ -0,0 +1,390 @@ +/* + * arch/arm/mach-at91/at91sam9263.c + * + * Copyright (C) 2007 Atmel Corporation. + * + * 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. + * + */ + +#include <linux/module.h> +#include <linux/pm.h> + +#include <asm/irq.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <mach/at91sam9263.h> +#include <mach/at91_pmc.h> +#include <mach/at91_rstc.h> +#include <mach/at91_shdwc.h> + +#include "generic.h" +#include "clock.h" + +static struct map_desc at91sam9263_io_desc[] __initdata = { + { + .virtual = AT91_VA_BASE_SYS, + .pfn = __phys_to_pfn(AT91_BASE_SYS), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = AT91_IO_VIRT_BASE - AT91SAM9263_SRAM0_SIZE, + .pfn = __phys_to_pfn(AT91SAM9263_SRAM0_BASE), + .length = AT91SAM9263_SRAM0_SIZE, + .type = MT_DEVICE, + }, { + .virtual = AT91_IO_VIRT_BASE - AT91SAM9263_SRAM0_SIZE - AT91SAM9263_SRAM1_SIZE, + .pfn = __phys_to_pfn(AT91SAM9263_SRAM1_BASE), + .length = AT91SAM9263_SRAM1_SIZE, + .type = MT_DEVICE, + }, +}; + +/* -------------------------------------------------------------------- + * Clocks + * -------------------------------------------------------------------- */ + +/* + * The peripheral clocks. + */ +static struct clk pioA_clk = { + .name = "pioA_clk", + .pmc_mask = 1 << AT91SAM9263_ID_PIOA, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioB_clk = { + .name = "pioB_clk", + .pmc_mask = 1 << AT91SAM9263_ID_PIOB, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioCDE_clk = { + .name = "pioCDE_clk", + .pmc_mask = 1 << AT91SAM9263_ID_PIOCDE, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart0_clk = { + .name = "usart0_clk", + .pmc_mask = 1 << AT91SAM9263_ID_US0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart1_clk = { + .name = "usart1_clk", + .pmc_mask = 1 << AT91SAM9263_ID_US1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart2_clk = { + .name = "usart2_clk", + .pmc_mask = 1 << AT91SAM9263_ID_US2, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk mmc0_clk = { + .name = "mci0_clk", + .pmc_mask = 1 << AT91SAM9263_ID_MCI0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk mmc1_clk = { + .name = "mci1_clk", + .pmc_mask = 1 << AT91SAM9263_ID_MCI1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk can_clk = { + .name = "can_clk", + .pmc_mask = 1 << AT91SAM9263_ID_CAN, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk twi_clk = { + .name = "twi_clk", + .pmc_mask = 1 << AT91SAM9263_ID_TWI, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk spi0_clk = { + .name = "spi0_clk", + .pmc_mask = 1 << AT91SAM9263_ID_SPI0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk spi1_clk = { + .name = "spi1_clk", + .pmc_mask = 1 << AT91SAM9263_ID_SPI1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ssc0_clk = { + .name = "ssc0_clk", + .pmc_mask = 1 << AT91SAM9263_ID_SSC0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ssc1_clk = { + .name = "ssc1_clk", + .pmc_mask = 1 << AT91SAM9263_ID_SSC1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ac97_clk = { + .name = "ac97_clk", + .pmc_mask = 1 << AT91SAM9263_ID_AC97C, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk tcb_clk = { + .name = "tcb_clk", + .pmc_mask = 1 << AT91SAM9263_ID_TCB, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pwm_clk = { + .name = "pwm_clk", + .pmc_mask = 1 << AT91SAM9263_ID_PWMC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk macb_clk = { + .name = "macb_clk", + .pmc_mask = 1 << AT91SAM9263_ID_EMAC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk dma_clk = { + .name = "dma_clk", + .pmc_mask = 1 << AT91SAM9263_ID_DMA, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk twodge_clk = { + .name = "2dge_clk", + .pmc_mask = 1 << AT91SAM9263_ID_2DGE, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk udc_clk = { + .name = "udc_clk", + .pmc_mask = 1 << AT91SAM9263_ID_UDP, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk isi_clk = { + .name = "isi_clk", + .pmc_mask = 1 << AT91SAM9263_ID_ISI, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk lcdc_clk = { + .name = "lcdc_clk", + .pmc_mask = 1 << AT91SAM9263_ID_LCDC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ohci_clk = { + .name = "ohci_clk", + .pmc_mask = 1 << AT91SAM9263_ID_UHP, + .type = CLK_TYPE_PERIPHERAL, +}; + +static struct clk *periph_clocks[] __initdata = { + &pioA_clk, + &pioB_clk, + &pioCDE_clk, + &usart0_clk, + &usart1_clk, + &usart2_clk, + &mmc0_clk, + &mmc1_clk, + &can_clk, + &twi_clk, + &spi0_clk, + &spi1_clk, + &ssc0_clk, + &ssc1_clk, + &ac97_clk, + &tcb_clk, + &pwm_clk, + &macb_clk, + &twodge_clk, + &udc_clk, + &isi_clk, + &lcdc_clk, + &dma_clk, + &ohci_clk, + // irq0 .. irq1 +}; + +static struct clk_lookup periph_clocks_lookups[] = { + CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), + CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), + CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.0", &mmc0_clk), + CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.1", &mmc1_clk), + CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), + CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), + CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb_clk), +}; + +static struct clk_lookup usart_clocks_lookups[] = { + CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck), + CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk), + CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk), + CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk), +}; + +/* + * The four programmable clocks. + * You must configure pin multiplexing to bring these signals out. + */ +static struct clk pck0 = { + .name = "pck0", + .pmc_mask = AT91_PMC_PCK0, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 0, +}; +static struct clk pck1 = { + .name = "pck1", + .pmc_mask = AT91_PMC_PCK1, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 1, +}; +static struct clk pck2 = { + .name = "pck2", + .pmc_mask = AT91_PMC_PCK2, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 2, +}; +static struct clk pck3 = { + .name = "pck3", + .pmc_mask = AT91_PMC_PCK3, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 3, +}; + +static void __init at91sam9263_register_clocks(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) + clk_register(periph_clocks[i]); + + clkdev_add_table(periph_clocks_lookups, + ARRAY_SIZE(periph_clocks_lookups)); + clkdev_add_table(usart_clocks_lookups, + ARRAY_SIZE(usart_clocks_lookups)); + + clk_register(&pck0); + clk_register(&pck1); + clk_register(&pck2); + clk_register(&pck3); +} + +static struct clk_lookup console_clock_lookup; + +void __init at91sam9263_set_console_clock(int id) +{ + if (id >= ARRAY_SIZE(usart_clocks_lookups)) + return; + + console_clock_lookup.con_id = "usart"; + console_clock_lookup.clk = usart_clocks_lookups[id].clk; + clkdev_add(&console_clock_lookup); +} + +/* -------------------------------------------------------------------- + * GPIO + * -------------------------------------------------------------------- */ + +static struct at91_gpio_bank at91sam9263_gpio[] = { + { + .id = AT91SAM9263_ID_PIOA, + .offset = AT91_PIOA, + .clock = &pioA_clk, + }, { + .id = AT91SAM9263_ID_PIOB, + .offset = AT91_PIOB, + .clock = &pioB_clk, + }, { + .id = AT91SAM9263_ID_PIOCDE, + .offset = AT91_PIOC, + .clock = &pioCDE_clk, + }, { + .id = AT91SAM9263_ID_PIOCDE, + .offset = AT91_PIOD, + .clock = &pioCDE_clk, + }, { + .id = AT91SAM9263_ID_PIOCDE, + .offset = AT91_PIOE, + .clock = &pioCDE_clk, + } +}; + +static void at91sam9263_poweroff(void) +{ + at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW); +} + + +/* -------------------------------------------------------------------- + * AT91SAM9263 processor initialization + * -------------------------------------------------------------------- */ + +void __init at91sam9263_map_io(void) +{ + /* Map peripherals */ + iotable_init(at91sam9263_io_desc, ARRAY_SIZE(at91sam9263_io_desc)); +} + +void __init at91sam9263_initialize(unsigned long main_clock) +{ + at91_arch_reset = at91sam9_alt_reset; + pm_power_off = at91sam9263_poweroff; + at91_extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1); + + /* Init clock subsystem */ + at91_clock_init(main_clock); + + /* Register the processor-specific clocks */ + at91sam9263_register_clocks(); + + /* Register GPIO subsystem */ + at91_gpio_init(at91sam9263_gpio, 5); +} + +/* -------------------------------------------------------------------- + * Interrupt initialization + * -------------------------------------------------------------------- */ + +/* + * The default interrupt priority levels (0 = lowest, 7 = highest). + */ +static unsigned int at91sam9263_default_irq_priority[NR_AIC_IRQS] __initdata = { + 7, /* Advanced Interrupt Controller (FIQ) */ + 7, /* System Peripherals */ + 1, /* Parallel IO Controller A */ + 1, /* Parallel IO Controller B */ + 1, /* Parallel IO Controller C, D and E */ + 0, + 0, + 5, /* USART 0 */ + 5, /* USART 1 */ + 5, /* USART 2 */ + 0, /* Multimedia Card Interface 0 */ + 0, /* Multimedia Card Interface 1 */ + 3, /* CAN */ + 6, /* Two-Wire Interface */ + 5, /* Serial Peripheral Interface 0 */ + 5, /* Serial Peripheral Interface 1 */ + 4, /* Serial Synchronous Controller 0 */ + 4, /* Serial Synchronous Controller 1 */ + 5, /* AC97 Controller */ + 0, /* Timer Counter 0, 1 and 2 */ + 0, /* Pulse Width Modulation Controller */ + 3, /* Ethernet */ + 0, + 0, /* 2D Graphic Engine */ + 2, /* USB Device Port */ + 0, /* Image Sensor Interface */ + 3, /* LDC Controller */ + 0, /* DMA Controller */ + 0, + 2, /* USB Host port */ + 0, /* Advanced Interrupt Controller (IRQ0) */ + 0, /* Advanced Interrupt Controller (IRQ1) */ +}; + +void __init at91sam9263_init_interrupts(unsigned int priority[NR_AIC_IRQS]) +{ + if (!priority) + priority = at91sam9263_default_irq_priority; + + /* Initialize the AIC interrupt controller */ + at91_aic_init(priority); + + /* Enable GPIO interrupts */ + at91_gpio_irq_setup(); +} diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c new file mode 100644 index 00000000..a050f41f --- /dev/null +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -0,0 +1,1434 @@ +/* + * arch/arm/mach-at91/at91sam9263_devices.c + * + * Copyright (C) 2007 Atmel Corporation. + * + * 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. + * + */ +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <linux/dma-mapping.h> +#include <linux/platform_device.h> +#include <linux/i2c-gpio.h> + +#include <linux/fb.h> +#include <video/atmel_lcdc.h> + +#include <mach/board.h> +#include <mach/gpio.h> +#include <mach/at91sam9263.h> +#include <mach/at91sam9263_matrix.h> +#include <mach/at91sam9_smc.h> + +#include "generic.h" + + +/* -------------------------------------------------------------------- + * USB Host + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) +static u64 ohci_dmamask = DMA_BIT_MASK(32); +static struct at91_usbh_data usbh_data; + +static struct resource usbh_resources[] = { + [0] = { + .start = AT91SAM9263_UHP_BASE, + .end = AT91SAM9263_UHP_BASE + SZ_1M - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9263_ID_UHP, + .end = AT91SAM9263_ID_UHP, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91_usbh_device = { + .name = "at91_ohci", + .id = -1, + .dev = { + .dma_mask = &ohci_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &usbh_data, + }, + .resource = usbh_resources, + .num_resources = ARRAY_SIZE(usbh_resources), +}; + +void __init at91_add_device_usbh(struct at91_usbh_data *data) +{ + int i; + + if (!data) + return; + + /* Enable VBus control for UHP ports */ + for (i = 0; i < data->ports; i++) { + if (data->vbus_pin[i]) + at91_set_gpio_output(data->vbus_pin[i], 0); + } + + usbh_data = *data; + platform_device_register(&at91_usbh_device); +} +#else +void __init at91_add_device_usbh(struct at91_usbh_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * USB Device (Gadget) + * -------------------------------------------------------------------- */ + +#ifdef CONFIG_USB_GADGET_AT91 +static struct at91_udc_data udc_data; + +static struct resource udc_resources[] = { + [0] = { + .start = AT91SAM9263_BASE_UDP, + .end = AT91SAM9263_BASE_UDP + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9263_ID_UDP, + .end = AT91SAM9263_ID_UDP, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91_udc_device = { + .name = "at91_udc", + .id = -1, + .dev = { + .platform_data = &udc_data, + }, + .resource = udc_resources, + .num_resources = ARRAY_SIZE(udc_resources), +}; + +void __init at91_add_device_udc(struct at91_udc_data *data) +{ + if (!data) + return; + + if (data->vbus_pin) { + at91_set_gpio_input(data->vbus_pin, 0); + at91_set_deglitch(data->vbus_pin, 1); + } + + /* Pullup pin is handled internally by USB device peripheral */ + + udc_data = *data; + platform_device_register(&at91_udc_device); +} +#else +void __init at91_add_device_udc(struct at91_udc_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * Ethernet + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) +static u64 eth_dmamask = DMA_BIT_MASK(32); +static struct at91_eth_data eth_data; + +static struct resource eth_resources[] = { + [0] = { + .start = AT91SAM9263_BASE_EMAC, + .end = AT91SAM9263_BASE_EMAC + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9263_ID_EMAC, + .end = AT91SAM9263_ID_EMAC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9263_eth_device = { + .name = "macb", + .id = -1, + .dev = { + .dma_mask = ð_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = ð_data, + }, + .resource = eth_resources, + .num_resources = ARRAY_SIZE(eth_resources), +}; + +void __init at91_add_device_eth(struct at91_eth_data *data) +{ + if (!data) + return; + + if (data->phy_irq_pin) { + at91_set_gpio_input(data->phy_irq_pin, 0); + at91_set_deglitch(data->phy_irq_pin, 1); + } + + /* Pins used for MII and RMII */ + at91_set_A_periph(AT91_PIN_PE21, 0); /* ETXCK_EREFCK */ + at91_set_B_periph(AT91_PIN_PC25, 0); /* ERXDV */ + at91_set_A_periph(AT91_PIN_PE25, 0); /* ERX0 */ + at91_set_A_periph(AT91_PIN_PE26, 0); /* ERX1 */ + at91_set_A_periph(AT91_PIN_PE27, 0); /* ERXER */ + at91_set_A_periph(AT91_PIN_PE28, 0); /* ETXEN */ + at91_set_A_periph(AT91_PIN_PE23, 0); /* ETX0 */ + at91_set_A_periph(AT91_PIN_PE24, 0); /* ETX1 */ + at91_set_A_periph(AT91_PIN_PE30, 0); /* EMDIO */ + at91_set_A_periph(AT91_PIN_PE29, 0); /* EMDC */ + + if (!data->is_rmii) { + at91_set_A_periph(AT91_PIN_PE22, 0); /* ECRS */ + at91_set_B_periph(AT91_PIN_PC26, 0); /* ECOL */ + at91_set_B_periph(AT91_PIN_PC22, 0); /* ERX2 */ + at91_set_B_periph(AT91_PIN_PC23, 0); /* ERX3 */ + at91_set_B_periph(AT91_PIN_PC27, 0); /* ERXCK */ + at91_set_B_periph(AT91_PIN_PC20, 0); /* ETX2 */ + at91_set_B_periph(AT91_PIN_PC21, 0); /* ETX3 */ + at91_set_B_periph(AT91_PIN_PC24, 0); /* ETXER */ + } + + eth_data = *data; + platform_device_register(&at91sam9263_eth_device); +} +#else +void __init at91_add_device_eth(struct at91_eth_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * MMC / SD + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) +static u64 mmc_dmamask = DMA_BIT_MASK(32); +static struct at91_mmc_data mmc0_data, mmc1_data; + +static struct resource mmc0_resources[] = { + [0] = { + .start = AT91SAM9263_BASE_MCI0, + .end = AT91SAM9263_BASE_MCI0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9263_ID_MCI0, + .end = AT91SAM9263_ID_MCI0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9263_mmc0_device = { + .name = "at91_mci", + .id = 0, + .dev = { + .dma_mask = &mmc_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &mmc0_data, + }, + .resource = mmc0_resources, + .num_resources = ARRAY_SIZE(mmc0_resources), +}; + +static struct resource mmc1_resources[] = { + [0] = { + .start = AT91SAM9263_BASE_MCI1, + .end = AT91SAM9263_BASE_MCI1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9263_ID_MCI1, + .end = AT91SAM9263_ID_MCI1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9263_mmc1_device = { + .name = "at91_mci", + .id = 1, + .dev = { + .dma_mask = &mmc_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &mmc1_data, + }, + .resource = mmc1_resources, + .num_resources = ARRAY_SIZE(mmc1_resources), +}; + +void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) +{ + if (!data) + return; + + /* input/irq */ + if (data->det_pin) { + at91_set_gpio_input(data->det_pin, 1); + at91_set_deglitch(data->det_pin, 1); + } + if (data->wp_pin) + at91_set_gpio_input(data->wp_pin, 1); + if (data->vcc_pin) + at91_set_gpio_output(data->vcc_pin, 0); + + if (mmc_id == 0) { /* MCI0 */ + /* CLK */ + at91_set_A_periph(AT91_PIN_PA12, 0); + + if (data->slot_b) { + /* CMD */ + at91_set_A_periph(AT91_PIN_PA16, 1); + + /* DAT0, maybe DAT1..DAT3 */ + at91_set_A_periph(AT91_PIN_PA17, 1); + if (data->wire4) { + at91_set_A_periph(AT91_PIN_PA18, 1); + at91_set_A_periph(AT91_PIN_PA19, 1); + at91_set_A_periph(AT91_PIN_PA20, 1); + } + } else { + /* CMD */ + at91_set_A_periph(AT91_PIN_PA1, 1); + + /* DAT0, maybe DAT1..DAT3 */ + at91_set_A_periph(AT91_PIN_PA0, 1); + if (data->wire4) { + at91_set_A_periph(AT91_PIN_PA3, 1); + at91_set_A_periph(AT91_PIN_PA4, 1); + at91_set_A_periph(AT91_PIN_PA5, 1); + } + } + + mmc0_data = *data; + platform_device_register(&at91sam9263_mmc0_device); + } else { /* MCI1 */ + /* CLK */ + at91_set_A_periph(AT91_PIN_PA6, 0); + + if (data->slot_b) { + /* CMD */ + at91_set_A_periph(AT91_PIN_PA21, 1); + + /* DAT0, maybe DAT1..DAT3 */ + at91_set_A_periph(AT91_PIN_PA22, 1); + if (data->wire4) { + at91_set_A_periph(AT91_PIN_PA23, 1); + at91_set_A_periph(AT91_PIN_PA24, 1); + at91_set_A_periph(AT91_PIN_PA25, 1); + } + } else { + /* CMD */ + at91_set_A_periph(AT91_PIN_PA7, 1); + + /* DAT0, maybe DAT1..DAT3 */ + at91_set_A_periph(AT91_PIN_PA8, 1); + if (data->wire4) { + at91_set_A_periph(AT91_PIN_PA9, 1); + at91_set_A_periph(AT91_PIN_PA10, 1); + at91_set_A_periph(AT91_PIN_PA11, 1); + } + } + + mmc1_data = *data; + platform_device_register(&at91sam9263_mmc1_device); + } +} +#else +void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} +#endif + +/* -------------------------------------------------------------------- + * Compact Flash (PCMCIA or IDE) + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE) || \ + defined(CONFIG_BLK_DEV_IDE_AT91) || defined(CONFIG_BLK_DEV_IDE_AT91_MODULE) + +static struct at91_cf_data cf0_data; + +static struct resource cf0_resources[] = { + [0] = { + .start = AT91_CHIPSELECT_4, + .end = AT91_CHIPSELECT_4 + SZ_256M - 1, + .flags = IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT, + } +}; + +static struct platform_device cf0_device = { + .id = 0, + .dev = { + .platform_data = &cf0_data, + }, + .resource = cf0_resources, + .num_resources = ARRAY_SIZE(cf0_resources), +}; + +static struct at91_cf_data cf1_data; + +static struct resource cf1_resources[] = { + [0] = { + .start = AT91_CHIPSELECT_5, + .end = AT91_CHIPSELECT_5 + SZ_256M - 1, + .flags = IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT, + } +}; + +static struct platform_device cf1_device = { + .id = 1, + .dev = { + .platform_data = &cf1_data, + }, + .resource = cf1_resources, + .num_resources = ARRAY_SIZE(cf1_resources), +}; + +void __init at91_add_device_cf(struct at91_cf_data *data) +{ + unsigned long ebi0_csa; + struct platform_device *pdev; + + if (!data) + return; + + /* + * assign CS4 or CS5 to SMC with Compact Flash logic support, + * we assume SMC timings are configured by board code, + * except True IDE where timings are controlled by driver + */ + ebi0_csa = at91_sys_read(AT91_MATRIX_EBI0CSA); + switch (data->chipselect) { + case 4: + at91_set_A_periph(AT91_PIN_PD6, 0); /* EBI0_NCS4/CFCS0 */ + ebi0_csa |= AT91_MATRIX_EBI0_CS4A_SMC_CF1; + cf0_data = *data; + pdev = &cf0_device; + break; + case 5: + at91_set_A_periph(AT91_PIN_PD7, 0); /* EBI0_NCS5/CFCS1 */ + ebi0_csa |= AT91_MATRIX_EBI0_CS5A_SMC_CF2; + cf1_data = *data; + pdev = &cf1_device; + break; + default: + printk(KERN_ERR "AT91 CF: bad chip-select requested (%u)\n", + data->chipselect); + return; + } + at91_sys_write(AT91_MATRIX_EBI0CSA, ebi0_csa); + + if (data->det_pin) { + at91_set_gpio_input(data->det_pin, 1); + at91_set_deglitch(data->det_pin, 1); + } + + if (data->irq_pin) { + at91_set_gpio_input(data->irq_pin, 1); + at91_set_deglitch(data->irq_pin, 1); + } + + if (data->vcc_pin) + /* initially off */ + at91_set_gpio_output(data->vcc_pin, 0); + + /* enable EBI controlled pins */ + at91_set_A_periph(AT91_PIN_PD5, 1); /* NWAIT */ + at91_set_A_periph(AT91_PIN_PD8, 0); /* CFCE1 */ + at91_set_A_periph(AT91_PIN_PD9, 0); /* CFCE2 */ + at91_set_A_periph(AT91_PIN_PD14, 0); /* CFNRW */ + + pdev->name = (data->flags & AT91_CF_TRUE_IDE) ? "at91_ide" : "at91_cf"; + platform_device_register(pdev); +} +#else +void __init at91_add_device_cf(struct at91_cf_data *data) {} +#endif + +/* -------------------------------------------------------------------- + * NAND / SmartMedia + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE) +static struct atmel_nand_data nand_data; + +#define NAND_BASE AT91_CHIPSELECT_3 + +static struct resource nand_resources[] = { + [0] = { + .start = NAND_BASE, + .end = NAND_BASE + SZ_256M - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91_BASE_SYS + AT91_ECC0, + .end = AT91_BASE_SYS + AT91_ECC0 + SZ_512 - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device at91sam9263_nand_device = { + .name = "atmel_nand", + .id = -1, + .dev = { + .platform_data = &nand_data, + }, + .resource = nand_resources, + .num_resources = ARRAY_SIZE(nand_resources), +}; + +void __init at91_add_device_nand(struct atmel_nand_data *data) +{ + unsigned long csa; + + if (!data) + return; + + csa = at91_sys_read(AT91_MATRIX_EBI0CSA); + at91_sys_write(AT91_MATRIX_EBI0CSA, csa | AT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA); + + /* enable pin */ + if (data->enable_pin) + at91_set_gpio_output(data->enable_pin, 1); + + /* ready/busy pin */ + if (data->rdy_pin) + at91_set_gpio_input(data->rdy_pin, 1); + + /* card detect pin */ + if (data->det_pin) + at91_set_gpio_input(data->det_pin, 1); + + nand_data = *data; + platform_device_register(&at91sam9263_nand_device); +} +#else +void __init at91_add_device_nand(struct atmel_nand_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * TWI (i2c) + * -------------------------------------------------------------------- */ + +/* + * Prefer the GPIO code since the TWI controller isn't robust + * (gets overruns and underruns under load) and can only issue + * repeated STARTs in one scenario (the driver doesn't yet handle them). + */ +#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) + +static struct i2c_gpio_platform_data pdata = { + .sda_pin = AT91_PIN_PB4, + .sda_is_open_drain = 1, + .scl_pin = AT91_PIN_PB5, + .scl_is_open_drain = 1, + .udelay = 2, /* ~100 kHz */ +}; + +static struct platform_device at91sam9263_twi_device = { + .name = "i2c-gpio", + .id = -1, + .dev.platform_data = &pdata, +}; + +void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) +{ + at91_set_GPIO_periph(AT91_PIN_PB4, 1); /* TWD (SDA) */ + at91_set_multi_drive(AT91_PIN_PB4, 1); + + at91_set_GPIO_periph(AT91_PIN_PB5, 1); /* TWCK (SCL) */ + at91_set_multi_drive(AT91_PIN_PB5, 1); + + i2c_register_board_info(0, devices, nr_devices); + platform_device_register(&at91sam9263_twi_device); +} + +#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) + +static struct resource twi_resources[] = { + [0] = { + .start = AT91SAM9263_BASE_TWI, + .end = AT91SAM9263_BASE_TWI + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9263_ID_TWI, + .end = AT91SAM9263_ID_TWI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9263_twi_device = { + .name = "at91_i2c", + .id = -1, + .resource = twi_resources, + .num_resources = ARRAY_SIZE(twi_resources), +}; + +void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) +{ + /* pins used for TWI interface */ + at91_set_A_periph(AT91_PIN_PB4, 0); /* TWD */ + at91_set_multi_drive(AT91_PIN_PB4, 1); + + at91_set_A_periph(AT91_PIN_PB5, 0); /* TWCK */ + at91_set_multi_drive(AT91_PIN_PB5, 1); + + i2c_register_board_info(0, devices, nr_devices); + platform_device_register(&at91sam9263_twi_device); +} +#else +void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {} +#endif + + +/* -------------------------------------------------------------------- + * SPI + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) +static u64 spi_dmamask = DMA_BIT_MASK(32); + +static struct resource spi0_resources[] = { + [0] = { + .start = AT91SAM9263_BASE_SPI0, + .end = AT91SAM9263_BASE_SPI0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9263_ID_SPI0, + .end = AT91SAM9263_ID_SPI0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9263_spi0_device = { + .name = "atmel_spi", + .id = 0, + .dev = { + .dma_mask = &spi_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = spi0_resources, + .num_resources = ARRAY_SIZE(spi0_resources), +}; + +static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA5, AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PB11 }; + +static struct resource spi1_resources[] = { + [0] = { + .start = AT91SAM9263_BASE_SPI1, + .end = AT91SAM9263_BASE_SPI1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9263_ID_SPI1, + .end = AT91SAM9263_ID_SPI1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9263_spi1_device = { + .name = "atmel_spi", + .id = 1, + .dev = { + .dma_mask = &spi_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = spi1_resources, + .num_resources = ARRAY_SIZE(spi1_resources), +}; + +static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB15, AT91_PIN_PB16, AT91_PIN_PB17, AT91_PIN_PB18 }; + +void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) +{ + int i; + unsigned long cs_pin; + short enable_spi0 = 0; + short enable_spi1 = 0; + + /* Choose SPI chip-selects */ + for (i = 0; i < nr_devices; i++) { + if (devices[i].controller_data) + cs_pin = (unsigned long) devices[i].controller_data; + else if (devices[i].bus_num == 0) + cs_pin = spi0_standard_cs[devices[i].chip_select]; + else + cs_pin = spi1_standard_cs[devices[i].chip_select]; + + if (devices[i].bus_num == 0) + enable_spi0 = 1; + else + enable_spi1 = 1; + + /* enable chip-select pin */ + at91_set_gpio_output(cs_pin, 1); + + /* pass chip-select pin to driver */ + devices[i].controller_data = (void *) cs_pin; + } + + spi_register_board_info(devices, nr_devices); + + /* Configure SPI bus(es) */ + if (enable_spi0) { + at91_set_B_periph(AT91_PIN_PA0, 0); /* SPI0_MISO */ + at91_set_B_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */ + at91_set_B_periph(AT91_PIN_PA2, 0); /* SPI0_SPCK */ + + platform_device_register(&at91sam9263_spi0_device); + } + if (enable_spi1) { + at91_set_A_periph(AT91_PIN_PB12, 0); /* SPI1_MISO */ + at91_set_A_periph(AT91_PIN_PB13, 0); /* SPI1_MOSI */ + at91_set_A_periph(AT91_PIN_PB14, 0); /* SPI1_SPCK */ + + platform_device_register(&at91sam9263_spi1_device); + } +} +#else +void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {} +#endif + + +/* -------------------------------------------------------------------- + * AC97 + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_SND_ATMEL_AC97C) || defined(CONFIG_SND_ATMEL_AC97C_MODULE) +static u64 ac97_dmamask = DMA_BIT_MASK(32); +static struct ac97c_platform_data ac97_data; + +static struct resource ac97_resources[] = { + [0] = { + .start = AT91SAM9263_BASE_AC97C, + .end = AT91SAM9263_BASE_AC97C + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9263_ID_AC97C, + .end = AT91SAM9263_ID_AC97C, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9263_ac97_device = { + .name = "atmel_ac97c", + .id = 0, + .dev = { + .dma_mask = &ac97_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &ac97_data, + }, + .resource = ac97_resources, + .num_resources = ARRAY_SIZE(ac97_resources), +}; + +void __init at91_add_device_ac97(struct ac97c_platform_data *data) +{ + if (!data) + return; + + at91_set_A_periph(AT91_PIN_PB0, 0); /* AC97FS */ + at91_set_A_periph(AT91_PIN_PB1, 0); /* AC97CK */ + at91_set_A_periph(AT91_PIN_PB2, 0); /* AC97TX */ + at91_set_A_periph(AT91_PIN_PB3, 0); /* AC97RX */ + + /* reset */ + if (data->reset_pin) + at91_set_gpio_output(data->reset_pin, 0); + + ac97_data = *data; + platform_device_register(&at91sam9263_ac97_device); +} +#else +void __init at91_add_device_ac97(struct ac97c_platform_data *data) {} +#endif + +/* -------------------------------------------------------------------- + * CAN Controller + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_CAN_AT91) || defined(CONFIG_CAN_AT91_MODULE) +static struct resource can_resources[] = { + [0] = { + .start = AT91SAM9263_BASE_CAN, + .end = AT91SAM9263_BASE_CAN + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9263_ID_CAN, + .end = AT91SAM9263_ID_CAN, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9263_can_device = { + .name = "at91_can", + .id = -1, + .resource = can_resources, + .num_resources = ARRAY_SIZE(can_resources), +}; + +void __init at91_add_device_can(struct at91_can_data *data) +{ + at91_set_A_periph(AT91_PIN_PA13, 0); /* CANTX */ + at91_set_A_periph(AT91_PIN_PA14, 0); /* CANRX */ + at91sam9263_can_device.dev.platform_data = data; + + platform_device_register(&at91sam9263_can_device); +} +#else +void __init at91_add_device_can(struct at91_can_data *data) {} +#endif + +/* -------------------------------------------------------------------- + * LCD Controller + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) +static u64 lcdc_dmamask = DMA_BIT_MASK(32); +static struct atmel_lcdfb_info lcdc_data; + +static struct resource lcdc_resources[] = { + [0] = { + .start = AT91SAM9263_LCDC_BASE, + .end = AT91SAM9263_LCDC_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9263_ID_LCDC, + .end = AT91SAM9263_ID_LCDC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91_lcdc_device = { + .name = "atmel_lcdfb", + .id = 0, + .dev = { + .dma_mask = &lcdc_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &lcdc_data, + }, + .resource = lcdc_resources, + .num_resources = ARRAY_SIZE(lcdc_resources), +}; + +void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) +{ + if (!data) + return; + + at91_set_A_periph(AT91_PIN_PC1, 0); /* LCDHSYNC */ + at91_set_A_periph(AT91_PIN_PC2, 0); /* LCDDOTCK */ + at91_set_A_periph(AT91_PIN_PC3, 0); /* LCDDEN */ + at91_set_B_periph(AT91_PIN_PB9, 0); /* LCDCC */ + at91_set_A_periph(AT91_PIN_PC6, 0); /* LCDD2 */ + at91_set_A_periph(AT91_PIN_PC7, 0); /* LCDD3 */ + at91_set_A_periph(AT91_PIN_PC8, 0); /* LCDD4 */ + at91_set_A_periph(AT91_PIN_PC9, 0); /* LCDD5 */ + at91_set_A_periph(AT91_PIN_PC10, 0); /* LCDD6 */ + at91_set_A_periph(AT91_PIN_PC11, 0); /* LCDD7 */ + at91_set_A_periph(AT91_PIN_PC14, 0); /* LCDD10 */ + at91_set_A_periph(AT91_PIN_PC15, 0); /* LCDD11 */ + at91_set_A_periph(AT91_PIN_PC16, 0); /* LCDD12 */ + at91_set_B_periph(AT91_PIN_PC12, 0); /* LCDD13 */ + at91_set_A_periph(AT91_PIN_PC18, 0); /* LCDD14 */ + at91_set_A_periph(AT91_PIN_PC19, 0); /* LCDD15 */ + at91_set_A_periph(AT91_PIN_PC22, 0); /* LCDD18 */ + at91_set_A_periph(AT91_PIN_PC23, 0); /* LCDD19 */ + at91_set_A_periph(AT91_PIN_PC24, 0); /* LCDD20 */ + at91_set_B_periph(AT91_PIN_PC17, 0); /* LCDD21 */ + at91_set_A_periph(AT91_PIN_PC26, 0); /* LCDD22 */ + at91_set_A_periph(AT91_PIN_PC27, 0); /* LCDD23 */ + + lcdc_data = *data; + platform_device_register(&at91_lcdc_device); +} +#else +void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {} +#endif + + +/* -------------------------------------------------------------------- + * Image Sensor Interface + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_VIDEO_AT91_ISI) || defined(CONFIG_VIDEO_AT91_ISI_MODULE) + +struct resource isi_resources[] = { + [0] = { + .start = AT91SAM9263_BASE_ISI, + .end = AT91SAM9263_BASE_ISI + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9263_ID_ISI, + .end = AT91SAM9263_ID_ISI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9263_isi_device = { + .name = "at91_isi", + .id = -1, + .resource = isi_resources, + .num_resources = ARRAY_SIZE(isi_resources), +}; + +void __init at91_add_device_isi(void) +{ + at91_set_A_periph(AT91_PIN_PE0, 0); /* ISI_D0 */ + at91_set_A_periph(AT91_PIN_PE1, 0); /* ISI_D1 */ + at91_set_A_periph(AT91_PIN_PE2, 0); /* ISI_D2 */ + at91_set_A_periph(AT91_PIN_PE3, 0); /* ISI_D3 */ + at91_set_A_periph(AT91_PIN_PE4, 0); /* ISI_D4 */ + at91_set_A_periph(AT91_PIN_PE5, 0); /* ISI_D5 */ + at91_set_A_periph(AT91_PIN_PE6, 0); /* ISI_D6 */ + at91_set_A_periph(AT91_PIN_PE7, 0); /* ISI_D7 */ + at91_set_A_periph(AT91_PIN_PE8, 0); /* ISI_PCK */ + at91_set_A_periph(AT91_PIN_PE9, 0); /* ISI_HSYNC */ + at91_set_A_periph(AT91_PIN_PE10, 0); /* ISI_VSYNC */ + at91_set_B_periph(AT91_PIN_PE11, 0); /* ISI_MCK (PCK3) */ + at91_set_B_periph(AT91_PIN_PE12, 0); /* ISI_PD8 */ + at91_set_B_periph(AT91_PIN_PE13, 0); /* ISI_PD9 */ + at91_set_B_periph(AT91_PIN_PE14, 0); /* ISI_PD10 */ + at91_set_B_periph(AT91_PIN_PE15, 0); /* ISI_PD11 */ +} +#else +void __init at91_add_device_isi(void) {} +#endif + + +/* -------------------------------------------------------------------- + * Timer/Counter block + * -------------------------------------------------------------------- */ + +#ifdef CONFIG_ATMEL_TCLIB + +static struct resource tcb_resources[] = { + [0] = { + .start = AT91SAM9263_BASE_TCB0, + .end = AT91SAM9263_BASE_TCB0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9263_ID_TCB, + .end = AT91SAM9263_ID_TCB, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9263_tcb_device = { + .name = "atmel_tcb", + .id = 0, + .resource = tcb_resources, + .num_resources = ARRAY_SIZE(tcb_resources), +}; + +static void __init at91_add_device_tc(void) +{ + platform_device_register(&at91sam9263_tcb_device); +} +#else +static void __init at91_add_device_tc(void) { } +#endif + + +/* -------------------------------------------------------------------- + * RTT + * -------------------------------------------------------------------- */ + +static struct resource rtt0_resources[] = { + { + .start = AT91_BASE_SYS + AT91_RTT0, + .end = AT91_BASE_SYS + AT91_RTT0 + SZ_16 - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device at91sam9263_rtt0_device = { + .name = "at91_rtt", + .id = 0, + .resource = rtt0_resources, + .num_resources = ARRAY_SIZE(rtt0_resources), +}; + +static struct resource rtt1_resources[] = { + { + .start = AT91_BASE_SYS + AT91_RTT1, + .end = AT91_BASE_SYS + AT91_RTT1 + SZ_16 - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device at91sam9263_rtt1_device = { + .name = "at91_rtt", + .id = 1, + .resource = rtt1_resources, + .num_resources = ARRAY_SIZE(rtt1_resources), +}; + +static void __init at91_add_device_rtt(void) +{ + platform_device_register(&at91sam9263_rtt0_device); + platform_device_register(&at91sam9263_rtt1_device); +} + + +/* -------------------------------------------------------------------- + * Watchdog + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) +static struct platform_device at91sam9263_wdt_device = { + .name = "at91_wdt", + .id = -1, + .num_resources = 0, +}; + +static void __init at91_add_device_watchdog(void) +{ + platform_device_register(&at91sam9263_wdt_device); +} +#else +static void __init at91_add_device_watchdog(void) {} +#endif + + +/* -------------------------------------------------------------------- + * PWM + * --------------------------------------------------------------------*/ + +#if defined(CONFIG_ATMEL_PWM) +static u32 pwm_mask; + +static struct resource pwm_resources[] = { + [0] = { + .start = AT91SAM9263_BASE_PWMC, + .end = AT91SAM9263_BASE_PWMC + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9263_ID_PWMC, + .end = AT91SAM9263_ID_PWMC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9263_pwm0_device = { + .name = "atmel_pwm", + .id = -1, + .dev = { + .platform_data = &pwm_mask, + }, + .resource = pwm_resources, + .num_resources = ARRAY_SIZE(pwm_resources), +}; + +void __init at91_add_device_pwm(u32 mask) +{ + if (mask & (1 << AT91_PWM0)) + at91_set_B_periph(AT91_PIN_PB7, 1); /* enable PWM0 */ + + if (mask & (1 << AT91_PWM1)) + at91_set_B_periph(AT91_PIN_PB8, 1); /* enable PWM1 */ + + if (mask & (1 << AT91_PWM2)) + at91_set_B_periph(AT91_PIN_PC29, 1); /* enable PWM2 */ + + if (mask & (1 << AT91_PWM3)) + at91_set_B_periph(AT91_PIN_PB29, 1); /* enable PWM3 */ + + pwm_mask = mask; + + platform_device_register(&at91sam9263_pwm0_device); +} +#else +void __init at91_add_device_pwm(u32 mask) {} +#endif + + +/* -------------------------------------------------------------------- + * SSC -- Synchronous Serial Controller + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE) +static u64 ssc0_dmamask = DMA_BIT_MASK(32); + +static struct resource ssc0_resources[] = { + [0] = { + .start = AT91SAM9263_BASE_SSC0, + .end = AT91SAM9263_BASE_SSC0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9263_ID_SSC0, + .end = AT91SAM9263_ID_SSC0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9263_ssc0_device = { + .name = "ssc", + .id = 0, + .dev = { + .dma_mask = &ssc0_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = ssc0_resources, + .num_resources = ARRAY_SIZE(ssc0_resources), +}; + +static inline void configure_ssc0_pins(unsigned pins) +{ + if (pins & ATMEL_SSC_TF) + at91_set_B_periph(AT91_PIN_PB0, 1); + if (pins & ATMEL_SSC_TK) + at91_set_B_periph(AT91_PIN_PB1, 1); + if (pins & ATMEL_SSC_TD) + at91_set_B_periph(AT91_PIN_PB2, 1); + if (pins & ATMEL_SSC_RD) + at91_set_B_periph(AT91_PIN_PB3, 1); + if (pins & ATMEL_SSC_RK) + at91_set_B_periph(AT91_PIN_PB4, 1); + if (pins & ATMEL_SSC_RF) + at91_set_B_periph(AT91_PIN_PB5, 1); +} + +static u64 ssc1_dmamask = DMA_BIT_MASK(32); + +static struct resource ssc1_resources[] = { + [0] = { + .start = AT91SAM9263_BASE_SSC1, + .end = AT91SAM9263_BASE_SSC1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9263_ID_SSC1, + .end = AT91SAM9263_ID_SSC1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9263_ssc1_device = { + .name = "ssc", + .id = 1, + .dev = { + .dma_mask = &ssc1_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = ssc1_resources, + .num_resources = ARRAY_SIZE(ssc1_resources), +}; + +static inline void configure_ssc1_pins(unsigned pins) +{ + if (pins & ATMEL_SSC_TF) + at91_set_A_periph(AT91_PIN_PB6, 1); + if (pins & ATMEL_SSC_TK) + at91_set_A_periph(AT91_PIN_PB7, 1); + if (pins & ATMEL_SSC_TD) + at91_set_A_periph(AT91_PIN_PB8, 1); + if (pins & ATMEL_SSC_RD) + at91_set_A_periph(AT91_PIN_PB9, 1); + if (pins & ATMEL_SSC_RK) + at91_set_A_periph(AT91_PIN_PB10, 1); + if (pins & ATMEL_SSC_RF) + at91_set_A_periph(AT91_PIN_PB11, 1); +} + +/* + * SSC controllers are accessed through library code, instead of any + * kind of all-singing/all-dancing driver. For example one could be + * used by a particular I2S audio codec's driver, while another one + * on the same system might be used by a custom data capture driver. + */ +void __init at91_add_device_ssc(unsigned id, unsigned pins) +{ + struct platform_device *pdev; + + /* + * NOTE: caller is responsible for passing information matching + * "pins" to whatever will be using each particular controller. + */ + switch (id) { + case AT91SAM9263_ID_SSC0: + pdev = &at91sam9263_ssc0_device; + configure_ssc0_pins(pins); + break; + case AT91SAM9263_ID_SSC1: + pdev = &at91sam9263_ssc1_device; + configure_ssc1_pins(pins); + break; + default: + return; + } + + platform_device_register(pdev); +} + +#else +void __init at91_add_device_ssc(unsigned id, unsigned pins) {} +#endif + + +/* -------------------------------------------------------------------- + * UART + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_SERIAL_ATMEL) + +static struct resource dbgu_resources[] = { + [0] = { + .start = AT91_VA_BASE_SYS + AT91_DBGU, + .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91_ID_SYS, + .end = AT91_ID_SYS, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data dbgu_data = { + .use_dma_tx = 0, + .use_dma_rx = 0, /* DBGU not capable of receive DMA */ + .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), +}; + +static u64 dbgu_dmamask = DMA_BIT_MASK(32); + +static struct platform_device at91sam9263_dbgu_device = { + .name = "atmel_usart", + .id = 0, + .dev = { + .dma_mask = &dbgu_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &dbgu_data, + }, + .resource = dbgu_resources, + .num_resources = ARRAY_SIZE(dbgu_resources), +}; + +static inline void configure_dbgu_pins(void) +{ + at91_set_A_periph(AT91_PIN_PC30, 0); /* DRXD */ + at91_set_A_periph(AT91_PIN_PC31, 1); /* DTXD */ +} + +static struct resource uart0_resources[] = { + [0] = { + .start = AT91SAM9263_BASE_US0, + .end = AT91SAM9263_BASE_US0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9263_ID_US0, + .end = AT91SAM9263_ID_US0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart0_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static u64 uart0_dmamask = DMA_BIT_MASK(32); + +static struct platform_device at91sam9263_uart0_device = { + .name = "atmel_usart", + .id = 1, + .dev = { + .dma_mask = &uart0_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &uart0_data, + }, + .resource = uart0_resources, + .num_resources = ARRAY_SIZE(uart0_resources), +}; + +static inline void configure_usart0_pins(unsigned pins) +{ + at91_set_A_periph(AT91_PIN_PA26, 1); /* TXD0 */ + at91_set_A_periph(AT91_PIN_PA27, 0); /* RXD0 */ + + if (pins & ATMEL_UART_RTS) + at91_set_A_periph(AT91_PIN_PA28, 0); /* RTS0 */ + if (pins & ATMEL_UART_CTS) + at91_set_A_periph(AT91_PIN_PA29, 0); /* CTS0 */ +} + +static struct resource uart1_resources[] = { + [0] = { + .start = AT91SAM9263_BASE_US1, + .end = AT91SAM9263_BASE_US1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9263_ID_US1, + .end = AT91SAM9263_ID_US1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart1_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static u64 uart1_dmamask = DMA_BIT_MASK(32); + +static struct platform_device at91sam9263_uart1_device = { + .name = "atmel_usart", + .id = 2, + .dev = { + .dma_mask = &uart1_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &uart1_data, + }, + .resource = uart1_resources, + .num_resources = ARRAY_SIZE(uart1_resources), +}; + +static inline void configure_usart1_pins(unsigned pins) +{ + at91_set_A_periph(AT91_PIN_PD0, 1); /* TXD1 */ + at91_set_A_periph(AT91_PIN_PD1, 0); /* RXD1 */ + + if (pins & ATMEL_UART_RTS) + at91_set_B_periph(AT91_PIN_PD7, 0); /* RTS1 */ + if (pins & ATMEL_UART_CTS) + at91_set_B_periph(AT91_PIN_PD8, 0); /* CTS1 */ +} + +static struct resource uart2_resources[] = { + [0] = { + .start = AT91SAM9263_BASE_US2, + .end = AT91SAM9263_BASE_US2 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9263_ID_US2, + .end = AT91SAM9263_ID_US2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart2_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static u64 uart2_dmamask = DMA_BIT_MASK(32); + +static struct platform_device at91sam9263_uart2_device = { + .name = "atmel_usart", + .id = 3, + .dev = { + .dma_mask = &uart2_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &uart2_data, + }, + .resource = uart2_resources, + .num_resources = ARRAY_SIZE(uart2_resources), +}; + +static inline void configure_usart2_pins(unsigned pins) +{ + at91_set_A_periph(AT91_PIN_PD2, 1); /* TXD2 */ + at91_set_A_periph(AT91_PIN_PD3, 0); /* RXD2 */ + + if (pins & ATMEL_UART_RTS) + at91_set_B_periph(AT91_PIN_PD5, 0); /* RTS2 */ + if (pins & ATMEL_UART_CTS) + at91_set_B_periph(AT91_PIN_PD6, 0); /* CTS2 */ +} + +static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ +struct platform_device *atmel_default_console_device; /* the serial console device */ + +void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) +{ + struct platform_device *pdev; + struct atmel_uart_data *pdata; + + switch (id) { + case 0: /* DBGU */ + pdev = &at91sam9263_dbgu_device; + configure_dbgu_pins(); + break; + case AT91SAM9263_ID_US0: + pdev = &at91sam9263_uart0_device; + configure_usart0_pins(pins); + break; + case AT91SAM9263_ID_US1: + pdev = &at91sam9263_uart1_device; + configure_usart1_pins(pins); + break; + case AT91SAM9263_ID_US2: + pdev = &at91sam9263_uart2_device; + configure_usart2_pins(pins); + break; + default: + return; + } + pdata = pdev->dev.platform_data; + pdata->num = portnr; /* update to mapped ID */ + + if (portnr < ATMEL_MAX_UART) + at91_uarts[portnr] = pdev; +} + +void __init at91_set_serial_console(unsigned portnr) +{ + if (portnr < ATMEL_MAX_UART) { + atmel_default_console_device = at91_uarts[portnr]; + at91sam9263_set_console_clock(at91_uarts[portnr]->id); + } +} + +void __init at91_add_device_serial(void) +{ + int i; + + for (i = 0; i < ATMEL_MAX_UART; i++) { + if (at91_uarts[i]) + platform_device_register(at91_uarts[i]); + } + + if (!atmel_default_console_device) + printk(KERN_INFO "AT91: No default serial console defined.\n"); +} +#else +void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} +void __init at91_set_serial_console(unsigned portnr) {} +void __init at91_add_device_serial(void) {} +#endif + + +/* -------------------------------------------------------------------- */ +/* + * These devices are always present and don't need any board-specific + * setup. + */ +static int __init at91_add_standard_devices(void) +{ + at91_add_device_rtt(); + at91_add_device_watchdog(); + at91_add_device_tc(); + return 0; +} + +arch_initcall(at91_add_standard_devices); diff --git a/arch/arm/mach-at91/at91sam926x_time.c b/arch/arm/mach-at91/at91sam926x_time.c new file mode 100644 index 00000000..4ba85499 --- /dev/null +++ b/arch/arm/mach-at91/at91sam926x_time.c @@ -0,0 +1,188 @@ +/* + * at91sam926x_time.c - Periodic Interval Timer (PIT) for at91sam926x + * + * Copyright (C) 2005-2006 M. Amine SAYA, ATMEL Rousset, France + * Revision 2005 M. Nicolas Diremdjian, ATMEL Rousset, France + * Converted to ClockSource/ClockEvents by David Brownell. + * + * 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/interrupt.h> +#include <linux/irq.h> +#include <linux/kernel.h> +#include <linux/clk.h> +#include <linux/clockchips.h> + +#include <asm/mach/time.h> + +#include <mach/at91_pit.h> + + +#define PIT_CPIV(x) ((x) & AT91_PIT_CPIV) +#define PIT_PICNT(x) (((x) & AT91_PIT_PICNT) >> 20) + +static u32 pit_cycle; /* write-once */ +static u32 pit_cnt; /* access only w/system irq blocked */ + + +/* + * Clocksource: just a monotonic counter of MCK/16 cycles. + * We don't care whether or not PIT irqs are enabled. + */ +static cycle_t read_pit_clk(struct clocksource *cs) +{ + unsigned long flags; + u32 elapsed; + u32 t; + + raw_local_irq_save(flags); + elapsed = pit_cnt; + t = at91_sys_read(AT91_PIT_PIIR); + raw_local_irq_restore(flags); + + elapsed += PIT_PICNT(t) * pit_cycle; + elapsed += PIT_CPIV(t); + return elapsed; +} + +static struct clocksource pit_clk = { + .name = "pit", + .rating = 175, + .read = read_pit_clk, + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + + +/* + * Clockevent device: interrupts every 1/HZ (== pit_cycles * MCK/16) + */ +static void +pit_clkevt_mode(enum clock_event_mode mode, struct clock_event_device *dev) +{ + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + /* update clocksource counter */ + pit_cnt += pit_cycle * PIT_PICNT(at91_sys_read(AT91_PIT_PIVR)); + at91_sys_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN + | AT91_PIT_PITIEN); + break; + case CLOCK_EVT_MODE_ONESHOT: + BUG(); + /* FALLTHROUGH */ + case CLOCK_EVT_MODE_SHUTDOWN: + case CLOCK_EVT_MODE_UNUSED: + /* disable irq, leaving the clocksource active */ + at91_sys_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN); + break; + case CLOCK_EVT_MODE_RESUME: + break; + } +} + +static struct clock_event_device pit_clkevt = { + .name = "pit", + .features = CLOCK_EVT_FEAT_PERIODIC, + .shift = 32, + .rating = 100, + .set_mode = pit_clkevt_mode, +}; + + +/* + * IRQ handler for the timer. + */ +static irqreturn_t at91sam926x_pit_interrupt(int irq, void *dev_id) +{ + /* + * irqs should be disabled here, but as the irq is shared they are only + * guaranteed to be off if the timer irq is registered first. + */ + WARN_ON_ONCE(!irqs_disabled()); + + /* The PIT interrupt may be disabled, and is shared */ + if ((pit_clkevt.mode == CLOCK_EVT_MODE_PERIODIC) + && (at91_sys_read(AT91_PIT_SR) & AT91_PIT_PITS)) { + unsigned nr_ticks; + + /* Get number of ticks performed before irq, and ack it */ + nr_ticks = PIT_PICNT(at91_sys_read(AT91_PIT_PIVR)); + do { + pit_cnt += pit_cycle; + pit_clkevt.event_handler(&pit_clkevt); + nr_ticks--; + } while (nr_ticks); + + return IRQ_HANDLED; + } + + return IRQ_NONE; +} + +static struct irqaction at91sam926x_pit_irq = { + .name = "at91_tick", + .flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .handler = at91sam926x_pit_interrupt +}; + +static void at91sam926x_pit_reset(void) +{ + /* Disable timer and irqs */ + at91_sys_write(AT91_PIT_MR, 0); + + /* Clear any pending interrupts, wait for PIT to stop counting */ + while (PIT_CPIV(at91_sys_read(AT91_PIT_PIVR)) != 0) + cpu_relax(); + + /* Start PIT but don't enable IRQ */ + at91_sys_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN); +} + +/* + * Set up both clocksource and clockevent support. + */ +static void __init at91sam926x_pit_init(void) +{ + unsigned long pit_rate; + unsigned bits; + + /* + * Use our actual MCK to figure out how many MCK/16 ticks per + * 1/HZ period (instead of a compile-time constant LATCH). + */ + pit_rate = clk_get_rate(clk_get(NULL, "mck")) / 16; + pit_cycle = (pit_rate + HZ/2) / HZ; + WARN_ON(((pit_cycle - 1) & ~AT91_PIT_PIV) != 0); + + /* Initialize and enable the timer */ + at91sam926x_pit_reset(); + + /* + * Register clocksource. The high order bits of PIV are unused, + * so this isn't a 32-bit counter unless we get clockevent irqs. + */ + bits = 12 /* PICNT */ + ilog2(pit_cycle) /* PIV */; + pit_clk.mask = CLOCKSOURCE_MASK(bits); + clocksource_register_hz(&pit_clk, pit_rate); + + /* Set up irq handler */ + setup_irq(AT91_ID_SYS, &at91sam926x_pit_irq); + + /* Set up and register clockevents */ + pit_clkevt.mult = div_sc(pit_rate, NSEC_PER_SEC, pit_clkevt.shift); + pit_clkevt.cpumask = cpumask_of(0); + clockevents_register_device(&pit_clkevt); +} + +static void at91sam926x_pit_suspend(void) +{ + /* Disable timer */ + at91_sys_write(AT91_PIT_MR, 0); +} + +struct sys_timer at91sam926x_timer = { + .init = at91sam926x_pit_init, + .suspend = at91sam926x_pit_suspend, + .resume = at91sam926x_pit_reset, +}; diff --git a/arch/arm/mach-at91/at91sam9_alt_reset.S b/arch/arm/mach-at91/at91sam9_alt_reset.S new file mode 100644 index 00000000..e0256deb --- /dev/null +++ b/arch/arm/mach-at91/at91sam9_alt_reset.S @@ -0,0 +1,48 @@ +/* + * reset AT91SAM9G20 as per errata + * + * (C) BitBox Ltd 2010 + * + * unless the SDRAM is cleanly shutdown before we hit the + * reset register it can be left driving the data bus and + * killing the chance of a subsequent boot from NAND + * + * 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. + */ + +#include <linux/linkage.h> +#include <asm/system.h> +#include <mach/hardware.h> +#include <mach/at91sam9_sdramc.h> +#include <mach/at91_rstc.h> + + .arm + + .globl at91sam9_alt_reset + +at91sam9_alt_reset: mrc p15, 0, r0, c1, c0, 0 + orr r0, r0, #CR_I + mcr p15, 0, r0, c1, c0, 0 @ enable I-cache + + ldr r0, .at91_va_base_sdramc @ preload constants + ldr r1, .at91_va_base_rstc_cr + + mov r2, #1 + mov r3, #AT91_SDRAMC_LPCB_POWER_DOWN + ldr r4, =AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST + + .balign 32 @ align to cache line + + str r2, [r0, #AT91_SDRAMC_TR] @ disable SDRAM access + str r3, [r0, #AT91_SDRAMC_LPR] @ power down SDRAM + str r4, [r1] @ reset processor + + b . + +.at91_va_base_sdramc: + .word AT91_VA_BASE_SYS + AT91_SDRAMC0 +.at91_va_base_rstc_cr: + .word AT91_VA_BASE_SYS + AT91_RSTC_CR diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c new file mode 100644 index 00000000..11e21412 --- /dev/null +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -0,0 +1,406 @@ +/* + * Chip-specific setup code for the AT91SAM9G45 family + * + * Copyright (C) 2009 Atmel Corporation. + * + * 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. + * + */ + +#include <linux/module.h> +#include <linux/pm.h> + +#include <asm/irq.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <mach/at91sam9g45.h> +#include <mach/at91_pmc.h> +#include <mach/at91_rstc.h> +#include <mach/at91_shdwc.h> +#include <mach/cpu.h> + +#include "generic.h" +#include "clock.h" + +static struct map_desc at91sam9g45_io_desc[] __initdata = { + { + .virtual = AT91_VA_BASE_SYS, + .pfn = __phys_to_pfn(AT91_BASE_SYS), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = AT91_IO_VIRT_BASE - AT91SAM9G45_SRAM_SIZE, + .pfn = __phys_to_pfn(AT91SAM9G45_SRAM_BASE), + .length = AT91SAM9G45_SRAM_SIZE, + .type = MT_DEVICE, + } +}; + +/* -------------------------------------------------------------------- + * Clocks + * -------------------------------------------------------------------- */ + +/* + * The peripheral clocks. + */ +static struct clk pioA_clk = { + .name = "pioA_clk", + .pmc_mask = 1 << AT91SAM9G45_ID_PIOA, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioB_clk = { + .name = "pioB_clk", + .pmc_mask = 1 << AT91SAM9G45_ID_PIOB, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioC_clk = { + .name = "pioC_clk", + .pmc_mask = 1 << AT91SAM9G45_ID_PIOC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioDE_clk = { + .name = "pioDE_clk", + .pmc_mask = 1 << AT91SAM9G45_ID_PIODE, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart0_clk = { + .name = "usart0_clk", + .pmc_mask = 1 << AT91SAM9G45_ID_US0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart1_clk = { + .name = "usart1_clk", + .pmc_mask = 1 << AT91SAM9G45_ID_US1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart2_clk = { + .name = "usart2_clk", + .pmc_mask = 1 << AT91SAM9G45_ID_US2, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart3_clk = { + .name = "usart3_clk", + .pmc_mask = 1 << AT91SAM9G45_ID_US3, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk mmc0_clk = { + .name = "mci0_clk", + .pmc_mask = 1 << AT91SAM9G45_ID_MCI0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk twi0_clk = { + .name = "twi0_clk", + .pmc_mask = 1 << AT91SAM9G45_ID_TWI0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk twi1_clk = { + .name = "twi1_clk", + .pmc_mask = 1 << AT91SAM9G45_ID_TWI1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk spi0_clk = { + .name = "spi0_clk", + .pmc_mask = 1 << AT91SAM9G45_ID_SPI0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk spi1_clk = { + .name = "spi1_clk", + .pmc_mask = 1 << AT91SAM9G45_ID_SPI1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ssc0_clk = { + .name = "ssc0_clk", + .pmc_mask = 1 << AT91SAM9G45_ID_SSC0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ssc1_clk = { + .name = "ssc1_clk", + .pmc_mask = 1 << AT91SAM9G45_ID_SSC1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk tcb0_clk = { + .name = "tcb0_clk", + .pmc_mask = 1 << AT91SAM9G45_ID_TCB, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pwm_clk = { + .name = "pwm_clk", + .pmc_mask = 1 << AT91SAM9G45_ID_PWMC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk tsc_clk = { + .name = "tsc_clk", + .pmc_mask = 1 << AT91SAM9G45_ID_TSC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk dma_clk = { + .name = "dma_clk", + .pmc_mask = 1 << AT91SAM9G45_ID_DMA, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk uhphs_clk = { + .name = "uhphs_clk", + .pmc_mask = 1 << AT91SAM9G45_ID_UHPHS, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk lcdc_clk = { + .name = "lcdc_clk", + .pmc_mask = 1 << AT91SAM9G45_ID_LCDC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ac97_clk = { + .name = "ac97_clk", + .pmc_mask = 1 << AT91SAM9G45_ID_AC97C, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk macb_clk = { + .name = "macb_clk", + .pmc_mask = 1 << AT91SAM9G45_ID_EMAC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk isi_clk = { + .name = "isi_clk", + .pmc_mask = 1 << AT91SAM9G45_ID_ISI, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk udphs_clk = { + .name = "udphs_clk", + .pmc_mask = 1 << AT91SAM9G45_ID_UDPHS, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk mmc1_clk = { + .name = "mci1_clk", + .pmc_mask = 1 << AT91SAM9G45_ID_MCI1, + .type = CLK_TYPE_PERIPHERAL, +}; + +/* Video decoder clock - Only for sam9m10/sam9m11 */ +static struct clk vdec_clk = { + .name = "vdec_clk", + .pmc_mask = 1 << AT91SAM9G45_ID_VDEC, + .type = CLK_TYPE_PERIPHERAL, +}; + +static struct clk *periph_clocks[] __initdata = { + &pioA_clk, + &pioB_clk, + &pioC_clk, + &pioDE_clk, + &usart0_clk, + &usart1_clk, + &usart2_clk, + &usart3_clk, + &mmc0_clk, + &twi0_clk, + &twi1_clk, + &spi0_clk, + &spi1_clk, + &ssc0_clk, + &ssc1_clk, + &tcb0_clk, + &pwm_clk, + &tsc_clk, + &dma_clk, + &uhphs_clk, + &lcdc_clk, + &ac97_clk, + &macb_clk, + &isi_clk, + &udphs_clk, + &mmc1_clk, + // irq0 +}; + +static struct clk_lookup periph_clocks_lookups[] = { + /* One additional fake clock for ohci */ + CLKDEV_CON_ID("ohci_clk", &uhphs_clk), + CLKDEV_CON_DEV_ID("ehci_clk", "atmel-ehci", &uhphs_clk), + CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk), + CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk), + CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.0", &mmc0_clk), + CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.1", &mmc1_clk), + CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), + CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), + CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb0_clk), + CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tcb0_clk), + CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), + CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), +}; + +static struct clk_lookup usart_clocks_lookups[] = { + CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck), + CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk), + CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk), + CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk), + CLKDEV_CON_DEV_ID("usart", "atmel_usart.4", &usart3_clk), +}; + +/* + * The two programmable clocks. + * You must configure pin multiplexing to bring these signals out. + */ +static struct clk pck0 = { + .name = "pck0", + .pmc_mask = AT91_PMC_PCK0, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 0, +}; +static struct clk pck1 = { + .name = "pck1", + .pmc_mask = AT91_PMC_PCK1, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 1, +}; + +static void __init at91sam9g45_register_clocks(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) + clk_register(periph_clocks[i]); + + clkdev_add_table(periph_clocks_lookups, + ARRAY_SIZE(periph_clocks_lookups)); + clkdev_add_table(usart_clocks_lookups, + ARRAY_SIZE(usart_clocks_lookups)); + + if (cpu_is_at91sam9m10() || cpu_is_at91sam9m11()) + clk_register(&vdec_clk); + + clk_register(&pck0); + clk_register(&pck1); +} + +static struct clk_lookup console_clock_lookup; + +void __init at91sam9g45_set_console_clock(int id) +{ + if (id >= ARRAY_SIZE(usart_clocks_lookups)) + return; + + console_clock_lookup.con_id = "usart"; + console_clock_lookup.clk = usart_clocks_lookups[id].clk; + clkdev_add(&console_clock_lookup); +} + +/* -------------------------------------------------------------------- + * GPIO + * -------------------------------------------------------------------- */ + +static struct at91_gpio_bank at91sam9g45_gpio[] = { + { + .id = AT91SAM9G45_ID_PIOA, + .offset = AT91_PIOA, + .clock = &pioA_clk, + }, { + .id = AT91SAM9G45_ID_PIOB, + .offset = AT91_PIOB, + .clock = &pioB_clk, + }, { + .id = AT91SAM9G45_ID_PIOC, + .offset = AT91_PIOC, + .clock = &pioC_clk, + }, { + .id = AT91SAM9G45_ID_PIODE, + .offset = AT91_PIOD, + .clock = &pioDE_clk, + }, { + .id = AT91SAM9G45_ID_PIODE, + .offset = AT91_PIOE, + .clock = &pioDE_clk, + } +}; + +static void at91sam9g45_reset(void) +{ + at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST); +} + +static void at91sam9g45_poweroff(void) +{ + at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW); +} + + +/* -------------------------------------------------------------------- + * AT91SAM9G45 processor initialization + * -------------------------------------------------------------------- */ + +void __init at91sam9g45_map_io(void) +{ + /* Map peripherals */ + iotable_init(at91sam9g45_io_desc, ARRAY_SIZE(at91sam9g45_io_desc)); +} + +void __init at91sam9g45_initialize(unsigned long main_clock) +{ + at91_arch_reset = at91sam9g45_reset; + pm_power_off = at91sam9g45_poweroff; + at91_extern_irq = (1 << AT91SAM9G45_ID_IRQ0); + + /* Init clock subsystem */ + at91_clock_init(main_clock); + + /* Register the processor-specific clocks */ + at91sam9g45_register_clocks(); + + /* Register GPIO subsystem */ + at91_gpio_init(at91sam9g45_gpio, 5); +} + +/* -------------------------------------------------------------------- + * Interrupt initialization + * -------------------------------------------------------------------- */ + +/* + * The default interrupt priority levels (0 = lowest, 7 = highest). + */ +static unsigned int at91sam9g45_default_irq_priority[NR_AIC_IRQS] __initdata = { + 7, /* Advanced Interrupt Controller (FIQ) */ + 7, /* System Peripherals */ + 1, /* Parallel IO Controller A */ + 1, /* Parallel IO Controller B */ + 1, /* Parallel IO Controller C */ + 1, /* Parallel IO Controller D and E */ + 0, + 5, /* USART 0 */ + 5, /* USART 1 */ + 5, /* USART 2 */ + 5, /* USART 3 */ + 0, /* Multimedia Card Interface 0 */ + 6, /* Two-Wire Interface 0 */ + 6, /* Two-Wire Interface 1 */ + 5, /* Serial Peripheral Interface 0 */ + 5, /* Serial Peripheral Interface 1 */ + 4, /* Serial Synchronous Controller 0 */ + 4, /* Serial Synchronous Controller 1 */ + 0, /* Timer Counter 0, 1, 2, 3, 4 and 5 */ + 0, /* Pulse Width Modulation Controller */ + 0, /* Touch Screen Controller */ + 0, /* DMA Controller */ + 2, /* USB Host High Speed port */ + 3, /* LDC Controller */ + 5, /* AC97 Controller */ + 3, /* Ethernet */ + 0, /* Image Sensor Interface */ + 2, /* USB Device High speed port */ + 0, + 0, /* Multimedia Card Interface 1 */ + 0, + 0, /* Advanced Interrupt Controller (IRQ0) */ +}; + +void __init at91sam9g45_init_interrupts(unsigned int priority[NR_AIC_IRQS]) +{ + if (!priority) + priority = at91sam9g45_default_irq_priority; + + /* Initialize the AIC interrupt controller */ + at91_aic_init(priority); + + /* Enable GPIO interrupts */ + at91_gpio_irq_setup(); +} diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c new file mode 100644 index 00000000..600bffb0 --- /dev/null +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -0,0 +1,1591 @@ +/* + * On-Chip devices setup code for the AT91SAM9G45 family + * + * Copyright (C) 2009 Atmel Corporation. + * + * 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. + * + */ +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <linux/dma-mapping.h> +#include <linux/platform_device.h> +#include <linux/i2c-gpio.h> +#include <linux/atmel-mci.h> + +#include <linux/fb.h> +#include <video/atmel_lcdc.h> + +#include <mach/board.h> +#include <mach/gpio.h> +#include <mach/at91sam9g45.h> +#include <mach/at91sam9g45_matrix.h> +#include <mach/at91sam9_smc.h> +#include <mach/at_hdmac.h> +#include <mach/atmel-mci.h> + +#include "generic.h" + + +/* -------------------------------------------------------------------- + * HDMAC - AHB DMA Controller + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_AT_HDMAC) || defined(CONFIG_AT_HDMAC_MODULE) +static u64 hdmac_dmamask = DMA_BIT_MASK(32); + +static struct at_dma_platform_data atdma_pdata = { + .nr_channels = 8, +}; + +static struct resource hdmac_resources[] = { + [0] = { + .start = AT91_BASE_SYS + AT91_DMA, + .end = AT91_BASE_SYS + AT91_DMA + SZ_512 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9G45_ID_DMA, + .end = AT91SAM9G45_ID_DMA, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at_hdmac_device = { + .name = "at_hdmac", + .id = -1, + .dev = { + .dma_mask = &hdmac_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &atdma_pdata, + }, + .resource = hdmac_resources, + .num_resources = ARRAY_SIZE(hdmac_resources), +}; + +void __init at91_add_device_hdmac(void) +{ + dma_cap_set(DMA_MEMCPY, atdma_pdata.cap_mask); + dma_cap_set(DMA_SLAVE, atdma_pdata.cap_mask); + platform_device_register(&at_hdmac_device); +} +#else +void __init at91_add_device_hdmac(void) {} +#endif + + +/* -------------------------------------------------------------------- + * USB Host (OHCI) + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) +static u64 ohci_dmamask = DMA_BIT_MASK(32); +static struct at91_usbh_data usbh_ohci_data; + +static struct resource usbh_ohci_resources[] = { + [0] = { + .start = AT91SAM9G45_OHCI_BASE, + .end = AT91SAM9G45_OHCI_BASE + SZ_1M - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9G45_ID_UHPHS, + .end = AT91SAM9G45_ID_UHPHS, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91_usbh_ohci_device = { + .name = "at91_ohci", + .id = -1, + .dev = { + .dma_mask = &ohci_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &usbh_ohci_data, + }, + .resource = usbh_ohci_resources, + .num_resources = ARRAY_SIZE(usbh_ohci_resources), +}; + +void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) +{ + int i; + + if (!data) + return; + + /* Enable VBus control for UHP ports */ + for (i = 0; i < data->ports; i++) { + if (data->vbus_pin[i]) + at91_set_gpio_output(data->vbus_pin[i], 0); + } + + usbh_ohci_data = *data; + platform_device_register(&at91_usbh_ohci_device); +} +#else +void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * USB Host HS (EHCI) + * Needs an OHCI host for low and full speed management + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_EHCI_HCD_MODULE) +static u64 ehci_dmamask = DMA_BIT_MASK(32); +static struct at91_usbh_data usbh_ehci_data; + +static struct resource usbh_ehci_resources[] = { + [0] = { + .start = AT91SAM9G45_EHCI_BASE, + .end = AT91SAM9G45_EHCI_BASE + SZ_1M - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9G45_ID_UHPHS, + .end = AT91SAM9G45_ID_UHPHS, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91_usbh_ehci_device = { + .name = "atmel-ehci", + .id = -1, + .dev = { + .dma_mask = &ehci_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &usbh_ehci_data, + }, + .resource = usbh_ehci_resources, + .num_resources = ARRAY_SIZE(usbh_ehci_resources), +}; + +void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data) +{ + int i; + + if (!data) + return; + + /* Enable VBus control for UHP ports */ + for (i = 0; i < data->ports; i++) { + if (data->vbus_pin[i]) + at91_set_gpio_output(data->vbus_pin[i], 0); + } + + usbh_ehci_data = *data; + platform_device_register(&at91_usbh_ehci_device); +} +#else +void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * USB HS Device (Gadget) + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_USB_GADGET_ATMEL_USBA) || defined(CONFIG_USB_GADGET_ATMEL_USBA_MODULE) +static struct resource usba_udc_resources[] = { + [0] = { + .start = AT91SAM9G45_UDPHS_FIFO, + .end = AT91SAM9G45_UDPHS_FIFO + SZ_512K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9G45_BASE_UDPHS, + .end = AT91SAM9G45_BASE_UDPHS + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = AT91SAM9G45_ID_UDPHS, + .end = AT91SAM9G45_ID_UDPHS, + .flags = IORESOURCE_IRQ, + }, +}; + +#define EP(nam, idx, maxpkt, maxbk, dma, isoc) \ + [idx] = { \ + .name = nam, \ + .index = idx, \ + .fifo_size = maxpkt, \ + .nr_banks = maxbk, \ + .can_dma = dma, \ + .can_isoc = isoc, \ + } + +static struct usba_ep_data usba_udc_ep[] __initdata = { + EP("ep0", 0, 64, 1, 0, 0), + EP("ep1", 1, 1024, 2, 1, 1), + EP("ep2", 2, 1024, 2, 1, 1), + EP("ep3", 3, 1024, 3, 1, 0), + EP("ep4", 4, 1024, 3, 1, 0), + EP("ep5", 5, 1024, 3, 1, 1), + EP("ep6", 6, 1024, 3, 1, 1), +}; + +#undef EP + +/* + * pdata doesn't have room for any endpoints, so we need to + * append room for the ones we need right after it. + */ +static struct { + struct usba_platform_data pdata; + struct usba_ep_data ep[7]; +} usba_udc_data; + +static struct platform_device at91_usba_udc_device = { + .name = "atmel_usba_udc", + .id = -1, + .dev = { + .platform_data = &usba_udc_data.pdata, + }, + .resource = usba_udc_resources, + .num_resources = ARRAY_SIZE(usba_udc_resources), +}; + +void __init at91_add_device_usba(struct usba_platform_data *data) +{ + usba_udc_data.pdata.vbus_pin = -EINVAL; + usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep); + memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep)); + + if (data && data->vbus_pin > 0) { + at91_set_gpio_input(data->vbus_pin, 0); + at91_set_deglitch(data->vbus_pin, 1); + usba_udc_data.pdata.vbus_pin = data->vbus_pin; + } + + /* Pullup pin is handled internally by USB device peripheral */ + + platform_device_register(&at91_usba_udc_device); +} +#else +void __init at91_add_device_usba(struct usba_platform_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * Ethernet + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) +static u64 eth_dmamask = DMA_BIT_MASK(32); +static struct at91_eth_data eth_data; + +static struct resource eth_resources[] = { + [0] = { + .start = AT91SAM9G45_BASE_EMAC, + .end = AT91SAM9G45_BASE_EMAC + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9G45_ID_EMAC, + .end = AT91SAM9G45_ID_EMAC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9g45_eth_device = { + .name = "macb", + .id = -1, + .dev = { + .dma_mask = ð_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = ð_data, + }, + .resource = eth_resources, + .num_resources = ARRAY_SIZE(eth_resources), +}; + +void __init at91_add_device_eth(struct at91_eth_data *data) +{ + if (!data) + return; + + if (data->phy_irq_pin) { + at91_set_gpio_input(data->phy_irq_pin, 0); + at91_set_deglitch(data->phy_irq_pin, 1); + } + + /* Pins used for MII and RMII */ + at91_set_A_periph(AT91_PIN_PA17, 0); /* ETXCK_EREFCK */ + at91_set_A_periph(AT91_PIN_PA15, 0); /* ERXDV */ + at91_set_A_periph(AT91_PIN_PA12, 0); /* ERX0 */ + at91_set_A_periph(AT91_PIN_PA13, 0); /* ERX1 */ + at91_set_A_periph(AT91_PIN_PA16, 0); /* ERXER */ + at91_set_A_periph(AT91_PIN_PA14, 0); /* ETXEN */ + at91_set_A_periph(AT91_PIN_PA10, 0); /* ETX0 */ + at91_set_A_periph(AT91_PIN_PA11, 0); /* ETX1 */ + at91_set_A_periph(AT91_PIN_PA19, 0); /* EMDIO */ + at91_set_A_periph(AT91_PIN_PA18, 0); /* EMDC */ + + if (!data->is_rmii) { + at91_set_B_periph(AT91_PIN_PA29, 0); /* ECRS */ + at91_set_B_periph(AT91_PIN_PA30, 0); /* ECOL */ + at91_set_B_periph(AT91_PIN_PA8, 0); /* ERX2 */ + at91_set_B_periph(AT91_PIN_PA9, 0); /* ERX3 */ + at91_set_B_periph(AT91_PIN_PA28, 0); /* ERXCK */ + at91_set_B_periph(AT91_PIN_PA6, 0); /* ETX2 */ + at91_set_B_periph(AT91_PIN_PA7, 0); /* ETX3 */ + at91_set_B_periph(AT91_PIN_PA27, 0); /* ETXER */ + } + + eth_data = *data; + platform_device_register(&at91sam9g45_eth_device); +} +#else +void __init at91_add_device_eth(struct at91_eth_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * MMC / SD + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE) +static u64 mmc_dmamask = DMA_BIT_MASK(32); +static struct mci_platform_data mmc0_data, mmc1_data; + +static struct resource mmc0_resources[] = { + [0] = { + .start = AT91SAM9G45_BASE_MCI0, + .end = AT91SAM9G45_BASE_MCI0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9G45_ID_MCI0, + .end = AT91SAM9G45_ID_MCI0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9g45_mmc0_device = { + .name = "atmel_mci", + .id = 0, + .dev = { + .dma_mask = &mmc_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &mmc0_data, + }, + .resource = mmc0_resources, + .num_resources = ARRAY_SIZE(mmc0_resources), +}; + +static struct resource mmc1_resources[] = { + [0] = { + .start = AT91SAM9G45_BASE_MCI1, + .end = AT91SAM9G45_BASE_MCI1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9G45_ID_MCI1, + .end = AT91SAM9G45_ID_MCI1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9g45_mmc1_device = { + .name = "atmel_mci", + .id = 1, + .dev = { + .dma_mask = &mmc_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &mmc1_data, + }, + .resource = mmc1_resources, + .num_resources = ARRAY_SIZE(mmc1_resources), +}; + +/* Consider only one slot : slot 0 */ +void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) +{ + + if (!data) + return; + + /* Must have at least one usable slot */ + if (!data->slot[0].bus_width) + return; + +#if defined(CONFIG_AT_HDMAC) || defined(CONFIG_AT_HDMAC_MODULE) + { + struct at_dma_slave *atslave; + struct mci_dma_data *alt_atslave; + + alt_atslave = kzalloc(sizeof(struct mci_dma_data), GFP_KERNEL); + atslave = &alt_atslave->sdata; + + /* DMA slave channel configuration */ + atslave->dma_dev = &at_hdmac_device.dev; + atslave->reg_width = AT_DMA_SLAVE_WIDTH_32BIT; + atslave->cfg = ATC_FIFOCFG_HALFFIFO + | ATC_SRC_H2SEL_HW | ATC_DST_H2SEL_HW; + atslave->ctrla = ATC_SCSIZE_16 | ATC_DCSIZE_16; + if (mmc_id == 0) /* MCI0 */ + atslave->cfg |= ATC_SRC_PER(AT_DMA_ID_MCI0) + | ATC_DST_PER(AT_DMA_ID_MCI0); + + else /* MCI1 */ + atslave->cfg |= ATC_SRC_PER(AT_DMA_ID_MCI1) + | ATC_DST_PER(AT_DMA_ID_MCI1); + + data->dma_slave = alt_atslave; + } +#endif + + + /* input/irq */ + if (data->slot[0].detect_pin) { + at91_set_gpio_input(data->slot[0].detect_pin, 1); + at91_set_deglitch(data->slot[0].detect_pin, 1); + } + if (data->slot[0].wp_pin) + at91_set_gpio_input(data->slot[0].wp_pin, 1); + + if (mmc_id == 0) { /* MCI0 */ + + /* CLK */ + at91_set_A_periph(AT91_PIN_PA0, 0); + + /* CMD */ + at91_set_A_periph(AT91_PIN_PA1, 1); + + /* DAT0, maybe DAT1..DAT3 and maybe DAT4..DAT7 */ + at91_set_A_periph(AT91_PIN_PA2, 1); + if (data->slot[0].bus_width == 4) { + at91_set_A_periph(AT91_PIN_PA3, 1); + at91_set_A_periph(AT91_PIN_PA4, 1); + at91_set_A_periph(AT91_PIN_PA5, 1); + if (data->slot[0].bus_width == 8) { + at91_set_A_periph(AT91_PIN_PA6, 1); + at91_set_A_periph(AT91_PIN_PA7, 1); + at91_set_A_periph(AT91_PIN_PA8, 1); + at91_set_A_periph(AT91_PIN_PA9, 1); + } + } + + mmc0_data = *data; + platform_device_register(&at91sam9g45_mmc0_device); + + } else { /* MCI1 */ + + /* CLK */ + at91_set_A_periph(AT91_PIN_PA31, 0); + + /* CMD */ + at91_set_A_periph(AT91_PIN_PA22, 1); + + /* DAT0, maybe DAT1..DAT3 and maybe DAT4..DAT7 */ + at91_set_A_periph(AT91_PIN_PA23, 1); + if (data->slot[0].bus_width == 4) { + at91_set_A_periph(AT91_PIN_PA24, 1); + at91_set_A_periph(AT91_PIN_PA25, 1); + at91_set_A_periph(AT91_PIN_PA26, 1); + if (data->slot[0].bus_width == 8) { + at91_set_A_periph(AT91_PIN_PA27, 1); + at91_set_A_periph(AT91_PIN_PA28, 1); + at91_set_A_periph(AT91_PIN_PA29, 1); + at91_set_A_periph(AT91_PIN_PA30, 1); + } + } + + mmc1_data = *data; + platform_device_register(&at91sam9g45_mmc1_device); + + } +} +#else +void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * NAND / SmartMedia + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE) +static struct atmel_nand_data nand_data; + +#define NAND_BASE AT91_CHIPSELECT_3 + +static struct resource nand_resources[] = { + [0] = { + .start = NAND_BASE, + .end = NAND_BASE + SZ_256M - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91_BASE_SYS + AT91_ECC, + .end = AT91_BASE_SYS + AT91_ECC + SZ_512 - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device at91sam9g45_nand_device = { + .name = "atmel_nand", + .id = -1, + .dev = { + .platform_data = &nand_data, + }, + .resource = nand_resources, + .num_resources = ARRAY_SIZE(nand_resources), +}; + +void __init at91_add_device_nand(struct atmel_nand_data *data) +{ + unsigned long csa; + + if (!data) + return; + + csa = at91_sys_read(AT91_MATRIX_EBICSA); + at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA); + + /* enable pin */ + if (data->enable_pin) + at91_set_gpio_output(data->enable_pin, 1); + + /* ready/busy pin */ + if (data->rdy_pin) + at91_set_gpio_input(data->rdy_pin, 1); + + /* card detect pin */ + if (data->det_pin) + at91_set_gpio_input(data->det_pin, 1); + + nand_data = *data; + platform_device_register(&at91sam9g45_nand_device); +} +#else +void __init at91_add_device_nand(struct atmel_nand_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * TWI (i2c) + * -------------------------------------------------------------------- */ + +/* + * Prefer the GPIO code since the TWI controller isn't robust + * (gets overruns and underruns under load) and can only issue + * repeated STARTs in one scenario (the driver doesn't yet handle them). + */ +#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) +static struct i2c_gpio_platform_data pdata_i2c0 = { + .sda_pin = AT91_PIN_PA20, + .sda_is_open_drain = 1, + .scl_pin = AT91_PIN_PA21, + .scl_is_open_drain = 1, + .udelay = 5, /* ~100 kHz */ +}; + +static struct platform_device at91sam9g45_twi0_device = { + .name = "i2c-gpio", + .id = 0, + .dev.platform_data = &pdata_i2c0, +}; + +static struct i2c_gpio_platform_data pdata_i2c1 = { + .sda_pin = AT91_PIN_PB10, + .sda_is_open_drain = 1, + .scl_pin = AT91_PIN_PB11, + .scl_is_open_drain = 1, + .udelay = 5, /* ~100 kHz */ +}; + +static struct platform_device at91sam9g45_twi1_device = { + .name = "i2c-gpio", + .id = 1, + .dev.platform_data = &pdata_i2c1, +}; + +void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices) +{ + i2c_register_board_info(i2c_id, devices, nr_devices); + + if (i2c_id == 0) { + at91_set_GPIO_periph(AT91_PIN_PA20, 1); /* TWD (SDA) */ + at91_set_multi_drive(AT91_PIN_PA20, 1); + + at91_set_GPIO_periph(AT91_PIN_PA21, 1); /* TWCK (SCL) */ + at91_set_multi_drive(AT91_PIN_PA21, 1); + + platform_device_register(&at91sam9g45_twi0_device); + } else { + at91_set_GPIO_periph(AT91_PIN_PB10, 1); /* TWD (SDA) */ + at91_set_multi_drive(AT91_PIN_PB10, 1); + + at91_set_GPIO_periph(AT91_PIN_PB11, 1); /* TWCK (SCL) */ + at91_set_multi_drive(AT91_PIN_PB11, 1); + + platform_device_register(&at91sam9g45_twi1_device); + } +} + +#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) +static struct resource twi0_resources[] = { + [0] = { + .start = AT91SAM9G45_BASE_TWI0, + .end = AT91SAM9G45_BASE_TWI0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9G45_ID_TWI0, + .end = AT91SAM9G45_ID_TWI0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9g45_twi0_device = { + .name = "at91_i2c", + .id = 0, + .resource = twi0_resources, + .num_resources = ARRAY_SIZE(twi0_resources), +}; + +static struct resource twi1_resources[] = { + [0] = { + .start = AT91SAM9G45_BASE_TWI1, + .end = AT91SAM9G45_BASE_TWI1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9G45_ID_TWI1, + .end = AT91SAM9G45_ID_TWI1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9g45_twi1_device = { + .name = "at91_i2c", + .id = 1, + .resource = twi1_resources, + .num_resources = ARRAY_SIZE(twi1_resources), +}; + +void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices) +{ + i2c_register_board_info(i2c_id, devices, nr_devices); + + /* pins used for TWI interface */ + if (i2c_id == 0) { + at91_set_A_periph(AT91_PIN_PA20, 0); /* TWD */ + at91_set_multi_drive(AT91_PIN_PA20, 1); + + at91_set_A_periph(AT91_PIN_PA21, 0); /* TWCK */ + at91_set_multi_drive(AT91_PIN_PA21, 1); + + platform_device_register(&at91sam9g45_twi0_device); + } else { + at91_set_A_periph(AT91_PIN_PB10, 0); /* TWD */ + at91_set_multi_drive(AT91_PIN_PB10, 1); + + at91_set_A_periph(AT91_PIN_PB11, 0); /* TWCK */ + at91_set_multi_drive(AT91_PIN_PB11, 1); + + platform_device_register(&at91sam9g45_twi1_device); + } +} +#else +void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices) {} +#endif + + +/* -------------------------------------------------------------------- + * SPI + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) +static u64 spi_dmamask = DMA_BIT_MASK(32); + +static struct resource spi0_resources[] = { + [0] = { + .start = AT91SAM9G45_BASE_SPI0, + .end = AT91SAM9G45_BASE_SPI0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9G45_ID_SPI0, + .end = AT91SAM9G45_ID_SPI0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9g45_spi0_device = { + .name = "atmel_spi", + .id = 0, + .dev = { + .dma_mask = &spi_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = spi0_resources, + .num_resources = ARRAY_SIZE(spi0_resources), +}; + +static const unsigned spi0_standard_cs[4] = { AT91_PIN_PB3, AT91_PIN_PB18, AT91_PIN_PB19, AT91_PIN_PD27 }; + +static struct resource spi1_resources[] = { + [0] = { + .start = AT91SAM9G45_BASE_SPI1, + .end = AT91SAM9G45_BASE_SPI1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9G45_ID_SPI1, + .end = AT91SAM9G45_ID_SPI1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9g45_spi1_device = { + .name = "atmel_spi", + .id = 1, + .dev = { + .dma_mask = &spi_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = spi1_resources, + .num_resources = ARRAY_SIZE(spi1_resources), +}; + +static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB17, AT91_PIN_PD28, AT91_PIN_PD18, AT91_PIN_PD19 }; + +void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) +{ + int i; + unsigned long cs_pin; + short enable_spi0 = 0; + short enable_spi1 = 0; + + /* Choose SPI chip-selects */ + for (i = 0; i < nr_devices; i++) { + if (devices[i].controller_data) + cs_pin = (unsigned long) devices[i].controller_data; + else if (devices[i].bus_num == 0) + cs_pin = spi0_standard_cs[devices[i].chip_select]; + else + cs_pin = spi1_standard_cs[devices[i].chip_select]; + + if (devices[i].bus_num == 0) + enable_spi0 = 1; + else + enable_spi1 = 1; + + /* enable chip-select pin */ + at91_set_gpio_output(cs_pin, 1); + + /* pass chip-select pin to driver */ + devices[i].controller_data = (void *) cs_pin; + } + + spi_register_board_info(devices, nr_devices); + + /* Configure SPI bus(es) */ + if (enable_spi0) { + at91_set_A_periph(AT91_PIN_PB0, 0); /* SPI0_MISO */ + at91_set_A_periph(AT91_PIN_PB1, 0); /* SPI0_MOSI */ + at91_set_A_periph(AT91_PIN_PB2, 0); /* SPI0_SPCK */ + + platform_device_register(&at91sam9g45_spi0_device); + } + if (enable_spi1) { + at91_set_A_periph(AT91_PIN_PB14, 0); /* SPI1_MISO */ + at91_set_A_periph(AT91_PIN_PB15, 0); /* SPI1_MOSI */ + at91_set_A_periph(AT91_PIN_PB16, 0); /* SPI1_SPCK */ + + platform_device_register(&at91sam9g45_spi1_device); + } +} +#else +void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {} +#endif + + +/* -------------------------------------------------------------------- + * AC97 + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_SND_ATMEL_AC97C) || defined(CONFIG_SND_ATMEL_AC97C_MODULE) +static u64 ac97_dmamask = DMA_BIT_MASK(32); +static struct ac97c_platform_data ac97_data; + +static struct resource ac97_resources[] = { + [0] = { + .start = AT91SAM9G45_BASE_AC97C, + .end = AT91SAM9G45_BASE_AC97C + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9G45_ID_AC97C, + .end = AT91SAM9G45_ID_AC97C, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9g45_ac97_device = { + .name = "atmel_ac97c", + .id = 0, + .dev = { + .dma_mask = &ac97_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &ac97_data, + }, + .resource = ac97_resources, + .num_resources = ARRAY_SIZE(ac97_resources), +}; + +void __init at91_add_device_ac97(struct ac97c_platform_data *data) +{ + if (!data) + return; + + at91_set_A_periph(AT91_PIN_PD8, 0); /* AC97FS */ + at91_set_A_periph(AT91_PIN_PD9, 0); /* AC97CK */ + at91_set_A_periph(AT91_PIN_PD7, 0); /* AC97TX */ + at91_set_A_periph(AT91_PIN_PD6, 0); /* AC97RX */ + + /* reset */ + if (data->reset_pin) + at91_set_gpio_output(data->reset_pin, 0); + + ac97_data = *data; + platform_device_register(&at91sam9g45_ac97_device); +} +#else +void __init at91_add_device_ac97(struct ac97c_platform_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * LCD Controller + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) +static u64 lcdc_dmamask = DMA_BIT_MASK(32); +static struct atmel_lcdfb_info lcdc_data; + +static struct resource lcdc_resources[] = { + [0] = { + .start = AT91SAM9G45_LCDC_BASE, + .end = AT91SAM9G45_LCDC_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9G45_ID_LCDC, + .end = AT91SAM9G45_ID_LCDC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91_lcdc_device = { + .name = "atmel_lcdfb", + .id = 0, + .dev = { + .dma_mask = &lcdc_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &lcdc_data, + }, + .resource = lcdc_resources, + .num_resources = ARRAY_SIZE(lcdc_resources), +}; + +void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) +{ + if (!data) + return; + + at91_set_A_periph(AT91_PIN_PE0, 0); /* LCDDPWR */ + + at91_set_A_periph(AT91_PIN_PE2, 0); /* LCDCC */ + at91_set_A_periph(AT91_PIN_PE3, 0); /* LCDVSYNC */ + at91_set_A_periph(AT91_PIN_PE4, 0); /* LCDHSYNC */ + at91_set_A_periph(AT91_PIN_PE5, 0); /* LCDDOTCK */ + at91_set_A_periph(AT91_PIN_PE6, 0); /* LCDDEN */ + at91_set_A_periph(AT91_PIN_PE7, 0); /* LCDD0 */ + at91_set_A_periph(AT91_PIN_PE8, 0); /* LCDD1 */ + at91_set_A_periph(AT91_PIN_PE9, 0); /* LCDD2 */ + at91_set_A_periph(AT91_PIN_PE10, 0); /* LCDD3 */ + at91_set_A_periph(AT91_PIN_PE11, 0); /* LCDD4 */ + at91_set_A_periph(AT91_PIN_PE12, 0); /* LCDD5 */ + at91_set_A_periph(AT91_PIN_PE13, 0); /* LCDD6 */ + at91_set_A_periph(AT91_PIN_PE14, 0); /* LCDD7 */ + at91_set_A_periph(AT91_PIN_PE15, 0); /* LCDD8 */ + at91_set_A_periph(AT91_PIN_PE16, 0); /* LCDD9 */ + at91_set_A_periph(AT91_PIN_PE17, 0); /* LCDD10 */ + at91_set_A_periph(AT91_PIN_PE18, 0); /* LCDD11 */ + at91_set_A_periph(AT91_PIN_PE19, 0); /* LCDD12 */ + at91_set_A_periph(AT91_PIN_PE20, 0); /* LCDD13 */ + at91_set_A_periph(AT91_PIN_PE21, 0); /* LCDD14 */ + at91_set_A_periph(AT91_PIN_PE22, 0); /* LCDD15 */ + at91_set_A_periph(AT91_PIN_PE23, 0); /* LCDD16 */ + at91_set_A_periph(AT91_PIN_PE24, 0); /* LCDD17 */ + at91_set_A_periph(AT91_PIN_PE25, 0); /* LCDD18 */ + at91_set_A_periph(AT91_PIN_PE26, 0); /* LCDD19 */ + at91_set_A_periph(AT91_PIN_PE27, 0); /* LCDD20 */ + at91_set_A_periph(AT91_PIN_PE28, 0); /* LCDD21 */ + at91_set_A_periph(AT91_PIN_PE29, 0); /* LCDD22 */ + at91_set_A_periph(AT91_PIN_PE30, 0); /* LCDD23 */ + + lcdc_data = *data; + platform_device_register(&at91_lcdc_device); +} +#else +void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {} +#endif + + +/* -------------------------------------------------------------------- + * Timer/Counter block + * -------------------------------------------------------------------- */ + +#ifdef CONFIG_ATMEL_TCLIB +static struct resource tcb0_resources[] = { + [0] = { + .start = AT91SAM9G45_BASE_TCB0, + .end = AT91SAM9G45_BASE_TCB0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9G45_ID_TCB, + .end = AT91SAM9G45_ID_TCB, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9g45_tcb0_device = { + .name = "atmel_tcb", + .id = 0, + .resource = tcb0_resources, + .num_resources = ARRAY_SIZE(tcb0_resources), +}; + +/* TCB1 begins with TC3 */ +static struct resource tcb1_resources[] = { + [0] = { + .start = AT91SAM9G45_BASE_TCB1, + .end = AT91SAM9G45_BASE_TCB1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9G45_ID_TCB, + .end = AT91SAM9G45_ID_TCB, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9g45_tcb1_device = { + .name = "atmel_tcb", + .id = 1, + .resource = tcb1_resources, + .num_resources = ARRAY_SIZE(tcb1_resources), +}; + +static void __init at91_add_device_tc(void) +{ + platform_device_register(&at91sam9g45_tcb0_device); + platform_device_register(&at91sam9g45_tcb1_device); +} +#else +static void __init at91_add_device_tc(void) { } +#endif + + +/* -------------------------------------------------------------------- + * RTC + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE) +static struct platform_device at91sam9g45_rtc_device = { + .name = "at91_rtc", + .id = -1, + .num_resources = 0, +}; + +static void __init at91_add_device_rtc(void) +{ + platform_device_register(&at91sam9g45_rtc_device); +} +#else +static void __init at91_add_device_rtc(void) {} +#endif + + +/* -------------------------------------------------------------------- + * Touchscreen + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) || defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC_MODULE) +static u64 tsadcc_dmamask = DMA_BIT_MASK(32); +static struct at91_tsadcc_data tsadcc_data; + +static struct resource tsadcc_resources[] = { + [0] = { + .start = AT91SAM9G45_BASE_TSC, + .end = AT91SAM9G45_BASE_TSC + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9G45_ID_TSC, + .end = AT91SAM9G45_ID_TSC, + .flags = IORESOURCE_IRQ, + } +}; + +static struct platform_device at91sam9g45_tsadcc_device = { + .name = "atmel_tsadcc", + .id = -1, + .dev = { + .dma_mask = &tsadcc_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &tsadcc_data, + }, + .resource = tsadcc_resources, + .num_resources = ARRAY_SIZE(tsadcc_resources), +}; + +void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data) +{ + if (!data) + return; + + at91_set_gpio_input(AT91_PIN_PD20, 0); /* AD0_XR */ + at91_set_gpio_input(AT91_PIN_PD21, 0); /* AD1_XL */ + at91_set_gpio_input(AT91_PIN_PD22, 0); /* AD2_YT */ + at91_set_gpio_input(AT91_PIN_PD23, 0); /* AD3_TB */ + + tsadcc_data = *data; + platform_device_register(&at91sam9g45_tsadcc_device); +} +#else +void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * RTT + * -------------------------------------------------------------------- */ + +static struct resource rtt_resources[] = { + { + .start = AT91_BASE_SYS + AT91_RTT, + .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device at91sam9g45_rtt_device = { + .name = "at91_rtt", + .id = 0, + .resource = rtt_resources, + .num_resources = ARRAY_SIZE(rtt_resources), +}; + +static void __init at91_add_device_rtt(void) +{ + platform_device_register(&at91sam9g45_rtt_device); +} + + +/* -------------------------------------------------------------------- + * Watchdog + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) +static struct platform_device at91sam9g45_wdt_device = { + .name = "at91_wdt", + .id = -1, + .num_resources = 0, +}; + +static void __init at91_add_device_watchdog(void) +{ + platform_device_register(&at91sam9g45_wdt_device); +} +#else +static void __init at91_add_device_watchdog(void) {} +#endif + + +/* -------------------------------------------------------------------- + * PWM + * --------------------------------------------------------------------*/ + +#if defined(CONFIG_ATMEL_PWM) || defined(CONFIG_ATMEL_PWM_MODULE) +static u32 pwm_mask; + +static struct resource pwm_resources[] = { + [0] = { + .start = AT91SAM9G45_BASE_PWMC, + .end = AT91SAM9G45_BASE_PWMC + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9G45_ID_PWMC, + .end = AT91SAM9G45_ID_PWMC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9g45_pwm0_device = { + .name = "atmel_pwm", + .id = -1, + .dev = { + .platform_data = &pwm_mask, + }, + .resource = pwm_resources, + .num_resources = ARRAY_SIZE(pwm_resources), +}; + +void __init at91_add_device_pwm(u32 mask) +{ + if (mask & (1 << AT91_PWM0)) + at91_set_B_periph(AT91_PIN_PD24, 1); /* enable PWM0 */ + + if (mask & (1 << AT91_PWM1)) + at91_set_B_periph(AT91_PIN_PD31, 1); /* enable PWM1 */ + + if (mask & (1 << AT91_PWM2)) + at91_set_B_periph(AT91_PIN_PD26, 1); /* enable PWM2 */ + + if (mask & (1 << AT91_PWM3)) + at91_set_B_periph(AT91_PIN_PD0, 1); /* enable PWM3 */ + + pwm_mask = mask; + + platform_device_register(&at91sam9g45_pwm0_device); +} +#else +void __init at91_add_device_pwm(u32 mask) {} +#endif + + +/* -------------------------------------------------------------------- + * SSC -- Synchronous Serial Controller + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE) +static u64 ssc0_dmamask = DMA_BIT_MASK(32); + +static struct resource ssc0_resources[] = { + [0] = { + .start = AT91SAM9G45_BASE_SSC0, + .end = AT91SAM9G45_BASE_SSC0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9G45_ID_SSC0, + .end = AT91SAM9G45_ID_SSC0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9g45_ssc0_device = { + .name = "ssc", + .id = 0, + .dev = { + .dma_mask = &ssc0_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = ssc0_resources, + .num_resources = ARRAY_SIZE(ssc0_resources), +}; + +static inline void configure_ssc0_pins(unsigned pins) +{ + if (pins & ATMEL_SSC_TF) + at91_set_A_periph(AT91_PIN_PD1, 1); + if (pins & ATMEL_SSC_TK) + at91_set_A_periph(AT91_PIN_PD0, 1); + if (pins & ATMEL_SSC_TD) + at91_set_A_periph(AT91_PIN_PD2, 1); + if (pins & ATMEL_SSC_RD) + at91_set_A_periph(AT91_PIN_PD3, 1); + if (pins & ATMEL_SSC_RK) + at91_set_A_periph(AT91_PIN_PD4, 1); + if (pins & ATMEL_SSC_RF) + at91_set_A_periph(AT91_PIN_PD5, 1); +} + +static u64 ssc1_dmamask = DMA_BIT_MASK(32); + +static struct resource ssc1_resources[] = { + [0] = { + .start = AT91SAM9G45_BASE_SSC1, + .end = AT91SAM9G45_BASE_SSC1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9G45_ID_SSC1, + .end = AT91SAM9G45_ID_SSC1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9g45_ssc1_device = { + .name = "ssc", + .id = 1, + .dev = { + .dma_mask = &ssc1_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = ssc1_resources, + .num_resources = ARRAY_SIZE(ssc1_resources), +}; + +static inline void configure_ssc1_pins(unsigned pins) +{ + if (pins & ATMEL_SSC_TF) + at91_set_A_periph(AT91_PIN_PD14, 1); + if (pins & ATMEL_SSC_TK) + at91_set_A_periph(AT91_PIN_PD12, 1); + if (pins & ATMEL_SSC_TD) + at91_set_A_periph(AT91_PIN_PD10, 1); + if (pins & ATMEL_SSC_RD) + at91_set_A_periph(AT91_PIN_PD11, 1); + if (pins & ATMEL_SSC_RK) + at91_set_A_periph(AT91_PIN_PD13, 1); + if (pins & ATMEL_SSC_RF) + at91_set_A_periph(AT91_PIN_PD15, 1); +} + +/* + * SSC controllers are accessed through library code, instead of any + * kind of all-singing/all-dancing driver. For example one could be + * used by a particular I2S audio codec's driver, while another one + * on the same system might be used by a custom data capture driver. + */ +void __init at91_add_device_ssc(unsigned id, unsigned pins) +{ + struct platform_device *pdev; + + /* + * NOTE: caller is responsible for passing information matching + * "pins" to whatever will be using each particular controller. + */ + switch (id) { + case AT91SAM9G45_ID_SSC0: + pdev = &at91sam9g45_ssc0_device; + configure_ssc0_pins(pins); + break; + case AT91SAM9G45_ID_SSC1: + pdev = &at91sam9g45_ssc1_device; + configure_ssc1_pins(pins); + break; + default: + return; + } + + platform_device_register(pdev); +} + +#else +void __init at91_add_device_ssc(unsigned id, unsigned pins) {} +#endif + + +/* -------------------------------------------------------------------- + * UART + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_SERIAL_ATMEL) +static struct resource dbgu_resources[] = { + [0] = { + .start = AT91_VA_BASE_SYS + AT91_DBGU, + .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91_ID_SYS, + .end = AT91_ID_SYS, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data dbgu_data = { + .use_dma_tx = 0, + .use_dma_rx = 0, + .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), +}; + +static u64 dbgu_dmamask = DMA_BIT_MASK(32); + +static struct platform_device at91sam9g45_dbgu_device = { + .name = "atmel_usart", + .id = 0, + .dev = { + .dma_mask = &dbgu_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &dbgu_data, + }, + .resource = dbgu_resources, + .num_resources = ARRAY_SIZE(dbgu_resources), +}; + +static inline void configure_dbgu_pins(void) +{ + at91_set_A_periph(AT91_PIN_PB12, 0); /* DRXD */ + at91_set_A_periph(AT91_PIN_PB13, 1); /* DTXD */ +} + +static struct resource uart0_resources[] = { + [0] = { + .start = AT91SAM9G45_BASE_US0, + .end = AT91SAM9G45_BASE_US0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9G45_ID_US0, + .end = AT91SAM9G45_ID_US0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart0_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static u64 uart0_dmamask = DMA_BIT_MASK(32); + +static struct platform_device at91sam9g45_uart0_device = { + .name = "atmel_usart", + .id = 1, + .dev = { + .dma_mask = &uart0_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &uart0_data, + }, + .resource = uart0_resources, + .num_resources = ARRAY_SIZE(uart0_resources), +}; + +static inline void configure_usart0_pins(unsigned pins) +{ + at91_set_A_periph(AT91_PIN_PB19, 1); /* TXD0 */ + at91_set_A_periph(AT91_PIN_PB18, 0); /* RXD0 */ + + if (pins & ATMEL_UART_RTS) + at91_set_B_periph(AT91_PIN_PB17, 0); /* RTS0 */ + if (pins & ATMEL_UART_CTS) + at91_set_B_periph(AT91_PIN_PB15, 0); /* CTS0 */ +} + +static struct resource uart1_resources[] = { + [0] = { + .start = AT91SAM9G45_BASE_US1, + .end = AT91SAM9G45_BASE_US1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9G45_ID_US1, + .end = AT91SAM9G45_ID_US1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart1_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static u64 uart1_dmamask = DMA_BIT_MASK(32); + +static struct platform_device at91sam9g45_uart1_device = { + .name = "atmel_usart", + .id = 2, + .dev = { + .dma_mask = &uart1_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &uart1_data, + }, + .resource = uart1_resources, + .num_resources = ARRAY_SIZE(uart1_resources), +}; + +static inline void configure_usart1_pins(unsigned pins) +{ + at91_set_A_periph(AT91_PIN_PB4, 1); /* TXD1 */ + at91_set_A_periph(AT91_PIN_PB5, 0); /* RXD1 */ + + if (pins & ATMEL_UART_RTS) + at91_set_A_periph(AT91_PIN_PD16, 0); /* RTS1 */ + if (pins & ATMEL_UART_CTS) + at91_set_A_periph(AT91_PIN_PD17, 0); /* CTS1 */ +} + +static struct resource uart2_resources[] = { + [0] = { + .start = AT91SAM9G45_BASE_US2, + .end = AT91SAM9G45_BASE_US2 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9G45_ID_US2, + .end = AT91SAM9G45_ID_US2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart2_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static u64 uart2_dmamask = DMA_BIT_MASK(32); + +static struct platform_device at91sam9g45_uart2_device = { + .name = "atmel_usart", + .id = 3, + .dev = { + .dma_mask = &uart2_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &uart2_data, + }, + .resource = uart2_resources, + .num_resources = ARRAY_SIZE(uart2_resources), +}; + +static inline void configure_usart2_pins(unsigned pins) +{ + at91_set_A_periph(AT91_PIN_PB6, 1); /* TXD2 */ + at91_set_A_periph(AT91_PIN_PB7, 0); /* RXD2 */ + + if (pins & ATMEL_UART_RTS) + at91_set_B_periph(AT91_PIN_PC9, 0); /* RTS2 */ + if (pins & ATMEL_UART_CTS) + at91_set_B_periph(AT91_PIN_PC11, 0); /* CTS2 */ +} + +static struct resource uart3_resources[] = { + [0] = { + .start = AT91SAM9G45_BASE_US3, + .end = AT91SAM9G45_BASE_US3 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9G45_ID_US3, + .end = AT91SAM9G45_ID_US3, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart3_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static u64 uart3_dmamask = DMA_BIT_MASK(32); + +static struct platform_device at91sam9g45_uart3_device = { + .name = "atmel_usart", + .id = 4, + .dev = { + .dma_mask = &uart3_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &uart3_data, + }, + .resource = uart3_resources, + .num_resources = ARRAY_SIZE(uart3_resources), +}; + +static inline void configure_usart3_pins(unsigned pins) +{ + at91_set_A_periph(AT91_PIN_PB8, 1); /* TXD3 */ + at91_set_A_periph(AT91_PIN_PB9, 0); /* RXD3 */ + + if (pins & ATMEL_UART_RTS) + at91_set_B_periph(AT91_PIN_PA23, 0); /* RTS3 */ + if (pins & ATMEL_UART_CTS) + at91_set_B_periph(AT91_PIN_PA24, 0); /* CTS3 */ +} + +static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ +struct platform_device *atmel_default_console_device; /* the serial console device */ + +void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) +{ + struct platform_device *pdev; + struct atmel_uart_data *pdata; + + switch (id) { + case 0: /* DBGU */ + pdev = &at91sam9g45_dbgu_device; + configure_dbgu_pins(); + break; + case AT91SAM9G45_ID_US0: + pdev = &at91sam9g45_uart0_device; + configure_usart0_pins(pins); + break; + case AT91SAM9G45_ID_US1: + pdev = &at91sam9g45_uart1_device; + configure_usart1_pins(pins); + break; + case AT91SAM9G45_ID_US2: + pdev = &at91sam9g45_uart2_device; + configure_usart2_pins(pins); + break; + case AT91SAM9G45_ID_US3: + pdev = &at91sam9g45_uart3_device; + configure_usart3_pins(pins); + break; + default: + return; + } + pdata = pdev->dev.platform_data; + pdata->num = portnr; /* update to mapped ID */ + + if (portnr < ATMEL_MAX_UART) + at91_uarts[portnr] = pdev; +} + +void __init at91_set_serial_console(unsigned portnr) +{ + if (portnr < ATMEL_MAX_UART) { + atmel_default_console_device = at91_uarts[portnr]; + at91sam9g45_set_console_clock(at91_uarts[portnr]->id); + } +} + +void __init at91_add_device_serial(void) +{ + int i; + + for (i = 0; i < ATMEL_MAX_UART; i++) { + if (at91_uarts[i]) + platform_device_register(at91_uarts[i]); + } + + if (!atmel_default_console_device) + printk(KERN_INFO "AT91: No default serial console defined.\n"); +} +#else +void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} +void __init at91_set_serial_console(unsigned portnr) {} +void __init at91_add_device_serial(void) {} +#endif + + +/* -------------------------------------------------------------------- */ +/* + * These devices are always present and don't need any board-specific + * setup. + */ +static int __init at91_add_standard_devices(void) +{ + at91_add_device_hdmac(); + at91_add_device_rtc(); + at91_add_device_rtt(); + at91_add_device_watchdog(); + at91_add_device_tc(); + return 0; +} + +arch_initcall(at91_add_standard_devices); diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c new file mode 100644 index 00000000..29dff18e --- /dev/null +++ b/arch/arm/mach-at91/at91sam9rl.c @@ -0,0 +1,383 @@ +/* + * arch/arm/mach-at91/at91sam9rl.c + * + * Copyright (C) 2005 SAN People + * Copyright (C) 2007 Atmel Corporation + * + * 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/pm.h> + +#include <asm/irq.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <mach/cpu.h> +#include <mach/at91sam9rl.h> +#include <mach/at91_pmc.h> +#include <mach/at91_rstc.h> +#include <mach/at91_shdwc.h> + +#include "generic.h" +#include "clock.h" + +static struct map_desc at91sam9rl_io_desc[] __initdata = { + { + .virtual = AT91_VA_BASE_SYS, + .pfn = __phys_to_pfn(AT91_BASE_SYS), + .length = SZ_16K, + .type = MT_DEVICE, + }, +}; + +static struct map_desc at91sam9rl_sram_desc[] __initdata = { + { + .pfn = __phys_to_pfn(AT91SAM9RL_SRAM_BASE), + .type = MT_DEVICE, + } +}; + +/* -------------------------------------------------------------------- + * Clocks + * -------------------------------------------------------------------- */ + +/* + * The peripheral clocks. + */ +static struct clk pioA_clk = { + .name = "pioA_clk", + .pmc_mask = 1 << AT91SAM9RL_ID_PIOA, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioB_clk = { + .name = "pioB_clk", + .pmc_mask = 1 << AT91SAM9RL_ID_PIOB, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioC_clk = { + .name = "pioC_clk", + .pmc_mask = 1 << AT91SAM9RL_ID_PIOC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioD_clk = { + .name = "pioD_clk", + .pmc_mask = 1 << AT91SAM9RL_ID_PIOD, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart0_clk = { + .name = "usart0_clk", + .pmc_mask = 1 << AT91SAM9RL_ID_US0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart1_clk = { + .name = "usart1_clk", + .pmc_mask = 1 << AT91SAM9RL_ID_US1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart2_clk = { + .name = "usart2_clk", + .pmc_mask = 1 << AT91SAM9RL_ID_US2, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart3_clk = { + .name = "usart3_clk", + .pmc_mask = 1 << AT91SAM9RL_ID_US3, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk mmc_clk = { + .name = "mci_clk", + .pmc_mask = 1 << AT91SAM9RL_ID_MCI, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk twi0_clk = { + .name = "twi0_clk", + .pmc_mask = 1 << AT91SAM9RL_ID_TWI0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk twi1_clk = { + .name = "twi1_clk", + .pmc_mask = 1 << AT91SAM9RL_ID_TWI1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk spi_clk = { + .name = "spi_clk", + .pmc_mask = 1 << AT91SAM9RL_ID_SPI, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ssc0_clk = { + .name = "ssc0_clk", + .pmc_mask = 1 << AT91SAM9RL_ID_SSC0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ssc1_clk = { + .name = "ssc1_clk", + .pmc_mask = 1 << AT91SAM9RL_ID_SSC1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk tc0_clk = { + .name = "tc0_clk", + .pmc_mask = 1 << AT91SAM9RL_ID_TC0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk tc1_clk = { + .name = "tc1_clk", + .pmc_mask = 1 << AT91SAM9RL_ID_TC1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk tc2_clk = { + .name = "tc2_clk", + .pmc_mask = 1 << AT91SAM9RL_ID_TC2, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pwm_clk = { + .name = "pwm_clk", + .pmc_mask = 1 << AT91SAM9RL_ID_PWMC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk tsc_clk = { + .name = "tsc_clk", + .pmc_mask = 1 << AT91SAM9RL_ID_TSC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk dma_clk = { + .name = "dma_clk", + .pmc_mask = 1 << AT91SAM9RL_ID_DMA, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk udphs_clk = { + .name = "udphs_clk", + .pmc_mask = 1 << AT91SAM9RL_ID_UDPHS, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk lcdc_clk = { + .name = "lcdc_clk", + .pmc_mask = 1 << AT91SAM9RL_ID_LCDC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ac97_clk = { + .name = "ac97_clk", + .pmc_mask = 1 << AT91SAM9RL_ID_AC97C, + .type = CLK_TYPE_PERIPHERAL, +}; + +static struct clk *periph_clocks[] __initdata = { + &pioA_clk, + &pioB_clk, + &pioC_clk, + &pioD_clk, + &usart0_clk, + &usart1_clk, + &usart2_clk, + &usart3_clk, + &mmc_clk, + &twi0_clk, + &twi1_clk, + &spi_clk, + &ssc0_clk, + &ssc1_clk, + &tc0_clk, + &tc1_clk, + &tc2_clk, + &pwm_clk, + &tsc_clk, + &dma_clk, + &udphs_clk, + &lcdc_clk, + &ac97_clk, + // irq0 +}; + +static struct clk_lookup periph_clocks_lookups[] = { + CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk), + CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk), + CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), + CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk), + CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk), + CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), + CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), +}; + +static struct clk_lookup usart_clocks_lookups[] = { + CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck), + CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk), + CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk), + CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk), + CLKDEV_CON_DEV_ID("usart", "atmel_usart.4", &usart3_clk), +}; + +/* + * The two programmable clocks. + * You must configure pin multiplexing to bring these signals out. + */ +static struct clk pck0 = { + .name = "pck0", + .pmc_mask = AT91_PMC_PCK0, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 0, +}; +static struct clk pck1 = { + .name = "pck1", + .pmc_mask = AT91_PMC_PCK1, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 1, +}; + +static void __init at91sam9rl_register_clocks(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) + clk_register(periph_clocks[i]); + + clkdev_add_table(periph_clocks_lookups, + ARRAY_SIZE(periph_clocks_lookups)); + clkdev_add_table(usart_clocks_lookups, + ARRAY_SIZE(usart_clocks_lookups)); + + clk_register(&pck0); + clk_register(&pck1); +} + +static struct clk_lookup console_clock_lookup; + +void __init at91sam9rl_set_console_clock(int id) +{ + if (id >= ARRAY_SIZE(usart_clocks_lookups)) + return; + + console_clock_lookup.con_id = "usart"; + console_clock_lookup.clk = usart_clocks_lookups[id].clk; + clkdev_add(&console_clock_lookup); +} + +/* -------------------------------------------------------------------- + * GPIO + * -------------------------------------------------------------------- */ + +static struct at91_gpio_bank at91sam9rl_gpio[] = { + { + .id = AT91SAM9RL_ID_PIOA, + .offset = AT91_PIOA, + .clock = &pioA_clk, + }, { + .id = AT91SAM9RL_ID_PIOB, + .offset = AT91_PIOB, + .clock = &pioB_clk, + }, { + .id = AT91SAM9RL_ID_PIOC, + .offset = AT91_PIOC, + .clock = &pioC_clk, + }, { + .id = AT91SAM9RL_ID_PIOD, + .offset = AT91_PIOD, + .clock = &pioD_clk, + } +}; + +static void at91sam9rl_poweroff(void) +{ + at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW); +} + + +/* -------------------------------------------------------------------- + * AT91SAM9RL processor initialization + * -------------------------------------------------------------------- */ + +void __init at91sam9rl_map_io(void) +{ + unsigned long cidr, sram_size; + + /* Map peripherals */ + iotable_init(at91sam9rl_io_desc, ARRAY_SIZE(at91sam9rl_io_desc)); + + cidr = at91_sys_read(AT91_DBGU_CIDR); + + switch (cidr & AT91_CIDR_SRAMSIZ) { + case AT91_CIDR_SRAMSIZ_32K: + sram_size = 2 * SZ_16K; + break; + case AT91_CIDR_SRAMSIZ_16K: + default: + sram_size = SZ_16K; + } + + at91sam9rl_sram_desc->virtual = AT91_IO_VIRT_BASE - sram_size; + at91sam9rl_sram_desc->length = sram_size; + + /* Map SRAM */ + iotable_init(at91sam9rl_sram_desc, ARRAY_SIZE(at91sam9rl_sram_desc)); +} + +void __init at91sam9rl_initialize(unsigned long main_clock) +{ + at91_arch_reset = at91sam9_alt_reset; + pm_power_off = at91sam9rl_poweroff; + at91_extern_irq = (1 << AT91SAM9RL_ID_IRQ0); + + /* Init clock subsystem */ + at91_clock_init(main_clock); + + /* Register the processor-specific clocks */ + at91sam9rl_register_clocks(); + + /* Register GPIO subsystem */ + at91_gpio_init(at91sam9rl_gpio, 4); +} + +/* -------------------------------------------------------------------- + * Interrupt initialization + * -------------------------------------------------------------------- */ + +/* + * The default interrupt priority levels (0 = lowest, 7 = highest). + */ +static unsigned int at91sam9rl_default_irq_priority[NR_AIC_IRQS] __initdata = { + 7, /* Advanced Interrupt Controller */ + 7, /* System Peripherals */ + 1, /* Parallel IO Controller A */ + 1, /* Parallel IO Controller B */ + 1, /* Parallel IO Controller C */ + 1, /* Parallel IO Controller D */ + 5, /* USART 0 */ + 5, /* USART 1 */ + 5, /* USART 2 */ + 5, /* USART 3 */ + 0, /* Multimedia Card Interface */ + 6, /* Two-Wire Interface 0 */ + 6, /* Two-Wire Interface 1 */ + 5, /* Serial Peripheral Interface */ + 4, /* Serial Synchronous Controller 0 */ + 4, /* Serial Synchronous Controller 1 */ + 0, /* Timer Counter 0 */ + 0, /* Timer Counter 1 */ + 0, /* Timer Counter 2 */ + 0, + 0, /* Touch Screen Controller */ + 0, /* DMA Controller */ + 2, /* USB Device High speed port */ + 2, /* LCD Controller */ + 6, /* AC97 Controller */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, /* Advanced Interrupt Controller */ +}; + +void __init at91sam9rl_init_interrupts(unsigned int priority[NR_AIC_IRQS]) +{ + if (!priority) + priority = at91sam9rl_default_irq_priority; + + /* Initialize the AIC interrupt controller */ + at91_aic_init(priority); + + /* Enable GPIO interrupts */ + at91_gpio_irq_setup(); +} diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c new file mode 100644 index 00000000..aacb19dc --- /dev/null +++ b/arch/arm/mach-at91/at91sam9rl_devices.c @@ -0,0 +1,1210 @@ +/* + * Copyright (C) 2007 Atmel Corporation + * + * 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 <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <linux/dma-mapping.h> +#include <linux/platform_device.h> +#include <linux/i2c-gpio.h> + +#include <linux/fb.h> +#include <video/atmel_lcdc.h> + +#include <mach/board.h> +#include <mach/gpio.h> +#include <mach/at91sam9rl.h> +#include <mach/at91sam9rl_matrix.h> +#include <mach/at91sam9_smc.h> +#include <mach/at_hdmac.h> + +#include "generic.h" + + +/* -------------------------------------------------------------------- + * HDMAC - AHB DMA Controller + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_AT_HDMAC) || defined(CONFIG_AT_HDMAC_MODULE) +static u64 hdmac_dmamask = DMA_BIT_MASK(32); + +static struct at_dma_platform_data atdma_pdata = { + .nr_channels = 2, +}; + +static struct resource hdmac_resources[] = { + [0] = { + .start = AT91_BASE_SYS + AT91_DMA, + .end = AT91_BASE_SYS + AT91_DMA + SZ_512 - 1, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = AT91SAM9RL_ID_DMA, + .end = AT91SAM9RL_ID_DMA, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at_hdmac_device = { + .name = "at_hdmac", + .id = -1, + .dev = { + .dma_mask = &hdmac_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &atdma_pdata, + }, + .resource = hdmac_resources, + .num_resources = ARRAY_SIZE(hdmac_resources), +}; + +void __init at91_add_device_hdmac(void) +{ + dma_cap_set(DMA_MEMCPY, atdma_pdata.cap_mask); + platform_device_register(&at_hdmac_device); +} +#else +void __init at91_add_device_hdmac(void) {} +#endif + +/* -------------------------------------------------------------------- + * USB HS Device (Gadget) + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_USB_GADGET_ATMEL_USBA) || defined(CONFIG_USB_GADGET_ATMEL_USBA_MODULE) + +static struct resource usba_udc_resources[] = { + [0] = { + .start = AT91SAM9RL_UDPHS_FIFO, + .end = AT91SAM9RL_UDPHS_FIFO + SZ_512K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9RL_BASE_UDPHS, + .end = AT91SAM9RL_BASE_UDPHS + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = AT91SAM9RL_ID_UDPHS, + .end = AT91SAM9RL_ID_UDPHS, + .flags = IORESOURCE_IRQ, + }, +}; + +#define EP(nam, idx, maxpkt, maxbk, dma, isoc) \ + [idx] = { \ + .name = nam, \ + .index = idx, \ + .fifo_size = maxpkt, \ + .nr_banks = maxbk, \ + .can_dma = dma, \ + .can_isoc = isoc, \ + } + +static struct usba_ep_data usba_udc_ep[] __initdata = { + EP("ep0", 0, 64, 1, 0, 0), + EP("ep1", 1, 1024, 2, 1, 1), + EP("ep2", 2, 1024, 2, 1, 1), + EP("ep3", 3, 1024, 3, 1, 0), + EP("ep4", 4, 1024, 3, 1, 0), + EP("ep5", 5, 1024, 3, 1, 1), + EP("ep6", 6, 1024, 3, 1, 1), +}; + +#undef EP + +/* + * pdata doesn't have room for any endpoints, so we need to + * append room for the ones we need right after it. + */ +static struct { + struct usba_platform_data pdata; + struct usba_ep_data ep[7]; +} usba_udc_data; + +static struct platform_device at91_usba_udc_device = { + .name = "atmel_usba_udc", + .id = -1, + .dev = { + .platform_data = &usba_udc_data.pdata, + }, + .resource = usba_udc_resources, + .num_resources = ARRAY_SIZE(usba_udc_resources), +}; + +void __init at91_add_device_usba(struct usba_platform_data *data) +{ + /* + * Invalid pins are 0 on AT91, but the usba driver is shared + * with AVR32, which use negative values instead. Once/if + * gpio_is_valid() is ported to AT91, revisit this code. + */ + usba_udc_data.pdata.vbus_pin = -EINVAL; + usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep); + memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep)); + + if (data && data->vbus_pin > 0) { + at91_set_gpio_input(data->vbus_pin, 0); + at91_set_deglitch(data->vbus_pin, 1); + usba_udc_data.pdata.vbus_pin = data->vbus_pin; + } + + /* Pullup pin is handled internally by USB device peripheral */ + + platform_device_register(&at91_usba_udc_device); +} +#else +void __init at91_add_device_usba(struct usba_platform_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * MMC / SD + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) +static u64 mmc_dmamask = DMA_BIT_MASK(32); +static struct at91_mmc_data mmc_data; + +static struct resource mmc_resources[] = { + [0] = { + .start = AT91SAM9RL_BASE_MCI, + .end = AT91SAM9RL_BASE_MCI + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9RL_ID_MCI, + .end = AT91SAM9RL_ID_MCI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9rl_mmc_device = { + .name = "at91_mci", + .id = -1, + .dev = { + .dma_mask = &mmc_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &mmc_data, + }, + .resource = mmc_resources, + .num_resources = ARRAY_SIZE(mmc_resources), +}; + +void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) +{ + if (!data) + return; + + /* input/irq */ + if (data->det_pin) { + at91_set_gpio_input(data->det_pin, 1); + at91_set_deglitch(data->det_pin, 1); + } + if (data->wp_pin) + at91_set_gpio_input(data->wp_pin, 1); + if (data->vcc_pin) + at91_set_gpio_output(data->vcc_pin, 0); + + /* CLK */ + at91_set_A_periph(AT91_PIN_PA2, 0); + + /* CMD */ + at91_set_A_periph(AT91_PIN_PA1, 1); + + /* DAT0, maybe DAT1..DAT3 */ + at91_set_A_periph(AT91_PIN_PA0, 1); + if (data->wire4) { + at91_set_A_periph(AT91_PIN_PA3, 1); + at91_set_A_periph(AT91_PIN_PA4, 1); + at91_set_A_periph(AT91_PIN_PA5, 1); + } + + mmc_data = *data; + platform_device_register(&at91sam9rl_mmc_device); +} +#else +void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * NAND / SmartMedia + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE) +static struct atmel_nand_data nand_data; + +#define NAND_BASE AT91_CHIPSELECT_3 + +static struct resource nand_resources[] = { + [0] = { + .start = NAND_BASE, + .end = NAND_BASE + SZ_256M - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91_BASE_SYS + AT91_ECC, + .end = AT91_BASE_SYS + AT91_ECC + SZ_512 - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device atmel_nand_device = { + .name = "atmel_nand", + .id = -1, + .dev = { + .platform_data = &nand_data, + }, + .resource = nand_resources, + .num_resources = ARRAY_SIZE(nand_resources), +}; + +void __init at91_add_device_nand(struct atmel_nand_data *data) +{ + unsigned long csa; + + if (!data) + return; + + csa = at91_sys_read(AT91_MATRIX_EBICSA); + at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); + + /* enable pin */ + if (data->enable_pin) + at91_set_gpio_output(data->enable_pin, 1); + + /* ready/busy pin */ + if (data->rdy_pin) + at91_set_gpio_input(data->rdy_pin, 1); + + /* card detect pin */ + if (data->det_pin) + at91_set_gpio_input(data->det_pin, 1); + + at91_set_A_periph(AT91_PIN_PB4, 0); /* NANDOE */ + at91_set_A_periph(AT91_PIN_PB5, 0); /* NANDWE */ + + nand_data = *data; + platform_device_register(&atmel_nand_device); +} + +#else +void __init at91_add_device_nand(struct atmel_nand_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * TWI (i2c) + * -------------------------------------------------------------------- */ + +/* + * Prefer the GPIO code since the TWI controller isn't robust + * (gets overruns and underruns under load) and can only issue + * repeated STARTs in one scenario (the driver doesn't yet handle them). + */ +#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) + +static struct i2c_gpio_platform_data pdata = { + .sda_pin = AT91_PIN_PA23, + .sda_is_open_drain = 1, + .scl_pin = AT91_PIN_PA24, + .scl_is_open_drain = 1, + .udelay = 2, /* ~100 kHz */ +}; + +static struct platform_device at91sam9rl_twi_device = { + .name = "i2c-gpio", + .id = -1, + .dev.platform_data = &pdata, +}; + +void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) +{ + at91_set_GPIO_periph(AT91_PIN_PA23, 1); /* TWD (SDA) */ + at91_set_multi_drive(AT91_PIN_PA23, 1); + + at91_set_GPIO_periph(AT91_PIN_PA24, 1); /* TWCK (SCL) */ + at91_set_multi_drive(AT91_PIN_PA24, 1); + + i2c_register_board_info(0, devices, nr_devices); + platform_device_register(&at91sam9rl_twi_device); +} + +#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) + +static struct resource twi_resources[] = { + [0] = { + .start = AT91SAM9RL_BASE_TWI0, + .end = AT91SAM9RL_BASE_TWI0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9RL_ID_TWI0, + .end = AT91SAM9RL_ID_TWI0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9rl_twi_device = { + .name = "at91_i2c", + .id = -1, + .resource = twi_resources, + .num_resources = ARRAY_SIZE(twi_resources), +}; + +void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) +{ + /* pins used for TWI interface */ + at91_set_A_periph(AT91_PIN_PA23, 0); /* TWD */ + at91_set_multi_drive(AT91_PIN_PA23, 1); + + at91_set_A_periph(AT91_PIN_PA24, 0); /* TWCK */ + at91_set_multi_drive(AT91_PIN_PA24, 1); + + i2c_register_board_info(0, devices, nr_devices); + platform_device_register(&at91sam9rl_twi_device); +} +#else +void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {} +#endif + + +/* -------------------------------------------------------------------- + * SPI + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) +static u64 spi_dmamask = DMA_BIT_MASK(32); + +static struct resource spi_resources[] = { + [0] = { + .start = AT91SAM9RL_BASE_SPI, + .end = AT91SAM9RL_BASE_SPI + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9RL_ID_SPI, + .end = AT91SAM9RL_ID_SPI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9rl_spi_device = { + .name = "atmel_spi", + .id = 0, + .dev = { + .dma_mask = &spi_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = spi_resources, + .num_resources = ARRAY_SIZE(spi_resources), +}; + +static const unsigned spi_standard_cs[4] = { AT91_PIN_PA28, AT91_PIN_PB7, AT91_PIN_PD8, AT91_PIN_PD9 }; + + +void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) +{ + int i; + unsigned long cs_pin; + + at91_set_A_periph(AT91_PIN_PA25, 0); /* MISO */ + at91_set_A_periph(AT91_PIN_PA26, 0); /* MOSI */ + at91_set_A_periph(AT91_PIN_PA27, 0); /* SPCK */ + + /* Enable SPI chip-selects */ + for (i = 0; i < nr_devices; i++) { + if (devices[i].controller_data) + cs_pin = (unsigned long) devices[i].controller_data; + else + cs_pin = spi_standard_cs[devices[i].chip_select]; + + /* enable chip-select pin */ + at91_set_gpio_output(cs_pin, 1); + + /* pass chip-select pin to driver */ + devices[i].controller_data = (void *) cs_pin; + } + + spi_register_board_info(devices, nr_devices); + platform_device_register(&at91sam9rl_spi_device); +} +#else +void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {} +#endif + + +/* -------------------------------------------------------------------- + * AC97 + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_SND_ATMEL_AC97C) || defined(CONFIG_SND_ATMEL_AC97C_MODULE) +static u64 ac97_dmamask = DMA_BIT_MASK(32); +static struct ac97c_platform_data ac97_data; + +static struct resource ac97_resources[] = { + [0] = { + .start = AT91SAM9RL_BASE_AC97C, + .end = AT91SAM9RL_BASE_AC97C + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9RL_ID_AC97C, + .end = AT91SAM9RL_ID_AC97C, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9rl_ac97_device = { + .name = "atmel_ac97c", + .id = 0, + .dev = { + .dma_mask = &ac97_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &ac97_data, + }, + .resource = ac97_resources, + .num_resources = ARRAY_SIZE(ac97_resources), +}; + +void __init at91_add_device_ac97(struct ac97c_platform_data *data) +{ + if (!data) + return; + + at91_set_A_periph(AT91_PIN_PD1, 0); /* AC97FS */ + at91_set_A_periph(AT91_PIN_PD2, 0); /* AC97CK */ + at91_set_A_periph(AT91_PIN_PD3, 0); /* AC97TX */ + at91_set_A_periph(AT91_PIN_PD4, 0); /* AC97RX */ + + /* reset */ + if (data->reset_pin) + at91_set_gpio_output(data->reset_pin, 0); + + ac97_data = *data; + platform_device_register(&at91sam9rl_ac97_device); +} +#else +void __init at91_add_device_ac97(struct ac97c_platform_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * LCD Controller + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) +static u64 lcdc_dmamask = DMA_BIT_MASK(32); +static struct atmel_lcdfb_info lcdc_data; + +static struct resource lcdc_resources[] = { + [0] = { + .start = AT91SAM9RL_LCDC_BASE, + .end = AT91SAM9RL_LCDC_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9RL_ID_LCDC, + .end = AT91SAM9RL_ID_LCDC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91_lcdc_device = { + .name = "atmel_lcdfb", + .id = 0, + .dev = { + .dma_mask = &lcdc_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &lcdc_data, + }, + .resource = lcdc_resources, + .num_resources = ARRAY_SIZE(lcdc_resources), +}; + +void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) +{ + if (!data) { + return; + } + + at91_set_B_periph(AT91_PIN_PC1, 0); /* LCDPWR */ + at91_set_A_periph(AT91_PIN_PC5, 0); /* LCDHSYNC */ + at91_set_A_periph(AT91_PIN_PC6, 0); /* LCDDOTCK */ + at91_set_A_periph(AT91_PIN_PC7, 0); /* LCDDEN */ + at91_set_A_periph(AT91_PIN_PC3, 0); /* LCDCC */ + at91_set_B_periph(AT91_PIN_PC9, 0); /* LCDD3 */ + at91_set_B_periph(AT91_PIN_PC10, 0); /* LCDD4 */ + at91_set_B_periph(AT91_PIN_PC11, 0); /* LCDD5 */ + at91_set_B_periph(AT91_PIN_PC12, 0); /* LCDD6 */ + at91_set_B_periph(AT91_PIN_PC13, 0); /* LCDD7 */ + at91_set_B_periph(AT91_PIN_PC15, 0); /* LCDD11 */ + at91_set_B_periph(AT91_PIN_PC16, 0); /* LCDD12 */ + at91_set_B_periph(AT91_PIN_PC17, 0); /* LCDD13 */ + at91_set_B_periph(AT91_PIN_PC18, 0); /* LCDD14 */ + at91_set_B_periph(AT91_PIN_PC19, 0); /* LCDD15 */ + at91_set_B_periph(AT91_PIN_PC20, 0); /* LCDD18 */ + at91_set_B_periph(AT91_PIN_PC21, 0); /* LCDD19 */ + at91_set_B_periph(AT91_PIN_PC22, 0); /* LCDD20 */ + at91_set_B_periph(AT91_PIN_PC23, 0); /* LCDD21 */ + at91_set_B_periph(AT91_PIN_PC24, 0); /* LCDD22 */ + at91_set_B_periph(AT91_PIN_PC25, 0); /* LCDD23 */ + + lcdc_data = *data; + platform_device_register(&at91_lcdc_device); +} +#else +void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {} +#endif + + +/* -------------------------------------------------------------------- + * Timer/Counter block + * -------------------------------------------------------------------- */ + +#ifdef CONFIG_ATMEL_TCLIB + +static struct resource tcb_resources[] = { + [0] = { + .start = AT91SAM9RL_BASE_TCB0, + .end = AT91SAM9RL_BASE_TCB0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9RL_ID_TC0, + .end = AT91SAM9RL_ID_TC0, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = AT91SAM9RL_ID_TC1, + .end = AT91SAM9RL_ID_TC1, + .flags = IORESOURCE_IRQ, + }, + [3] = { + .start = AT91SAM9RL_ID_TC2, + .end = AT91SAM9RL_ID_TC2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9rl_tcb_device = { + .name = "atmel_tcb", + .id = 0, + .resource = tcb_resources, + .num_resources = ARRAY_SIZE(tcb_resources), +}; + +static void __init at91_add_device_tc(void) +{ + platform_device_register(&at91sam9rl_tcb_device); +} +#else +static void __init at91_add_device_tc(void) { } +#endif + + +/* -------------------------------------------------------------------- + * Touchscreen + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) || defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC_MODULE) +static u64 tsadcc_dmamask = DMA_BIT_MASK(32); +static struct at91_tsadcc_data tsadcc_data; + +static struct resource tsadcc_resources[] = { + [0] = { + .start = AT91SAM9RL_BASE_TSC, + .end = AT91SAM9RL_BASE_TSC + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9RL_ID_TSC, + .end = AT91SAM9RL_ID_TSC, + .flags = IORESOURCE_IRQ, + } +}; + +static struct platform_device at91sam9rl_tsadcc_device = { + .name = "atmel_tsadcc", + .id = -1, + .dev = { + .dma_mask = &tsadcc_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &tsadcc_data, + }, + .resource = tsadcc_resources, + .num_resources = ARRAY_SIZE(tsadcc_resources), +}; + +void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data) +{ + if (!data) + return; + + at91_set_A_periph(AT91_PIN_PA17, 0); /* AD0_XR */ + at91_set_A_periph(AT91_PIN_PA18, 0); /* AD1_XL */ + at91_set_A_periph(AT91_PIN_PA19, 0); /* AD2_YT */ + at91_set_A_periph(AT91_PIN_PA20, 0); /* AD3_TB */ + + tsadcc_data = *data; + platform_device_register(&at91sam9rl_tsadcc_device); +} +#else +void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * RTC + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE) +static struct platform_device at91sam9rl_rtc_device = { + .name = "at91_rtc", + .id = -1, + .num_resources = 0, +}; + +static void __init at91_add_device_rtc(void) +{ + platform_device_register(&at91sam9rl_rtc_device); +} +#else +static void __init at91_add_device_rtc(void) {} +#endif + + +/* -------------------------------------------------------------------- + * RTT + * -------------------------------------------------------------------- */ + +static struct resource rtt_resources[] = { + { + .start = AT91_BASE_SYS + AT91_RTT, + .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device at91sam9rl_rtt_device = { + .name = "at91_rtt", + .id = 0, + .resource = rtt_resources, + .num_resources = ARRAY_SIZE(rtt_resources), +}; + +static void __init at91_add_device_rtt(void) +{ + platform_device_register(&at91sam9rl_rtt_device); +} + + +/* -------------------------------------------------------------------- + * Watchdog + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) +static struct platform_device at91sam9rl_wdt_device = { + .name = "at91_wdt", + .id = -1, + .num_resources = 0, +}; + +static void __init at91_add_device_watchdog(void) +{ + platform_device_register(&at91sam9rl_wdt_device); +} +#else +static void __init at91_add_device_watchdog(void) {} +#endif + + +/* -------------------------------------------------------------------- + * PWM + * --------------------------------------------------------------------*/ + +#if defined(CONFIG_ATMEL_PWM) +static u32 pwm_mask; + +static struct resource pwm_resources[] = { + [0] = { + .start = AT91SAM9RL_BASE_PWMC, + .end = AT91SAM9RL_BASE_PWMC + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9RL_ID_PWMC, + .end = AT91SAM9RL_ID_PWMC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9rl_pwm0_device = { + .name = "atmel_pwm", + .id = -1, + .dev = { + .platform_data = &pwm_mask, + }, + .resource = pwm_resources, + .num_resources = ARRAY_SIZE(pwm_resources), +}; + +void __init at91_add_device_pwm(u32 mask) +{ + if (mask & (1 << AT91_PWM0)) + at91_set_B_periph(AT91_PIN_PB8, 1); /* enable PWM0 */ + + if (mask & (1 << AT91_PWM1)) + at91_set_B_periph(AT91_PIN_PB9, 1); /* enable PWM1 */ + + if (mask & (1 << AT91_PWM2)) + at91_set_B_periph(AT91_PIN_PD5, 1); /* enable PWM2 */ + + if (mask & (1 << AT91_PWM3)) + at91_set_B_periph(AT91_PIN_PD8, 1); /* enable PWM3 */ + + pwm_mask = mask; + + platform_device_register(&at91sam9rl_pwm0_device); +} +#else +void __init at91_add_device_pwm(u32 mask) {} +#endif + + +/* -------------------------------------------------------------------- + * SSC -- Synchronous Serial Controller + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE) +static u64 ssc0_dmamask = DMA_BIT_MASK(32); + +static struct resource ssc0_resources[] = { + [0] = { + .start = AT91SAM9RL_BASE_SSC0, + .end = AT91SAM9RL_BASE_SSC0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9RL_ID_SSC0, + .end = AT91SAM9RL_ID_SSC0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9rl_ssc0_device = { + .name = "ssc", + .id = 0, + .dev = { + .dma_mask = &ssc0_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = ssc0_resources, + .num_resources = ARRAY_SIZE(ssc0_resources), +}; + +static inline void configure_ssc0_pins(unsigned pins) +{ + if (pins & ATMEL_SSC_TF) + at91_set_A_periph(AT91_PIN_PC0, 1); + if (pins & ATMEL_SSC_TK) + at91_set_A_periph(AT91_PIN_PC1, 1); + if (pins & ATMEL_SSC_TD) + at91_set_A_periph(AT91_PIN_PA15, 1); + if (pins & ATMEL_SSC_RD) + at91_set_A_periph(AT91_PIN_PA16, 1); + if (pins & ATMEL_SSC_RK) + at91_set_B_periph(AT91_PIN_PA10, 1); + if (pins & ATMEL_SSC_RF) + at91_set_B_periph(AT91_PIN_PA22, 1); +} + +static u64 ssc1_dmamask = DMA_BIT_MASK(32); + +static struct resource ssc1_resources[] = { + [0] = { + .start = AT91SAM9RL_BASE_SSC1, + .end = AT91SAM9RL_BASE_SSC1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9RL_ID_SSC1, + .end = AT91SAM9RL_ID_SSC1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9rl_ssc1_device = { + .name = "ssc", + .id = 1, + .dev = { + .dma_mask = &ssc1_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = ssc1_resources, + .num_resources = ARRAY_SIZE(ssc1_resources), +}; + +static inline void configure_ssc1_pins(unsigned pins) +{ + if (pins & ATMEL_SSC_TF) + at91_set_B_periph(AT91_PIN_PA29, 1); + if (pins & ATMEL_SSC_TK) + at91_set_B_periph(AT91_PIN_PA30, 1); + if (pins & ATMEL_SSC_TD) + at91_set_B_periph(AT91_PIN_PA13, 1); + if (pins & ATMEL_SSC_RD) + at91_set_B_periph(AT91_PIN_PA14, 1); + if (pins & ATMEL_SSC_RK) + at91_set_B_periph(AT91_PIN_PA9, 1); + if (pins & ATMEL_SSC_RF) + at91_set_B_periph(AT91_PIN_PA8, 1); +} + +/* + * SSC controllers are accessed through library code, instead of any + * kind of all-singing/all-dancing driver. For example one could be + * used by a particular I2S audio codec's driver, while another one + * on the same system might be used by a custom data capture driver. + */ +void __init at91_add_device_ssc(unsigned id, unsigned pins) +{ + struct platform_device *pdev; + + /* + * NOTE: caller is responsible for passing information matching + * "pins" to whatever will be using each particular controller. + */ + switch (id) { + case AT91SAM9RL_ID_SSC0: + pdev = &at91sam9rl_ssc0_device; + configure_ssc0_pins(pins); + break; + case AT91SAM9RL_ID_SSC1: + pdev = &at91sam9rl_ssc1_device; + configure_ssc1_pins(pins); + break; + default: + return; + } + + platform_device_register(pdev); +} + +#else +void __init at91_add_device_ssc(unsigned id, unsigned pins) {} +#endif + + +/* -------------------------------------------------------------------- + * UART + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_SERIAL_ATMEL) +static struct resource dbgu_resources[] = { + [0] = { + .start = AT91_VA_BASE_SYS + AT91_DBGU, + .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91_ID_SYS, + .end = AT91_ID_SYS, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data dbgu_data = { + .use_dma_tx = 0, + .use_dma_rx = 0, /* DBGU not capable of receive DMA */ + .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), +}; + +static u64 dbgu_dmamask = DMA_BIT_MASK(32); + +static struct platform_device at91sam9rl_dbgu_device = { + .name = "atmel_usart", + .id = 0, + .dev = { + .dma_mask = &dbgu_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &dbgu_data, + }, + .resource = dbgu_resources, + .num_resources = ARRAY_SIZE(dbgu_resources), +}; + +static inline void configure_dbgu_pins(void) +{ + at91_set_A_periph(AT91_PIN_PA21, 0); /* DRXD */ + at91_set_A_periph(AT91_PIN_PA22, 1); /* DTXD */ +} + +static struct resource uart0_resources[] = { + [0] = { + .start = AT91SAM9RL_BASE_US0, + .end = AT91SAM9RL_BASE_US0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9RL_ID_US0, + .end = AT91SAM9RL_ID_US0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart0_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static u64 uart0_dmamask = DMA_BIT_MASK(32); + +static struct platform_device at91sam9rl_uart0_device = { + .name = "atmel_usart", + .id = 1, + .dev = { + .dma_mask = &uart0_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &uart0_data, + }, + .resource = uart0_resources, + .num_resources = ARRAY_SIZE(uart0_resources), +}; + +static inline void configure_usart0_pins(unsigned pins) +{ + at91_set_A_periph(AT91_PIN_PA6, 1); /* TXD0 */ + at91_set_A_periph(AT91_PIN_PA7, 0); /* RXD0 */ + + if (pins & ATMEL_UART_RTS) + at91_set_A_periph(AT91_PIN_PA9, 0); /* RTS0 */ + if (pins & ATMEL_UART_CTS) + at91_set_A_periph(AT91_PIN_PA10, 0); /* CTS0 */ + if (pins & ATMEL_UART_DSR) + at91_set_A_periph(AT91_PIN_PD14, 0); /* DSR0 */ + if (pins & ATMEL_UART_DTR) + at91_set_A_periph(AT91_PIN_PD15, 0); /* DTR0 */ + if (pins & ATMEL_UART_DCD) + at91_set_A_periph(AT91_PIN_PD16, 0); /* DCD0 */ + if (pins & ATMEL_UART_RI) + at91_set_A_periph(AT91_PIN_PD17, 0); /* RI0 */ +} + +static struct resource uart1_resources[] = { + [0] = { + .start = AT91SAM9RL_BASE_US1, + .end = AT91SAM9RL_BASE_US1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9RL_ID_US1, + .end = AT91SAM9RL_ID_US1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart1_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static u64 uart1_dmamask = DMA_BIT_MASK(32); + +static struct platform_device at91sam9rl_uart1_device = { + .name = "atmel_usart", + .id = 2, + .dev = { + .dma_mask = &uart1_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &uart1_data, + }, + .resource = uart1_resources, + .num_resources = ARRAY_SIZE(uart1_resources), +}; + +static inline void configure_usart1_pins(unsigned pins) +{ + at91_set_A_periph(AT91_PIN_PA11, 1); /* TXD1 */ + at91_set_A_periph(AT91_PIN_PA12, 0); /* RXD1 */ + + if (pins & ATMEL_UART_RTS) + at91_set_B_periph(AT91_PIN_PA18, 0); /* RTS1 */ + if (pins & ATMEL_UART_CTS) + at91_set_B_periph(AT91_PIN_PA19, 0); /* CTS1 */ +} + +static struct resource uart2_resources[] = { + [0] = { + .start = AT91SAM9RL_BASE_US2, + .end = AT91SAM9RL_BASE_US2 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9RL_ID_US2, + .end = AT91SAM9RL_ID_US2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart2_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static u64 uart2_dmamask = DMA_BIT_MASK(32); + +static struct platform_device at91sam9rl_uart2_device = { + .name = "atmel_usart", + .id = 3, + .dev = { + .dma_mask = &uart2_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &uart2_data, + }, + .resource = uart2_resources, + .num_resources = ARRAY_SIZE(uart2_resources), +}; + +static inline void configure_usart2_pins(unsigned pins) +{ + at91_set_A_periph(AT91_PIN_PA13, 1); /* TXD2 */ + at91_set_A_periph(AT91_PIN_PA14, 0); /* RXD2 */ + + if (pins & ATMEL_UART_RTS) + at91_set_A_periph(AT91_PIN_PA29, 0); /* RTS2 */ + if (pins & ATMEL_UART_CTS) + at91_set_A_periph(AT91_PIN_PA30, 0); /* CTS2 */ +} + +static struct resource uart3_resources[] = { + [0] = { + .start = AT91SAM9RL_BASE_US3, + .end = AT91SAM9RL_BASE_US3 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9RL_ID_US3, + .end = AT91SAM9RL_ID_US3, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart3_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static u64 uart3_dmamask = DMA_BIT_MASK(32); + +static struct platform_device at91sam9rl_uart3_device = { + .name = "atmel_usart", + .id = 4, + .dev = { + .dma_mask = &uart3_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &uart3_data, + }, + .resource = uart3_resources, + .num_resources = ARRAY_SIZE(uart3_resources), +}; + +static inline void configure_usart3_pins(unsigned pins) +{ + at91_set_A_periph(AT91_PIN_PB0, 1); /* TXD3 */ + at91_set_A_periph(AT91_PIN_PB1, 0); /* RXD3 */ + + if (pins & ATMEL_UART_RTS) + at91_set_B_periph(AT91_PIN_PD4, 0); /* RTS3 */ + if (pins & ATMEL_UART_CTS) + at91_set_B_periph(AT91_PIN_PD3, 0); /* CTS3 */ +} + +static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ +struct platform_device *atmel_default_console_device; /* the serial console device */ + +void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) +{ + struct platform_device *pdev; + struct atmel_uart_data *pdata; + + switch (id) { + case 0: /* DBGU */ + pdev = &at91sam9rl_dbgu_device; + configure_dbgu_pins(); + break; + case AT91SAM9RL_ID_US0: + pdev = &at91sam9rl_uart0_device; + configure_usart0_pins(pins); + break; + case AT91SAM9RL_ID_US1: + pdev = &at91sam9rl_uart1_device; + configure_usart1_pins(pins); + break; + case AT91SAM9RL_ID_US2: + pdev = &at91sam9rl_uart2_device; + configure_usart2_pins(pins); + break; + case AT91SAM9RL_ID_US3: + pdev = &at91sam9rl_uart3_device; + configure_usart3_pins(pins); + break; + default: + return; + } + pdata = pdev->dev.platform_data; + pdata->num = portnr; /* update to mapped ID */ + + if (portnr < ATMEL_MAX_UART) + at91_uarts[portnr] = pdev; +} + +void __init at91_set_serial_console(unsigned portnr) +{ + if (portnr < ATMEL_MAX_UART) { + atmel_default_console_device = at91_uarts[portnr]; + at91sam9rl_set_console_clock(at91_uarts[portnr]->id); + } +} + +void __init at91_add_device_serial(void) +{ + int i; + + for (i = 0; i < ATMEL_MAX_UART; i++) { + if (at91_uarts[i]) + platform_device_register(at91_uarts[i]); + } + + if (!atmel_default_console_device) + printk(KERN_INFO "AT91: No default serial console defined.\n"); +} +#else +void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} +void __init at91_set_serial_console(unsigned portnr) {} +void __init at91_add_device_serial(void) {} +#endif + + +/* -------------------------------------------------------------------- */ + +/* + * These devices are always present and don't need any board-specific + * setup. + */ +static int __init at91_add_standard_devices(void) +{ + at91_add_device_hdmac(); + at91_add_device_rtc(); + at91_add_device_rtt(); + at91_add_device_watchdog(); + at91_add_device_tc(); + return 0; +} + +arch_initcall(at91_add_standard_devices); diff --git a/arch/arm/mach-at91/at91x40.c b/arch/arm/mach-at91/at91x40.c new file mode 100644 index 00000000..56ba3bd0 --- /dev/null +++ b/arch/arm/mach-at91/at91x40.c @@ -0,0 +1,78 @@ +/* + * arch/arm/mach-at91/at91x40.c + * + * (C) Copyright 2007, Greg Ungerer <gerg@snapgear.com> + * Copyright (C) 2005 SAN People + * + * 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. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/irq.h> +#include <asm/mach/arch.h> +#include <mach/at91x40.h> +#include <mach/at91_st.h> +#include <mach/timex.h> +#include "generic.h" + +/* + * Export the clock functions for the AT91X40. Some external code common + * to all AT91 family parts relys on this, like the gpio and serial support. + */ +int clk_enable(struct clk *clk) +{ + return 0; +} + +void clk_disable(struct clk *clk) +{ +} + +unsigned long clk_get_rate(struct clk *clk) +{ + return AT91X40_MASTER_CLOCK; +} + +void __init at91x40_initialize(unsigned long main_clock) +{ + at91_extern_irq = (1 << AT91X40_ID_IRQ0) | (1 << AT91X40_ID_IRQ1) + | (1 << AT91X40_ID_IRQ2); +} + +/* + * The default interrupt priority levels (0 = lowest, 7 = highest). + */ +static unsigned int at91x40_default_irq_priority[NR_AIC_IRQS] __initdata = { + 7, /* Advanced Interrupt Controller (FIQ) */ + 0, /* System Peripherals */ + 0, /* USART 0 */ + 0, /* USART 1 */ + 2, /* Timer Counter 0 */ + 2, /* Timer Counter 1 */ + 2, /* Timer Counter 2 */ + 0, /* Watchdog timer */ + 0, /* Parallel IO Controller A */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* External IRQ0 */ + 0, /* External IRQ1 */ + 0, /* External IRQ2 */ +}; + +void __init at91x40_init_interrupts(unsigned int priority[NR_AIC_IRQS]) +{ + if (!priority) + priority = at91x40_default_irq_priority; + + at91_aic_init(priority); +} + diff --git a/arch/arm/mach-at91/at91x40_time.c b/arch/arm/mach-at91/at91x40_time.c new file mode 100644 index 00000000..dfff2895 --- /dev/null +++ b/arch/arm/mach-at91/at91x40_time.c @@ -0,0 +1,80 @@ +/* + * arch/arm/mach-at91/at91x40_time.c + * + * (C) Copyright 2007, Greg Ungerer <gerg@snapgear.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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/time.h> +#include <linux/io.h> +#include <mach/hardware.h> +#include <asm/mach/time.h> +#include <mach/at91_tc.h> + +/* + * 3 counter/timer units present. + */ +#define AT91_TC_CLK0BASE 0 +#define AT91_TC_CLK1BASE 0x40 +#define AT91_TC_CLK2BASE 0x80 + +static unsigned long at91x40_gettimeoffset(void) +{ + return (at91_sys_read(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CV) * 1000000 / (AT91X40_MASTER_CLOCK / 128)); +} + +static irqreturn_t at91x40_timer_interrupt(int irq, void *dev_id) +{ + at91_sys_read(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_SR); + timer_tick(); + return IRQ_HANDLED; +} + +static struct irqaction at91x40_timer_irq = { + .name = "at91_tick", + .flags = IRQF_DISABLED | IRQF_TIMER, + .handler = at91x40_timer_interrupt +}; + +void __init at91x40_timer_init(void) +{ + unsigned int v; + + at91_sys_write(AT91_TC + AT91_TC_BCR, 0); + v = at91_sys_read(AT91_TC + AT91_TC_BMR); + v = (v & ~AT91_TC_TC1XC1S) | AT91_TC_TC1XC1S_NONE; + at91_sys_write(AT91_TC + AT91_TC_BMR, v); + + at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CCR, AT91_TC_CLKDIS); + at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CMR, (AT91_TC_TIMER_CLOCK4 | AT91_TC_CPCTRG)); + at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_IDR, 0xffffffff); + at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_RC, (AT91X40_MASTER_CLOCK / 128) / HZ - 1); + at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_IER, (1<<4)); + + setup_irq(AT91X40_ID_TC1, &at91x40_timer_irq); + + at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CCR, (AT91_TC_SWTRG | AT91_TC_CLKEN)); +} + +struct sys_timer at91x40_timer = { + .init = at91x40_timer_init, + .offset = at91x40_gettimeoffset, +}; + diff --git a/arch/arm/mach-at91/board-1arm.c b/arch/arm/mach-at91/board-1arm.c new file mode 100644 index 00000000..ab1d463a --- /dev/null +++ b/arch/arm/mach-at91/board-1arm.c @@ -0,0 +1,104 @@ +/* + * linux/arch/arm/mach-at91/board-1arm.c + * + * Copyright (C) 2005 SAN People + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/platform_device.h> + +#include <mach/hardware.h> +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <mach/board.h> +#include <mach/gpio.h> +#include <mach/cpu.h> + +#include "generic.h" + + +static void __init onearm_init_early(void) +{ + /* Set cpu type: PQFP */ + at91rm9200_set_type(ARCH_REVISON_9200_PQFP); + + /* Initialize processor: 18.432 MHz crystal */ + at91rm9200_initialize(18432000); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1 (Rx, Tx, CTS, RTS) */ + at91_register_uart(AT91RM9200_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* USART1 on ttyS2 (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91RM9200_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD + | ATMEL_UART_RI); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init onearm_init_irq(void) +{ + at91rm9200_init_interrupts(NULL); +} + +static struct at91_eth_data __initdata onearm_eth_data = { + .phy_irq_pin = AT91_PIN_PC4, + .is_rmii = 1, +}; + +static struct at91_usbh_data __initdata onearm_usbh_data = { + .ports = 1, +}; + +static struct at91_udc_data __initdata onearm_udc_data = { + .vbus_pin = AT91_PIN_PC2, + .pullup_pin = AT91_PIN_PC3, +}; + +static void __init onearm_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* Ethernet */ + at91_add_device_eth(&onearm_eth_data); + /* USB Host */ + at91_add_device_usbh(&onearm_usbh_data); + /* USB Device */ + at91_add_device_udc(&onearm_udc_data); +} + +MACHINE_START(ONEARM, "Ajeco 1ARM single board computer") + /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */ + .timer = &at91rm9200_timer, + .map_io = at91rm9200_map_io, + .init_early = onearm_init_early, + .init_irq = onearm_init_irq, + .init_machine = onearm_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-afeb-9260v1.c b/arch/arm/mach-at91/board-afeb-9260v1.c new file mode 100644 index 00000000..a4924de4 --- /dev/null +++ b/arch/arm/mach-at91/board-afeb-9260v1.c @@ -0,0 +1,227 @@ +/* + * linux/arch/arm/mach-at91/board-afeb-9260v1.c + * + * Copyright (C) 2005 SAN People + * Copyright (C) 2006 Atmel + * Copyright (C) 2008 Sergey Lapin + * + * A custom board designed as open hardware; PCBs and various information + * is available at http://groups.google.com/group/arm9fpga-evolution-board/ + * Subversion repository: svn://194.85.238.22/home/users/george/svn/arm9eb + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> +#include <linux/clk.h> +#include <linux/dma-mapping.h> + +#include <mach/hardware.h> +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <mach/board.h> +#include <mach/gpio.h> + +#include "generic.h" + + +static void __init afeb9260_init_early(void) +{ + /* Initialize processor: 18.432 MHz crystal */ + at91sam9260_initialize(18432000); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91SAM9260_ID_US0, 1, + ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR + | ATMEL_UART_DCD | ATMEL_UART_RI); + + /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */ + at91_register_uart(AT91SAM9260_ID_US1, 2, + ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init afeb9260_init_irq(void) +{ + at91sam9260_init_interrupts(NULL); +} + + +/* + * USB Host port + */ +static struct at91_usbh_data __initdata afeb9260_usbh_data = { + .ports = 1, +}; + +/* + * USB Device port + */ +static struct at91_udc_data __initdata afeb9260_udc_data = { + .vbus_pin = AT91_PIN_PC5, + .pullup_pin = 0, /* pull-up driven by UDC */ +}; + + + +/* + * SPI devices. + */ +static struct spi_board_info afeb9260_spi_devices[] = { + { /* DataFlash chip */ + .modalias = "mtd_dataflash", + .chip_select = 1, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +}; + + +/* + * MACB Ethernet device + */ +static struct at91_eth_data __initdata afeb9260_macb_data = { + .phy_irq_pin = AT91_PIN_PA9, + .is_rmii = 0, +}; + + +/* + * NAND flash + */ +static struct mtd_partition __initdata afeb9260_nand_partition[] = { + { + .name = "bootloader", + .offset = 0, + .size = (640 * SZ_1K), + }, + { + .name = "kernel", + .offset = MTDPART_OFS_NXTBLK, + .size = SZ_2M, + }, + { + .name = "rootfs", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(afeb9260_nand_partition); + return afeb9260_nand_partition; +} + +static struct atmel_nand_data __initdata afeb9260_nand_data = { + .ale = 21, + .cle = 22, + .rdy_pin = AT91_PIN_PC13, + .enable_pin = AT91_PIN_PC14, + .partition_info = nand_partitions, + .bus_width_16 = 0, +}; + + +/* + * MCI (SD/MMC) + */ +static struct at91_mmc_data __initdata afeb9260_mmc_data = { + .det_pin = AT91_PIN_PC9, + .wp_pin = AT91_PIN_PC4, + .slot_b = 1, + .wire4 = 1, +}; + + + +static struct i2c_board_info __initdata afeb9260_i2c_devices[] = { + { + I2C_BOARD_INFO("tlv320aic23", 0x1a), + }, { + I2C_BOARD_INFO("fm3130", 0x68), + }, { + I2C_BOARD_INFO("24c64", 0x50), + }, +}; + +/* + * IDE (CF True IDE mode) + */ +static struct at91_cf_data afeb9260_cf_data = { + .chipselect = 4, + .irq_pin = AT91_PIN_PA6, + .rst_pin = AT91_PIN_PA7, + .flags = AT91_CF_TRUE_IDE, +}; + +static void __init afeb9260_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* USB Host */ + at91_add_device_usbh(&afeb9260_usbh_data); + /* USB Device */ + at91_add_device_udc(&afeb9260_udc_data); + /* SPI */ + at91_add_device_spi(afeb9260_spi_devices, + ARRAY_SIZE(afeb9260_spi_devices)); + /* NAND */ + at91_add_device_nand(&afeb9260_nand_data); + /* Ethernet */ + at91_add_device_eth(&afeb9260_macb_data); + + /* Standard function's pin assignments are not + * appropriate for us and generic code provide + * no API to configure these pins any other way */ + at91_set_B_periph(AT91_PIN_PA10, 0); /* ETX2 */ + at91_set_B_periph(AT91_PIN_PA11, 0); /* ETX3 */ + /* MMC */ + at91_add_device_mmc(0, &afeb9260_mmc_data); + /* I2C */ + at91_add_device_i2c(afeb9260_i2c_devices, + ARRAY_SIZE(afeb9260_i2c_devices)); + /* Audio */ + at91_add_device_ssc(AT91SAM9260_ID_SSC, ATMEL_SSC_TX); + /* IDE */ + at91_add_device_cf(&afeb9260_cf_data); +} + +MACHINE_START(AFEB9260, "Custom afeb9260 board") + /* Maintainer: Sergey Lapin <slapin@ossfans.org> */ + .timer = &at91sam926x_timer, + .map_io = at91sam9260_map_io, + .init_early = afeb9260_init_early, + .init_irq = afeb9260_init_irq, + .init_machine = afeb9260_board_init, +MACHINE_END + diff --git a/arch/arm/mach-at91/board-cam60.c b/arch/arm/mach-at91/board-cam60.c new file mode 100644 index 00000000..148fccb9 --- /dev/null +++ b/arch/arm/mach-at91/board-cam60.c @@ -0,0 +1,206 @@ +/* + * KwikByte CAM60 (KB9260) + * + * based on board-sam9260ek.c + * Copyright (C) 2005 SAN People + * Copyright (C) 2006 Atmel + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> +#include <linux/spi/flash.h> + +#include <mach/hardware.h> +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <mach/board.h> +#include <mach/gpio.h> +#include <mach/at91sam9_smc.h> + +#include "sam9_smc.h" +#include "generic.h" + + +static void __init cam60_init_early(void) +{ + /* Initialize processor: 10 MHz crystal */ + at91sam9260_initialize(10000000); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init cam60_init_irq(void) +{ + at91sam9260_init_interrupts(NULL); +} + + +/* + * USB Host + */ +static struct at91_usbh_data __initdata cam60_usbh_data = { + .ports = 1, +}; + + +/* + * SPI devices. + */ +#if defined(CONFIG_MTD_DATAFLASH) +static struct mtd_partition cam60_spi_partitions[] = { + { + .name = "BOOT1", + .offset = 0, + .size = 4 * 1056, + }, + { + .name = "BOOT2", + .offset = MTDPART_OFS_NXTBLK, + .size = 256 * 1056, + }, + { + .name = "kernel", + .offset = MTDPART_OFS_NXTBLK, + .size = 2222 * 1056, + }, + { + .name = "file system", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct flash_platform_data cam60_spi_flash_platform_data = { + .name = "spi_flash", + .parts = cam60_spi_partitions, + .nr_parts = ARRAY_SIZE(cam60_spi_partitions) +}; +#endif + +static struct spi_board_info cam60_spi_devices[] __initdata = { +#if defined(CONFIG_MTD_DATAFLASH) + { /* DataFlash chip */ + .modalias = "mtd_dataflash", + .chip_select = 0, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + .platform_data = &cam60_spi_flash_platform_data + }, +#endif +}; + + +/* + * MACB Ethernet device + */ +static struct __initdata at91_eth_data cam60_macb_data = { + .phy_irq_pin = AT91_PIN_PB5, + .is_rmii = 0, +}; + + +/* + * NAND Flash + */ +static struct mtd_partition __initdata cam60_nand_partition[] = { + { + .name = "nand_fs", + .offset = 0, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(cam60_nand_partition); + return cam60_nand_partition; +} + +static struct atmel_nand_data __initdata cam60_nand_data = { + .ale = 21, + .cle = 22, + // .det_pin = ... not there + .rdy_pin = AT91_PIN_PA9, + .enable_pin = AT91_PIN_PA7, + .partition_info = nand_partitions, +}; + +static struct sam9_smc_config __initdata cam60_nand_smc_config = { + .ncs_read_setup = 0, + .nrd_setup = 1, + .ncs_write_setup = 0, + .nwe_setup = 1, + + .ncs_read_pulse = 3, + .nrd_pulse = 3, + .ncs_write_pulse = 3, + .nwe_pulse = 3, + + .read_cycle = 5, + .write_cycle = 5, + + .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8, + .tdf_cycles = 2, +}; + +static void __init cam60_add_device_nand(void) +{ + /* configure chip-select 3 (NAND) */ + sam9_smc_configure(3, &cam60_nand_smc_config); + + at91_add_device_nand(&cam60_nand_data); +} + + +static void __init cam60_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* SPI */ + at91_add_device_spi(cam60_spi_devices, ARRAY_SIZE(cam60_spi_devices)); + /* Ethernet */ + at91_add_device_eth(&cam60_macb_data); + /* USB Host */ + /* enable USB power supply circuit */ + at91_set_gpio_output(AT91_PIN_PB18, 1); + at91_add_device_usbh(&cam60_usbh_data); + /* NAND */ + cam60_add_device_nand(); +} + +MACHINE_START(CAM60, "KwikByte CAM60") + /* Maintainer: KwikByte */ + .timer = &at91sam926x_timer, + .map_io = at91sam9260_map_io, + .init_early = cam60_init_early, + .init_irq = cam60_init_irq, + .init_machine = cam60_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-cap9adk.c b/arch/arm/mach-at91/board-cap9adk.c new file mode 100644 index 00000000..cdb65d48 --- /dev/null +++ b/arch/arm/mach-at91/board-cap9adk.c @@ -0,0 +1,404 @@ +/* + * linux/arch/arm/mach-at91/board-cap9adk.c + * + * Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com> + * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com> + * Copyright (C) 2005 SAN People + * Copyright (C) 2007 Atmel Corporation. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> +#include <linux/spi/ads7846.h> +#include <linux/fb.h> +#include <linux/mtd/physmap.h> + +#include <video/atmel_lcdc.h> + +#include <mach/hardware.h> +#include <asm/setup.h> +#include <asm/mach-types.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <mach/board.h> +#include <mach/gpio.h> +#include <mach/at91cap9_matrix.h> +#include <mach/at91sam9_smc.h> +#include <mach/system_rev.h> + +#include "sam9_smc.h" +#include "generic.h" + + +static void __init cap9adk_init_early(void) +{ + /* Initialize processor: 12 MHz crystal */ + at91cap9_initialize(12000000); + + /* Setup the LEDs: USER1 and USER2 LED for cpu/timer... */ + at91_init_leds(AT91_PIN_PA10, AT91_PIN_PA11); + /* ... POWER LED always on */ + at91_set_gpio_output(AT91_PIN_PC29, 1); + + /* Setup the serial ports and console */ + at91_register_uart(0, 0, 0); /* DBGU = ttyS0 */ + at91_set_serial_console(0); +} + +static void __init cap9adk_init_irq(void) +{ + at91cap9_init_interrupts(NULL); +} + + +/* + * USB Host port + */ +static struct at91_usbh_data __initdata cap9adk_usbh_data = { + .ports = 2, +}; + +/* + * USB HS Device port + */ +static struct usba_platform_data __initdata cap9adk_usba_udc_data = { + .vbus_pin = AT91_PIN_PB31, +}; + +/* + * ADS7846 Touchscreen + */ +#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) +static int ads7843_pendown_state(void) +{ + return !at91_get_gpio_value(AT91_PIN_PC4); /* Touchscreen PENIRQ */ +} + +static struct ads7846_platform_data ads_info = { + .model = 7843, + .x_min = 150, + .x_max = 3830, + .y_min = 190, + .y_max = 3830, + .vref_delay_usecs = 100, + .x_plate_ohms = 450, + .y_plate_ohms = 250, + .pressure_max = 15000, + .debounce_max = 1, + .debounce_rep = 0, + .debounce_tol = (~0), + .get_pendown_state = ads7843_pendown_state, +}; + +static void __init cap9adk_add_device_ts(void) +{ + at91_set_gpio_input(AT91_PIN_PC4, 1); /* Touchscreen PENIRQ */ + at91_set_gpio_input(AT91_PIN_PC5, 1); /* Touchscreen BUSY */ +} +#else +static void __init cap9adk_add_device_ts(void) {} +#endif + + +/* + * SPI devices. + */ +static struct spi_board_info cap9adk_spi_devices[] = { +#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD) + { /* DataFlash card */ + .modalias = "mtd_dataflash", + .chip_select = 0, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +#endif +#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) + { + .modalias = "ads7846", + .chip_select = 3, /* can be 2 or 3, depending on J2 jumper */ + .max_speed_hz = 125000 * 26, /* (max sample rate @ 3V) * (cmd + data + overhead) */ + .bus_num = 0, + .platform_data = &ads_info, + .irq = AT91_PIN_PC4, + }, +#endif +}; + + +/* + * MCI (SD/MMC) + */ +static struct at91_mmc_data __initdata cap9adk_mmc_data = { + .wire4 = 1, +// .det_pin = ... not connected +// .wp_pin = ... not connected +// .vcc_pin = ... not connected +}; + + +/* + * MACB Ethernet device + */ +static struct at91_eth_data __initdata cap9adk_macb_data = { + .is_rmii = 1, +}; + + +/* + * NAND flash + */ +static struct mtd_partition __initdata cap9adk_nand_partitions[] = { + { + .name = "NAND partition", + .offset = 0, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(cap9adk_nand_partitions); + return cap9adk_nand_partitions; +} + +static struct atmel_nand_data __initdata cap9adk_nand_data = { + .ale = 21, + .cle = 22, +// .det_pin = ... not connected +// .rdy_pin = ... not connected + .enable_pin = AT91_PIN_PD15, + .partition_info = nand_partitions, +}; + +static struct sam9_smc_config __initdata cap9adk_nand_smc_config = { + .ncs_read_setup = 1, + .nrd_setup = 2, + .ncs_write_setup = 1, + .nwe_setup = 2, + + .ncs_read_pulse = 6, + .nrd_pulse = 4, + .ncs_write_pulse = 6, + .nwe_pulse = 4, + + .read_cycle = 8, + .write_cycle = 8, + + .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE, + .tdf_cycles = 1, +}; + +static void __init cap9adk_add_device_nand(void) +{ + unsigned long csa; + + csa = at91_sys_read(AT91_MATRIX_EBICSA); + at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_VDDIOMSEL_3_3V); + + cap9adk_nand_data.bus_width_16 = board_have_nand_16bit(); + /* setup bus-width (8 or 16) */ + if (cap9adk_nand_data.bus_width_16) + cap9adk_nand_smc_config.mode |= AT91_SMC_DBW_16; + else + cap9adk_nand_smc_config.mode |= AT91_SMC_DBW_8; + + /* configure chip-select 3 (NAND) */ + sam9_smc_configure(3, &cap9adk_nand_smc_config); + + at91_add_device_nand(&cap9adk_nand_data); +} + + +/* + * NOR flash + */ +static struct mtd_partition cap9adk_nor_partitions[] = { + { + .name = "NOR partition", + .offset = 0, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct physmap_flash_data cap9adk_nor_data = { + .width = 2, + .parts = cap9adk_nor_partitions, + .nr_parts = ARRAY_SIZE(cap9adk_nor_partitions), +}; + +#define NOR_BASE AT91_CHIPSELECT_0 +#define NOR_SIZE SZ_8M + +static struct resource nor_flash_resources[] = { + { + .start = NOR_BASE, + .end = NOR_BASE + NOR_SIZE - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device cap9adk_nor_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &cap9adk_nor_data, + }, + .resource = nor_flash_resources, + .num_resources = ARRAY_SIZE(nor_flash_resources), +}; + +static struct sam9_smc_config __initdata cap9adk_nor_smc_config = { + .ncs_read_setup = 2, + .nrd_setup = 4, + .ncs_write_setup = 2, + .nwe_setup = 4, + + .ncs_read_pulse = 10, + .nrd_pulse = 8, + .ncs_write_pulse = 10, + .nwe_pulse = 8, + + .read_cycle = 16, + .write_cycle = 16, + + .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_WRITE | AT91_SMC_DBW_16, + .tdf_cycles = 1, +}; + +static __init void cap9adk_add_device_nor(void) +{ + unsigned long csa; + + csa = at91_sys_read(AT91_MATRIX_EBICSA); + at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_VDDIOMSEL_3_3V); + + /* configure chip-select 0 (NOR) */ + sam9_smc_configure(0, &cap9adk_nor_smc_config); + + platform_device_register(&cap9adk_nor_flash); +} + + +/* + * LCD Controller + */ +#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) +static struct fb_videomode at91_tft_vga_modes[] = { + { + .name = "TX09D50VM1CCA @ 60", + .refresh = 60, + .xres = 240, .yres = 320, + .pixclock = KHZ2PICOS(4965), + + .left_margin = 1, .right_margin = 33, + .upper_margin = 1, .lower_margin = 0, + .hsync_len = 5, .vsync_len = 1, + + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = FB_VMODE_NONINTERLACED, + }, +}; + +static struct fb_monspecs at91fb_default_monspecs = { + .manufacturer = "HIT", + .monitor = "TX09D70VM1CCA", + + .modedb = at91_tft_vga_modes, + .modedb_len = ARRAY_SIZE(at91_tft_vga_modes), + .hfmin = 15000, + .hfmax = 64000, + .vfmin = 50, + .vfmax = 150, +}; + +#define AT91CAP9_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \ + | ATMEL_LCDC_DISTYPE_TFT \ + | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE) + +static void at91_lcdc_power_control(int on) +{ + if (on) + at91_set_gpio_value(AT91_PIN_PC0, 0); /* power up */ + else + at91_set_gpio_value(AT91_PIN_PC0, 1); /* power down */ +} + +/* Driver datas */ +static struct atmel_lcdfb_info __initdata cap9adk_lcdc_data = { + .default_bpp = 16, + .default_dmacon = ATMEL_LCDC_DMAEN, + .default_lcdcon2 = AT91CAP9_DEFAULT_LCDCON2, + .default_monspecs = &at91fb_default_monspecs, + .atmel_lcdfb_power_control = at91_lcdc_power_control, + .guard_time = 1, +}; + +#else +static struct atmel_lcdfb_info __initdata cap9adk_lcdc_data; +#endif + + +/* + * AC97 + */ +static struct ac97c_platform_data cap9adk_ac97_data = { +// .reset_pin = ... not connected +}; + + +static void __init cap9adk_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* USB Host */ + at91_add_device_usbh(&cap9adk_usbh_data); + /* USB HS */ + at91_add_device_usba(&cap9adk_usba_udc_data); + /* SPI */ + at91_add_device_spi(cap9adk_spi_devices, ARRAY_SIZE(cap9adk_spi_devices)); + /* Touchscreen */ + cap9adk_add_device_ts(); + /* MMC */ + at91_add_device_mmc(1, &cap9adk_mmc_data); + /* Ethernet */ + at91_add_device_eth(&cap9adk_macb_data); + /* NAND */ + cap9adk_add_device_nand(); + /* NOR Flash */ + cap9adk_add_device_nor(); + /* I2C */ + at91_add_device_i2c(NULL, 0); + /* LCD Controller */ + at91_add_device_lcdc(&cap9adk_lcdc_data); + /* AC97 */ + at91_add_device_ac97(&cap9adk_ac97_data); +} + +MACHINE_START(AT91CAP9ADK, "Atmel AT91CAP9A-DK") + /* Maintainer: Stelian Pop <stelian.pop@leadtechdesign.com> */ + .timer = &at91sam926x_timer, + .map_io = at91cap9_map_io, + .init_early = cap9adk_init_early, + .init_irq = cap9adk_init_irq, + .init_machine = cap9adk_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-carmeva.c b/arch/arm/mach-at91/board-carmeva.c new file mode 100644 index 00000000..f36b1868 --- /dev/null +++ b/arch/arm/mach-at91/board-carmeva.c @@ -0,0 +1,170 @@ +/* + * linux/arch/arm/mach-at91/board-carmeva.c + * + * Copyright (c) 2005 Peer Georgi + * Conitec Datasystems + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/platform_device.h> + +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <mach/hardware.h> +#include <mach/board.h> +#include <mach/gpio.h> + +#include "generic.h" + + +static void __init carmeva_init_early(void) +{ + /* Initialize processor: 20.000 MHz crystal */ + at91rm9200_initialize(20000000); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD + | ATMEL_UART_RI); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init carmeva_init_irq(void) +{ + at91rm9200_init_interrupts(NULL); +} + +static struct at91_eth_data __initdata carmeva_eth_data = { + .phy_irq_pin = AT91_PIN_PC4, + .is_rmii = 1, +}; + +static struct at91_usbh_data __initdata carmeva_usbh_data = { + .ports = 2, +}; + +static struct at91_udc_data __initdata carmeva_udc_data = { + .vbus_pin = AT91_PIN_PD12, + .pullup_pin = AT91_PIN_PD9, +}; + +/* FIXME: user dependent */ +// static struct at91_cf_data __initdata carmeva_cf_data = { +// .det_pin = AT91_PIN_PB0, +// .rst_pin = AT91_PIN_PC5, + // .irq_pin = ... not connected + // .vcc_pin = ... always powered +// }; + +static struct at91_mmc_data __initdata carmeva_mmc_data = { + .slot_b = 0, + .wire4 = 1, + .det_pin = AT91_PIN_PB10, + .wp_pin = AT91_PIN_PC14, +}; + +static struct spi_board_info carmeva_spi_devices[] = { + { /* DataFlash chip */ + .modalias = "mtd_dataflash", + .chip_select = 0, + .max_speed_hz = 10 * 1000 * 1000, + }, + { /* User accessible spi - cs1 (250KHz) */ + .modalias = "spi-cs1", + .chip_select = 1, + .max_speed_hz = 250 * 1000, + }, + { /* User accessible spi - cs2 (1MHz) */ + .modalias = "spi-cs2", + .chip_select = 2, + .max_speed_hz = 1 * 1000 * 1000, + }, + { /* User accessible spi - cs3 (10MHz) */ + .modalias = "spi-cs3", + .chip_select = 3, + .max_speed_hz = 10 * 1000 * 1000, + }, +}; + +static struct gpio_led carmeva_leds[] = { + { /* "user led 1", LED9 */ + .name = "led9", + .gpio = AT91_PIN_PA21, + .active_low = 1, + .default_trigger = "heartbeat", + }, + { /* "user led 2", LED10 */ + .name = "led10", + .gpio = AT91_PIN_PA25, + .active_low = 1, + }, + { /* "user led 3", LED11 */ + .name = "led11", + .gpio = AT91_PIN_PA26, + .active_low = 1, + }, + { /* "user led 4", LED12 */ + .name = "led12", + .gpio = AT91_PIN_PA18, + .active_low = 1, + } +}; + +static void __init carmeva_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* Ethernet */ + at91_add_device_eth(&carmeva_eth_data); + /* USB Host */ + at91_add_device_usbh(&carmeva_usbh_data); + /* USB Device */ + at91_add_device_udc(&carmeva_udc_data); + /* I2C */ + at91_add_device_i2c(NULL, 0); + /* SPI */ + at91_add_device_spi(carmeva_spi_devices, ARRAY_SIZE(carmeva_spi_devices)); + /* Compact Flash */ +// at91_add_device_cf(&carmeva_cf_data); + /* MMC */ + at91_add_device_mmc(0, &carmeva_mmc_data); + /* LEDs */ + at91_gpio_leds(carmeva_leds, ARRAY_SIZE(carmeva_leds)); +} + +MACHINE_START(CARMEVA, "Carmeva") + /* Maintainer: Conitec Datasystems */ + .timer = &at91rm9200_timer, + .map_io = at91rm9200_map_io, + .init_early = carmeva_init_early, + .init_irq = carmeva_init_irq, + .init_machine = carmeva_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-cpu9krea.c b/arch/arm/mach-at91/board-cpu9krea.c new file mode 100644 index 00000000..98051108 --- /dev/null +++ b/arch/arm/mach-at91/board-cpu9krea.c @@ -0,0 +1,383 @@ +/* + * linux/arch/arm/mach-at91/board-cpu9krea.c + * + * Copyright (C) 2005 SAN People + * Copyright (C) 2006 Atmel + * Copyright (C) 2009 Eric Benard - eric@eukrea.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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/clk.h> +#include <linux/gpio_keys.h> +#include <linux/input.h> +#include <linux/mtd/physmap.h> + +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <mach/hardware.h> +#include <mach/board.h> +#include <mach/gpio.h> +#include <mach/at91sam9_smc.h> +#include <mach/at91sam9260_matrix.h> + +#include "sam9_smc.h" +#include "generic.h" + +static void __init cpu9krea_init_early(void) +{ + /* Initialize processor: 18.432 MHz crystal */ + at91sam9260_initialize(18432000); + + /* DGBU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | + ATMEL_UART_RTS | ATMEL_UART_DTR | ATMEL_UART_DSR | + ATMEL_UART_DCD | ATMEL_UART_RI); + + /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */ + at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | + ATMEL_UART_RTS); + + /* USART2 on ttyS3. (Rx, Tx, RTS, CTS) */ + at91_register_uart(AT91SAM9260_ID_US2, 3, ATMEL_UART_CTS | + ATMEL_UART_RTS); + + /* USART3 on ttyS4. (Rx, Tx) */ + at91_register_uart(AT91SAM9260_ID_US3, 4, 0); + + /* USART4 on ttyS5. (Rx, Tx) */ + at91_register_uart(AT91SAM9260_ID_US4, 5, 0); + + /* USART5 on ttyS6. (Rx, Tx) */ + at91_register_uart(AT91SAM9260_ID_US5, 6, 0); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init cpu9krea_init_irq(void) +{ + at91sam9260_init_interrupts(NULL); +} + +/* + * USB Host port + */ +static struct at91_usbh_data __initdata cpu9krea_usbh_data = { + .ports = 2, +}; + +/* + * USB Device port + */ +static struct at91_udc_data __initdata cpu9krea_udc_data = { + .vbus_pin = AT91_PIN_PC8, + .pullup_pin = 0, /* pull-up driven by UDC */ +}; + +/* + * MACB Ethernet device + */ +static struct at91_eth_data __initdata cpu9krea_macb_data = { + .is_rmii = 1, +}; + +/* + * NAND flash + */ +static struct atmel_nand_data __initdata cpu9krea_nand_data = { + .ale = 21, + .cle = 22, + .rdy_pin = AT91_PIN_PC13, + .enable_pin = AT91_PIN_PC14, + .bus_width_16 = 0, +}; + +#ifdef CONFIG_MACH_CPU9260 +static struct sam9_smc_config __initdata cpu9krea_nand_smc_config = { + .ncs_read_setup = 0, + .nrd_setup = 1, + .ncs_write_setup = 0, + .nwe_setup = 1, + + .ncs_read_pulse = 3, + .nrd_pulse = 3, + .ncs_write_pulse = 3, + .nwe_pulse = 3, + + .read_cycle = 5, + .write_cycle = 5, + + .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE + | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8, + .tdf_cycles = 2, +}; +#else +static struct sam9_smc_config __initdata cpu9krea_nand_smc_config = { + .ncs_read_setup = 0, + .nrd_setup = 2, + .ncs_write_setup = 0, + .nwe_setup = 2, + + .ncs_read_pulse = 4, + .nrd_pulse = 4, + .ncs_write_pulse = 4, + .nwe_pulse = 4, + + .read_cycle = 7, + .write_cycle = 7, + + .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE + | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8, + .tdf_cycles = 3, +}; +#endif + +static void __init cpu9krea_add_device_nand(void) +{ + sam9_smc_configure(3, &cpu9krea_nand_smc_config); + at91_add_device_nand(&cpu9krea_nand_data); +} + +/* + * NOR flash + */ +static struct physmap_flash_data cpuat9260_nor_data = { + .width = 2, +}; + +#define NOR_BASE AT91_CHIPSELECT_0 +#define NOR_SIZE SZ_64M + +static struct resource nor_flash_resources[] = { + { + .start = NOR_BASE, + .end = NOR_BASE + NOR_SIZE - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device cpu9krea_nor_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &cpuat9260_nor_data, + }, + .resource = nor_flash_resources, + .num_resources = ARRAY_SIZE(nor_flash_resources), +}; + +#ifdef CONFIG_MACH_CPU9260 +static struct sam9_smc_config __initdata cpu9krea_nor_smc_config = { + .ncs_read_setup = 0, + .nrd_setup = 1, + .ncs_write_setup = 0, + .nwe_setup = 1, + + .ncs_read_pulse = 10, + .nrd_pulse = 10, + .ncs_write_pulse = 6, + .nwe_pulse = 6, + + .read_cycle = 12, + .write_cycle = 8, + + .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE + | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_WRITE + | AT91_SMC_DBW_16, + .tdf_cycles = 2, +}; +#else +static struct sam9_smc_config __initdata cpu9krea_nor_smc_config = { + .ncs_read_setup = 0, + .nrd_setup = 1, + .ncs_write_setup = 0, + .nwe_setup = 1, + + .ncs_read_pulse = 13, + .nrd_pulse = 13, + .ncs_write_pulse = 8, + .nwe_pulse = 8, + + .read_cycle = 15, + .write_cycle = 10, + + .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE + | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_WRITE + | AT91_SMC_DBW_16, + .tdf_cycles = 2, +}; +#endif + +static __init void cpu9krea_add_device_nor(void) +{ + unsigned long csa; + + csa = at91_sys_read(AT91_MATRIX_EBICSA); + at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_VDDIOMSEL_3_3V); + + /* configure chip-select 0 (NOR) */ + sam9_smc_configure(0, &cpu9krea_nor_smc_config); + + platform_device_register(&cpu9krea_nor_flash); +} + +/* + * LEDs + */ +static struct gpio_led cpu9krea_leds[] = { + { /* LED1 */ + .name = "LED1", + .gpio = AT91_PIN_PC11, + .active_low = 1, + .default_trigger = "timer", + }, + { /* LED2 */ + .name = "LED2", + .gpio = AT91_PIN_PC12, + .active_low = 1, + .default_trigger = "heartbeat", + }, + { /* LED3 */ + .name = "LED3", + .gpio = AT91_PIN_PC7, + .active_low = 1, + .default_trigger = "none", + }, + { /* LED4 */ + .name = "LED4", + .gpio = AT91_PIN_PC9, + .active_low = 1, + .default_trigger = "none", + } +}; + +static struct i2c_board_info __initdata cpu9krea_i2c_devices[] = { + { + I2C_BOARD_INFO("rtc-ds1307", 0x68), + .type = "ds1339", + }, +}; + +/* + * GPIO Buttons + */ +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +static struct gpio_keys_button cpu9krea_buttons[] = { + { + .gpio = AT91_PIN_PC3, + .code = BTN_0, + .desc = "BP1", + .active_low = 1, + .wakeup = 1, + }, + { + .gpio = AT91_PIN_PB20, + .code = BTN_1, + .desc = "BP2", + .active_low = 1, + .wakeup = 1, + } +}; + +static struct gpio_keys_platform_data cpu9krea_button_data = { + .buttons = cpu9krea_buttons, + .nbuttons = ARRAY_SIZE(cpu9krea_buttons), +}; + +static struct platform_device cpu9krea_button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &cpu9krea_button_data, + } +}; + +static void __init cpu9krea_add_device_buttons(void) +{ + at91_set_gpio_input(AT91_PIN_PC3, 1); /* BP1 */ + at91_set_deglitch(AT91_PIN_PC3, 1); + at91_set_gpio_input(AT91_PIN_PB20, 1); /* BP2 */ + at91_set_deglitch(AT91_PIN_PB20, 1); + + platform_device_register(&cpu9krea_button_device); +} +#else +static void __init cpu9krea_add_device_buttons(void) +{ +} +#endif + +/* + * MCI (SD/MMC) + */ +static struct at91_mmc_data __initdata cpu9krea_mmc_data = { + .slot_b = 0, + .wire4 = 1, + .det_pin = AT91_PIN_PA29, +}; + +static void __init cpu9krea_board_init(void) +{ + /* NOR */ + cpu9krea_add_device_nor(); + /* Serial */ + at91_add_device_serial(); + /* USB Host */ + at91_add_device_usbh(&cpu9krea_usbh_data); + /* USB Device */ + at91_add_device_udc(&cpu9krea_udc_data); + /* NAND */ + cpu9krea_add_device_nand(); + /* Ethernet */ + at91_add_device_eth(&cpu9krea_macb_data); + /* MMC */ + at91_add_device_mmc(0, &cpu9krea_mmc_data); + /* I2C */ + at91_add_device_i2c(cpu9krea_i2c_devices, + ARRAY_SIZE(cpu9krea_i2c_devices)); + /* LEDs */ + at91_gpio_leds(cpu9krea_leds, ARRAY_SIZE(cpu9krea_leds)); + /* Push Buttons */ + cpu9krea_add_device_buttons(); +} + +#ifdef CONFIG_MACH_CPU9260 +MACHINE_START(CPUAT9260, "Eukrea CPU9260") +#else +MACHINE_START(CPUAT9G20, "Eukrea CPU9G20") +#endif + /* Maintainer: Eric Benard - EUKREA Electromatique */ + .timer = &at91sam926x_timer, + .map_io = at91sam9260_map_io, + .init_early = cpu9krea_init_early, + .init_irq = cpu9krea_init_irq, + .init_machine = cpu9krea_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-cpuat91.c b/arch/arm/mach-at91/board-cpuat91.c new file mode 100644 index 00000000..6daabe39 --- /dev/null +++ b/arch/arm/mach-at91/board-cpuat91.c @@ -0,0 +1,187 @@ +/* + * linux/arch/arm/mach-at91/board-cpuat91.c + * + * Copyright (C) 2009 Eric Benard - eric@eukrea.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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/mtd/physmap.h> +#include <linux/mtd/plat-ram.h> + +#include <mach/hardware.h> +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <mach/board.h> +#include <mach/gpio.h> +#include <mach/at91rm9200_mc.h> +#include <mach/cpu.h> + +#include "generic.h" + +static struct gpio_led cpuat91_leds[] = { + { + .name = "led1", + .default_trigger = "heartbeat", + .active_low = 1, + .gpio = AT91_PIN_PC0, + }, +}; + +static void __init cpuat91_init_early(void) +{ + /* Set cpu type: PQFP */ + at91rm9200_set_type(ARCH_REVISON_9200_PQFP); + + /* Initialize processor: 18.432 MHz crystal */ + at91rm9200_initialize(18432000); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1. (Rx, Tx, CTS, RTS) */ + at91_register_uart(AT91RM9200_ID_US0, 1, ATMEL_UART_CTS | + ATMEL_UART_RTS); + + /* USART1 on ttyS2. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91RM9200_ID_US1, 2, ATMEL_UART_CTS | + ATMEL_UART_RTS | ATMEL_UART_DTR | ATMEL_UART_DSR | + ATMEL_UART_DCD | ATMEL_UART_RI); + + /* USART2 on ttyS3 (Rx, Tx) */ + at91_register_uart(AT91RM9200_ID_US2, 3, 0); + + /* USART3 on ttyS4 (Rx, Tx, CTS, RTS) */ + at91_register_uart(AT91RM9200_ID_US3, 4, ATMEL_UART_CTS | + ATMEL_UART_RTS); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init cpuat91_init_irq(void) +{ + at91rm9200_init_interrupts(NULL); +} + +static struct at91_eth_data __initdata cpuat91_eth_data = { + .is_rmii = 1, +}; + +static struct at91_usbh_data __initdata cpuat91_usbh_data = { + .ports = 1, +}; + +static struct at91_udc_data __initdata cpuat91_udc_data = { + .vbus_pin = AT91_PIN_PC15, + .pullup_pin = AT91_PIN_PC14, +}; + +static struct at91_mmc_data __initdata cpuat91_mmc_data = { + .det_pin = AT91_PIN_PC2, + .wire4 = 1, +}; + +static struct physmap_flash_data cpuat91_flash_data = { + .width = 2, +}; + +static struct resource cpuat91_flash_resource = { + .start = AT91_CHIPSELECT_0, + .end = AT91_CHIPSELECT_0 + SZ_16M - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device cpuat91_norflash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &cpuat91_flash_data, + }, + .resource = &cpuat91_flash_resource, + .num_resources = 1, +}; + +#ifdef CONFIG_MTD_PLATRAM +struct platdata_mtd_ram at91_sram_pdata = { + .mapname = "SRAM", + .bankwidth = 2, +}; + +static struct resource at91_sram_resource[] = { + [0] = { + .start = AT91RM9200_SRAM_BASE, + .end = AT91RM9200_SRAM_BASE + AT91RM9200_SRAM_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device at91_sram = { + .name = "mtd-ram", + .id = 0, + .resource = at91_sram_resource, + .num_resources = ARRAY_SIZE(at91_sram_resource), + .dev = { + .platform_data = &at91_sram_pdata, + }, +}; +#endif /* MTD_PLATRAM */ + +static struct platform_device *platform_devices[] __initdata = { + &cpuat91_norflash, +#ifdef CONFIG_MTD_PLATRAM + &at91_sram, +#endif /* CONFIG_MTD_PLATRAM */ +}; + +static void __init cpuat91_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* LEDs. */ + at91_gpio_leds(cpuat91_leds, ARRAY_SIZE(cpuat91_leds)); + /* Ethernet */ + at91_add_device_eth(&cpuat91_eth_data); + /* USB Host */ + at91_add_device_usbh(&cpuat91_usbh_data); + /* USB Device */ + at91_add_device_udc(&cpuat91_udc_data); + /* MMC */ + at91_add_device_mmc(0, &cpuat91_mmc_data); + /* I2C */ + at91_add_device_i2c(NULL, 0); + /* Platform devices */ + platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); +} + +MACHINE_START(CPUAT91, "Eukrea") + /* Maintainer: Eric Benard - EUKREA Electromatique */ + .timer = &at91rm9200_timer, + .map_io = at91rm9200_map_io, + .init_early = cpuat91_init_early, + .init_irq = cpuat91_init_irq, + .init_machine = cpuat91_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-csb337.c b/arch/arm/mach-at91/board-csb337.c new file mode 100644 index 00000000..d98bcec1 --- /dev/null +++ b/arch/arm/mach-at91/board-csb337.c @@ -0,0 +1,265 @@ +/* + * linux/arch/arm/mach-at91/board-csb337.c + * + * Copyright (C) 2005 SAN People + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> +#include <linux/mtd/physmap.h> +#include <linux/input.h> +#include <linux/gpio_keys.h> + +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <mach/hardware.h> +#include <mach/board.h> +#include <mach/gpio.h> + +#include "generic.h" + + +static void __init csb337_init_early(void) +{ + /* Initialize processor: 3.6864 MHz crystal */ + at91rm9200_initialize(3686400); + + /* Setup the LEDs */ + at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1); + + /* DBGU on ttyS0 */ + at91_register_uart(0, 0, 0); + + /* make console=ttyS0 the default */ + at91_set_serial_console(0); +} + +static void __init csb337_init_irq(void) +{ + at91rm9200_init_interrupts(NULL); +} + +static struct at91_eth_data __initdata csb337_eth_data = { + .phy_irq_pin = AT91_PIN_PC2, + .is_rmii = 0, +}; + +static struct at91_usbh_data __initdata csb337_usbh_data = { + .ports = 2, +}; + +static struct at91_udc_data __initdata csb337_udc_data = { + // this has no VBUS sensing pin + .pullup_pin = AT91_PIN_PA24, +}; + +static struct i2c_board_info __initdata csb337_i2c_devices[] = { + { + I2C_BOARD_INFO("ds1307", 0x68), + }, +}; + +static struct at91_cf_data __initdata csb337_cf_data = { + /* + * connector P4 on the CSB 337 mates to + * connector P8 on the CSB 300CF + */ + + /* CSB337 specific */ + .det_pin = AT91_PIN_PC3, + + /* CSB300CF specific */ + .irq_pin = AT91_PIN_PA19, + .vcc_pin = AT91_PIN_PD0, + .rst_pin = AT91_PIN_PD2, +}; + +static struct at91_mmc_data __initdata csb337_mmc_data = { + .det_pin = AT91_PIN_PD5, + .slot_b = 0, + .wire4 = 1, + .wp_pin = AT91_PIN_PD6, +}; + +static struct spi_board_info csb337_spi_devices[] = { + { /* CAN controller */ + .modalias = "sak82c900", + .chip_select = 0, + .max_speed_hz = 6 * 1000 * 1000, + }, +}; + +#define CSB_FLASH_BASE AT91_CHIPSELECT_0 +#define CSB_FLASH_SIZE SZ_8M + +static struct mtd_partition csb_flash_partitions[] = { + { + .name = "uMON flash", + .offset = 0, + .size = MTDPART_SIZ_FULL, + .mask_flags = MTD_WRITEABLE, /* read only */ + } +}; + +static struct physmap_flash_data csb_flash_data = { + .width = 2, + .parts = csb_flash_partitions, + .nr_parts = ARRAY_SIZE(csb_flash_partitions), +}; + +static struct resource csb_flash_resources[] = { + { + .start = CSB_FLASH_BASE, + .end = CSB_FLASH_BASE + CSB_FLASH_SIZE - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device csb_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &csb_flash_data, + }, + .resource = csb_flash_resources, + .num_resources = ARRAY_SIZE(csb_flash_resources), +}; + +/* + * GPIO Buttons (on CSB300) + */ +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +static struct gpio_keys_button csb300_buttons[] = { + { + .gpio = AT91_PIN_PB29, + .code = BTN_0, + .desc = "sw0", + .active_low = 1, + .wakeup = 1, + }, + { + .gpio = AT91_PIN_PB28, + .code = BTN_1, + .desc = "sw1", + .active_low = 1, + .wakeup = 1, + }, + { + .gpio = AT91_PIN_PA21, + .code = BTN_2, + .desc = "sw2", + .active_low = 1, + .wakeup = 1, + } +}; + +static struct gpio_keys_platform_data csb300_button_data = { + .buttons = csb300_buttons, + .nbuttons = ARRAY_SIZE(csb300_buttons), +}; + +static struct platform_device csb300_button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &csb300_button_data, + } +}; + +static void __init csb300_add_device_buttons(void) +{ + at91_set_gpio_input(AT91_PIN_PB29, 1); /* sw0 */ + at91_set_deglitch(AT91_PIN_PB29, 1); + at91_set_gpio_input(AT91_PIN_PB28, 1); /* sw1 */ + at91_set_deglitch(AT91_PIN_PB28, 1); + at91_set_gpio_input(AT91_PIN_PA21, 1); /* sw2 */ + at91_set_deglitch(AT91_PIN_PA21, 1); + + platform_device_register(&csb300_button_device); +} +#else +static void __init csb300_add_device_buttons(void) {} +#endif + +static struct gpio_led csb_leds[] = { + { /* "led0", yellow */ + .name = "led0", + .gpio = AT91_PIN_PB2, + .active_low = 1, + .default_trigger = "heartbeat", + }, + { /* "led1", green */ + .name = "led1", + .gpio = AT91_PIN_PB1, + .active_low = 1, + .default_trigger = "mmc0", + }, + { /* "led2", yellow */ + .name = "led2", + .gpio = AT91_PIN_PB0, + .active_low = 1, + .default_trigger = "ide-disk", + } +}; + + +static void __init csb337_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* Ethernet */ + at91_add_device_eth(&csb337_eth_data); + /* USB Host */ + at91_add_device_usbh(&csb337_usbh_data); + /* USB Device */ + at91_add_device_udc(&csb337_udc_data); + /* I2C */ + at91_add_device_i2c(csb337_i2c_devices, ARRAY_SIZE(csb337_i2c_devices)); + /* Compact Flash */ + at91_set_gpio_input(AT91_PIN_PB22, 1); /* IOIS16 */ + at91_add_device_cf(&csb337_cf_data); + /* SPI */ + at91_add_device_spi(csb337_spi_devices, ARRAY_SIZE(csb337_spi_devices)); + /* MMC */ + at91_add_device_mmc(0, &csb337_mmc_data); + /* NOR flash */ + platform_device_register(&csb_flash); + /* LEDs */ + at91_gpio_leds(csb_leds, ARRAY_SIZE(csb_leds)); + /* Switches on CSB300 */ + csb300_add_device_buttons(); +} + +MACHINE_START(CSB337, "Cogent CSB337") + /* Maintainer: Bill Gatliff */ + .timer = &at91rm9200_timer, + .map_io = at91rm9200_map_io, + .init_early = csb337_init_early, + .init_irq = csb337_init_irq, + .init_machine = csb337_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-csb637.c b/arch/arm/mach-at91/board-csb637.c new file mode 100644 index 00000000..019aab4e --- /dev/null +++ b/arch/arm/mach-at91/board-csb637.c @@ -0,0 +1,146 @@ +/* + * linux/arch/arm/mach-at91/board-csb637.c + * + * Copyright (C) 2005 SAN People + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/mtd/physmap.h> + +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <mach/hardware.h> +#include <mach/board.h> +#include <mach/gpio.h> + +#include "generic.h" + + +static void __init csb637_init_early(void) +{ + /* Initialize processor: 3.6864 MHz crystal */ + at91rm9200_initialize(3686400); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* make console=ttyS0 (ie, DBGU) the default */ + at91_set_serial_console(0); +} + +static void __init csb637_init_irq(void) +{ + at91rm9200_init_interrupts(NULL); +} + +static struct at91_eth_data __initdata csb637_eth_data = { + .phy_irq_pin = AT91_PIN_PC0, + .is_rmii = 0, +}; + +static struct at91_usbh_data __initdata csb637_usbh_data = { + .ports = 2, +}; + +static struct at91_udc_data __initdata csb637_udc_data = { + .vbus_pin = AT91_PIN_PB28, + .pullup_pin = AT91_PIN_PB1, +}; + +#define CSB_FLASH_BASE AT91_CHIPSELECT_0 +#define CSB_FLASH_SIZE SZ_16M + +static struct mtd_partition csb_flash_partitions[] = { + { + .name = "uMON flash", + .offset = 0, + .size = MTDPART_SIZ_FULL, + .mask_flags = MTD_WRITEABLE, /* read only */ + } +}; + +static struct physmap_flash_data csb_flash_data = { + .width = 2, + .parts = csb_flash_partitions, + .nr_parts = ARRAY_SIZE(csb_flash_partitions), +}; + +static struct resource csb_flash_resources[] = { + { + .start = CSB_FLASH_BASE, + .end = CSB_FLASH_BASE + CSB_FLASH_SIZE - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device csb_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &csb_flash_data, + }, + .resource = csb_flash_resources, + .num_resources = ARRAY_SIZE(csb_flash_resources), +}; + +static struct gpio_led csb_leds[] = { + { /* "d1", red */ + .name = "d1", + .gpio = AT91_PIN_PB2, + .active_low = 1, + .default_trigger = "heartbeat", + }, +}; + +static void __init csb637_board_init(void) +{ + /* LED(s) */ + at91_gpio_leds(csb_leds, ARRAY_SIZE(csb_leds)); + /* Serial */ + at91_add_device_serial(); + /* Ethernet */ + at91_add_device_eth(&csb637_eth_data); + /* USB Host */ + at91_add_device_usbh(&csb637_usbh_data); + /* USB Device */ + at91_add_device_udc(&csb637_udc_data); + /* I2C */ + at91_add_device_i2c(NULL, 0); + /* SPI */ + at91_add_device_spi(NULL, 0); + /* NOR flash */ + platform_device_register(&csb_flash); +} + +MACHINE_START(CSB637, "Cogent CSB637") + /* Maintainer: Bill Gatliff */ + .timer = &at91rm9200_timer, + .map_io = at91rm9200_map_io, + .init_early = csb637_init_early, + .init_irq = csb637_init_irq, + .init_machine = csb637_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-eb01.c b/arch/arm/mach-at91/board-eb01.c new file mode 100644 index 00000000..d2023f27 --- /dev/null +++ b/arch/arm/mach-at91/board-eb01.c @@ -0,0 +1,49 @@ +/* + * arch/arm/mach-at91/board-eb01.c + * + * (C) Copyright 2007, Greg Ungerer <gerg@snapgear.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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/irq.h> +#include <asm/mach-types.h> +#include <mach/hardware.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <mach/board.h> +#include "generic.h" + +static void __init at91eb01_init_irq(void) +{ + at91x40_init_interrupts(NULL); +} + +static void __init at91eb01_init_early(void) +{ + at91x40_initialize(40000000); +} + +MACHINE_START(AT91EB01, "Atmel AT91 EB01") + /* Maintainer: Greg Ungerer <gerg@snapgear.com> */ + .timer = &at91x40_timer, + .init_early = at91eb01_init_early, + .init_irq = at91eb01_init_irq, +MACHINE_END + diff --git a/arch/arm/mach-at91/board-eb9200.c b/arch/arm/mach-at91/board-eb9200.c new file mode 100644 index 00000000..e9484535 --- /dev/null +++ b/arch/arm/mach-at91/board-eb9200.c @@ -0,0 +1,128 @@ +/* + * linux/arch/arm/mach-at91/board-eb9200.c + * + * Copyright (C) 2005 SAN People, adapted for ATEB9200 from Embest + * by Andrew Patrikalakis + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/device.h> + +#include <mach/hardware.h> +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <mach/board.h> +#include <mach/gpio.h> + +#include "generic.h" + + +static void __init eb9200_init_early(void) +{ + /* Initialize processor: 18.432 MHz crystal */ + at91rm9200_initialize(18432000); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD + | ATMEL_UART_RI); + + /* USART2 on ttyS2. (Rx, Tx) - IRDA */ + at91_register_uart(AT91RM9200_ID_US2, 2, 0); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init eb9200_init_irq(void) +{ + at91rm9200_init_interrupts(NULL); +} + +static struct at91_eth_data __initdata eb9200_eth_data = { + .phy_irq_pin = AT91_PIN_PC4, + .is_rmii = 1, +}; + +static struct at91_usbh_data __initdata eb9200_usbh_data = { + .ports = 2, +}; + +static struct at91_udc_data __initdata eb9200_udc_data = { + .vbus_pin = AT91_PIN_PD4, + .pullup_pin = AT91_PIN_PD5, +}; + +static struct at91_cf_data __initdata eb9200_cf_data = { + .det_pin = AT91_PIN_PB0, + .rst_pin = AT91_PIN_PC5, + // .irq_pin = ... not connected + // .vcc_pin = ... always powered +}; + +static struct at91_mmc_data __initdata eb9200_mmc_data = { + .slot_b = 0, + .wire4 = 1, +}; + +static struct i2c_board_info __initdata eb9200_i2c_devices[] = { + { + I2C_BOARD_INFO("24c512", 0x50), + }, +}; + + +static void __init eb9200_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* Ethernet */ + at91_add_device_eth(&eb9200_eth_data); + /* USB Host */ + at91_add_device_usbh(&eb9200_usbh_data); + /* USB Device */ + at91_add_device_udc(&eb9200_udc_data); + /* I2C */ + at91_add_device_i2c(eb9200_i2c_devices, ARRAY_SIZE(eb9200_i2c_devices)); + /* Compact Flash */ + at91_add_device_cf(&eb9200_cf_data); + /* SPI */ + at91_add_device_spi(NULL, 0); + /* MMC */ + /* only supports 1 or 4 bit interface, not wired through to SPI */ + at91_add_device_mmc(0, &eb9200_mmc_data); +} + +MACHINE_START(ATEB9200, "Embest ATEB9200") + .timer = &at91rm9200_timer, + .map_io = at91rm9200_map_io, + .init_early = eb9200_init_early, + .init_irq = eb9200_init_irq, + .init_machine = eb9200_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-ecbat91.c b/arch/arm/mach-at91/board-ecbat91.c new file mode 100644 index 00000000..a6f57faa --- /dev/null +++ b/arch/arm/mach-at91/board-ecbat91.c @@ -0,0 +1,180 @@ +/* + * linux/arch/arm/mach-at91rm9200/board-ecbat91.c + * Copyright (C) 2007 emQbit.com. + * + * We started from board-dk.c, which is Copyright (C) 2005 SAN People. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> +#include <linux/spi/flash.h> + +#include <mach/hardware.h> +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <mach/board.h> +#include <mach/gpio.h> +#include <mach/cpu.h> + +#include "generic.h" + + +static void __init ecb_at91init_early(void) +{ + /* Set cpu type: PQFP */ + at91rm9200_set_type(ARCH_REVISON_9200_PQFP); + + /* Initialize processor: 18.432 MHz crystal */ + at91rm9200_initialize(18432000); + + /* Setup the LEDs */ + at91_init_leds(AT91_PIN_PC7, AT91_PIN_PC7); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1. (Rx & Tx only) */ + at91_register_uart(AT91RM9200_ID_US0, 1, 0); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init ecb_at91init_irq(void) +{ + at91rm9200_init_interrupts(NULL); +} + +static struct at91_eth_data __initdata ecb_at91eth_data = { + .phy_irq_pin = AT91_PIN_PC4, + .is_rmii = 0, +}; + +static struct at91_usbh_data __initdata ecb_at91usbh_data = { + .ports = 1, +}; + +static struct at91_mmc_data __initdata ecb_at91mmc_data = { + .slot_b = 0, + .wire4 = 1, +}; + + +#if defined(CONFIG_MTD_DATAFLASH) +static struct mtd_partition __initdata my_flash0_partitions[] = +{ + { /* 0x8400 */ + .name = "Darrell-loader", + .offset = 0, + .size = 12 * 1056, + }, + { + .name = "U-boot", + .offset = MTDPART_OFS_NXTBLK, + .size = 110 * 1056, + }, + { /* 1336 (167 blocks) pages * 1056 bytes = 0x158700 bytes */ + .name = "UBoot-env", + .offset = MTDPART_OFS_NXTBLK, + .size = 8 * 1056, + }, + { /* 1336 (167 blocks) pages * 1056 bytes = 0x158700 bytes */ + .name = "Kernel", + .offset = MTDPART_OFS_NXTBLK, + .size = 1534 * 1056, + }, + { /* 190200 - jffs2 root filesystem */ + .name = "Filesystem", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL, /* 26 sectors */ + } +}; + +static struct flash_platform_data __initdata my_flash0_platform = { + .name = "Removable flash card", + .parts = my_flash0_partitions, + .nr_parts = ARRAY_SIZE(my_flash0_partitions) +}; + +#endif + +static struct spi_board_info __initdata ecb_at91spi_devices[] = { + { /* DataFlash chip */ + .modalias = "mtd_dataflash", + .chip_select = 0, + .max_speed_hz = 10 * 1000 * 1000, + .bus_num = 0, +#if defined(CONFIG_MTD_DATAFLASH) + .platform_data = &my_flash0_platform, +#endif + }, + { /* User accessible spi - cs1 (250KHz) */ + .modalias = "spi-cs1", + .chip_select = 1, + .max_speed_hz = 250 * 1000, + }, + { /* User accessible spi - cs2 (1MHz) */ + .modalias = "spi-cs2", + .chip_select = 2, + .max_speed_hz = 1 * 1000 * 1000, + }, + { /* User accessible spi - cs3 (10MHz) */ + .modalias = "spi-cs3", + .chip_select = 3, + .max_speed_hz = 10 * 1000 * 1000, + }, +}; + +static void __init ecb_at91board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + + /* Ethernet */ + at91_add_device_eth(&ecb_at91eth_data); + + /* USB Host */ + at91_add_device_usbh(&ecb_at91usbh_data); + + /* I2C */ + at91_add_device_i2c(NULL, 0); + + /* MMC */ + at91_add_device_mmc(0, &ecb_at91mmc_data); + + /* SPI */ + at91_add_device_spi(ecb_at91spi_devices, ARRAY_SIZE(ecb_at91spi_devices)); +} + +MACHINE_START(ECBAT91, "emQbit's ECB_AT91") + /* Maintainer: emQbit.com */ + .timer = &at91rm9200_timer, + .map_io = at91rm9200_map_io, + .init_early = ecb_at91init_early, + .init_irq = ecb_at91init_irq, + .init_machine = ecb_at91board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-eco920.c b/arch/arm/mach-at91/board-eco920.c new file mode 100644 index 00000000..bfc0062d --- /dev/null +++ b/arch/arm/mach-at91/board-eco920.c @@ -0,0 +1,142 @@ +/* + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/mtd/physmap.h> +#include <linux/gpio.h> + +#include <asm/mach-types.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <mach/board.h> +#include <mach/at91rm9200_mc.h> +#include <mach/cpu.h> + +#include "generic.h" + +static void __init eco920_init_early(void) +{ + /* Set cpu type: PQFP */ + at91rm9200_set_type(ARCH_REVISON_9200_PQFP); + + at91rm9200_initialize(18432000); + + /* Setup the LEDs */ + at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1); + + /* DBGU on ttyS0. (Rx & Tx only */ + at91_register_uart(0, 0, 0); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init eco920_init_irq(void) +{ + at91rm9200_init_interrupts(NULL); +} + +static struct at91_eth_data __initdata eco920_eth_data = { + .phy_irq_pin = AT91_PIN_PC2, + .is_rmii = 1, +}; + +static struct at91_usbh_data __initdata eco920_usbh_data = { + .ports = 1, +}; + +static struct at91_udc_data __initdata eco920_udc_data = { + .vbus_pin = AT91_PIN_PB12, + .pullup_pin = AT91_PIN_PB13, +}; + +static struct at91_mmc_data __initdata eco920_mmc_data = { + .slot_b = 0, + .wire4 = 0, +}; + +static struct physmap_flash_data eco920_flash_data = { + .width = 2, +}; + +static struct resource eco920_flash_resource = { + .start = 0x11000000, + .end = 0x11ffffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device eco920_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &eco920_flash_data, + }, + .resource = &eco920_flash_resource, + .num_resources = 1, +}; + +static struct spi_board_info eco920_spi_devices[] = { + { /* CAN controller */ + .modalias = "tlv5638", + .chip_select = 3, + .max_speed_hz = 20 * 1000 * 1000, + .mode = SPI_CPHA, + }, +}; + +static void __init eco920_board_init(void) +{ + at91_add_device_serial(); + at91_add_device_eth(&eco920_eth_data); + at91_add_device_usbh(&eco920_usbh_data); + at91_add_device_udc(&eco920_udc_data); + + at91_add_device_mmc(0, &eco920_mmc_data); + platform_device_register(&eco920_flash); + + at91_sys_write(AT91_SMC_CSR(7), AT91_SMC_RWHOLD_(1) + | AT91_SMC_RWSETUP_(1) + | AT91_SMC_DBW_8 + | AT91_SMC_WSEN + | AT91_SMC_NWS_(15)); + + at91_set_A_periph(AT91_PIN_PC6, 1); + + at91_set_gpio_input(AT91_PIN_PA23, 0); + at91_set_deglitch(AT91_PIN_PA23, 1); + +/* Initialization of the Static Memory Controller for Chip Select 3 */ + at91_sys_write(AT91_SMC_CSR(3), + AT91_SMC_DBW_16 | /* 16 bit */ + AT91_SMC_WSEN | + AT91_SMC_NWS_(5) | /* wait states */ + AT91_SMC_TDF_(1) /* float time */ + ); + + at91_add_device_spi(eco920_spi_devices, ARRAY_SIZE(eco920_spi_devices)); +} + +MACHINE_START(ECO920, "eco920") + /* Maintainer: Sascha Hauer */ + .timer = &at91rm9200_timer, + .map_io = at91rm9200_map_io, + .init_early = eco920_init_early, + .init_irq = eco920_init_irq, + .init_machine = eco920_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-flexibity.c b/arch/arm/mach-at91/board-flexibity.c new file mode 100644 index 00000000..466c063b --- /dev/null +++ b/arch/arm/mach-at91/board-flexibity.c @@ -0,0 +1,162 @@ +/* + * linux/arch/arm/mach-at91/board-flexibity.c + * + * Copyright (C) 2010 Flexibity + * Copyright (C) 2005 SAN People + * Copyright (C) 2006 Atmel + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> +#include <linux/input.h> +#include <linux/gpio.h> + +#include <asm/mach-types.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <mach/hardware.h> +#include <mach/board.h> + +#include "generic.h" + +static void __init flexibity_init_early(void) +{ + /* Initialize processor: 18.432 MHz crystal */ + at91sam9260_initialize(18432000); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init flexibity_init_irq(void) +{ + at91sam9260_init_interrupts(NULL); +} + +/* USB Host port */ +static struct at91_usbh_data __initdata flexibity_usbh_data = { + .ports = 2, +}; + +/* USB Device port */ +static struct at91_udc_data __initdata flexibity_udc_data = { + .vbus_pin = AT91_PIN_PC5, + .pullup_pin = 0, /* pull-up driven by UDC */ +}; + +/* SPI devices */ +static struct spi_board_info flexibity_spi_devices[] = { + { /* DataFlash chip */ + .modalias = "mtd_dataflash", + .chip_select = 1, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +}; + +/* MCI (SD/MMC) */ +static struct at91_mmc_data __initdata flexibity_mmc_data = { + .slot_b = 0, + .wire4 = 1, + .det_pin = AT91_PIN_PC9, + .wp_pin = AT91_PIN_PC4, +}; + +/* LEDs */ +static struct gpio_led flexibity_leds[] = { + { + .name = "usb1:green", + .gpio = AT91_PIN_PA12, + .active_low = 1, + .default_trigger = "default-on", + }, + { + .name = "usb1:red", + .gpio = AT91_PIN_PA13, + .active_low = 1, + .default_trigger = "default-on", + }, + { + .name = "usb2:green", + .gpio = AT91_PIN_PB26, + .active_low = 1, + .default_trigger = "default-on", + }, + { + .name = "usb2:red", + .gpio = AT91_PIN_PB27, + .active_low = 1, + .default_trigger = "default-on", + }, + { + .name = "usb3:green", + .gpio = AT91_PIN_PC8, + .active_low = 1, + .default_trigger = "default-on", + }, + { + .name = "usb3:red", + .gpio = AT91_PIN_PC6, + .active_low = 1, + .default_trigger = "default-on", + }, + { + .name = "usb4:green", + .gpio = AT91_PIN_PB4, + .active_low = 1, + .default_trigger = "default-on", + }, + { + .name = "usb4:red", + .gpio = AT91_PIN_PB5, + .active_low = 1, + .default_trigger = "default-on", + } +}; + +static void __init flexibity_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* USB Host */ + at91_add_device_usbh(&flexibity_usbh_data); + /* USB Device */ + at91_add_device_udc(&flexibity_udc_data); + /* SPI */ + at91_add_device_spi(flexibity_spi_devices, + ARRAY_SIZE(flexibity_spi_devices)); + /* MMC */ + at91_add_device_mmc(0, &flexibity_mmc_data); + /* LEDs */ + at91_gpio_leds(flexibity_leds, ARRAY_SIZE(flexibity_leds)); +} + +MACHINE_START(FLEXIBITY, "Flexibity Connect") + /* Maintainer: Maxim Osipov */ + .timer = &at91sam926x_timer, + .map_io = at91sam9260_map_io, + .init_early = flexibity_init_early, + .init_irq = flexibity_init_irq, + .init_machine = flexibity_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-foxg20.c b/arch/arm/mach-at91/board-foxg20.c new file mode 100644 index 00000000..e2d1dc9e --- /dev/null +++ b/arch/arm/mach-at91/board-foxg20.c @@ -0,0 +1,274 @@ +/* + * Copyright (C) 2005 SAN People + * Copyright (C) 2008 Atmel + * Copyright (C) 2010 Lee McLoughlin - lee@lmmrtech.com + * Copyright (C) 2010 Sergio Tanzilli - tanzilli@acmesystems.it + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> +#include <linux/spi/at73c213.h> +#include <linux/gpio.h> +#include <linux/gpio_keys.h> +#include <linux/input.h> +#include <linux/clk.h> +#include <linux/w1-gpio.h> + +#include <mach/hardware.h> +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <mach/board.h> +#include <mach/at91sam9_smc.h> + +#include "sam9_smc.h" +#include "generic.h" + +/* + * The FOX Board G20 hardware comes as the "Netus G20" board with + * just the cpu, ram, dataflash and two header connectors. + * This is plugged into the FOX Board which provides the ethernet, + * usb, rtc, leds, switch, ... + * + * For more info visit: http://www.acmesystems.it/foxg20 + */ + + +static void __init foxg20_init_early(void) +{ + /* Initialize processor: 18.432 MHz crystal */ + at91sam9260_initialize(18432000); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91SAM9260_ID_US0, 1, + ATMEL_UART_CTS + | ATMEL_UART_RTS + | ATMEL_UART_DTR + | ATMEL_UART_DSR + | ATMEL_UART_DCD + | ATMEL_UART_RI); + + /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */ + at91_register_uart(AT91SAM9260_ID_US1, 2, + ATMEL_UART_CTS + | ATMEL_UART_RTS); + + /* USART2 on ttyS3. (Rx & Tx only) */ + at91_register_uart(AT91SAM9260_ID_US2, 3, 0); + + /* USART3 on ttyS4. (Rx, Tx, RTS, CTS) */ + at91_register_uart(AT91SAM9260_ID_US3, 4, + ATMEL_UART_CTS + | ATMEL_UART_RTS); + + /* USART4 on ttyS5. (Rx & Tx only) */ + at91_register_uart(AT91SAM9260_ID_US4, 5, 0); + + /* USART5 on ttyS6. (Rx & Tx only) */ + at91_register_uart(AT91SAM9260_ID_US5, 6, 0); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); + + /* Set the internal pull-up resistor on DRXD */ + at91_set_A_periph(AT91_PIN_PB14, 1); + +} + +static void __init foxg20_init_irq(void) +{ + at91sam9260_init_interrupts(NULL); +} + + +/* + * USB Host port + */ +static struct at91_usbh_data __initdata foxg20_usbh_data = { + .ports = 2, +}; + +/* + * USB Device port + */ +static struct at91_udc_data __initdata foxg20_udc_data = { + .vbus_pin = AT91_PIN_PC6, + .pullup_pin = 0, /* pull-up driven by UDC */ +}; + + +/* + * SPI devices. + */ +static struct spi_board_info foxg20_spi_devices[] = { +#if !defined(CONFIG_MMC_AT91) + { + .modalias = "mtd_dataflash", + .chip_select = 1, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +#endif +}; + + +/* + * MACB Ethernet device + */ +static struct at91_eth_data __initdata foxg20_macb_data = { + .phy_irq_pin = AT91_PIN_PA7, + .is_rmii = 1, +}; + +/* + * MCI (SD/MMC) + * det_pin, wp_pin and vcc_pin are not connected + */ +static struct at91_mmc_data __initdata foxg20_mmc_data = { + .slot_b = 1, + .wire4 = 1, +}; + + +/* + * LEDs + */ +static struct gpio_led foxg20_leds[] = { + { /* user led, red */ + .name = "user_led", + .gpio = AT91_PIN_PC7, + .active_low = 0, + .default_trigger = "heartbeat", + }, +}; + + +/* + * GPIO Buttons + */ +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +static struct gpio_keys_button foxg20_buttons[] = { + { + .gpio = AT91_PIN_PC4, + .code = BTN_1, + .desc = "Button 1", + .active_low = 1, + .wakeup = 1, + }, +}; + +static struct gpio_keys_platform_data foxg20_button_data = { + .buttons = foxg20_buttons, + .nbuttons = ARRAY_SIZE(foxg20_buttons), +}; + +static struct platform_device foxg20_button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &foxg20_button_data, + } +}; + +static void __init foxg20_add_device_buttons(void) +{ + at91_set_gpio_input(AT91_PIN_PC4, 1); /* btn1 */ + at91_set_deglitch(AT91_PIN_PC4, 1); + + platform_device_register(&foxg20_button_device); +} +#else +static void __init foxg20_add_device_buttons(void) {} +#endif + + +#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) +static struct w1_gpio_platform_data w1_gpio_pdata = { + /* If you choose to use a pin other than PB16 it needs to be 3.3V */ + .pin = AT91_PIN_PB16, + .is_open_drain = 1, +}; + +static struct platform_device w1_device = { + .name = "w1-gpio", + .id = -1, + .dev.platform_data = &w1_gpio_pdata, +}; + +static void __init at91_add_device_w1(void) +{ + at91_set_GPIO_periph(w1_gpio_pdata.pin, 1); + at91_set_multi_drive(w1_gpio_pdata.pin, 1); + platform_device_register(&w1_device); +} + +#endif + + +static struct i2c_board_info __initdata foxg20_i2c_devices[] = { + { + I2C_BOARD_INFO("24c512", 0x50), + }, +}; + + +static void __init foxg20_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* USB Host */ + at91_add_device_usbh(&foxg20_usbh_data); + /* USB Device */ + at91_add_device_udc(&foxg20_udc_data); + /* SPI */ + at91_add_device_spi(foxg20_spi_devices, ARRAY_SIZE(foxg20_spi_devices)); + /* Ethernet */ + at91_add_device_eth(&foxg20_macb_data); + /* MMC */ + at91_add_device_mmc(0, &foxg20_mmc_data); + /* I2C */ + at91_add_device_i2c(foxg20_i2c_devices, ARRAY_SIZE(foxg20_i2c_devices)); + /* LEDs */ + at91_gpio_leds(foxg20_leds, ARRAY_SIZE(foxg20_leds)); + /* Push Buttons */ + foxg20_add_device_buttons(); +#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) + at91_add_device_w1(); +#endif +} + +MACHINE_START(ACMENETUSFOXG20, "Acme Systems srl FOX Board G20") + /* Maintainer: Sergio Tanzilli */ + .timer = &at91sam926x_timer, + .map_io = at91sam9260_map_io, + .init_early = foxg20_init_early, + .init_irq = foxg20_init_irq, + .init_machine = foxg20_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-gsia18s.c b/arch/arm/mach-at91/board-gsia18s.c new file mode 100644 index 00000000..1d4f36b3 --- /dev/null +++ b/arch/arm/mach-at91/board-gsia18s.c @@ -0,0 +1,584 @@ +/* + * Copyright (C) 2010 Christian Glindkamp <christian.glindkamp@taskit.de> + * taskit GmbH + * 2010 Igor Plyatov <plyatov@gmail.com> + * GeoSIG Ltd + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/platform_device.h> +#include <linux/gpio.h> +#include <linux/w1-gpio.h> +#include <linux/i2c.h> +#include <linux/i2c/pcf857x.h> +#include <linux/gpio_keys.h> +#include <linux/input.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#include <mach/board.h> +#include <mach/at91sam9_smc.h> +#include <mach/gsia18s.h> +#include <mach/stamp9g20.h> + +#include "sam9_smc.h" +#include "generic.h" + +static void __init gsia18s_init_early(void) +{ + stamp9g20_init_early(); + + /* + * USART0 on ttyS1 (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI). + * Used for Internal Analog Modem. + */ + at91_register_uart(AT91SAM9260_ID_US0, 1, + ATMEL_UART_CTS | ATMEL_UART_RTS | + ATMEL_UART_DTR | ATMEL_UART_DSR | + ATMEL_UART_DCD | ATMEL_UART_RI); + /* + * USART1 on ttyS2 (Rx, Tx, CTS, RTS). + * Used for GPS or WiFi or Data stream. + */ + at91_register_uart(AT91SAM9260_ID_US1, 2, + ATMEL_UART_CTS | ATMEL_UART_RTS); + /* + * USART2 on ttyS3 (Rx, Tx, CTS, RTS). + * Used for External Modem. + */ + at91_register_uart(AT91SAM9260_ID_US2, 3, + ATMEL_UART_CTS | ATMEL_UART_RTS); + /* + * USART3 on ttyS4 (Rx, Tx, RTS). + * Used for RS-485. + */ + at91_register_uart(AT91SAM9260_ID_US3, 4, ATMEL_UART_RTS); + + /* + * USART4 on ttyS5 (Rx, Tx). + * Used for TRX433 Radio Module. + */ + at91_register_uart(AT91SAM9260_ID_US4, 5, 0); +} + +static void __init init_irq(void) +{ + at91sam9260_init_interrupts(NULL); +} + +/* + * Two USB Host ports + */ +static struct at91_usbh_data __initdata usbh_data = { + .ports = 2, +}; + +/* + * USB Device port + */ +static struct at91_udc_data __initdata udc_data = { + .vbus_pin = AT91_PIN_PA22, + .pullup_pin = 0, /* pull-up driven by UDC */ +}; + +/* + * MACB Ethernet device + */ +static struct at91_eth_data __initdata macb_data = { + .phy_irq_pin = AT91_PIN_PA28, + .is_rmii = 1, +}; + +/* + * LEDs and GPOs + */ +static struct gpio_led gpio_leds[] = { + { + .name = "gpo:spi1reset", + .gpio = AT91_PIN_PC1, + .active_low = 0, + .default_trigger = "none", + .default_state = LEDS_GPIO_DEFSTATE_OFF, + }, + { + .name = "gpo:trig_net_out", + .gpio = AT91_PIN_PB20, + .active_low = 0, + .default_trigger = "none", + .default_state = LEDS_GPIO_DEFSTATE_OFF, + }, + { + .name = "gpo:trig_net_dir", + .gpio = AT91_PIN_PB19, + .active_low = 0, + .default_trigger = "none", + .default_state = LEDS_GPIO_DEFSTATE_OFF, + }, + { + .name = "gpo:charge_dis", + .gpio = AT91_PIN_PC2, + .active_low = 0, + .default_trigger = "none", + .default_state = LEDS_GPIO_DEFSTATE_OFF, + }, + { + .name = "led:event", + .gpio = AT91_PIN_PB17, + .active_low = 1, + .default_trigger = "none", + .default_state = LEDS_GPIO_DEFSTATE_OFF, + }, + { + .name = "led:lan", + .gpio = AT91_PIN_PB18, + .active_low = 1, + .default_trigger = "none", + .default_state = LEDS_GPIO_DEFSTATE_OFF, + }, + { + .name = "led:error", + .gpio = AT91_PIN_PB16, + .active_low = 1, + .default_trigger = "none", + .default_state = LEDS_GPIO_DEFSTATE_ON, + } +}; + +static struct gpio_led_platform_data gpio_led_info = { + .leds = gpio_leds, + .num_leds = ARRAY_SIZE(gpio_leds), +}; + +static struct platform_device leds = { + .name = "leds-gpio", + .id = 0, + .dev = { + .platform_data = &gpio_led_info, + } +}; + +static void __init gsia18s_leds_init(void) +{ + platform_device_register(&leds); +} + +/* PCF8574 0x20 GPIO - U1 on the GS_IA18-CB_V3 board */ +static struct gpio_led pcf_gpio_leds1[] = { + { /* bit 0 */ + .name = "gpo:hdc_power", + .gpio = PCF_GPIO_HDC_POWER, + .active_low = 0, + .default_trigger = "none", + .default_state = LEDS_GPIO_DEFSTATE_OFF, + }, + { /* bit 1 */ + .name = "gpo:wifi_setup", + .gpio = PCF_GPIO_WIFI_SETUP, + .active_low = 1, + .default_trigger = "none", + .default_state = LEDS_GPIO_DEFSTATE_OFF, + }, + { /* bit 2 */ + .name = "gpo:wifi_enable", + .gpio = PCF_GPIO_WIFI_ENABLE, + .active_low = 1, + .default_trigger = "none", + .default_state = LEDS_GPIO_DEFSTATE_OFF, + }, + { /* bit 3 */ + .name = "gpo:wifi_reset", + .gpio = PCF_GPIO_WIFI_RESET, + .active_low = 1, + .default_trigger = "none", + .default_state = LEDS_GPIO_DEFSTATE_ON, + }, + /* bit 4 used as GPI */ + { /* bit 5 */ + .name = "gpo:gps_setup", + .gpio = PCF_GPIO_GPS_SETUP, + .active_low = 1, + .default_trigger = "none", + .default_state = LEDS_GPIO_DEFSTATE_OFF, + }, + { /* bit 6 */ + .name = "gpo:gps_standby", + .gpio = PCF_GPIO_GPS_STANDBY, + .active_low = 0, + .default_trigger = "none", + .default_state = LEDS_GPIO_DEFSTATE_ON, + }, + { /* bit 7 */ + .name = "gpo:gps_power", + .gpio = PCF_GPIO_GPS_POWER, + .active_low = 0, + .default_trigger = "none", + .default_state = LEDS_GPIO_DEFSTATE_OFF, + } +}; + +static struct gpio_led_platform_data pcf_gpio_led_info1 = { + .leds = pcf_gpio_leds1, + .num_leds = ARRAY_SIZE(pcf_gpio_leds1), +}; + +static struct platform_device pcf_leds1 = { + .name = "leds-gpio", /* GS_IA18-CB_board */ + .id = 1, + .dev = { + .platform_data = &pcf_gpio_led_info1, + } +}; + +/* PCF8574 0x22 GPIO - U1 on the GS_2G_OPT1-A_V0 board (Alarm) */ +static struct gpio_led pcf_gpio_leds2[] = { + { /* bit 0 */ + .name = "gpo:alarm_1", + .gpio = PCF_GPIO_ALARM1, + .active_low = 1, + .default_trigger = "none", + .default_state = LEDS_GPIO_DEFSTATE_OFF, + }, + { /* bit 1 */ + .name = "gpo:alarm_2", + .gpio = PCF_GPIO_ALARM2, + .active_low = 1, + .default_trigger = "none", + .default_state = LEDS_GPIO_DEFSTATE_OFF, + }, + { /* bit 2 */ + .name = "gpo:alarm_3", + .gpio = PCF_GPIO_ALARM3, + .active_low = 1, + .default_trigger = "none", + .default_state = LEDS_GPIO_DEFSTATE_OFF, + }, + { /* bit 3 */ + .name = "gpo:alarm_4", + .gpio = PCF_GPIO_ALARM4, + .active_low = 1, + .default_trigger = "none", + .default_state = LEDS_GPIO_DEFSTATE_OFF, + }, + /* bits 4, 5, 6 not used */ + { /* bit 7 */ + .name = "gpo:alarm_v_relay_on", + .gpio = PCF_GPIO_ALARM_V_RELAY_ON, + .active_low = 0, + .default_trigger = "none", + .default_state = LEDS_GPIO_DEFSTATE_OFF, + }, +}; + +static struct gpio_led_platform_data pcf_gpio_led_info2 = { + .leds = pcf_gpio_leds2, + .num_leds = ARRAY_SIZE(pcf_gpio_leds2), +}; + +static struct platform_device pcf_leds2 = { + .name = "leds-gpio", + .id = 2, + .dev = { + .platform_data = &pcf_gpio_led_info2, + } +}; + +/* PCF8574 0x24 GPIO U1 on the GS_2G-OPT23-A_V0 board (Modem) */ +static struct gpio_led pcf_gpio_leds3[] = { + { /* bit 0 */ + .name = "gpo:modem_power", + .gpio = PCF_GPIO_MODEM_POWER, + .active_low = 1, + .default_trigger = "none", + .default_state = LEDS_GPIO_DEFSTATE_OFF, + }, + /* bits 1 and 2 not used */ + { /* bit 3 */ + .name = "gpo:modem_reset", + .gpio = PCF_GPIO_MODEM_RESET, + .active_low = 1, + .default_trigger = "none", + .default_state = LEDS_GPIO_DEFSTATE_ON, + }, + /* bits 4, 5 and 6 not used */ + { /* bit 7 */ + .name = "gpo:trx_reset", + .gpio = PCF_GPIO_TRX_RESET, + .active_low = 1, + .default_trigger = "none", + .default_state = LEDS_GPIO_DEFSTATE_ON, + } +}; + +static struct gpio_led_platform_data pcf_gpio_led_info3 = { + .leds = pcf_gpio_leds3, + .num_leds = ARRAY_SIZE(pcf_gpio_leds3), +}; + +static struct platform_device pcf_leds3 = { + .name = "leds-gpio", + .id = 3, + .dev = { + .platform_data = &pcf_gpio_led_info3, + } +}; + +static void __init gsia18s_pcf_leds_init(void) +{ + platform_device_register(&pcf_leds1); + platform_device_register(&pcf_leds2); + platform_device_register(&pcf_leds3); +} + +/* + * SPI busses. + */ +static struct spi_board_info gsia18s_spi_devices[] = { + { /* User accessible spi0, cs0 used for communication with MSP RTC */ + .modalias = "spidev", + .bus_num = 0, + .chip_select = 0, + .max_speed_hz = 580000, + .mode = SPI_MODE_1, + }, + { /* User accessible spi1, cs0 used for communication with int. DSP */ + .modalias = "spidev", + .bus_num = 1, + .chip_select = 0, + .max_speed_hz = 5600000, + .mode = SPI_MODE_0, + }, + { /* User accessible spi1, cs1 used for communication with ext. DSP */ + .modalias = "spidev", + .bus_num = 1, + .chip_select = 1, + .max_speed_hz = 5600000, + .mode = SPI_MODE_0, + }, + { /* User accessible spi1, cs2 used for communication with ext. DSP */ + .modalias = "spidev", + .bus_num = 1, + .chip_select = 2, + .max_speed_hz = 5600000, + .mode = SPI_MODE_0, + }, + { /* User accessible spi1, cs3 used for communication with ext. DSP */ + .modalias = "spidev", + .bus_num = 1, + .chip_select = 3, + .max_speed_hz = 5600000, + .mode = SPI_MODE_0, + } +}; + +/* + * GPI Buttons + */ +static struct gpio_keys_button buttons[] = { + { + .gpio = GPIO_TRIG_NET_IN, + .code = BTN_1, + .desc = "TRIG_NET_IN", + .type = EV_KEY, + .active_low = 0, + .wakeup = 1, + }, + { /* SW80 on the GS_IA18_S-MN board*/ + .gpio = GPIO_CARD_UNMOUNT_0, + .code = BTN_2, + .desc = "Card umount 0", + .type = EV_KEY, + .active_low = 1, + .wakeup = 1, + }, + { /* SW79 on the GS_IA18_S-MN board*/ + .gpio = GPIO_CARD_UNMOUNT_1, + .code = BTN_3, + .desc = "Card umount 1", + .type = EV_KEY, + .active_low = 1, + .wakeup = 1, + }, + { /* SW280 on the GS_IA18-CB board*/ + .gpio = GPIO_KEY_POWER, + .code = KEY_POWER, + .desc = "Power Off Button", + .type = EV_KEY, + .active_low = 0, + .wakeup = 1, + } +}; + +static struct gpio_keys_platform_data button_data = { + .buttons = buttons, + .nbuttons = ARRAY_SIZE(buttons), +}; + +static struct platform_device button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &button_data, + } +}; + +static void __init gsia18s_add_device_buttons(void) +{ + at91_set_gpio_input(GPIO_TRIG_NET_IN, 1); + at91_set_deglitch(GPIO_TRIG_NET_IN, 1); + at91_set_gpio_input(GPIO_CARD_UNMOUNT_0, 1); + at91_set_deglitch(GPIO_CARD_UNMOUNT_0, 1); + at91_set_gpio_input(GPIO_CARD_UNMOUNT_1, 1); + at91_set_deglitch(GPIO_CARD_UNMOUNT_1, 1); + at91_set_gpio_input(GPIO_KEY_POWER, 0); + at91_set_deglitch(GPIO_KEY_POWER, 1); + + platform_device_register(&button_device); +} + +/* + * I2C + */ +static int pcf8574x_0x20_setup(struct i2c_client *client, int gpio, + unsigned int ngpio, void *context) +{ + int status; + + status = gpio_request(gpio + PCF_GPIO_ETH_DETECT, "eth_det"); + if (status < 0) { + pr_err("error: can't request GPIO%d\n", + gpio + PCF_GPIO_ETH_DETECT); + return status; + } + status = gpio_direction_input(gpio + PCF_GPIO_ETH_DETECT); + if (status < 0) { + pr_err("error: can't setup GPIO%d as input\n", + gpio + PCF_GPIO_ETH_DETECT); + return status; + } + status = gpio_export(gpio + PCF_GPIO_ETH_DETECT, false); + if (status < 0) { + pr_err("error: can't export GPIO%d\n", + gpio + PCF_GPIO_ETH_DETECT); + return status; + } + status = gpio_sysfs_set_active_low(gpio + PCF_GPIO_ETH_DETECT, 1); + if (status < 0) { + pr_err("error: gpio_sysfs_set active_low(GPIO%d, 1)\n", + gpio + PCF_GPIO_ETH_DETECT); + return status; + } + + return 0; +} + +static int pcf8574x_0x20_teardown(struct i2c_client *client, int gpio, + unsigned ngpio, void *context) +{ + gpio_free(gpio + PCF_GPIO_ETH_DETECT); + return 0; +} + +static struct pcf857x_platform_data pcf20_pdata = { + .gpio_base = GS_IA18_S_PCF_GPIO_BASE0, + .n_latch = (1 << 4), + .setup = pcf8574x_0x20_setup, + .teardown = pcf8574x_0x20_teardown, +}; + +static struct pcf857x_platform_data pcf22_pdata = { + .gpio_base = GS_IA18_S_PCF_GPIO_BASE1, +}; + +static struct pcf857x_platform_data pcf24_pdata = { + .gpio_base = GS_IA18_S_PCF_GPIO_BASE2, +}; + +static struct i2c_board_info __initdata gsia18s_i2c_devices[] = { + { /* U1 on the GS_IA18-CB_V3 board */ + I2C_BOARD_INFO("pcf8574", 0x20), + .platform_data = &pcf20_pdata, + }, + { /* U1 on the GS_2G_OPT1-A_V0 board (Alarm) */ + I2C_BOARD_INFO("pcf8574", 0x22), + .platform_data = &pcf22_pdata, + }, + { /* U1 on the GS_2G-OPT23-A_V0 board (Modem) */ + I2C_BOARD_INFO("pcf8574", 0x24), + .platform_data = &pcf24_pdata, + }, + { /* U161 on the GS_IA18_S-MN board */ + I2C_BOARD_INFO("24c1024", 0x50), + }, + { /* U162 on the GS_IA18_S-MN board */ + I2C_BOARD_INFO("24c01", 0x53), + }, +}; + +/* + * Compact Flash + */ +static struct at91_cf_data __initdata gsia18s_cf1_data = { + .irq_pin = AT91_PIN_PA27, + .det_pin = AT91_PIN_PB30, + .rst_pin = AT91_PIN_PB31, + .chipselect = 5, + .flags = AT91_CF_TRUE_IDE, +}; + +/* Power Off by RTC */ +static void gsia18s_power_off(void) +{ + pr_notice("Power supply will be switched off automatically now or after 60 seconds without ArmDAS.\n"); + at91_set_gpio_output(AT91_PIN_PA25, 1); + /* Spin to death... */ + while (1) + ; +} + +static int __init gsia18s_power_off_init(void) +{ + pm_power_off = gsia18s_power_off; + return 0; +} + +/* ---------------------------------------------------------------------------*/ + +static void __init gsia18s_board_init(void) +{ + stamp9g20_board_init(); + at91_add_device_usbh(&usbh_data); + at91_add_device_udc(&udc_data); + at91_add_device_eth(&macb_data); + gsia18s_leds_init(); + gsia18s_pcf_leds_init(); + gsia18s_add_device_buttons(); + at91_add_device_i2c(gsia18s_i2c_devices, + ARRAY_SIZE(gsia18s_i2c_devices)); + at91_add_device_cf(&gsia18s_cf1_data); + at91_add_device_spi(gsia18s_spi_devices, + ARRAY_SIZE(gsia18s_spi_devices)); + gsia18s_power_off_init(); +} + +MACHINE_START(GSIA18S, "GS_IA18_S") + .timer = &at91sam926x_timer, + .map_io = at91sam9260_map_io, + .init_early = gsia18s_init_early, + .init_irq = init_irq, + .init_machine = gsia18s_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-kafa.c b/arch/arm/mach-at91/board-kafa.c new file mode 100644 index 00000000..9b003ff7 --- /dev/null +++ b/arch/arm/mach-at91/board-kafa.c @@ -0,0 +1,106 @@ +/* + * linux/arch/arm/mach-at91/board-kafa.c + * + * Copyright (C) 2006 Sperry-Sun + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/platform_device.h> + +#include <mach/hardware.h> +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <mach/board.h> +#include <mach/gpio.h> +#include <mach/cpu.h> + +#include "generic.h" + + +static void __init kafa_init_early(void) +{ + /* Set cpu type: PQFP */ + at91rm9200_set_type(ARCH_REVISON_9200_PQFP); + + /* Initialize processor: 18.432 MHz crystal */ + at91rm9200_initialize(18432000); + + /* Set up the LEDs */ + at91_init_leds(AT91_PIN_PB4, AT91_PIN_PB4); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1 (Rx, Tx, CTS, RTS) */ + at91_register_uart(AT91RM9200_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init kafa_init_irq(void) +{ + at91rm9200_init_interrupts(NULL); +} + +static struct at91_eth_data __initdata kafa_eth_data = { + .phy_irq_pin = AT91_PIN_PC4, + .is_rmii = 0, +}; + +static struct at91_usbh_data __initdata kafa_usbh_data = { + .ports = 1, +}; + +static struct at91_udc_data __initdata kafa_udc_data = { + .vbus_pin = AT91_PIN_PB6, + .pullup_pin = AT91_PIN_PB7, +}; + +static void __init kafa_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* Ethernet */ + at91_add_device_eth(&kafa_eth_data); + /* USB Host */ + at91_add_device_usbh(&kafa_usbh_data); + /* USB Device */ + at91_add_device_udc(&kafa_udc_data); + /* I2C */ + at91_add_device_i2c(NULL, 0); + /* SPI */ + at91_add_device_spi(NULL, 0); +} + +MACHINE_START(KAFA, "Sperry-Sun KAFA") + /* Maintainer: Sergei Sharonov */ + .timer = &at91rm9200_timer, + .map_io = at91rm9200_map_io, + .init_early = kafa_init_early, + .init_irq = kafa_init_irq, + .init_machine = kafa_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-kb9202.c b/arch/arm/mach-at91/board-kb9202.c new file mode 100644 index 00000000..a813a74b --- /dev/null +++ b/arch/arm/mach-at91/board-kb9202.c @@ -0,0 +1,147 @@ +/* + * linux/arch/arm/mach-at91/board-kb9202.c + * + * Copyright (c) 2005 kb_admin + * KwikByte, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/platform_device.h> + +#include <mach/hardware.h> +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <mach/board.h> +#include <mach/gpio.h> +#include <mach/cpu.h> +#include <mach/at91rm9200_mc.h> + +#include "generic.h" + + +static void __init kb9202_init_early(void) +{ + /* Set cpu type: PQFP */ + at91rm9200_set_type(ARCH_REVISON_9200_PQFP); + + /* Initialize processor: 10 MHz crystal */ + at91rm9200_initialize(10000000); + + /* Set up the LEDs */ + at91_init_leds(AT91_PIN_PC19, AT91_PIN_PC18); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1 (Rx & Tx only) */ + at91_register_uart(AT91RM9200_ID_US0, 1, 0); + + /* USART1 on ttyS2 (Rx & Tx only) - IRDA (optional) */ + at91_register_uart(AT91RM9200_ID_US1, 2, 0); + + /* USART3 on ttyS3 (Rx, Tx, CTS, RTS) - RS485 (optional) */ + at91_register_uart(AT91RM9200_ID_US3, 3, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init kb9202_init_irq(void) +{ + at91rm9200_init_interrupts(NULL); +} + +static struct at91_eth_data __initdata kb9202_eth_data = { + .phy_irq_pin = AT91_PIN_PB29, + .is_rmii = 0, +}; + +static struct at91_usbh_data __initdata kb9202_usbh_data = { + .ports = 1, +}; + +static struct at91_udc_data __initdata kb9202_udc_data = { + .vbus_pin = AT91_PIN_PB24, + .pullup_pin = AT91_PIN_PB22, +}; + +static struct at91_mmc_data __initdata kb9202_mmc_data = { + .det_pin = AT91_PIN_PB2, + .slot_b = 0, + .wire4 = 1, +}; + +static struct mtd_partition __initdata kb9202_nand_partition[] = { + { + .name = "nand_fs", + .offset = 0, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(kb9202_nand_partition); + return kb9202_nand_partition; +} + +static struct atmel_nand_data __initdata kb9202_nand_data = { + .ale = 22, + .cle = 21, + // .det_pin = ... not there + .rdy_pin = AT91_PIN_PC29, + .enable_pin = AT91_PIN_PC28, + .partition_info = nand_partitions, +}; + +static void __init kb9202_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* Ethernet */ + at91_add_device_eth(&kb9202_eth_data); + /* USB Host */ + at91_add_device_usbh(&kb9202_usbh_data); + /* USB Device */ + at91_add_device_udc(&kb9202_udc_data); + /* MMC */ + at91_add_device_mmc(0, &kb9202_mmc_data); + /* I2C */ + at91_add_device_i2c(NULL, 0); + /* SPI */ + at91_add_device_spi(NULL, 0); + /* NAND */ + at91_add_device_nand(&kb9202_nand_data); +} + +MACHINE_START(KB9200, "KB920x") + /* Maintainer: KwikByte, Inc. */ + .timer = &at91rm9200_timer, + .map_io = at91rm9200_map_io, + .init_early = kb9202_init_early, + .init_irq = kb9202_init_irq, + .init_machine = kb9202_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-neocore926.c b/arch/arm/mach-at91/board-neocore926.c new file mode 100644 index 00000000..961e805d --- /dev/null +++ b/arch/arm/mach-at91/board-neocore926.c @@ -0,0 +1,395 @@ +/* + * linux/arch/arm/mach-at91/board-neocore926.c + * + * Copyright (C) 2005 SAN People + * Copyright (C) 2007 Atmel Corporation + * Copyright (C) 2008 ADENEO. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> +#include <linux/spi/ads7846.h> +#include <linux/fb.h> +#include <linux/gpio_keys.h> +#include <linux/input.h> + +#include <video/atmel_lcdc.h> + +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/irq.h> +#include <asm/sizes.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <mach/hardware.h> +#include <mach/board.h> +#include <mach/gpio.h> +#include <mach/at91sam9_smc.h> + +#include "sam9_smc.h" +#include "generic.h" + + +static void __init neocore926_init_early(void) +{ + /* Initialize processor: 20 MHz crystal */ + at91sam9263_initialize(20000000); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1. (Rx, Tx, RTS, CTS) */ + at91_register_uart(AT91SAM9263_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init neocore926_init_irq(void) +{ + at91sam9263_init_interrupts(NULL); +} + + +/* + * USB Host port + */ +static struct at91_usbh_data __initdata neocore926_usbh_data = { + .ports = 2, + .vbus_pin = { AT91_PIN_PA24, AT91_PIN_PA21 }, +}; + +/* + * USB Device port + */ +static struct at91_udc_data __initdata neocore926_udc_data = { + .vbus_pin = AT91_PIN_PA25, + .pullup_pin = 0, /* pull-up driven by UDC */ +}; + + +/* + * ADS7846 Touchscreen + */ +#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) +static int ads7843_pendown_state(void) +{ + return !at91_get_gpio_value(AT91_PIN_PA15); /* Touchscreen PENIRQ */ +} + +static struct ads7846_platform_data ads_info = { + .model = 7843, + .x_min = 150, + .x_max = 3830, + .y_min = 190, + .y_max = 3830, + .vref_delay_usecs = 100, + .x_plate_ohms = 450, + .y_plate_ohms = 250, + .pressure_max = 15000, + .debounce_max = 1, + .debounce_rep = 0, + .debounce_tol = (~0), + .get_pendown_state = ads7843_pendown_state, +}; + +static void __init neocore926_add_device_ts(void) +{ + at91_set_B_periph(AT91_PIN_PA15, 1); /* External IRQ1, with pullup */ + at91_set_gpio_input(AT91_PIN_PC13, 1); /* Touchscreen BUSY signal */ +} +#else +static void __init neocore926_add_device_ts(void) {} +#endif + +/* + * SPI devices. + */ +static struct spi_board_info neocore926_spi_devices[] = { +#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD) + { /* DataFlash card */ + .modalias = "mtd_dataflash", + .chip_select = 0, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +#endif +#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) + { + .modalias = "ads7846", + .chip_select = 1, + .max_speed_hz = 125000 * 16, + .bus_num = 0, + .platform_data = &ads_info, + .irq = AT91SAM9263_ID_IRQ1, + }, +#endif +}; + + +/* + * MCI (SD/MMC) + */ +static struct at91_mmc_data __initdata neocore926_mmc_data = { + .wire4 = 1, + .det_pin = AT91_PIN_PE18, + .wp_pin = AT91_PIN_PE19, +}; + + +/* + * MACB Ethernet device + */ +static struct at91_eth_data __initdata neocore926_macb_data = { + .phy_irq_pin = AT91_PIN_PE31, + .is_rmii = 1, +}; + + +/* + * NAND flash + */ +static struct mtd_partition __initdata neocore926_nand_partition[] = { + { + .name = "Linux Kernel", /* "Partition 1", */ + .offset = 0, + .size = SZ_8M, + }, + { + .name = "Filesystem", /* "Partition 2", */ + .offset = MTDPART_OFS_NXTBLK, + .size = SZ_32M, + }, + { + .name = "Free", /* "Partition 3", */ + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(neocore926_nand_partition); + return neocore926_nand_partition; +} + +static struct atmel_nand_data __initdata neocore926_nand_data = { + .ale = 21, + .cle = 22, + .rdy_pin = AT91_PIN_PB19, + .rdy_pin_active_low = 1, + .enable_pin = AT91_PIN_PD15, + .partition_info = nand_partitions, +}; + +static struct sam9_smc_config __initdata neocore926_nand_smc_config = { + .ncs_read_setup = 0, + .nrd_setup = 1, + .ncs_write_setup = 0, + .nwe_setup = 1, + + .ncs_read_pulse = 4, + .nrd_pulse = 4, + .ncs_write_pulse = 4, + .nwe_pulse = 4, + + .read_cycle = 6, + .write_cycle = 6, + + .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8, + .tdf_cycles = 2, +}; + +static void __init neocore926_add_device_nand(void) +{ + /* configure chip-select 3 (NAND) */ + sam9_smc_configure(3, &neocore926_nand_smc_config); + + at91_add_device_nand(&neocore926_nand_data); +} + + +/* + * LCD Controller + */ +#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) +static struct fb_videomode at91_tft_vga_modes[] = { + { + .name = "TX09D50VM1CCA @ 60", + .refresh = 60, + .xres = 240, .yres = 320, + .pixclock = KHZ2PICOS(5000), + + .left_margin = 1, .right_margin = 33, + .upper_margin = 1, .lower_margin = 0, + .hsync_len = 5, .vsync_len = 1, + + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = FB_VMODE_NONINTERLACED, + }, +}; + +static struct fb_monspecs at91fb_default_monspecs = { + .manufacturer = "HIT", + .monitor = "TX09D70VM1CCA", + + .modedb = at91_tft_vga_modes, + .modedb_len = ARRAY_SIZE(at91_tft_vga_modes), + .hfmin = 15000, + .hfmax = 64000, + .vfmin = 50, + .vfmax = 150, +}; + +#define AT91SAM9263_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \ + | ATMEL_LCDC_DISTYPE_TFT \ + | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE) + +static void at91_lcdc_power_control(int on) +{ + at91_set_gpio_value(AT91_PIN_PA30, on); +} + +/* Driver datas */ +static struct atmel_lcdfb_info __initdata neocore926_lcdc_data = { + .lcdcon_is_backlight = true, + .default_bpp = 16, + .default_dmacon = ATMEL_LCDC_DMAEN, + .default_lcdcon2 = AT91SAM9263_DEFAULT_LCDCON2, + .default_monspecs = &at91fb_default_monspecs, + .atmel_lcdfb_power_control = at91_lcdc_power_control, + .guard_time = 1, + .lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB555, +}; + +#else +static struct atmel_lcdfb_info __initdata neocore926_lcdc_data; +#endif + + +/* + * GPIO Buttons + */ +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +static struct gpio_keys_button neocore926_buttons[] = { + { /* BP1, "leftclic" */ + .code = BTN_LEFT, + .gpio = AT91_PIN_PC5, + .active_low = 1, + .desc = "left_click", + .wakeup = 1, + }, + { /* BP2, "rightclic" */ + .code = BTN_RIGHT, + .gpio = AT91_PIN_PC4, + .active_low = 1, + .desc = "right_click", + .wakeup = 1, + }, +}; + +static struct gpio_keys_platform_data neocore926_button_data = { + .buttons = neocore926_buttons, + .nbuttons = ARRAY_SIZE(neocore926_buttons), +}; + +static struct platform_device neocore926_button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &neocore926_button_data, + } +}; + +static void __init neocore926_add_device_buttons(void) +{ + at91_set_GPIO_periph(AT91_PIN_PC5, 0); /* left button */ + at91_set_deglitch(AT91_PIN_PC5, 1); + at91_set_GPIO_periph(AT91_PIN_PC4, 0); /* right button */ + at91_set_deglitch(AT91_PIN_PC4, 1); + + platform_device_register(&neocore926_button_device); +} +#else +static void __init neocore926_add_device_buttons(void) {} +#endif + + +/* + * AC97 + */ +static struct ac97c_platform_data neocore926_ac97_data = { + .reset_pin = AT91_PIN_PA13, +}; + + +static void __init neocore926_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + + /* USB Host */ + at91_add_device_usbh(&neocore926_usbh_data); + + /* USB Device */ + at91_add_device_udc(&neocore926_udc_data); + + /* SPI */ + at91_set_gpio_output(AT91_PIN_PE20, 1); /* select spi0 clock */ + at91_add_device_spi(neocore926_spi_devices, ARRAY_SIZE(neocore926_spi_devices)); + + /* Touchscreen */ + neocore926_add_device_ts(); + + /* MMC */ + at91_add_device_mmc(1, &neocore926_mmc_data); + + /* Ethernet */ + at91_add_device_eth(&neocore926_macb_data); + + /* NAND */ + neocore926_add_device_nand(); + + /* I2C */ + at91_add_device_i2c(NULL, 0); + + /* LCD Controller */ + at91_add_device_lcdc(&neocore926_lcdc_data); + + /* Push Buttons */ + neocore926_add_device_buttons(); + + /* AC97 */ + at91_add_device_ac97(&neocore926_ac97_data); +} + +MACHINE_START(NEOCORE926, "ADENEO NEOCORE 926") + /* Maintainer: ADENEO */ + .timer = &at91sam926x_timer, + .map_io = at91sam9263_map_io, + .init_early = neocore926_init_early, + .init_irq = neocore926_init_irq, + .init_machine = neocore926_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-pcontrol-g20.c b/arch/arm/mach-at91/board-pcontrol-g20.c new file mode 100644 index 00000000..21a21af2 --- /dev/null +++ b/arch/arm/mach-at91/board-pcontrol-g20.c @@ -0,0 +1,230 @@ +/* + * Copyright (C) 2010 Christian Glindkamp <christian.glindkamp@taskit.de> + * taskit GmbH + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +/* + * copied and adjusted from board-stamp9g20.c + * by Peter Gsellmann <pgsellmann@portner-elektronik.at> + */ + +#include <linux/mm.h> +#include <linux/platform_device.h> +#include <linux/gpio.h> +#include <linux/w1-gpio.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#include <mach/board.h> +#include <mach/at91sam9_smc.h> +#include <mach/stamp9g20.h> + +#include "sam9_smc.h" +#include "generic.h" + + +static void __init pcontrol_g20_init_early(void) +{ + stamp9g20_init_early(); + + /* USART0 on ttyS1. (Rx, Tx, CTS, RTS) piggyback A2 */ + at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS + | ATMEL_UART_RTS); + + /* USART1 on ttyS2. (Rx, Tx, CTS, RTS) isolated RS485 X5 */ + at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS + | ATMEL_UART_RTS); + + /* USART2 on ttyS3. (Rx, Tx) 9bit-Bus Multidrop-mode X4 */ + at91_register_uart(AT91SAM9260_ID_US4, 3, 0); +} + + +static void __init init_irq(void) +{ + at91sam9260_init_interrupts(NULL); +} + + +static struct sam9_smc_config __initdata pcontrol_smc_config[2] = { { + .ncs_read_setup = 16, + .nrd_setup = 18, + .ncs_write_setup = 16, + .nwe_setup = 18, + + .ncs_read_pulse = 63, + .nrd_pulse = 55, + .ncs_write_pulse = 63, + .nwe_pulse = 55, + + .read_cycle = 127, + .write_cycle = 127, + + .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE + | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_SELECT + | AT91_SMC_DBW_8 | AT91_SMC_PS_4 + | AT91_SMC_TDFMODE, + .tdf_cycles = 3, +}, { + .ncs_read_setup = 0, + .nrd_setup = 0, + .ncs_write_setup = 0, + .nwe_setup = 1, + + .ncs_read_pulse = 8, + .nrd_pulse = 8, + .ncs_write_pulse = 5, + .nwe_pulse = 4, + + .read_cycle = 8, + .write_cycle = 7, + + .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE + | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_SELECT + | AT91_SMC_DBW_16 | AT91_SMC_PS_8 + | AT91_SMC_TDFMODE, + .tdf_cycles = 1, +} }; + +static void __init add_device_pcontrol(void) +{ + /* configure chip-select 4 (IO compatible to 8051 X4 ) */ + sam9_smc_configure(4, &pcontrol_smc_config[0]); + /* configure chip-select 7 (FerroRAM 256KiBx16bit MR2A16A D4 ) */ + sam9_smc_configure(7, &pcontrol_smc_config[1]); +} + + +/* + * USB Host port + */ +static struct at91_usbh_data __initdata usbh_data = { + .ports = 2, +}; + + +/* + * USB Device port + */ +static struct at91_udc_data __initdata pcontrol_g20_udc_data = { + .vbus_pin = AT91_PIN_PA22, /* Detect +5V bus voltage */ + .pullup_pin = AT91_PIN_PA4, /* K-state, active low */ +}; + + +/* + * MACB Ethernet device + */ +static struct at91_eth_data __initdata macb_data = { + .phy_irq_pin = AT91_PIN_PA28, + .is_rmii = 1, +}; + + +/* + * I2C devices: eeprom and phy/switch + */ +static struct i2c_board_info __initdata pcontrol_g20_i2c_devices[] = { +{ /* D7 address width=2, 8KiB */ + I2C_BOARD_INFO("24c64", 0x50) +}, { /* D8 address width=1, 1 byte has 32 bits! */ + I2C_BOARD_INFO("lan9303", 0x0a) +}, }; + + +/* + * LEDs + */ +static struct gpio_led pcontrol_g20_leds[] = { + { + .name = "LED1", /* red H5 */ + .gpio = AT91_PIN_PB18, + .active_low = 1, + .default_trigger = "none", /* supervisor */ + }, { + .name = "LED2", /* yellow H7 */ + .gpio = AT91_PIN_PB19, + .active_low = 1, + .default_trigger = "mmc0", /* SD-card activity */ + }, { + .name = "LED3", /* green H2 */ + .gpio = AT91_PIN_PB20, + .active_low = 1, + .default_trigger = "heartbeat", /* blinky */ + }, { + .name = "LED4", /* red H3 */ + .gpio = AT91_PIN_PC6, + .active_low = 1, + .default_trigger = "none", /* connection lost */ + }, { + .name = "LED5", /* yellow H6 */ + .gpio = AT91_PIN_PC7, + .active_low = 1, + .default_trigger = "none", /* unsent data */ + }, { + .name = "LED6", /* green H1 */ + .gpio = AT91_PIN_PC9, + .active_low = 1, + .default_trigger = "none", /* snafu */ + } +}; + + +/* + * SPI devices + */ +static struct spi_board_info pcontrol_g20_spi_devices[] = { + { + .modalias = "spidev", /* HMI port X4 */ + .chip_select = 1, + .max_speed_hz = 50 * 1000 * 1000, + .bus_num = 0, + }, { + .modalias = "spidev", /* piggyback A2 */ + .chip_select = 0, + .max_speed_hz = 50 * 1000 * 1000, + .bus_num = 1, + }, +}; + + +static void __init pcontrol_g20_board_init(void) +{ + stamp9g20_board_init(); + at91_add_device_usbh(&usbh_data); + at91_add_device_eth(&macb_data); + at91_add_device_i2c(pcontrol_g20_i2c_devices, + ARRAY_SIZE(pcontrol_g20_i2c_devices)); + add_device_pcontrol(); + at91_add_device_spi(pcontrol_g20_spi_devices, + ARRAY_SIZE(pcontrol_g20_spi_devices)); + at91_add_device_udc(&pcontrol_g20_udc_data); + at91_gpio_leds(pcontrol_g20_leds, + ARRAY_SIZE(pcontrol_g20_leds)); + /* piggyback A2 */ + at91_set_gpio_output(AT91_PIN_PB31, 1); +} + + +MACHINE_START(PCONTROL_G20, "PControl G20") + /* Maintainer: pgsellmann@portner-elektronik.at */ + .timer = &at91sam926x_timer, + .map_io = at91sam9260_map_io, + .init_early = pcontrol_g20_init_early, + .init_irq = init_irq, + .init_machine = pcontrol_g20_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-picotux200.c b/arch/arm/mach-at91/board-picotux200.c new file mode 100644 index 00000000..756cc2a7 --- /dev/null +++ b/arch/arm/mach-at91/board-picotux200.c @@ -0,0 +1,131 @@ +/* + * linux/arch/arm/mach-at91/board-picotux200.c + * + * Copyright (C) 2005 SAN People + * Copyright (C) 2007 Kleinhenz Elektronik GmbH + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> +#include <linux/mtd/physmap.h> + +#include <mach/hardware.h> +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <mach/board.h> +#include <mach/gpio.h> +#include <mach/at91rm9200_mc.h> + +#include "generic.h" + + +static void __init picotux200_init_early(void) +{ + /* Initialize processor: 18.432 MHz crystal */ + at91rm9200_initialize(18432000); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD + | ATMEL_UART_RI); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init picotux200_init_irq(void) +{ + at91rm9200_init_interrupts(NULL); +} + +static struct at91_eth_data __initdata picotux200_eth_data = { + .phy_irq_pin = AT91_PIN_PC4, + .is_rmii = 1, +}; + +static struct at91_usbh_data __initdata picotux200_usbh_data = { + .ports = 1, +}; + +static struct at91_mmc_data __initdata picotux200_mmc_data = { + .det_pin = AT91_PIN_PB27, + .slot_b = 0, + .wire4 = 1, + .wp_pin = AT91_PIN_PA17, +}; + +#define PICOTUX200_FLASH_BASE AT91_CHIPSELECT_0 +#define PICOTUX200_FLASH_SIZE SZ_4M + +static struct physmap_flash_data picotux200_flash_data = { + .width = 2, +}; + +static struct resource picotux200_flash_resource = { + .start = PICOTUX200_FLASH_BASE, + .end = PICOTUX200_FLASH_BASE + PICOTUX200_FLASH_SIZE - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device picotux200_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &picotux200_flash_data, + }, + .resource = &picotux200_flash_resource, + .num_resources = 1, +}; + +static void __init picotux200_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* Ethernet */ + at91_add_device_eth(&picotux200_eth_data); + /* USB Host */ + at91_add_device_usbh(&picotux200_usbh_data); + /* I2C */ + at91_add_device_i2c(NULL, 0); + /* MMC */ + at91_set_gpio_output(AT91_PIN_PB22, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */ + at91_add_device_mmc(0, &picotux200_mmc_data); + /* NOR Flash */ + platform_device_register(&picotux200_flash); +} + +MACHINE_START(PICOTUX2XX, "picotux 200") + /* Maintainer: Kleinhenz Elektronik GmbH */ + .timer = &at91rm9200_timer, + .map_io = at91rm9200_map_io, + .init_early = picotux200_init_early, + .init_irq = picotux200_init_irq, + .init_machine = picotux200_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-qil-a9260.c b/arch/arm/mach-at91/board-qil-a9260.c new file mode 100644 index 00000000..d1a6001b --- /dev/null +++ b/arch/arm/mach-at91/board-qil-a9260.c @@ -0,0 +1,276 @@ +/* + * linux/arch/arm/mach-at91/board-qil-a9260.c + * + * Copyright (C) 2005 SAN People + * Copyright (C) 2006 Atmel + * Copyright (C) 2007 Calao-systems + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> +#include <linux/gpio_keys.h> +#include <linux/input.h> +#include <linux/clk.h> + +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <mach/hardware.h> +#include <mach/board.h> +#include <mach/gpio.h> +#include <mach/at91sam9_smc.h> +#include <mach/at91_shdwc.h> + +#include "sam9_smc.h" +#include "generic.h" + + +static void __init ek_init_early(void) +{ + /* Initialize processor: 12.000 MHz crystal */ + at91sam9260_initialize(12000000); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD + | ATMEL_UART_RI); + + /* USART1 on ttyS2. (Rx, Tx, CTS, RTS) */ + at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* USART2 on ttyS3. (Rx, Tx, CTS, RTS) */ + at91_register_uart(AT91SAM9260_ID_US2, 3, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* set serial console to ttyS1 (ie, USART0) */ + at91_set_serial_console(1); + +} + +static void __init ek_init_irq(void) +{ + at91sam9260_init_interrupts(NULL); +} + + +/* + * USB Host port + */ +static struct at91_usbh_data __initdata ek_usbh_data = { + .ports = 2, +}; + +/* + * USB Device port + */ +static struct at91_udc_data __initdata ek_udc_data = { + .vbus_pin = AT91_PIN_PC5, + .pullup_pin = 0, /* pull-up driven by UDC */ +}; + +/* + * SPI devices. + */ +static struct spi_board_info ek_spi_devices[] = { +#if defined(CONFIG_RTC_DRV_M41T94) + { /* M41T94 RTC */ + .modalias = "m41t94", + .chip_select = 0, + .max_speed_hz = 1 * 1000 * 1000, + .bus_num = 0, + } +#endif +}; + +/* + * MACB Ethernet device + */ +static struct at91_eth_data __initdata ek_macb_data = { + .phy_irq_pin = AT91_PIN_PA31, + .is_rmii = 1, +}; + +/* + * NAND flash + */ +static struct mtd_partition __initdata ek_nand_partition[] = { + { + .name = "Uboot & Kernel", + .offset = 0, + .size = SZ_16M, + }, + { + .name = "Root FS", + .offset = MTDPART_OFS_NXTBLK, + .size = 120 * SZ_1M, + }, + { + .name = "FS", + .offset = MTDPART_OFS_NXTBLK, + .size = 120 * SZ_1M, + }, +}; + +static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(ek_nand_partition); + return ek_nand_partition; +} + +static struct atmel_nand_data __initdata ek_nand_data = { + .ale = 21, + .cle = 22, +// .det_pin = ... not connected + .rdy_pin = AT91_PIN_PC13, + .enable_pin = AT91_PIN_PC14, + .partition_info = nand_partitions, +}; + +static struct sam9_smc_config __initdata ek_nand_smc_config = { + .ncs_read_setup = 0, + .nrd_setup = 1, + .ncs_write_setup = 0, + .nwe_setup = 1, + + .ncs_read_pulse = 3, + .nrd_pulse = 3, + .ncs_write_pulse = 3, + .nwe_pulse = 3, + + .read_cycle = 5, + .write_cycle = 5, + + .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8, + .tdf_cycles = 2, +}; + +static void __init ek_add_device_nand(void) +{ + /* configure chip-select 3 (NAND) */ + sam9_smc_configure(3, &ek_nand_smc_config); + + at91_add_device_nand(&ek_nand_data); +} + +/* + * MCI (SD/MMC) + */ +static struct at91_mmc_data __initdata ek_mmc_data = { + .slot_b = 0, + .wire4 = 1, +// .det_pin = ... not connected +// .wp_pin = ... not connected +// .vcc_pin = ... not connected +}; + +/* + * GPIO Buttons + */ +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +static struct gpio_keys_button ek_buttons[] = { + { /* USER PUSH BUTTON */ + .code = KEY_ENTER, + .gpio = AT91_PIN_PB10, + .active_low = 1, + .desc = "user_pb", + .wakeup = 1, + } +}; + +static struct gpio_keys_platform_data ek_button_data = { + .buttons = ek_buttons, + .nbuttons = ARRAY_SIZE(ek_buttons), +}; + +static struct platform_device ek_button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &ek_button_data, + } +}; + +static void __init ek_add_device_buttons(void) +{ + at91_set_GPIO_periph(AT91_PIN_PB10, 1); /* user push button, pull up enabled */ + at91_set_deglitch(AT91_PIN_PB10, 1); + + platform_device_register(&ek_button_device); +} +#else +static void __init ek_add_device_buttons(void) {} +#endif + +/* + * LEDs + */ +static struct gpio_led ek_leds[] = { + { /* user_led (green) */ + .name = "user_led", + .gpio = AT91_PIN_PB21, + .active_low = 0, + .default_trigger = "heartbeat", + } +}; + +static void __init ek_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* USB Host */ + at91_add_device_usbh(&ek_usbh_data); + /* USB Device */ + at91_add_device_udc(&ek_udc_data); + /* SPI */ + at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); + /* NAND */ + ek_add_device_nand(); + /* I2C */ + at91_add_device_i2c(NULL, 0); + /* Ethernet */ + at91_add_device_eth(&ek_macb_data); + /* MMC */ + at91_add_device_mmc(0, &ek_mmc_data); + /* Push Buttons */ + ek_add_device_buttons(); + /* LEDs */ + at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); + /* shutdown controller, wakeup button (5 msec low) */ + at91_sys_write(AT91_SHDW_MR, AT91_SHDW_CPTWK0_(10) | AT91_SHDW_WKMODE0_LOW + | AT91_SHDW_RTTWKEN); +} + +MACHINE_START(QIL_A9260, "CALAO QIL_A9260") + /* Maintainer: calao-systems */ + .timer = &at91sam926x_timer, + .map_io = at91sam9260_map_io, + .init_early = ek_init_early, + .init_irq = ek_init_irq, + .init_machine = ek_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-rm9200dk.c b/arch/arm/mach-at91/board-rm9200dk.c new file mode 100644 index 00000000..aef96277 --- /dev/null +++ b/arch/arm/mach-at91/board-rm9200dk.c @@ -0,0 +1,235 @@ +/* + * linux/arch/arm/mach-at91/board-rm9200dk.c + * + * Copyright (C) 2005 SAN People + * + * Epson S1D framebuffer glue code is: + * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org> + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> +#include <linux/mtd/physmap.h> + +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <mach/hardware.h> +#include <mach/board.h> +#include <mach/gpio.h> +#include <mach/at91rm9200_mc.h> + +#include "generic.h" + + +static void __init dk_init_early(void) +{ + /* Initialize processor: 18.432 MHz crystal */ + at91rm9200_initialize(18432000); + + /* Setup the LEDs */ + at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD + | ATMEL_UART_RI); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init dk_init_irq(void) +{ + at91rm9200_init_interrupts(NULL); +} + +static struct at91_eth_data __initdata dk_eth_data = { + .phy_irq_pin = AT91_PIN_PC4, + .is_rmii = 1, +}; + +static struct at91_usbh_data __initdata dk_usbh_data = { + .ports = 2, +}; + +static struct at91_udc_data __initdata dk_udc_data = { + .vbus_pin = AT91_PIN_PD4, + .pullup_pin = AT91_PIN_PD5, +}; + +static struct at91_cf_data __initdata dk_cf_data = { + .det_pin = AT91_PIN_PB0, + .rst_pin = AT91_PIN_PC5, + // .irq_pin = ... not connected + // .vcc_pin = ... always powered +}; + +#ifndef CONFIG_MTD_AT91_DATAFLASH_CARD +static struct at91_mmc_data __initdata dk_mmc_data = { + .slot_b = 0, + .wire4 = 1, +}; +#endif + +static struct spi_board_info dk_spi_devices[] = { + { /* DataFlash chip */ + .modalias = "mtd_dataflash", + .chip_select = 0, + .max_speed_hz = 15 * 1000 * 1000, + }, + { /* UR6HCPS2-SP40 PS2-to-SPI adapter */ + .modalias = "ur6hcps2", + .chip_select = 1, + .max_speed_hz = 250 * 1000, + }, + { /* TLV1504 ADC, 4 channels, 10 bits; one is a temp sensor */ + .modalias = "tlv1504", + .chip_select = 2, + .max_speed_hz = 20 * 1000 * 1000, + }, +#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD + { /* DataFlash card */ + .modalias = "mtd_dataflash", + .chip_select = 3, + .max_speed_hz = 15 * 1000 * 1000, + } +#endif +}; + +static struct i2c_board_info __initdata dk_i2c_devices[] = { + { + I2C_BOARD_INFO("ics1523", 0x26), + }, + { + I2C_BOARD_INFO("x9429", 0x28), + }, + { + I2C_BOARD_INFO("24c1024", 0x50), + } +}; + +static struct mtd_partition __initdata dk_nand_partition[] = { + { + .name = "NAND Partition 1", + .offset = 0, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(dk_nand_partition); + return dk_nand_partition; +} + +static struct atmel_nand_data __initdata dk_nand_data = { + .ale = 22, + .cle = 21, + .det_pin = AT91_PIN_PB1, + .rdy_pin = AT91_PIN_PC2, + // .enable_pin = ... not there + .partition_info = nand_partitions, +}; + +#define DK_FLASH_BASE AT91_CHIPSELECT_0 +#define DK_FLASH_SIZE SZ_2M + +static struct physmap_flash_data dk_flash_data = { + .width = 2, +}; + +static struct resource dk_flash_resource = { + .start = DK_FLASH_BASE, + .end = DK_FLASH_BASE + DK_FLASH_SIZE - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device dk_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &dk_flash_data, + }, + .resource = &dk_flash_resource, + .num_resources = 1, +}; + +static struct gpio_led dk_leds[] = { + { + .name = "led0", + .gpio = AT91_PIN_PB2, + .active_low = 1, + .default_trigger = "heartbeat", + } +}; + +static void __init dk_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* Ethernet */ + at91_add_device_eth(&dk_eth_data); + /* USB Host */ + at91_add_device_usbh(&dk_usbh_data); + /* USB Device */ + at91_add_device_udc(&dk_udc_data); + at91_set_multi_drive(dk_udc_data.pullup_pin, 1); /* pullup_pin is connected to reset */ + /* Compact Flash */ + at91_add_device_cf(&dk_cf_data); + /* I2C */ + at91_add_device_i2c(dk_i2c_devices, ARRAY_SIZE(dk_i2c_devices)); + /* SPI */ + at91_add_device_spi(dk_spi_devices, ARRAY_SIZE(dk_spi_devices)); +#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD + /* DataFlash card */ + at91_set_gpio_output(AT91_PIN_PB7, 0); +#else + /* MMC */ + at91_set_gpio_output(AT91_PIN_PB7, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */ + at91_add_device_mmc(0, &dk_mmc_data); +#endif + /* NAND */ + at91_add_device_nand(&dk_nand_data); + /* NOR Flash */ + platform_device_register(&dk_flash); + /* LEDs */ + at91_gpio_leds(dk_leds, ARRAY_SIZE(dk_leds)); + /* VGA */ +// dk_add_device_video(); +} + +MACHINE_START(AT91RM9200DK, "Atmel AT91RM9200-DK") + /* Maintainer: SAN People/Atmel */ + .timer = &at91rm9200_timer, + .map_io = at91rm9200_map_io, + .init_early = dk_init_early, + .init_irq = dk_init_irq, + .init_machine = dk_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-rm9200ek.c b/arch/arm/mach-at91/board-rm9200ek.c new file mode 100644 index 00000000..015a0218 --- /dev/null +++ b/arch/arm/mach-at91/board-rm9200ek.c @@ -0,0 +1,201 @@ +/* + * linux/arch/arm/mach-at91/board-rm9200ek.c + * + * Copyright (C) 2005 SAN People + * + * Epson S1D framebuffer glue code is: + * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org> + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> +#include <linux/mtd/physmap.h> + +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <mach/hardware.h> +#include <mach/board.h> +#include <mach/gpio.h> +#include <mach/at91rm9200_mc.h> + +#include "generic.h" + + +static void __init ek_init_early(void) +{ + /* Initialize processor: 18.432 MHz crystal */ + at91rm9200_initialize(18432000); + + /* Setup the LEDs */ + at91_init_leds(AT91_PIN_PB1, AT91_PIN_PB2); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD + | ATMEL_UART_RI); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init ek_init_irq(void) +{ + at91rm9200_init_interrupts(NULL); +} + +static struct at91_eth_data __initdata ek_eth_data = { + .phy_irq_pin = AT91_PIN_PC4, + .is_rmii = 1, +}; + +static struct at91_usbh_data __initdata ek_usbh_data = { + .ports = 2, +}; + +static struct at91_udc_data __initdata ek_udc_data = { + .vbus_pin = AT91_PIN_PD4, + .pullup_pin = AT91_PIN_PD5, +}; + +#ifndef CONFIG_MTD_AT91_DATAFLASH_CARD +static struct at91_mmc_data __initdata ek_mmc_data = { + .det_pin = AT91_PIN_PB27, + .slot_b = 0, + .wire4 = 1, + .wp_pin = AT91_PIN_PA17, +}; +#endif + +static struct spi_board_info ek_spi_devices[] = { + { /* DataFlash chip */ + .modalias = "mtd_dataflash", + .chip_select = 0, + .max_speed_hz = 15 * 1000 * 1000, + }, +#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD + { /* DataFlash card */ + .modalias = "mtd_dataflash", + .chip_select = 3, + .max_speed_hz = 15 * 1000 * 1000, + }, +#endif +}; + +static struct i2c_board_info __initdata ek_i2c_devices[] = { + { + I2C_BOARD_INFO("ics1523", 0x26), + }, + { + I2C_BOARD_INFO("dac3550", 0x4d), + } +}; + +#define EK_FLASH_BASE AT91_CHIPSELECT_0 +#define EK_FLASH_SIZE SZ_2M + +static struct physmap_flash_data ek_flash_data = { + .width = 2, +}; + +static struct resource ek_flash_resource = { + .start = EK_FLASH_BASE, + .end = EK_FLASH_BASE + EK_FLASH_SIZE - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device ek_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &ek_flash_data, + }, + .resource = &ek_flash_resource, + .num_resources = 1, +}; + +static struct gpio_led ek_leds[] = { + { /* "user led 1", DS2 */ + .name = "green", + .gpio = AT91_PIN_PB0, + .active_low = 1, + .default_trigger = "mmc0", + }, + { /* "user led 2", DS4 */ + .name = "yellow", + .gpio = AT91_PIN_PB1, + .active_low = 1, + .default_trigger = "heartbeat", + }, + { /* "user led 3", DS6 */ + .name = "red", + .gpio = AT91_PIN_PB2, + .active_low = 1, + } +}; + +static void __init ek_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* Ethernet */ + at91_add_device_eth(&ek_eth_data); + /* USB Host */ + at91_add_device_usbh(&ek_usbh_data); + /* USB Device */ + at91_add_device_udc(&ek_udc_data); + at91_set_multi_drive(ek_udc_data.pullup_pin, 1); /* pullup_pin is connected to reset */ + /* I2C */ + at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices)); + /* SPI */ + at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); +#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD + /* DataFlash card */ + at91_set_gpio_output(AT91_PIN_PB22, 0); +#else + /* MMC */ + at91_set_gpio_output(AT91_PIN_PB22, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */ + at91_add_device_mmc(0, &ek_mmc_data); +#endif + /* NOR Flash */ + platform_device_register(&ek_flash); + /* LEDs */ + at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); + /* VGA */ +// ek_add_device_video(); +} + +MACHINE_START(AT91RM9200EK, "Atmel AT91RM9200-EK") + /* Maintainer: SAN People/Atmel */ + .timer = &at91rm9200_timer, + .map_io = at91rm9200_map_io, + .init_early = ek_init_early, + .init_irq = ek_init_irq, + .init_machine = ek_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-sam9-l9260.c b/arch/arm/mach-at91/board-sam9-l9260.c new file mode 100644 index 00000000..aaf1bf09 --- /dev/null +++ b/arch/arm/mach-at91/board-sam9-l9260.c @@ -0,0 +1,220 @@ +/* + * linux/arch/arm/mach-at91/board-sam9-l9260.c + * + * Copyright (C) 2005 SAN People + * Copyright (C) 2006 Atmel + * Copyright (C) 2007 Olimex Ltd + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> + +#include <mach/hardware.h> +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <mach/board.h> +#include <mach/gpio.h> +#include <mach/at91sam9_smc.h> + +#include "sam9_smc.h" +#include "generic.h" + + +static void __init ek_init_early(void) +{ + /* Initialize processor: 18.432 MHz crystal */ + at91sam9260_initialize(18432000); + + /* Setup the LEDs */ + at91_init_leds(AT91_PIN_PA9, AT91_PIN_PA6); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD + | ATMEL_UART_RI); + + /* USART1 on ttyS2. (Rx, Tx, CTS, RTS) */ + at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init ek_init_irq(void) +{ + at91sam9260_init_interrupts(NULL); +} + + +/* + * USB Host port + */ +static struct at91_usbh_data __initdata ek_usbh_data = { + .ports = 2, +}; + +/* + * USB Device port + */ +static struct at91_udc_data __initdata ek_udc_data = { + .vbus_pin = AT91_PIN_PC5, + .pullup_pin = 0, /* pull-up driven by UDC */ +}; + + +/* + * SPI devices. + */ +static struct spi_board_info ek_spi_devices[] = { +#if !defined(CONFIG_MMC_AT91) + { /* DataFlash chip */ + .modalias = "mtd_dataflash", + .chip_select = 1, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD) + { /* DataFlash card */ + .modalias = "mtd_dataflash", + .chip_select = 0, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +#endif +#endif +}; + + +/* + * MACB Ethernet device + */ +static struct at91_eth_data __initdata ek_macb_data = { + .phy_irq_pin = AT91_PIN_PA7, + .is_rmii = 0, +}; + + +/* + * NAND flash + */ +static struct mtd_partition __initdata ek_nand_partition[] = { + { + .name = "Bootloader Area", + .offset = 0, + .size = 10 * SZ_1M, + }, + { + .name = "User Area", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(ek_nand_partition); + return ek_nand_partition; +} + +static struct atmel_nand_data __initdata ek_nand_data = { + .ale = 21, + .cle = 22, +// .det_pin = ... not connected + .rdy_pin = AT91_PIN_PC13, + .enable_pin = AT91_PIN_PC14, + .partition_info = nand_partitions, +}; + +static struct sam9_smc_config __initdata ek_nand_smc_config = { + .ncs_read_setup = 0, + .nrd_setup = 1, + .ncs_write_setup = 0, + .nwe_setup = 1, + + .ncs_read_pulse = 3, + .nrd_pulse = 3, + .ncs_write_pulse = 3, + .nwe_pulse = 3, + + .read_cycle = 5, + .write_cycle = 5, + + .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8, + .tdf_cycles = 2, +}; + +static void __init ek_add_device_nand(void) +{ + /* configure chip-select 3 (NAND) */ + sam9_smc_configure(3, &ek_nand_smc_config); + + at91_add_device_nand(&ek_nand_data); +} + + +/* + * MCI (SD/MMC) + */ +static struct at91_mmc_data __initdata ek_mmc_data = { + .slot_b = 1, + .wire4 = 1, + .det_pin = AT91_PIN_PC8, + .wp_pin = AT91_PIN_PC4, +// .vcc_pin = ... not connected +}; + +static void __init ek_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* USB Host */ + at91_add_device_usbh(&ek_usbh_data); + /* USB Device */ + at91_add_device_udc(&ek_udc_data); + /* SPI */ + at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); + /* NAND */ + ek_add_device_nand(); + /* Ethernet */ + at91_add_device_eth(&ek_macb_data); + /* MMC */ + at91_add_device_mmc(0, &ek_mmc_data); + /* I2C */ + at91_add_device_i2c(NULL, 0); +} + +MACHINE_START(SAM9_L9260, "Olimex SAM9-L9260") + /* Maintainer: Olimex */ + .timer = &at91sam926x_timer, + .map_io = at91sam9260_map_io, + .init_early = ek_init_early, + .init_irq = ek_init_irq, + .init_machine = ek_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-sam9260ek.c b/arch/arm/mach-at91/board-sam9260ek.c new file mode 100644 index 00000000..5c240743 --- /dev/null +++ b/arch/arm/mach-at91/board-sam9260ek.c @@ -0,0 +1,361 @@ +/* + * linux/arch/arm/mach-at91/board-sam9260ek.c + * + * Copyright (C) 2005 SAN People + * Copyright (C) 2006 Atmel + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> +#include <linux/spi/at73c213.h> +#include <linux/clk.h> +#include <linux/i2c/at24.h> +#include <linux/gpio_keys.h> +#include <linux/input.h> + +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <mach/hardware.h> +#include <mach/board.h> +#include <mach/gpio.h> +#include <mach/at91sam9_smc.h> +#include <mach/at91_shdwc.h> +#include <mach/system_rev.h> + +#include "sam9_smc.h" +#include "generic.h" + + +static void __init ek_init_early(void) +{ + /* Initialize processor: 18.432 MHz crystal */ + at91sam9260_initialize(18432000); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD + | ATMEL_UART_RI); + + /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */ + at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init ek_init_irq(void) +{ + at91sam9260_init_interrupts(NULL); +} + + +/* + * USB Host port + */ +static struct at91_usbh_data __initdata ek_usbh_data = { + .ports = 2, +}; + +/* + * USB Device port + */ +static struct at91_udc_data __initdata ek_udc_data = { + .vbus_pin = AT91_PIN_PC5, + .pullup_pin = 0, /* pull-up driven by UDC */ +}; + + +/* + * Audio + */ +static struct at73c213_board_info at73c213_data = { + .ssc_id = 0, + .shortname = "AT91SAM9260-EK external DAC", +}; + +#if defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE) +static void __init at73c213_set_clk(struct at73c213_board_info *info) +{ + struct clk *pck0; + struct clk *plla; + + pck0 = clk_get(NULL, "pck0"); + plla = clk_get(NULL, "plla"); + + /* AT73C213 MCK Clock */ + at91_set_B_periph(AT91_PIN_PC1, 0); /* PCK0 */ + + clk_set_parent(pck0, plla); + clk_put(plla); + + info->dac_clk = pck0; +} +#else +static void __init at73c213_set_clk(struct at73c213_board_info *info) {} +#endif + +/* + * SPI devices. + */ +static struct spi_board_info ek_spi_devices[] = { +#if !defined(CONFIG_MMC_AT91) + { /* DataFlash chip */ + .modalias = "mtd_dataflash", + .chip_select = 1, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD) + { /* DataFlash card */ + .modalias = "mtd_dataflash", + .chip_select = 0, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +#endif +#endif +#if defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE) + { /* AT73C213 DAC */ + .modalias = "at73c213", + .chip_select = 0, + .max_speed_hz = 10 * 1000 * 1000, + .bus_num = 1, + .mode = SPI_MODE_1, + .platform_data = &at73c213_data, + }, +#endif +}; + + +/* + * MACB Ethernet device + */ +static struct at91_eth_data __initdata ek_macb_data = { + .phy_irq_pin = AT91_PIN_PA7, + .is_rmii = 1, +}; + + +/* + * NAND flash + */ +static struct mtd_partition __initdata ek_nand_partition[] = { + { + .name = "Partition 1", + .offset = 0, + .size = SZ_256K, + }, + { + .name = "Partition 2", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(ek_nand_partition); + return ek_nand_partition; +} + +static struct atmel_nand_data __initdata ek_nand_data = { + .ale = 21, + .cle = 22, +// .det_pin = ... not connected + .rdy_pin = AT91_PIN_PC13, + .enable_pin = AT91_PIN_PC14, + .partition_info = nand_partitions, +}; + +static struct sam9_smc_config __initdata ek_nand_smc_config = { + .ncs_read_setup = 0, + .nrd_setup = 1, + .ncs_write_setup = 0, + .nwe_setup = 1, + + .ncs_read_pulse = 3, + .nrd_pulse = 3, + .ncs_write_pulse = 3, + .nwe_pulse = 3, + + .read_cycle = 5, + .write_cycle = 5, + + .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE, + .tdf_cycles = 2, +}; + +static void __init ek_add_device_nand(void) +{ + ek_nand_data.bus_width_16 = board_have_nand_16bit(); + /* setup bus-width (8 or 16) */ + if (ek_nand_data.bus_width_16) + ek_nand_smc_config.mode |= AT91_SMC_DBW_16; + else + ek_nand_smc_config.mode |= AT91_SMC_DBW_8; + + /* configure chip-select 3 (NAND) */ + sam9_smc_configure(3, &ek_nand_smc_config); + + at91_add_device_nand(&ek_nand_data); +} + + +/* + * MCI (SD/MMC) + */ +static struct at91_mmc_data __initdata ek_mmc_data = { + .slot_b = 1, + .wire4 = 1, +// .det_pin = ... not connected +// .wp_pin = ... not connected +// .vcc_pin = ... not connected +}; + + +/* + * LEDs + */ +static struct gpio_led ek_leds[] = { + { /* "bottom" led, green, userled1 to be defined */ + .name = "ds5", + .gpio = AT91_PIN_PA6, + .active_low = 1, + .default_trigger = "none", + }, + { /* "power" led, yellow */ + .name = "ds1", + .gpio = AT91_PIN_PA9, + .default_trigger = "heartbeat", + } +}; + +/* + * I2C devices + */ +static struct at24_platform_data at24c512 = { + .byte_len = SZ_512K / 8, + .page_size = 128, + .flags = AT24_FLAG_ADDR16, +}; + +static struct i2c_board_info __initdata ek_i2c_devices[] = { + { + I2C_BOARD_INFO("24c512", 0x50), + .platform_data = &at24c512, + }, + /* more devices can be added using expansion connectors */ +}; + + +/* + * GPIO Buttons + */ +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +static struct gpio_keys_button ek_buttons[] = { + { + .gpio = AT91_PIN_PA30, + .code = BTN_3, + .desc = "Button 3", + .active_low = 1, + .wakeup = 1, + }, + { + .gpio = AT91_PIN_PA31, + .code = BTN_4, + .desc = "Button 4", + .active_low = 1, + .wakeup = 1, + } +}; + +static struct gpio_keys_platform_data ek_button_data = { + .buttons = ek_buttons, + .nbuttons = ARRAY_SIZE(ek_buttons), +}; + +static struct platform_device ek_button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &ek_button_data, + } +}; + +static void __init ek_add_device_buttons(void) +{ + at91_set_gpio_input(AT91_PIN_PA30, 1); /* btn3 */ + at91_set_deglitch(AT91_PIN_PA30, 1); + at91_set_gpio_input(AT91_PIN_PA31, 1); /* btn4 */ + at91_set_deglitch(AT91_PIN_PA31, 1); + + platform_device_register(&ek_button_device); +} +#else +static void __init ek_add_device_buttons(void) {} +#endif + + +static void __init ek_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* USB Host */ + at91_add_device_usbh(&ek_usbh_data); + /* USB Device */ + at91_add_device_udc(&ek_udc_data); + /* SPI */ + at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); + /* NAND */ + ek_add_device_nand(); + /* Ethernet */ + at91_add_device_eth(&ek_macb_data); + /* MMC */ + at91_add_device_mmc(0, &ek_mmc_data); + /* I2C */ + at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices)); + /* SSC (to AT73C213) */ + at73c213_set_clk(&at73c213_data); + at91_add_device_ssc(AT91SAM9260_ID_SSC, ATMEL_SSC_TX); + /* LEDs */ + at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); + /* Push Buttons */ + ek_add_device_buttons(); +} + +MACHINE_START(AT91SAM9260EK, "Atmel AT91SAM9260-EK") + /* Maintainer: Atmel */ + .timer = &at91sam926x_timer, + .map_io = at91sam9260_map_io, + .init_early = ek_init_early, + .init_irq = ek_init_irq, + .init_machine = ek_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c new file mode 100644 index 00000000..b60c22b6 --- /dev/null +++ b/arch/arm/mach-at91/board-sam9261ek.c @@ -0,0 +1,628 @@ +/* + * linux/arch/arm/mach-at91/board-sam9261ek.c + * + * Copyright (C) 2005 SAN People + * Copyright (C) 2006 Atmel + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> +#include <linux/spi/ads7846.h> +#include <linux/spi/at73c213.h> +#include <linux/clk.h> +#include <linux/dm9000.h> +#include <linux/fb.h> +#include <linux/gpio_keys.h> +#include <linux/input.h> + +#include <video/atmel_lcdc.h> + +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <mach/hardware.h> +#include <mach/board.h> +#include <mach/gpio.h> +#include <mach/at91sam9_smc.h> +#include <mach/at91_shdwc.h> +#include <mach/system_rev.h> + +#include "sam9_smc.h" +#include "generic.h" + + +static void __init ek_init_early(void) +{ + /* Initialize processor: 18.432 MHz crystal */ + at91sam9261_initialize(18432000); + + /* Setup the LEDs */ + at91_init_leds(AT91_PIN_PA13, AT91_PIN_PA14); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init ek_init_irq(void) +{ + at91sam9261_init_interrupts(NULL); +} + + +/* + * DM9000 ethernet device + */ +#if defined(CONFIG_DM9000) +static struct resource dm9000_resource[] = { + [0] = { + .start = AT91_CHIPSELECT_2, + .end = AT91_CHIPSELECT_2 + 3, + .flags = IORESOURCE_MEM + }, + [1] = { + .start = AT91_CHIPSELECT_2 + 0x44, + .end = AT91_CHIPSELECT_2 + 0xFF, + .flags = IORESOURCE_MEM + }, + [2] = { + .start = AT91_PIN_PC11, + .end = AT91_PIN_PC11, + .flags = IORESOURCE_IRQ + | IORESOURCE_IRQ_LOWEDGE | IORESOURCE_IRQ_HIGHEDGE, + } +}; + +static struct dm9000_plat_data dm9000_platdata = { + .flags = DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM, +}; + +static struct platform_device dm9000_device = { + .name = "dm9000", + .id = 0, + .num_resources = ARRAY_SIZE(dm9000_resource), + .resource = dm9000_resource, + .dev = { + .platform_data = &dm9000_platdata, + } +}; + +/* + * SMC timings for the DM9000. + * Note: These timings were calculated for MASTER_CLOCK = 100000000 according to the DM9000 timings. + */ +static struct sam9_smc_config __initdata dm9000_smc_config = { + .ncs_read_setup = 0, + .nrd_setup = 2, + .ncs_write_setup = 0, + .nwe_setup = 2, + + .ncs_read_pulse = 8, + .nrd_pulse = 4, + .ncs_write_pulse = 8, + .nwe_pulse = 4, + + .read_cycle = 16, + .write_cycle = 16, + + .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_WRITE | AT91_SMC_DBW_16, + .tdf_cycles = 1, +}; + +static void __init ek_add_device_dm9000(void) +{ + /* Configure chip-select 2 (DM9000) */ + sam9_smc_configure(2, &dm9000_smc_config); + + /* Configure Reset signal as output */ + at91_set_gpio_output(AT91_PIN_PC10, 0); + + /* Configure Interrupt pin as input, no pull-up */ + at91_set_gpio_input(AT91_PIN_PC11, 0); + + platform_device_register(&dm9000_device); +} +#else +static void __init ek_add_device_dm9000(void) {} +#endif /* CONFIG_DM9000 */ + + +/* + * USB Host Port + */ +static struct at91_usbh_data __initdata ek_usbh_data = { + .ports = 2, +}; + + +/* + * USB Device Port + */ +static struct at91_udc_data __initdata ek_udc_data = { + .vbus_pin = AT91_PIN_PB29, + .pullup_pin = 0, /* pull-up driven by UDC */ +}; + + +/* + * NAND flash + */ +static struct mtd_partition __initdata ek_nand_partition[] = { + { + .name = "Partition 1", + .offset = 0, + .size = SZ_256K, + }, + { + .name = "Partition 2", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(ek_nand_partition); + return ek_nand_partition; +} + +static struct atmel_nand_data __initdata ek_nand_data = { + .ale = 22, + .cle = 21, +// .det_pin = ... not connected + .rdy_pin = AT91_PIN_PC15, + .enable_pin = AT91_PIN_PC14, + .partition_info = nand_partitions, +}; + +static struct sam9_smc_config __initdata ek_nand_smc_config = { + .ncs_read_setup = 0, + .nrd_setup = 1, + .ncs_write_setup = 0, + .nwe_setup = 1, + + .ncs_read_pulse = 3, + .nrd_pulse = 3, + .ncs_write_pulse = 3, + .nwe_pulse = 3, + + .read_cycle = 5, + .write_cycle = 5, + + .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE, + .tdf_cycles = 2, +}; + +static void __init ek_add_device_nand(void) +{ + ek_nand_data.bus_width_16 = board_have_nand_16bit(); + /* setup bus-width (8 or 16) */ + if (ek_nand_data.bus_width_16) + ek_nand_smc_config.mode |= AT91_SMC_DBW_16; + else + ek_nand_smc_config.mode |= AT91_SMC_DBW_8; + + /* configure chip-select 3 (NAND) */ + sam9_smc_configure(3, &ek_nand_smc_config); + + at91_add_device_nand(&ek_nand_data); +} + +/* + * SPI related devices + */ +#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) + +/* + * ADS7846 Touchscreen + */ +#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) + +static int ads7843_pendown_state(void) +{ + return !at91_get_gpio_value(AT91_PIN_PC2); /* Touchscreen PENIRQ */ +} + +static struct ads7846_platform_data ads_info = { + .model = 7843, + .x_min = 150, + .x_max = 3830, + .y_min = 190, + .y_max = 3830, + .vref_delay_usecs = 100, + .x_plate_ohms = 450, + .y_plate_ohms = 250, + .pressure_max = 15000, + .debounce_max = 1, + .debounce_rep = 0, + .debounce_tol = (~0), + .get_pendown_state = ads7843_pendown_state, +}; + +static void __init ek_add_device_ts(void) +{ + at91_set_B_periph(AT91_PIN_PC2, 1); /* External IRQ0, with pullup */ + at91_set_gpio_input(AT91_PIN_PA11, 1); /* Touchscreen BUSY signal */ +} +#else +static void __init ek_add_device_ts(void) {} +#endif + +/* + * Audio + */ +static struct at73c213_board_info at73c213_data = { + .ssc_id = 1, +#if defined(CONFIG_MACH_AT91SAM9261EK) + .shortname = "AT91SAM9261-EK external DAC", +#else + .shortname = "AT91SAM9G10-EK external DAC", +#endif +}; + +#if defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE) +static void __init at73c213_set_clk(struct at73c213_board_info *info) +{ + struct clk *pck2; + struct clk *plla; + + pck2 = clk_get(NULL, "pck2"); + plla = clk_get(NULL, "plla"); + + /* AT73C213 MCK Clock */ + at91_set_B_periph(AT91_PIN_PB31, 0); /* PCK2 */ + + clk_set_parent(pck2, plla); + clk_put(plla); + + info->dac_clk = pck2; +} +#else +static void __init at73c213_set_clk(struct at73c213_board_info *info) {} +#endif + +/* + * SPI devices + */ +static struct spi_board_info ek_spi_devices[] = { + { /* DataFlash chip */ + .modalias = "mtd_dataflash", + .chip_select = 0, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) + { + .modalias = "ads7846", + .chip_select = 2, + .max_speed_hz = 125000 * 26, /* (max sample rate @ 3V) * (cmd + data + overhead) */ + .bus_num = 0, + .platform_data = &ads_info, + .irq = AT91SAM9261_ID_IRQ0, + .controller_data = (void *) AT91_PIN_PA28, /* CS pin */ + }, +#endif +#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD) + { /* DataFlash card - jumper (J12) configurable to CS3 or CS0 */ + .modalias = "mtd_dataflash", + .chip_select = 3, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +#elif defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE) + { /* AT73C213 DAC */ + .modalias = "at73c213", + .chip_select = 3, + .max_speed_hz = 10 * 1000 * 1000, + .bus_num = 0, + .mode = SPI_MODE_1, + .platform_data = &at73c213_data, + .controller_data = (void*) AT91_PIN_PA29, /* default for CS3 is PA6, but it must be PA29 */ + }, +#endif +}; + +#else /* CONFIG_SPI_ATMEL_* */ +/* spi0 and mmc/sd share the same PIO pins: cannot be used at the same time */ + +/* + * MCI (SD/MMC) + * det_pin, wp_pin and vcc_pin are not connected + */ +static struct at91_mmc_data __initdata ek_mmc_data = { + .wire4 = 1, +}; + +#endif /* CONFIG_SPI_ATMEL_* */ + + +/* + * LCD Controller + */ +#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) + +#if defined(CONFIG_FB_ATMEL_STN) + +/* STN */ +static struct fb_videomode at91_stn_modes[] = { + { + .name = "SP06Q002 @ 75", + .refresh = 75, + .xres = 320, .yres = 240, + .pixclock = KHZ2PICOS(1440), + + .left_margin = 1, .right_margin = 1, + .upper_margin = 0, .lower_margin = 0, + .hsync_len = 1, .vsync_len = 1, + + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = FB_VMODE_NONINTERLACED, + }, +}; + +static struct fb_monspecs at91fb_default_stn_monspecs = { + .manufacturer = "HIT", + .monitor = "SP06Q002", + + .modedb = at91_stn_modes, + .modedb_len = ARRAY_SIZE(at91_stn_modes), + .hfmin = 15000, + .hfmax = 64000, + .vfmin = 50, + .vfmax = 150, +}; + +#define AT91SAM9261_DEFAULT_STN_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \ + | ATMEL_LCDC_DISTYPE_STNMONO \ + | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE \ + | ATMEL_LCDC_IFWIDTH_4 \ + | ATMEL_LCDC_SCANMOD_SINGLE) + +static void at91_lcdc_stn_power_control(int on) +{ + /* backlight */ + if (on) { /* power up */ + at91_set_gpio_value(AT91_PIN_PC14, 0); + at91_set_gpio_value(AT91_PIN_PC15, 0); + } else { /* power down */ + at91_set_gpio_value(AT91_PIN_PC14, 1); + at91_set_gpio_value(AT91_PIN_PC15, 1); + } +} + +static struct atmel_lcdfb_info __initdata ek_lcdc_data = { + .default_bpp = 1, + .default_dmacon = ATMEL_LCDC_DMAEN, + .default_lcdcon2 = AT91SAM9261_DEFAULT_STN_LCDCON2, + .default_monspecs = &at91fb_default_stn_monspecs, + .atmel_lcdfb_power_control = at91_lcdc_stn_power_control, + .guard_time = 1, +#if defined(CONFIG_MACH_AT91SAM9G10EK) + .lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB, +#endif +}; + +#else + +/* TFT */ +static struct fb_videomode at91_tft_vga_modes[] = { + { + .name = "TX09D50VM1CCA @ 60", + .refresh = 60, + .xres = 240, .yres = 320, + .pixclock = KHZ2PICOS(4965), + + .left_margin = 1, .right_margin = 33, + .upper_margin = 1, .lower_margin = 0, + .hsync_len = 5, .vsync_len = 1, + + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = FB_VMODE_NONINTERLACED, + }, +}; + +static struct fb_monspecs at91fb_default_tft_monspecs = { + .manufacturer = "HIT", + .monitor = "TX09D50VM1CCA", + + .modedb = at91_tft_vga_modes, + .modedb_len = ARRAY_SIZE(at91_tft_vga_modes), + .hfmin = 15000, + .hfmax = 64000, + .vfmin = 50, + .vfmax = 150, +}; + +#define AT91SAM9261_DEFAULT_TFT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \ + | ATMEL_LCDC_DISTYPE_TFT \ + | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE) + +static void at91_lcdc_tft_power_control(int on) +{ + if (on) + at91_set_gpio_value(AT91_PIN_PA12, 0); /* power up */ + else + at91_set_gpio_value(AT91_PIN_PA12, 1); /* power down */ +} + +static struct atmel_lcdfb_info __initdata ek_lcdc_data = { + .lcdcon_is_backlight = true, + .default_bpp = 16, + .default_dmacon = ATMEL_LCDC_DMAEN, + .default_lcdcon2 = AT91SAM9261_DEFAULT_TFT_LCDCON2, + .default_monspecs = &at91fb_default_tft_monspecs, + .atmel_lcdfb_power_control = at91_lcdc_tft_power_control, + .guard_time = 1, +#if defined(CONFIG_MACH_AT91SAM9G10EK) + .lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB, +#endif +}; +#endif + +#else +static struct atmel_lcdfb_info __initdata ek_lcdc_data; +#endif + + +/* + * GPIO Buttons + */ +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +static struct gpio_keys_button ek_buttons[] = { + { + .gpio = AT91_PIN_PA27, + .code = BTN_0, + .desc = "Button 0", + .active_low = 1, + .wakeup = 1, + }, + { + .gpio = AT91_PIN_PA26, + .code = BTN_1, + .desc = "Button 1", + .active_low = 1, + .wakeup = 1, + }, + { + .gpio = AT91_PIN_PA25, + .code = BTN_2, + .desc = "Button 2", + .active_low = 1, + .wakeup = 1, + }, + { + .gpio = AT91_PIN_PA24, + .code = BTN_3, + .desc = "Button 3", + .active_low = 1, + .wakeup = 1, + } +}; + +static struct gpio_keys_platform_data ek_button_data = { + .buttons = ek_buttons, + .nbuttons = ARRAY_SIZE(ek_buttons), +}; + +static struct platform_device ek_button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &ek_button_data, + } +}; + +static void __init ek_add_device_buttons(void) +{ + at91_set_gpio_input(AT91_PIN_PA27, 1); /* btn0 */ + at91_set_deglitch(AT91_PIN_PA27, 1); + at91_set_gpio_input(AT91_PIN_PA26, 1); /* btn1 */ + at91_set_deglitch(AT91_PIN_PA26, 1); + at91_set_gpio_input(AT91_PIN_PA25, 1); /* btn2 */ + at91_set_deglitch(AT91_PIN_PA25, 1); + at91_set_gpio_input(AT91_PIN_PA24, 1); /* btn3 */ + at91_set_deglitch(AT91_PIN_PA24, 1); + + platform_device_register(&ek_button_device); +} +#else +static void __init ek_add_device_buttons(void) {} +#endif + +/* + * LEDs + */ +static struct gpio_led ek_leds[] = { + { /* "bottom" led, green, userled1 to be defined */ + .name = "ds7", + .gpio = AT91_PIN_PA14, + .active_low = 1, + .default_trigger = "none", + }, + { /* "top" led, green, userled2 to be defined */ + .name = "ds8", + .gpio = AT91_PIN_PA13, + .active_low = 1, + .default_trigger = "none", + }, + { /* "power" led, yellow */ + .name = "ds1", + .gpio = AT91_PIN_PA23, + .default_trigger = "heartbeat", + } +}; + +static void __init ek_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* USB Host */ + at91_add_device_usbh(&ek_usbh_data); + /* USB Device */ + at91_add_device_udc(&ek_udc_data); + /* I2C */ + at91_add_device_i2c(NULL, 0); + /* NAND */ + ek_add_device_nand(); + /* DM9000 ethernet */ + ek_add_device_dm9000(); + + /* spi0 and mmc/sd share the same PIO pins */ +#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) + /* SPI */ + at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); + /* Touchscreen */ + ek_add_device_ts(); + /* SSC (to AT73C213) */ + at73c213_set_clk(&at73c213_data); + at91_add_device_ssc(AT91SAM9261_ID_SSC1, ATMEL_SSC_TX); +#else + /* MMC */ + at91_add_device_mmc(0, &ek_mmc_data); +#endif + /* LCD Controller */ + at91_add_device_lcdc(&ek_lcdc_data); + /* Push Buttons */ + ek_add_device_buttons(); + /* LEDs */ + at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); +} + +#if defined(CONFIG_MACH_AT91SAM9261EK) +MACHINE_START(AT91SAM9261EK, "Atmel AT91SAM9261-EK") +#else +MACHINE_START(AT91SAM9G10EK, "Atmel AT91SAM9G10-EK") +#endif + /* Maintainer: Atmel */ + .timer = &at91sam926x_timer, + .map_io = at91sam9261_map_io, + .init_early = ek_init_early, + .init_irq = ek_init_irq, + .init_machine = ek_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c new file mode 100644 index 00000000..9bbdc92e --- /dev/null +++ b/arch/arm/mach-at91/board-sam9263ek.c @@ -0,0 +1,459 @@ +/* + * linux/arch/arm/mach-at91/board-sam9263ek.c + * + * Copyright (C) 2005 SAN People + * Copyright (C) 2007 Atmel Corporation. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> +#include <linux/spi/ads7846.h> +#include <linux/i2c/at24.h> +#include <linux/fb.h> +#include <linux/gpio_keys.h> +#include <linux/input.h> +#include <linux/leds.h> + +#include <video/atmel_lcdc.h> + +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <mach/hardware.h> +#include <mach/board.h> +#include <mach/gpio.h> +#include <mach/at91sam9_smc.h> +#include <mach/at91_shdwc.h> +#include <mach/system_rev.h> + +#include "sam9_smc.h" +#include "generic.h" + + +static void __init ek_init_early(void) +{ + /* Initialize processor: 16.367 MHz crystal */ + at91sam9263_initialize(16367660); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1. (Rx, Tx, RTS, CTS) */ + at91_register_uart(AT91SAM9263_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init ek_init_irq(void) +{ + at91sam9263_init_interrupts(NULL); +} + + +/* + * USB Host port + */ +static struct at91_usbh_data __initdata ek_usbh_data = { + .ports = 2, + .vbus_pin = { AT91_PIN_PA24, AT91_PIN_PA21 }, +}; + +/* + * USB Device port + */ +static struct at91_udc_data __initdata ek_udc_data = { + .vbus_pin = AT91_PIN_PA25, + .pullup_pin = 0, /* pull-up driven by UDC */ +}; + + +/* + * ADS7846 Touchscreen + */ +#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) +static int ads7843_pendown_state(void) +{ + return !at91_get_gpio_value(AT91_PIN_PA15); /* Touchscreen PENIRQ */ +} + +static struct ads7846_platform_data ads_info = { + .model = 7843, + .x_min = 150, + .x_max = 3830, + .y_min = 190, + .y_max = 3830, + .vref_delay_usecs = 100, + .x_plate_ohms = 450, + .y_plate_ohms = 250, + .pressure_max = 15000, + .debounce_max = 1, + .debounce_rep = 0, + .debounce_tol = (~0), + .get_pendown_state = ads7843_pendown_state, +}; + +static void __init ek_add_device_ts(void) +{ + at91_set_B_periph(AT91_PIN_PA15, 1); /* External IRQ1, with pullup */ + at91_set_gpio_input(AT91_PIN_PA31, 1); /* Touchscreen BUSY signal */ +} +#else +static void __init ek_add_device_ts(void) {} +#endif + +/* + * SPI devices. + */ +static struct spi_board_info ek_spi_devices[] = { +#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD) + { /* DataFlash card */ + .modalias = "mtd_dataflash", + .chip_select = 0, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +#endif +#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) + { + .modalias = "ads7846", + .chip_select = 3, + .max_speed_hz = 125000 * 26, /* (max sample rate @ 3V) * (cmd + data + overhead) */ + .bus_num = 0, + .platform_data = &ads_info, + .irq = AT91SAM9263_ID_IRQ1, + }, +#endif +}; + + +/* + * MCI (SD/MMC) + */ +static struct at91_mmc_data __initdata ek_mmc_data = { + .wire4 = 1, + .det_pin = AT91_PIN_PE18, + .wp_pin = AT91_PIN_PE19, +// .vcc_pin = ... not connected +}; + + +/* + * MACB Ethernet device + */ +static struct at91_eth_data __initdata ek_macb_data = { + .phy_irq_pin = AT91_PIN_PE31, + .is_rmii = 1, +}; + + +/* + * NAND flash + */ +static struct mtd_partition __initdata ek_nand_partition[] = { + { + .name = "Partition 1", + .offset = 0, + .size = SZ_64M, + }, + { + .name = "Partition 2", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(ek_nand_partition); + return ek_nand_partition; +} + +static struct atmel_nand_data __initdata ek_nand_data = { + .ale = 21, + .cle = 22, +// .det_pin = ... not connected + .rdy_pin = AT91_PIN_PA22, + .enable_pin = AT91_PIN_PD15, + .partition_info = nand_partitions, +}; + +static struct sam9_smc_config __initdata ek_nand_smc_config = { + .ncs_read_setup = 0, + .nrd_setup = 1, + .ncs_write_setup = 0, + .nwe_setup = 1, + + .ncs_read_pulse = 3, + .nrd_pulse = 3, + .ncs_write_pulse = 3, + .nwe_pulse = 3, + + .read_cycle = 5, + .write_cycle = 5, + + .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE, + .tdf_cycles = 2, +}; + +static void __init ek_add_device_nand(void) +{ + ek_nand_data.bus_width_16 = board_have_nand_16bit(); + /* setup bus-width (8 or 16) */ + if (ek_nand_data.bus_width_16) + ek_nand_smc_config.mode |= AT91_SMC_DBW_16; + else + ek_nand_smc_config.mode |= AT91_SMC_DBW_8; + + /* configure chip-select 3 (NAND) */ + sam9_smc_configure(3, &ek_nand_smc_config); + + at91_add_device_nand(&ek_nand_data); +} + + +/* + * I2C devices + */ +static struct at24_platform_data at24c512 = { + .byte_len = SZ_512K / 8, + .page_size = 128, + .flags = AT24_FLAG_ADDR16, +}; + + +static struct i2c_board_info __initdata ek_i2c_devices[] = { + { + I2C_BOARD_INFO("24c512", 0x50), + .platform_data = &at24c512, + }, + /* more devices can be added using expansion connectors */ +}; + +/* + * LCD Controller + */ +#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) +static struct fb_videomode at91_tft_vga_modes[] = { + { + .name = "TX09D50VM1CCA @ 60", + .refresh = 60, + .xres = 240, .yres = 320, + .pixclock = KHZ2PICOS(4965), + + .left_margin = 1, .right_margin = 33, + .upper_margin = 1, .lower_margin = 0, + .hsync_len = 5, .vsync_len = 1, + + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = FB_VMODE_NONINTERLACED, + }, +}; + +static struct fb_monspecs at91fb_default_monspecs = { + .manufacturer = "HIT", + .monitor = "TX09D70VM1CCA", + + .modedb = at91_tft_vga_modes, + .modedb_len = ARRAY_SIZE(at91_tft_vga_modes), + .hfmin = 15000, + .hfmax = 64000, + .vfmin = 50, + .vfmax = 150, +}; + +#define AT91SAM9263_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \ + | ATMEL_LCDC_DISTYPE_TFT \ + | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE) + +static void at91_lcdc_power_control(int on) +{ + at91_set_gpio_value(AT91_PIN_PA30, on); +} + +/* Driver datas */ +static struct atmel_lcdfb_info __initdata ek_lcdc_data = { + .lcdcon_is_backlight = true, + .default_bpp = 16, + .default_dmacon = ATMEL_LCDC_DMAEN, + .default_lcdcon2 = AT91SAM9263_DEFAULT_LCDCON2, + .default_monspecs = &at91fb_default_monspecs, + .atmel_lcdfb_power_control = at91_lcdc_power_control, + .guard_time = 1, +}; + +#else +static struct atmel_lcdfb_info __initdata ek_lcdc_data; +#endif + + +/* + * GPIO Buttons + */ +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +static struct gpio_keys_button ek_buttons[] = { + { /* BP1, "leftclic" */ + .code = BTN_LEFT, + .gpio = AT91_PIN_PC5, + .active_low = 1, + .desc = "left_click", + .wakeup = 1, + }, + { /* BP2, "rightclic" */ + .code = BTN_RIGHT, + .gpio = AT91_PIN_PC4, + .active_low = 1, + .desc = "right_click", + .wakeup = 1, + } +}; + +static struct gpio_keys_platform_data ek_button_data = { + .buttons = ek_buttons, + .nbuttons = ARRAY_SIZE(ek_buttons), +}; + +static struct platform_device ek_button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &ek_button_data, + } +}; + +static void __init ek_add_device_buttons(void) +{ + at91_set_GPIO_periph(AT91_PIN_PC5, 1); /* left button */ + at91_set_deglitch(AT91_PIN_PC5, 1); + at91_set_GPIO_periph(AT91_PIN_PC4, 1); /* right button */ + at91_set_deglitch(AT91_PIN_PC4, 1); + + platform_device_register(&ek_button_device); +} +#else +static void __init ek_add_device_buttons(void) {} +#endif + + +/* + * AC97 + * reset_pin is not connected: NRST + */ +static struct ac97c_platform_data ek_ac97_data = { +}; + + +/* + * LEDs ... these could all be PWM-driven, for variable brightness + */ +static struct gpio_led ek_leds[] = { + { /* "right" led, green, userled2 (could be driven by pwm2) */ + .name = "ds2", + .gpio = AT91_PIN_PC29, + .active_low = 1, + .default_trigger = "nand-disk", + }, + { /* "power" led, yellow (could be driven by pwm0) */ + .name = "ds3", + .gpio = AT91_PIN_PB7, + .default_trigger = "heartbeat", + } +}; + +/* + * PWM Leds + */ +static struct gpio_led ek_pwm_led[] = { + /* For now only DS1 is PWM-driven (by pwm1) */ + { + .name = "ds1", + .gpio = 1, /* is PWM channel number */ + .active_low = 1, + .default_trigger = "none", + } +}; + +/* + * CAN + */ +static void sam9263ek_transceiver_switch(int on) +{ + if (on) { + at91_set_gpio_output(AT91_PIN_PA18, 1); /* CANRXEN */ + at91_set_gpio_output(AT91_PIN_PA19, 0); /* CANRS */ + } else { + at91_set_gpio_output(AT91_PIN_PA18, 0); /* CANRXEN */ + at91_set_gpio_output(AT91_PIN_PA19, 1); /* CANRS */ + } +} + +static struct at91_can_data ek_can_data = { + .transceiver_switch = sam9263ek_transceiver_switch, +}; + +static void __init ek_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* USB Host */ + at91_add_device_usbh(&ek_usbh_data); + /* USB Device */ + at91_add_device_udc(&ek_udc_data); + /* SPI */ + at91_set_gpio_output(AT91_PIN_PE20, 1); /* select spi0 clock */ + at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); + /* Touchscreen */ + ek_add_device_ts(); + /* MMC */ + at91_add_device_mmc(1, &ek_mmc_data); + /* Ethernet */ + at91_add_device_eth(&ek_macb_data); + /* NAND */ + ek_add_device_nand(); + /* I2C */ + at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices)); + /* LCD Controller */ + at91_add_device_lcdc(&ek_lcdc_data); + /* Push Buttons */ + ek_add_device_buttons(); + /* AC97 */ + at91_add_device_ac97(&ek_ac97_data); + /* LEDs */ + at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); + at91_pwm_leds(ek_pwm_led, ARRAY_SIZE(ek_pwm_led)); + /* CAN */ + at91_add_device_can(&ek_can_data); +} + +MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK") + /* Maintainer: Atmel */ + .timer = &at91sam926x_timer, + .map_io = at91sam9263_map_io, + .init_early = ek_init_early, + .init_irq = ek_init_irq, + .init_machine = ek_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c new file mode 100644 index 00000000..1325a501 --- /dev/null +++ b/arch/arm/mach-at91/board-sam9g20ek.c @@ -0,0 +1,420 @@ +/* + * Copyright (C) 2005 SAN People + * Copyright (C) 2008 Atmel + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> +#include <linux/spi/at73c213.h> +#include <linux/gpio_keys.h> +#include <linux/input.h> +#include <linux/clk.h> +#include <linux/regulator/machine.h> +#include <linux/regulator/fixed.h> +#include <linux/regulator/consumer.h> + +#include <mach/hardware.h> +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <mach/board.h> +#include <mach/gpio.h> +#include <mach/at91sam9_smc.h> +#include <mach/system_rev.h> + +#include "sam9_smc.h" +#include "generic.h" + +/* + * board revision encoding + * bit 0: + * 0 => 1 sd/mmc slot + * 1 => 2 sd/mmc slots connectors (board from revision C) + */ +#define HAVE_2MMC (1 << 0) +static int inline ek_have_2mmc(void) +{ + return machine_is_at91sam9g20ek_2mmc() || (system_rev & HAVE_2MMC); +} + + +static void __init ek_init_early(void) +{ + /* Initialize processor: 18.432 MHz crystal */ + at91sam9260_initialize(18432000); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD + | ATMEL_UART_RI); + + /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */ + at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init ek_init_irq(void) +{ + at91sam9260_init_interrupts(NULL); +} + + +/* + * USB Host port + */ +static struct at91_usbh_data __initdata ek_usbh_data = { + .ports = 2, +}; + +/* + * USB Device port + */ +static struct at91_udc_data __initdata ek_udc_data = { + .vbus_pin = AT91_PIN_PC5, + .pullup_pin = 0, /* pull-up driven by UDC */ +}; + + +/* + * SPI devices. + */ +static struct spi_board_info ek_spi_devices[] = { +#if !(defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_AT91)) + { /* DataFlash chip */ + .modalias = "mtd_dataflash", + .chip_select = 1, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD) + { /* DataFlash card */ + .modalias = "mtd_dataflash", + .chip_select = 0, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +#endif +#endif +}; + + +/* + * MACB Ethernet device + */ +static struct at91_eth_data __initdata ek_macb_data = { + .phy_irq_pin = AT91_PIN_PA7, + .is_rmii = 1, +}; + +static void __init ek_add_device_macb(void) +{ + if (ek_have_2mmc()) + ek_macb_data.phy_irq_pin = AT91_PIN_PB0; + + at91_add_device_eth(&ek_macb_data); +} + +/* + * NAND flash + */ +static struct mtd_partition __initdata ek_nand_partition[] = { + { + .name = "Bootstrap", + .offset = 0, + .size = 4 * SZ_1M, + }, + { + .name = "Partition 1", + .offset = MTDPART_OFS_NXTBLK, + .size = 60 * SZ_1M, + }, + { + .name = "Partition 2", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(ek_nand_partition); + return ek_nand_partition; +} + +/* det_pin is not connected */ +static struct atmel_nand_data __initdata ek_nand_data = { + .ale = 21, + .cle = 22, + .rdy_pin = AT91_PIN_PC13, + .enable_pin = AT91_PIN_PC14, + .partition_info = nand_partitions, +}; + +static struct sam9_smc_config __initdata ek_nand_smc_config = { + .ncs_read_setup = 0, + .nrd_setup = 2, + .ncs_write_setup = 0, + .nwe_setup = 2, + + .ncs_read_pulse = 4, + .nrd_pulse = 4, + .ncs_write_pulse = 4, + .nwe_pulse = 4, + + .read_cycle = 7, + .write_cycle = 7, + + .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE, + .tdf_cycles = 3, +}; + +static void __init ek_add_device_nand(void) +{ + ek_nand_data.bus_width_16 = board_have_nand_16bit(); + /* setup bus-width (8 or 16) */ + if (ek_nand_data.bus_width_16) + ek_nand_smc_config.mode |= AT91_SMC_DBW_16; + else + ek_nand_smc_config.mode |= AT91_SMC_DBW_8; + + /* configure chip-select 3 (NAND) */ + sam9_smc_configure(3, &ek_nand_smc_config); + + at91_add_device_nand(&ek_nand_data); +} + + +/* + * MCI (SD/MMC) + * wp_pin and vcc_pin are not connected + */ +#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE) +static struct mci_platform_data __initdata ek_mmc_data = { + .slot[1] = { + .bus_width = 4, + .detect_pin = AT91_PIN_PC9, + }, + +}; +#else +static struct at91_mmc_data __initdata ek_mmc_data = { + .slot_b = 1, /* Only one slot so use slot B */ + .wire4 = 1, + .det_pin = AT91_PIN_PC9, +}; +#endif + +static void __init ek_add_device_mmc(void) +{ +#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE) + if (ek_have_2mmc()) { + ek_mmc_data.slot[0].bus_width = 4; + ek_mmc_data.slot[0].detect_pin = AT91_PIN_PC2; + } + at91_add_device_mci(0, &ek_mmc_data); +#else + at91_add_device_mmc(0, &ek_mmc_data); +#endif +} + +/* + * LEDs + */ +static struct gpio_led ek_leds[] = { + { /* "bottom" led, green, userled1 to be defined */ + .name = "ds5", + .gpio = AT91_PIN_PA6, + .active_low = 1, + .default_trigger = "none", + }, + { /* "power" led, yellow */ + .name = "ds1", + .gpio = AT91_PIN_PA9, + .default_trigger = "heartbeat", + } +}; + +static void __init ek_add_device_gpio_leds(void) +{ + if (ek_have_2mmc()) { + ek_leds[0].gpio = AT91_PIN_PB8; + ek_leds[1].gpio = AT91_PIN_PB9; + } + + at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); +} + +/* + * GPIO Buttons + */ +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +static struct gpio_keys_button ek_buttons[] = { + { + .gpio = AT91_PIN_PA30, + .code = BTN_3, + .desc = "Button 3", + .active_low = 1, + .wakeup = 1, + }, + { + .gpio = AT91_PIN_PA31, + .code = BTN_4, + .desc = "Button 4", + .active_low = 1, + .wakeup = 1, + } +}; + +static struct gpio_keys_platform_data ek_button_data = { + .buttons = ek_buttons, + .nbuttons = ARRAY_SIZE(ek_buttons), +}; + +static struct platform_device ek_button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &ek_button_data, + } +}; + +static void __init ek_add_device_buttons(void) +{ + at91_set_gpio_input(AT91_PIN_PA30, 1); /* btn3 */ + at91_set_deglitch(AT91_PIN_PA30, 1); + at91_set_gpio_input(AT91_PIN_PA31, 1); /* btn4 */ + at91_set_deglitch(AT91_PIN_PA31, 1); + + platform_device_register(&ek_button_device); +} +#else +static void __init ek_add_device_buttons(void) {} +#endif + +#if defined(CONFIG_REGULATOR_FIXED_VOLTAGE) || defined(CONFIG_REGULATOR_FIXED_VOLTAGE_MODULE) +static struct regulator_consumer_supply ek_audio_consumer_supplies[] = { + REGULATOR_SUPPLY("AVDD", "0-001b"), + REGULATOR_SUPPLY("HPVDD", "0-001b"), + REGULATOR_SUPPLY("DBVDD", "0-001b"), + REGULATOR_SUPPLY("DCVDD", "0-001b"), +}; + +static struct regulator_init_data ek_avdd_reg_init_data = { + .constraints = { + .name = "3V3", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .consumer_supplies = ek_audio_consumer_supplies, + .num_consumer_supplies = ARRAY_SIZE(ek_audio_consumer_supplies), +}; + +static struct fixed_voltage_config ek_vdd_pdata = { + .supply_name = "board-3V3", + .microvolts = 3300000, + .gpio = -EINVAL, + .enabled_at_boot = 0, + .init_data = &ek_avdd_reg_init_data, +}; +static struct platform_device ek_voltage_regulator = { + .name = "reg-fixed-voltage", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &ek_vdd_pdata, + }, +}; +static void __init ek_add_regulators(void) +{ + platform_device_register(&ek_voltage_regulator); +} +#else +static void __init ek_add_regulators(void) {} +#endif + + +static struct i2c_board_info __initdata ek_i2c_devices[] = { + { + I2C_BOARD_INFO("24c512", 0x50) + }, + { + I2C_BOARD_INFO("wm8731", 0x1b) + }, +}; + + +static void __init ek_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* USB Host */ + at91_add_device_usbh(&ek_usbh_data); + /* USB Device */ + at91_add_device_udc(&ek_udc_data); + /* SPI */ + at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); + /* NAND */ + ek_add_device_nand(); + /* Ethernet */ + ek_add_device_macb(); + /* Regulators */ + ek_add_regulators(); + /* MMC */ + ek_add_device_mmc(); + /* I2C */ + at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices)); + /* LEDs */ + ek_add_device_gpio_leds(); + /* Push Buttons */ + ek_add_device_buttons(); + /* PCK0 provides MCLK to the WM8731 */ + at91_set_B_periph(AT91_PIN_PC1, 0); + /* SSC (for WM8731) */ + at91_add_device_ssc(AT91SAM9260_ID_SSC, ATMEL_SSC_TX); +} + +MACHINE_START(AT91SAM9G20EK, "Atmel AT91SAM9G20-EK") + /* Maintainer: Atmel */ + .timer = &at91sam926x_timer, + .map_io = at91sam9260_map_io, + .init_early = ek_init_early, + .init_irq = ek_init_irq, + .init_machine = ek_board_init, +MACHINE_END + +MACHINE_START(AT91SAM9G20EK_2MMC, "Atmel AT91SAM9G20-EK 2 MMC Slot Mod") + /* Maintainer: Atmel */ + .timer = &at91sam926x_timer, + .map_io = at91sam9260_map_io, + .init_early = ek_init_early, + .init_irq = ek_init_irq, + .init_machine = ek_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c new file mode 100644 index 00000000..33eaa135 --- /dev/null +++ b/arch/arm/mach-at91/board-sam9m10g45ek.c @@ -0,0 +1,429 @@ +/* + * Board-specific setup code for the AT91SAM9M10G45 Evaluation Kit family + * + * Covers: * AT91SAM9G45-EKES board + * * AT91SAM9M10G45-EK board + * + * Copyright (C) 2009 Atmel Corporation. + * + * 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. + * + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> +#include <linux/fb.h> +#include <linux/gpio_keys.h> +#include <linux/input.h> +#include <linux/leds.h> +#include <linux/clk.h> +#include <linux/atmel-mci.h> + +#include <mach/hardware.h> +#include <video/atmel_lcdc.h> + +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <mach/board.h> +#include <mach/gpio.h> +#include <mach/at91sam9_smc.h> +#include <mach/at91_shdwc.h> +#include <mach/system_rev.h> + +#include "sam9_smc.h" +#include "generic.h" + + +static void __init ek_init_early(void) +{ + /* Initialize processor: 12.000 MHz crystal */ + at91sam9g45_initialize(12000000); + + /* DGBU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 not connected on the -EK board */ + /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */ + at91_register_uart(AT91SAM9G45_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init ek_init_irq(void) +{ + at91sam9g45_init_interrupts(NULL); +} + + +/* + * USB HS Host port (common to OHCI & EHCI) + */ +static struct at91_usbh_data __initdata ek_usbh_hs_data = { + .ports = 2, + .vbus_pin = {AT91_PIN_PD1, AT91_PIN_PD3}, +}; + + +/* + * USB HS Device port + */ +static struct usba_platform_data __initdata ek_usba_udc_data = { + .vbus_pin = AT91_PIN_PB19, +}; + + +/* + * SPI devices. + */ +static struct spi_board_info ek_spi_devices[] = { + { /* DataFlash chip */ + .modalias = "mtd_dataflash", + .chip_select = 0, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +}; + + +/* + * MCI (SD/MMC) + */ +static struct mci_platform_data __initdata mci0_data = { + .slot[0] = { + .bus_width = 4, + .detect_pin = AT91_PIN_PD10, + }, +}; + +static struct mci_platform_data __initdata mci1_data = { + .slot[0] = { + .bus_width = 4, + .detect_pin = AT91_PIN_PD11, + .wp_pin = AT91_PIN_PD29, + }, +}; + + +/* + * MACB Ethernet device + */ +static struct at91_eth_data __initdata ek_macb_data = { + .phy_irq_pin = AT91_PIN_PD5, + .is_rmii = 1, +}; + + +/* + * NAND flash + */ +static struct mtd_partition __initdata ek_nand_partition[] = { + { + .name = "Partition 1", + .offset = 0, + .size = SZ_64M, + }, + { + .name = "Partition 2", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(ek_nand_partition); + return ek_nand_partition; +} + +/* det_pin is not connected */ +static struct atmel_nand_data __initdata ek_nand_data = { + .ale = 21, + .cle = 22, + .rdy_pin = AT91_PIN_PC8, + .enable_pin = AT91_PIN_PC14, + .partition_info = nand_partitions, +}; + +static struct sam9_smc_config __initdata ek_nand_smc_config = { + .ncs_read_setup = 0, + .nrd_setup = 2, + .ncs_write_setup = 0, + .nwe_setup = 2, + + .ncs_read_pulse = 4, + .nrd_pulse = 4, + .ncs_write_pulse = 4, + .nwe_pulse = 4, + + .read_cycle = 7, + .write_cycle = 7, + + .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE, + .tdf_cycles = 3, +}; + +static void __init ek_add_device_nand(void) +{ + ek_nand_data.bus_width_16 = board_have_nand_16bit(); + /* setup bus-width (8 or 16) */ + if (ek_nand_data.bus_width_16) + ek_nand_smc_config.mode |= AT91_SMC_DBW_16; + else + ek_nand_smc_config.mode |= AT91_SMC_DBW_8; + + /* configure chip-select 3 (NAND) */ + sam9_smc_configure(3, &ek_nand_smc_config); + + at91_add_device_nand(&ek_nand_data); +} + + +/* + * LCD Controller + */ +#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) +static struct fb_videomode at91_tft_vga_modes[] = { + { + .name = "LG", + .refresh = 60, + .xres = 480, .yres = 272, + .pixclock = KHZ2PICOS(9000), + + .left_margin = 1, .right_margin = 1, + .upper_margin = 40, .lower_margin = 1, + .hsync_len = 45, .vsync_len = 1, + + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + }, +}; + +static struct fb_monspecs at91fb_default_monspecs = { + .manufacturer = "LG", + .monitor = "LB043WQ1", + + .modedb = at91_tft_vga_modes, + .modedb_len = ARRAY_SIZE(at91_tft_vga_modes), + .hfmin = 15000, + .hfmax = 17640, + .vfmin = 57, + .vfmax = 67, +}; + +#define AT91SAM9G45_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \ + | ATMEL_LCDC_DISTYPE_TFT \ + | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE) + +/* Driver datas */ +static struct atmel_lcdfb_info __initdata ek_lcdc_data = { + .lcdcon_is_backlight = true, + .default_bpp = 32, + .default_dmacon = ATMEL_LCDC_DMAEN, + .default_lcdcon2 = AT91SAM9G45_DEFAULT_LCDCON2, + .default_monspecs = &at91fb_default_monspecs, + .guard_time = 9, + .lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB, +}; + +#else +static struct atmel_lcdfb_info __initdata ek_lcdc_data; +#endif + + +/* + * Touchscreen + */ +static struct at91_tsadcc_data ek_tsadcc_data = { + .adc_clock = 300000, + .pendet_debounce = 0x0d, + .ts_sample_hold_time = 0x0a, +}; + + +/* + * GPIO Buttons + */ +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +static struct gpio_keys_button ek_buttons[] = { + { /* BP1, "leftclic" */ + .code = BTN_LEFT, + .gpio = AT91_PIN_PB6, + .active_low = 1, + .desc = "left_click", + .wakeup = 1, + }, + { /* BP2, "rightclic" */ + .code = BTN_RIGHT, + .gpio = AT91_PIN_PB7, + .active_low = 1, + .desc = "right_click", + .wakeup = 1, + }, + /* BP3, "joystick" */ + { + .code = KEY_LEFT, + .gpio = AT91_PIN_PB14, + .active_low = 1, + .desc = "Joystick Left", + }, + { + .code = KEY_RIGHT, + .gpio = AT91_PIN_PB15, + .active_low = 1, + .desc = "Joystick Right", + }, + { + .code = KEY_UP, + .gpio = AT91_PIN_PB16, + .active_low = 1, + .desc = "Joystick Up", + }, + { + .code = KEY_DOWN, + .gpio = AT91_PIN_PB17, + .active_low = 1, + .desc = "Joystick Down", + }, + { + .code = KEY_ENTER, + .gpio = AT91_PIN_PB18, + .active_low = 1, + .desc = "Joystick Press", + }, +}; + +static struct gpio_keys_platform_data ek_button_data = { + .buttons = ek_buttons, + .nbuttons = ARRAY_SIZE(ek_buttons), +}; + +static struct platform_device ek_button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &ek_button_data, + } +}; + +static void __init ek_add_device_buttons(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(ek_buttons); i++) { + at91_set_GPIO_periph(ek_buttons[i].gpio, 1); + at91_set_deglitch(ek_buttons[i].gpio, 1); + } + + platform_device_register(&ek_button_device); +} +#else +static void __init ek_add_device_buttons(void) {} +#endif + + +/* + * AC97 + * reset_pin is not connected: NRST + */ +static struct ac97c_platform_data ek_ac97_data = { +}; + + +/* + * LEDs ... these could all be PWM-driven, for variable brightness + */ +static struct gpio_led ek_leds[] = { + { /* "top" led, red, powerled */ + .name = "d8", + .gpio = AT91_PIN_PD30, + .default_trigger = "heartbeat", + }, + { /* "left" led, green, userled2, pwm3 */ + .name = "d6", + .gpio = AT91_PIN_PD0, + .active_low = 1, + .default_trigger = "nand-disk", + }, +#if !(defined(CONFIG_LEDS_ATMEL_PWM) || defined(CONFIG_LEDS_ATMEL_PWM_MODULE)) + { /* "right" led, green, userled1, pwm1 */ + .name = "d7", + .gpio = AT91_PIN_PD31, + .active_low = 1, + .default_trigger = "mmc0", + }, +#endif +}; + + +/* + * PWM Leds + */ +static struct gpio_led ek_pwm_led[] = { +#if defined(CONFIG_LEDS_ATMEL_PWM) || defined(CONFIG_LEDS_ATMEL_PWM_MODULE) + { /* "right" led, green, userled1, pwm1 */ + .name = "d7", + .gpio = 1, /* is PWM channel number */ + .active_low = 1, + .default_trigger = "none", + }, +#endif +}; + + + +static void __init ek_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* USB HS Host */ + at91_add_device_usbh_ohci(&ek_usbh_hs_data); + at91_add_device_usbh_ehci(&ek_usbh_hs_data); + /* USB HS Device */ + at91_add_device_usba(&ek_usba_udc_data); + /* SPI */ + at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); + /* MMC */ + at91_add_device_mci(0, &mci0_data); + at91_add_device_mci(1, &mci1_data); + /* Ethernet */ + at91_add_device_eth(&ek_macb_data); + /* NAND */ + ek_add_device_nand(); + /* I2C */ + at91_add_device_i2c(0, NULL, 0); + /* LCD Controller */ + at91_add_device_lcdc(&ek_lcdc_data); + /* Touch Screen */ + at91_add_device_tsadcc(&ek_tsadcc_data); + /* Push Buttons */ + ek_add_device_buttons(); + /* AC97 */ + at91_add_device_ac97(&ek_ac97_data); + /* LEDs */ + at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); + at91_pwm_leds(ek_pwm_led, ARRAY_SIZE(ek_pwm_led)); +} + +MACHINE_START(AT91SAM9M10G45EK, "Atmel AT91SAM9M10G45-EK") + /* Maintainer: Atmel */ + .timer = &at91sam926x_timer, + .map_io = at91sam9g45_map_io, + .init_early = ek_init_early, + .init_irq = ek_init_irq, + .init_machine = ek_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c new file mode 100644 index 00000000..effb399a --- /dev/null +++ b/arch/arm/mach-at91/board-sam9rlek.c @@ -0,0 +1,337 @@ +/* + * Copyright (C) 2005 SAN People + * Copyright (C) 2007 Atmel Corporation + * + * 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/types.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> +#include <linux/fb.h> +#include <linux/clk.h> +#include <linux/input.h> +#include <linux/gpio_keys.h> + +#include <video/atmel_lcdc.h> + +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <mach/hardware.h> +#include <mach/board.h> +#include <mach/gpio.h> +#include <mach/at91sam9_smc.h> +#include <mach/at91_shdwc.h> + +#include "sam9_smc.h" +#include "generic.h" + + +static void __init ek_init_early(void) +{ + /* Initialize processor: 12.000 MHz crystal */ + at91sam9rl_initialize(12000000); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1. (Rx, Tx, CTS, RTS) */ + at91_register_uart(AT91SAM9RL_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init ek_init_irq(void) +{ + at91sam9rl_init_interrupts(NULL); +} + + +/* + * USB HS Device port + */ +static struct usba_platform_data __initdata ek_usba_udc_data = { + .vbus_pin = AT91_PIN_PA8, +}; + + +/* + * MCI (SD/MMC) + */ +static struct at91_mmc_data __initdata ek_mmc_data = { + .wire4 = 1, + .det_pin = AT91_PIN_PA15, +// .wp_pin = ... not connected +// .vcc_pin = ... not connected +}; + + +/* + * NAND flash + */ +static struct mtd_partition __initdata ek_nand_partition[] = { + { + .name = "Partition 1", + .offset = 0, + .size = SZ_256K, + }, + { + .name = "Partition 2", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(ek_nand_partition); + return ek_nand_partition; +} + +static struct atmel_nand_data __initdata ek_nand_data = { + .ale = 21, + .cle = 22, +// .det_pin = ... not connected + .rdy_pin = AT91_PIN_PD17, + .enable_pin = AT91_PIN_PB6, + .partition_info = nand_partitions, +}; + +static struct sam9_smc_config __initdata ek_nand_smc_config = { + .ncs_read_setup = 0, + .nrd_setup = 1, + .ncs_write_setup = 0, + .nwe_setup = 1, + + .ncs_read_pulse = 3, + .nrd_pulse = 3, + .ncs_write_pulse = 3, + .nwe_pulse = 3, + + .read_cycle = 5, + .write_cycle = 5, + + .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8, + .tdf_cycles = 2, +}; + +static void __init ek_add_device_nand(void) +{ + /* configure chip-select 3 (NAND) */ + sam9_smc_configure(3, &ek_nand_smc_config); + + at91_add_device_nand(&ek_nand_data); +} + + +/* + * SPI devices + */ +static struct spi_board_info ek_spi_devices[] = { + { /* DataFlash chip */ + .modalias = "mtd_dataflash", + .chip_select = 0, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +}; + + +/* + * LCD Controller + */ +#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) +static struct fb_videomode at91_tft_vga_modes[] = { + { + .name = "TX09D50VM1CCA @ 60", + .refresh = 60, + .xres = 240, .yres = 320, + .pixclock = KHZ2PICOS(4965), + + .left_margin = 1, .right_margin = 33, + .upper_margin = 1, .lower_margin = 0, + .hsync_len = 5, .vsync_len = 1, + + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = FB_VMODE_NONINTERLACED, + }, +}; + +static struct fb_monspecs at91fb_default_monspecs = { + .manufacturer = "HIT", + .monitor = "TX09D50VM1CCA", + + .modedb = at91_tft_vga_modes, + .modedb_len = ARRAY_SIZE(at91_tft_vga_modes), + .hfmin = 15000, + .hfmax = 64000, + .vfmin = 50, + .vfmax = 150, +}; + +#define AT91SAM9RL_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \ + | ATMEL_LCDC_DISTYPE_TFT \ + | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE) + +static void at91_lcdc_power_control(int on) +{ + if (on) + at91_set_gpio_value(AT91_PIN_PC1, 0); /* power up */ + else + at91_set_gpio_value(AT91_PIN_PC1, 1); /* power down */ +} + +/* Driver datas */ +static struct atmel_lcdfb_info __initdata ek_lcdc_data = { + .lcdcon_is_backlight = true, + .default_bpp = 16, + .default_dmacon = ATMEL_LCDC_DMAEN, + .default_lcdcon2 = AT91SAM9RL_DEFAULT_LCDCON2, + .default_monspecs = &at91fb_default_monspecs, + .atmel_lcdfb_power_control = at91_lcdc_power_control, + .guard_time = 1, + .lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB, +}; + +#else +static struct atmel_lcdfb_info __initdata ek_lcdc_data; +#endif + + +/* + * AC97 + * reset_pin is not connected: NRST + */ +static struct ac97c_platform_data ek_ac97_data = { +}; + + +/* + * LEDs + */ +static struct gpio_led ek_leds[] = { + { /* "bottom" led, green, userled1 to be defined */ + .name = "ds1", + .gpio = AT91_PIN_PD15, + .active_low = 1, + .default_trigger = "none", + }, + { /* "bottom" led, green, userled2 to be defined */ + .name = "ds2", + .gpio = AT91_PIN_PD16, + .active_low = 1, + .default_trigger = "none", + }, + { /* "power" led, yellow */ + .name = "ds3", + .gpio = AT91_PIN_PD14, + .default_trigger = "heartbeat", + } +}; + + +/* + * Touchscreen + */ +static struct at91_tsadcc_data ek_tsadcc_data = { + .adc_clock = 1000000, + .pendet_debounce = 0x0f, + .ts_sample_hold_time = 0x03, +}; + + +/* + * GPIO Buttons + */ +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +static struct gpio_keys_button ek_buttons[] = { + { + .gpio = AT91_PIN_PB0, + .code = BTN_2, + .desc = "Right Click", + .active_low = 1, + .wakeup = 1, + }, + { + .gpio = AT91_PIN_PB1, + .code = BTN_1, + .desc = "Left Click", + .active_low = 1, + .wakeup = 1, + } +}; + +static struct gpio_keys_platform_data ek_button_data = { + .buttons = ek_buttons, + .nbuttons = ARRAY_SIZE(ek_buttons), +}; + +static struct platform_device ek_button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &ek_button_data, + } +}; + +static void __init ek_add_device_buttons(void) +{ + at91_set_gpio_input(AT91_PIN_PB1, 1); /* btn1 */ + at91_set_deglitch(AT91_PIN_PB1, 1); + at91_set_gpio_input(AT91_PIN_PB0, 1); /* btn2 */ + at91_set_deglitch(AT91_PIN_PB0, 1); + + platform_device_register(&ek_button_device); +} +#else +static void __init ek_add_device_buttons(void) {} +#endif + + +static void __init ek_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* USB HS */ + at91_add_device_usba(&ek_usba_udc_data); + /* I2C */ + at91_add_device_i2c(NULL, 0); + /* NAND */ + ek_add_device_nand(); + /* SPI */ + at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); + /* MMC */ + at91_add_device_mmc(0, &ek_mmc_data); + /* LCD Controller */ + at91_add_device_lcdc(&ek_lcdc_data); + /* AC97 */ + at91_add_device_ac97(&ek_ac97_data); + /* Touch Screen Controller */ + at91_add_device_tsadcc(&ek_tsadcc_data); + /* LEDs */ + at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); + /* Push Buttons */ + ek_add_device_buttons(); +} + +MACHINE_START(AT91SAM9RLEK, "Atmel AT91SAM9RL-EK") + /* Maintainer: Atmel */ + .timer = &at91sam926x_timer, + .map_io = at91sam9rl_map_io, + .init_early = ek_init_early, + .init_irq = ek_init_irq, + .init_machine = ek_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-snapper9260.c b/arch/arm/mach-at91/board-snapper9260.c new file mode 100644 index 00000000..3eb0a115 --- /dev/null +++ b/arch/arm/mach-at91/board-snapper9260.c @@ -0,0 +1,188 @@ +/* + * linux/arch/arm/mach-at91/board-snapper9260.c + * + * Copyright (C) 2010 Bluewater System Ltd + * + * Author: Andre Renaud <andre@bluewatersys.com> + * Author: Ryan Mallon <ryan@bluewatersys.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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <linux/init.h> +#include <linux/gpio.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> +#include <linux/i2c/pca953x.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#include <mach/hardware.h> +#include <mach/board.h> +#include <mach/at91sam9_smc.h> + +#include "sam9_smc.h" +#include "generic.h" + +#define SNAPPER9260_IO_EXP_GPIO(x) (NR_BUILTIN_GPIO + (x)) + +static void __init snapper9260_init_early(void) +{ + at91sam9260_initialize(18432000); + + /* Debug on ttyS0 */ + at91_register_uart(0, 0, 0); + at91_set_serial_console(0); + + at91_register_uart(AT91SAM9260_ID_US0, 1, + ATMEL_UART_CTS | ATMEL_UART_RTS); + at91_register_uart(AT91SAM9260_ID_US1, 2, + ATMEL_UART_CTS | ATMEL_UART_RTS); + at91_register_uart(AT91SAM9260_ID_US2, 3, 0); +} + +static void __init snapper9260_init_irq(void) +{ + at91sam9260_init_interrupts(NULL); +} + +static struct at91_usbh_data __initdata snapper9260_usbh_data = { + .ports = 2, +}; + +static struct at91_udc_data __initdata snapper9260_udc_data = { + .vbus_pin = SNAPPER9260_IO_EXP_GPIO(5), + .vbus_active_low = 1, + .vbus_polled = 1, +}; + +static struct at91_eth_data snapper9260_macb_data = { + .is_rmii = 1, +}; + +static struct mtd_partition __initdata snapper9260_nand_partitions[] = { + { + .name = "Preboot", + .offset = 0, + .size = SZ_128K, + }, + { + .name = "Bootloader", + .offset = MTDPART_OFS_APPEND, + .size = SZ_256K, + }, + { + .name = "Environment", + .offset = MTDPART_OFS_APPEND, + .size = SZ_128K, + }, + { + .name = "Kernel", + .offset = MTDPART_OFS_APPEND, + .size = SZ_4M, + }, + { + .name = "Filesystem", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct mtd_partition * __init +snapper9260_nand_partition_info(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(snapper9260_nand_partitions); + return snapper9260_nand_partitions; +} + +static struct atmel_nand_data __initdata snapper9260_nand_data = { + .ale = 21, + .cle = 22, + .rdy_pin = AT91_PIN_PC13, + .partition_info = snapper9260_nand_partition_info, + .bus_width_16 = 0, +}; + +static struct sam9_smc_config __initdata snapper9260_nand_smc_config = { + .ncs_read_setup = 0, + .nrd_setup = 0, + .ncs_write_setup = 0, + .nwe_setup = 0, + + .ncs_read_pulse = 5, + .nrd_pulse = 2, + .ncs_write_pulse = 5, + .nwe_pulse = 2, + + .read_cycle = 7, + .write_cycle = 7, + + .mode = (AT91_SMC_READMODE | AT91_SMC_WRITEMODE | + AT91_SMC_EXNWMODE_DISABLE), + .tdf_cycles = 1, +}; + +static struct pca953x_platform_data snapper9260_io_expander_data = { + .gpio_base = SNAPPER9260_IO_EXP_GPIO(0), +}; + +static struct i2c_board_info __initdata snapper9260_i2c_devices[] = { + { + /* IO expander */ + I2C_BOARD_INFO("max7312", 0x28), + .platform_data = &snapper9260_io_expander_data, + }, + { + /* Audio codec */ + I2C_BOARD_INFO("tlv320aic23", 0x1a), + }, + { + /* RTC */ + I2C_BOARD_INFO("isl1208", 0x6f), + .irq = gpio_to_irq(AT91_PIN_PA31), + }, +}; + +static void __init snapper9260_add_device_nand(void) +{ + at91_set_A_periph(AT91_PIN_PC14, 0); + sam9_smc_configure(3, &snapper9260_nand_smc_config); + at91_add_device_nand(&snapper9260_nand_data); +} + +static void __init snapper9260_board_init(void) +{ + at91_add_device_i2c(snapper9260_i2c_devices, + ARRAY_SIZE(snapper9260_i2c_devices)); + at91_add_device_serial(); + at91_add_device_usbh(&snapper9260_usbh_data); + at91_add_device_udc(&snapper9260_udc_data); + at91_add_device_eth(&snapper9260_macb_data); + at91_add_device_ssc(AT91SAM9260_ID_SSC, (ATMEL_SSC_TF | ATMEL_SSC_TK | + ATMEL_SSC_TD | ATMEL_SSC_RD)); + snapper9260_add_device_nand(); +} + +MACHINE_START(SNAPPER_9260, "Bluewater Systems Snapper 9260/9G20 module") + .timer = &at91sam926x_timer, + .map_io = at91sam9260_map_io, + .init_early = snapper9260_init_early, + .init_irq = snapper9260_init_irq, + .init_machine = snapper9260_board_init, +MACHINE_END + + diff --git a/arch/arm/mach-at91/board-stamp9g20.c b/arch/arm/mach-at91/board-stamp9g20.c new file mode 100644 index 00000000..5e5c8568 --- /dev/null +++ b/arch/arm/mach-at91/board-stamp9g20.c @@ -0,0 +1,315 @@ +/* + * Copyright (C) 2010 Christian Glindkamp <christian.glindkamp@taskit.de> + * taskit GmbH + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/mm.h> +#include <linux/platform_device.h> +#include <linux/gpio.h> +#include <linux/w1-gpio.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#include <mach/board.h> +#include <mach/at91sam9_smc.h> + +#include "sam9_smc.h" +#include "generic.h" + + +void __init stamp9g20_init_early(void) +{ + /* Initialize processor: 18.432 MHz crystal */ + at91sam9260_initialize(18432000); + + /* DGBU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init stamp9g20evb_init_early(void) +{ + stamp9g20_init_early(); + + /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR + | ATMEL_UART_DCD | ATMEL_UART_RI); +} + +static void __init portuxg20_init_early(void) +{ + stamp9g20_init_early(); + + /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR + | ATMEL_UART_DCD | ATMEL_UART_RI); + + /* USART1 on ttyS2. (Rx, Tx, CTS, RTS) */ + at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* USART2 on ttyS3. (Rx, Tx, CTS, RTS) */ + at91_register_uart(AT91SAM9260_ID_US2, 3, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* USART4 on ttyS5. (Rx, Tx only) */ + at91_register_uart(AT91SAM9260_ID_US4, 5, 0); + + /* USART5 on ttyS6. (Rx, Tx only) */ + at91_register_uart(AT91SAM9260_ID_US5, 6, 0); +} + +static void __init init_irq(void) +{ + at91sam9260_init_interrupts(NULL); +} + + +/* + * NAND flash + */ +static struct atmel_nand_data __initdata nand_data = { + .ale = 21, + .cle = 22, + .rdy_pin = AT91_PIN_PC13, + .enable_pin = AT91_PIN_PC14, + .bus_width_16 = 0, +}; + +static struct sam9_smc_config __initdata nand_smc_config = { + .ncs_read_setup = 0, + .nrd_setup = 2, + .ncs_write_setup = 0, + .nwe_setup = 2, + + .ncs_read_pulse = 4, + .nrd_pulse = 4, + .ncs_write_pulse = 4, + .nwe_pulse = 4, + + .read_cycle = 7, + .write_cycle = 7, + + .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8, + .tdf_cycles = 3, +}; + +static void __init add_device_nand(void) +{ + /* configure chip-select 3 (NAND) */ + sam9_smc_configure(3, &nand_smc_config); + + at91_add_device_nand(&nand_data); +} + + +/* + * MCI (SD/MMC) + * det_pin, wp_pin and vcc_pin are not connected + */ +#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE) +static struct mci_platform_data __initdata mmc_data = { + .slot[0] = { + .bus_width = 4, + }, +}; +#else +static struct at91_mmc_data __initdata mmc_data = { + .slot_b = 0, + .wire4 = 1, +}; +#endif + + +/* + * USB Host port + */ +static struct at91_usbh_data __initdata usbh_data = { + .ports = 2, +}; + + +/* + * USB Device port + */ +static struct at91_udc_data __initdata portuxg20_udc_data = { + .vbus_pin = AT91_PIN_PC7, + .pullup_pin = 0, /* pull-up driven by UDC */ +}; + +static struct at91_udc_data __initdata stamp9g20evb_udc_data = { + .vbus_pin = AT91_PIN_PA22, + .pullup_pin = 0, /* pull-up driven by UDC */ +}; + + +/* + * MACB Ethernet device + */ +static struct at91_eth_data __initdata macb_data = { + .phy_irq_pin = AT91_PIN_PA28, + .is_rmii = 1, +}; + + +/* + * LEDs + */ +static struct gpio_led portuxg20_leds[] = { + { + .name = "LED2", + .gpio = AT91_PIN_PC5, + .default_trigger = "none", + }, { + .name = "LED3", + .gpio = AT91_PIN_PC4, + .default_trigger = "none", + }, { + .name = "LED4", + .gpio = AT91_PIN_PC10, + .default_trigger = "heartbeat", + } +}; + +static struct gpio_led stamp9g20evb_leds[] = { + { + .name = "D8", + .gpio = AT91_PIN_PB18, + .active_low = 1, + .default_trigger = "none", + }, { + .name = "D9", + .gpio = AT91_PIN_PB19, + .active_low = 1, + .default_trigger = "none", + }, { + .name = "D10", + .gpio = AT91_PIN_PB20, + .active_low = 1, + .default_trigger = "heartbeat", + } +}; + + +/* + * SPI devices + */ +static struct spi_board_info portuxg20_spi_devices[] = { + { + .modalias = "spidev", + .chip_select = 0, + .max_speed_hz = 1 * 1000 * 1000, + .bus_num = 0, + }, { + .modalias = "spidev", + .chip_select = 0, + .max_speed_hz = 1 * 1000 * 1000, + .bus_num = 1, + }, +}; + + +/* + * Dallas 1-Wire + */ +static struct w1_gpio_platform_data w1_gpio_pdata = { + .pin = AT91_PIN_PA29, + .is_open_drain = 1, +}; + +static struct platform_device w1_device = { + .name = "w1-gpio", + .id = -1, + .dev.platform_data = &w1_gpio_pdata, +}; + +void add_w1(void) +{ + at91_set_GPIO_periph(w1_gpio_pdata.pin, 1); + at91_set_multi_drive(w1_gpio_pdata.pin, 1); + platform_device_register(&w1_device); +} + + +void __init stamp9g20_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* NAND */ + add_device_nand(); + /* MMC */ +#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE) + at91_add_device_mci(0, &mmc_data); +#else + at91_add_device_mmc(0, &mmc_data); +#endif + /* W1 */ + add_w1(); +} + +static void __init portuxg20_board_init(void) +{ + stamp9g20_board_init(); + /* USB Host */ + at91_add_device_usbh(&usbh_data); + /* USB Device */ + at91_add_device_udc(&portuxg20_udc_data); + /* Ethernet */ + at91_add_device_eth(&macb_data); + /* I2C */ + at91_add_device_i2c(NULL, 0); + /* SPI */ + at91_add_device_spi(portuxg20_spi_devices, ARRAY_SIZE(portuxg20_spi_devices)); + /* LEDs */ + at91_gpio_leds(portuxg20_leds, ARRAY_SIZE(portuxg20_leds)); +} + +static void __init stamp9g20evb_board_init(void) +{ + stamp9g20_board_init(); + /* USB Host */ + at91_add_device_usbh(&usbh_data); + /* USB Device */ + at91_add_device_udc(&stamp9g20evb_udc_data); + /* Ethernet */ + at91_add_device_eth(&macb_data); + /* I2C */ + at91_add_device_i2c(NULL, 0); + /* LEDs */ + at91_gpio_leds(stamp9g20evb_leds, ARRAY_SIZE(stamp9g20evb_leds)); +} + +MACHINE_START(PORTUXG20, "taskit PortuxG20") + /* Maintainer: taskit GmbH */ + .timer = &at91sam926x_timer, + .map_io = at91sam9260_map_io, + .init_early = portuxg20_init_early, + .init_irq = init_irq, + .init_machine = portuxg20_board_init, +MACHINE_END + +MACHINE_START(STAMP9G20, "taskit Stamp9G20") + /* Maintainer: taskit GmbH */ + .timer = &at91sam926x_timer, + .map_io = at91sam9260_map_io, + .init_early = stamp9g20evb_init_early, + .init_irq = init_irq, + .init_machine = stamp9g20evb_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-usb-a9260.c b/arch/arm/mach-at91/board-usb-a9260.c new file mode 100644 index 00000000..0e784e6f --- /dev/null +++ b/arch/arm/mach-at91/board-usb-a9260.c @@ -0,0 +1,236 @@ +/* + * linux/arch/arm/mach-at91/board-usb-a9260.c + * + * Copyright (C) 2005 SAN People + * Copyright (C) 2006 Atmel + * Copyright (C) 2007 Calao-systems + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> +#include <linux/gpio_keys.h> +#include <linux/input.h> +#include <linux/clk.h> + +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <mach/hardware.h> +#include <mach/board.h> +#include <mach/gpio.h> +#include <mach/at91sam9_smc.h> +#include <mach/at91_shdwc.h> + +#include "sam9_smc.h" +#include "generic.h" + + +static void __init ek_init_early(void) +{ + /* Initialize processor: 12.000 MHz crystal */ + at91sam9260_initialize(12000000); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init ek_init_irq(void) +{ + at91sam9260_init_interrupts(NULL); +} + + +/* + * USB Host port + */ +static struct at91_usbh_data __initdata ek_usbh_data = { + .ports = 2, +}; + +/* + * USB Device port + */ +static struct at91_udc_data __initdata ek_udc_data = { + .vbus_pin = AT91_PIN_PC5, + .pullup_pin = 0, /* pull-up driven by UDC */ +}; + +/* + * MACB Ethernet device + */ +static struct at91_eth_data __initdata ek_macb_data = { + .phy_irq_pin = AT91_PIN_PA31, + .is_rmii = 1, +}; + +/* + * NAND flash + */ +static struct mtd_partition __initdata ek_nand_partition[] = { + { + .name = "Uboot & Kernel", + .offset = 0, + .size = SZ_16M, + }, + { + .name = "Root FS", + .offset = MTDPART_OFS_NXTBLK, + .size = 120 * SZ_1M, + }, + { + .name = "FS", + .offset = MTDPART_OFS_NXTBLK, + .size = 120 * SZ_1M, + } +}; + +static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(ek_nand_partition); + return ek_nand_partition; +} + +static struct atmel_nand_data __initdata ek_nand_data = { + .ale = 21, + .cle = 22, +// .det_pin = ... not connected + .rdy_pin = AT91_PIN_PC13, + .enable_pin = AT91_PIN_PC14, + .partition_info = nand_partitions, +}; + +static struct sam9_smc_config __initdata ek_nand_smc_config = { + .ncs_read_setup = 0, + .nrd_setup = 1, + .ncs_write_setup = 0, + .nwe_setup = 1, + + .ncs_read_pulse = 3, + .nrd_pulse = 3, + .ncs_write_pulse = 3, + .nwe_pulse = 3, + + .read_cycle = 5, + .write_cycle = 5, + + .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8, + .tdf_cycles = 2, +}; + +static void __init ek_add_device_nand(void) +{ + /* configure chip-select 3 (NAND) */ + sam9_smc_configure(3, &ek_nand_smc_config); + + at91_add_device_nand(&ek_nand_data); +} + +/* + * GPIO Buttons + */ + +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +static struct gpio_keys_button ek_buttons[] = { + { /* USER PUSH BUTTON */ + .code = KEY_ENTER, + .gpio = AT91_PIN_PB10, + .active_low = 1, + .desc = "user_pb", + .wakeup = 1, + } +}; + +static struct gpio_keys_platform_data ek_button_data = { + .buttons = ek_buttons, + .nbuttons = ARRAY_SIZE(ek_buttons), +}; + +static struct platform_device ek_button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &ek_button_data, + } +}; + +static void __init ek_add_device_buttons(void) +{ + at91_set_GPIO_periph(AT91_PIN_PB10, 1); /* user push button, pull up enabled */ + at91_set_deglitch(AT91_PIN_PB10, 1); + + platform_device_register(&ek_button_device); +} +#else +static void __init ek_add_device_buttons(void) {} +#endif + +/* + * LEDs + */ +static struct gpio_led ek_leds[] = { + { /* user_led (green) */ + .name = "user_led", + .gpio = AT91_PIN_PB21, + .active_low = 0, + .default_trigger = "heartbeat", + } +}; + +static void __init ek_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* USB Host */ + at91_add_device_usbh(&ek_usbh_data); + /* USB Device */ + at91_add_device_udc(&ek_udc_data); + /* NAND */ + ek_add_device_nand(); + /* I2C */ + at91_add_device_i2c(NULL, 0); + /* Ethernet */ + at91_add_device_eth(&ek_macb_data); + /* Push Buttons */ + ek_add_device_buttons(); + /* LEDs */ + at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); + /* shutdown controller, wakeup button (5 msec low) */ + at91_sys_write(AT91_SHDW_MR, AT91_SHDW_CPTWK0_(10) | AT91_SHDW_WKMODE0_LOW + | AT91_SHDW_RTTWKEN); +} + +MACHINE_START(USB_A9260, "CALAO USB_A9260") + /* Maintainer: calao-systems */ + .timer = &at91sam926x_timer, + .map_io = at91sam9260_map_io, + .init_early = ek_init_early, + .init_irq = ek_init_irq, + .init_machine = ek_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-usb-a9263.c b/arch/arm/mach-at91/board-usb-a9263.c new file mode 100644 index 00000000..cf626dd1 --- /dev/null +++ b/arch/arm/mach-at91/board-usb-a9263.c @@ -0,0 +1,252 @@ +/* + * linux/arch/arm/mach-at91/board-usb-a9263.c + * + * Copyright (C) 2005 SAN People + * Copyright (C) 2007 Atmel Corporation. + * Copyright (C) 2007 Calao-systems + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> +#include <linux/gpio_keys.h> +#include <linux/input.h> + +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <mach/hardware.h> +#include <mach/board.h> +#include <mach/gpio.h> +#include <mach/at91sam9_smc.h> +#include <mach/at91_shdwc.h> + +#include "sam9_smc.h" +#include "generic.h" + + +static void __init ek_init_early(void) +{ + /* Initialize processor: 12.00 MHz crystal */ + at91sam9263_initialize(12000000); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init ek_init_irq(void) +{ + at91sam9263_init_interrupts(NULL); +} + + +/* + * USB Host port + */ +static struct at91_usbh_data __initdata ek_usbh_data = { + .ports = 2, +}; + +/* + * USB Device port + */ +static struct at91_udc_data __initdata ek_udc_data = { + .vbus_pin = AT91_PIN_PB11, + .pullup_pin = 0, /* pull-up driven by UDC */ +}; + +/* + * SPI devices. + */ +static struct spi_board_info ek_spi_devices[] = { +#if !defined(CONFIG_MMC_AT91) + { /* DataFlash chip */ + .modalias = "mtd_dataflash", + .chip_select = 0, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + } +#endif +}; + +/* + * MACB Ethernet device + */ +static struct at91_eth_data __initdata ek_macb_data = { + .phy_irq_pin = AT91_PIN_PE31, + .is_rmii = 1, +}; + +/* + * NAND flash + */ +static struct mtd_partition __initdata ek_nand_partition[] = { + { + .name = "Linux Kernel", + .offset = 0, + .size = SZ_16M, + }, + { + .name = "Root FS", + .offset = MTDPART_OFS_NXTBLK, + .size = 120 * SZ_1M, + }, + { + .name = "FS", + .offset = MTDPART_OFS_NXTBLK, + .size = 120 * SZ_1M, + } +}; + +static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(ek_nand_partition); + return ek_nand_partition; +} + +static struct atmel_nand_data __initdata ek_nand_data = { + .ale = 21, + .cle = 22, +// .det_pin = ... not connected + .rdy_pin = AT91_PIN_PA22, + .enable_pin = AT91_PIN_PD15, + .partition_info = nand_partitions, +}; + +static struct sam9_smc_config __initdata ek_nand_smc_config = { + .ncs_read_setup = 0, + .nrd_setup = 1, + .ncs_write_setup = 0, + .nwe_setup = 1, + + .ncs_read_pulse = 3, + .nrd_pulse = 3, + .ncs_write_pulse = 3, + .nwe_pulse = 3, + + .read_cycle = 5, + .write_cycle = 5, + + .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8, + .tdf_cycles = 2, +}; + +static void __init ek_add_device_nand(void) +{ + /* configure chip-select 3 (NAND) */ + sam9_smc_configure(3, &ek_nand_smc_config); + + at91_add_device_nand(&ek_nand_data); +} + + +/* + * GPIO Buttons + */ +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +static struct gpio_keys_button ek_buttons[] = { + { /* USER PUSH BUTTON */ + .code = KEY_ENTER, + .gpio = AT91_PIN_PB10, + .active_low = 1, + .desc = "user_pb", + .wakeup = 1, + } +}; + +static struct gpio_keys_platform_data ek_button_data = { + .buttons = ek_buttons, + .nbuttons = ARRAY_SIZE(ek_buttons), +}; + +static struct platform_device ek_button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &ek_button_data, + } +}; + +static void __init ek_add_device_buttons(void) +{ + at91_set_GPIO_periph(AT91_PIN_PB10, 1); /* user push button, pull up enabled */ + at91_set_deglitch(AT91_PIN_PB10, 1); + + platform_device_register(&ek_button_device); +} +#else +static void __init ek_add_device_buttons(void) {} +#endif + +/* + * LEDs + */ +static struct gpio_led ek_leds[] = { + { /* user_led (green) */ + .name = "user_led", + .gpio = AT91_PIN_PB21, + .active_low = 1, + .default_trigger = "heartbeat", + } +}; + + +static void __init ek_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* USB Host */ + at91_add_device_usbh(&ek_usbh_data); + /* USB Device */ + at91_add_device_udc(&ek_udc_data); + /* SPI */ + at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); + /* Ethernet */ + at91_add_device_eth(&ek_macb_data); + /* NAND */ + ek_add_device_nand(); + /* I2C */ + at91_add_device_i2c(NULL, 0); + /* Push Buttons */ + ek_add_device_buttons(); + /* LEDs */ + at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); + /* shutdown controller, wakeup button (5 msec low) */ + at91_sys_write(AT91_SHDW_MR, AT91_SHDW_CPTWK0_(10) | AT91_SHDW_WKMODE0_LOW + | AT91_SHDW_RTTWKEN); +} + +MACHINE_START(USB_A9263, "CALAO USB_A9263") + /* Maintainer: calao-systems */ + .timer = &at91sam926x_timer, + .map_io = at91sam9263_map_io, + .init_early = ek_init_early, + .init_irq = ek_init_irq, + .init_machine = ek_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-yl-9200.c b/arch/arm/mach-at91/board-yl-9200.c new file mode 100644 index 00000000..c208cc33 --- /dev/null +++ b/arch/arm/mach-at91/board-yl-9200.c @@ -0,0 +1,606 @@ +/* + * linux/arch/arm/mach-at91/board-yl-9200.c + * + * Adapted from various board files in arch/arm/mach-at91 + * + * Modifications for YL-9200 platform: + * Copyright (C) 2007 S. Birtles + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/dma-mapping.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> +#include <linux/spi/ads7846.h> +#include <linux/mtd/physmap.h> +#include <linux/gpio_keys.h> +#include <linux/input.h> + +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <mach/hardware.h> +#include <mach/board.h> +#include <mach/gpio.h> +#include <mach/at91rm9200_mc.h> +#include <mach/cpu.h> + +#include "generic.h" + + +static void __init yl9200_init_early(void) +{ + /* Set cpu type: PQFP */ + at91rm9200_set_type(ARCH_REVISON_9200_PQFP); + + /* Initialize processor: 18.432 MHz crystal */ + at91rm9200_initialize(18432000); + + /* Setup the LEDs D2=PB17 (timer), D3=PB16 (cpu) */ + at91_init_leds(AT91_PIN_PB16, AT91_PIN_PB17); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD + | ATMEL_UART_RI); + + /* USART0 on ttyS2. (Rx & Tx only to JP3) */ + at91_register_uart(AT91RM9200_ID_US0, 2, 0); + + /* USART3 on ttyS3. (Rx, Tx, RTS - RS485 interface) */ + at91_register_uart(AT91RM9200_ID_US3, 3, ATMEL_UART_RTS); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init yl9200_init_irq(void) +{ + at91rm9200_init_interrupts(NULL); +} + + +/* + * LEDs + */ +static struct gpio_led yl9200_leds[] = { + { /* D2 */ + .name = "led2", + .gpio = AT91_PIN_PB17, + .active_low = 1, + .default_trigger = "timer", + }, + { /* D3 */ + .name = "led3", + .gpio = AT91_PIN_PB16, + .active_low = 1, + .default_trigger = "heartbeat", + }, + { /* D4 */ + .name = "led4", + .gpio = AT91_PIN_PB15, + .active_low = 1, + }, + { /* D5 */ + .name = "led5", + .gpio = AT91_PIN_PB8, + .active_low = 1, + } +}; + +/* + * Ethernet + */ +static struct at91_eth_data __initdata yl9200_eth_data = { + .phy_irq_pin = AT91_PIN_PB28, + .is_rmii = 1, +}; + +/* + * USB Host + */ +static struct at91_usbh_data __initdata yl9200_usbh_data = { + .ports = 1, /* PQFP version of AT91RM9200 */ +}; + +/* + * USB Device + */ +static struct at91_udc_data __initdata yl9200_udc_data = { + .pullup_pin = AT91_PIN_PC4, + .vbus_pin = AT91_PIN_PC5, + .pullup_active_low = 1, /* Active Low due to PNP transistor (pg 7) */ + +}; + +/* + * MMC + */ +static struct at91_mmc_data __initdata yl9200_mmc_data = { + .det_pin = AT91_PIN_PB9, + // .wp_pin = ... not connected + .wire4 = 1, +}; + +/* + * NAND Flash + */ +static struct mtd_partition __initdata yl9200_nand_partition[] = { + { + .name = "AT91 NAND partition 1, boot", + .offset = 0, + .size = SZ_256K + }, + { + .name = "AT91 NAND partition 2, kernel", + .offset = MTDPART_OFS_NXTBLK, + .size = (2 * SZ_1M) - SZ_256K + }, + { + .name = "AT91 NAND partition 3, filesystem", + .offset = MTDPART_OFS_NXTBLK, + .size = 14 * SZ_1M + }, + { + .name = "AT91 NAND partition 4, storage", + .offset = MTDPART_OFS_NXTBLK, + .size = SZ_16M + }, + { + .name = "AT91 NAND partition 5, ext-fs", + .offset = MTDPART_OFS_NXTBLK, + .size = SZ_32M + } +}; + +static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(yl9200_nand_partition); + return yl9200_nand_partition; +} + +static struct atmel_nand_data __initdata yl9200_nand_data = { + .ale = 6, + .cle = 7, + // .det_pin = ... not connected + .rdy_pin = AT91_PIN_PC14, /* R/!B (Sheet10) */ + .enable_pin = AT91_PIN_PC15, /* !CE (Sheet10) */ + .partition_info = nand_partitions, +}; + +/* + * NOR Flash + */ +#define YL9200_FLASH_BASE AT91_CHIPSELECT_0 +#define YL9200_FLASH_SIZE SZ_16M + +static struct mtd_partition yl9200_flash_partitions[] = { + { + .name = "Bootloader", + .offset = 0, + .size = SZ_256K, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + { + .name = "Kernel", + .offset = MTDPART_OFS_NXTBLK, + .size = (2 * SZ_1M) - SZ_256K + }, + { + .name = "Filesystem", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL + } +}; + +static struct physmap_flash_data yl9200_flash_data = { + .width = 2, + .parts = yl9200_flash_partitions, + .nr_parts = ARRAY_SIZE(yl9200_flash_partitions), +}; + +static struct resource yl9200_flash_resources[] = { + { + .start = YL9200_FLASH_BASE, + .end = YL9200_FLASH_BASE + YL9200_FLASH_SIZE - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device yl9200_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &yl9200_flash_data, + }, + .resource = yl9200_flash_resources, + .num_resources = ARRAY_SIZE(yl9200_flash_resources), +}; + +/* + * I2C (TWI) + */ +static struct i2c_board_info __initdata yl9200_i2c_devices[] = { + { /* EEPROM */ + I2C_BOARD_INFO("24c128", 0x50), + } +}; + +/* + * GPIO Buttons +*/ +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +static struct gpio_keys_button yl9200_buttons[] = { + { + .gpio = AT91_PIN_PA24, + .code = BTN_2, + .desc = "SW2", + .active_low = 1, + .wakeup = 1, + }, + { + .gpio = AT91_PIN_PB1, + .code = BTN_3, + .desc = "SW3", + .active_low = 1, + .wakeup = 1, + }, + { + .gpio = AT91_PIN_PB2, + .code = BTN_4, + .desc = "SW4", + .active_low = 1, + .wakeup = 1, + }, + { + .gpio = AT91_PIN_PB6, + .code = BTN_5, + .desc = "SW5", + .active_low = 1, + .wakeup = 1, + } +}; + +static struct gpio_keys_platform_data yl9200_button_data = { + .buttons = yl9200_buttons, + .nbuttons = ARRAY_SIZE(yl9200_buttons), +}; + +static struct platform_device yl9200_button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &yl9200_button_data, + } +}; + +static void __init yl9200_add_device_buttons(void) +{ + at91_set_gpio_input(AT91_PIN_PA24, 1); /* SW2 */ + at91_set_deglitch(AT91_PIN_PA24, 1); + at91_set_gpio_input(AT91_PIN_PB1, 1); /* SW3 */ + at91_set_deglitch(AT91_PIN_PB1, 1); + at91_set_gpio_input(AT91_PIN_PB2, 1); /* SW4 */ + at91_set_deglitch(AT91_PIN_PB2, 1); + at91_set_gpio_input(AT91_PIN_PB6, 1); /* SW5 */ + at91_set_deglitch(AT91_PIN_PB6, 1); + + /* Enable buttons (Sheet 5) */ + at91_set_gpio_output(AT91_PIN_PB7, 1); + + platform_device_register(&yl9200_button_device); +} +#else +static void __init yl9200_add_device_buttons(void) {} +#endif + +/* + * Touchscreen + */ +#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) +static int ads7843_pendown_state(void) +{ + return !at91_get_gpio_value(AT91_PIN_PB11); /* Touchscreen PENIRQ */ +} + +static struct ads7846_platform_data ads_info = { + .model = 7843, + .x_min = 150, + .x_max = 3830, + .y_min = 190, + .y_max = 3830, + .vref_delay_usecs = 100, + + /* For a 8" touch-screen */ + // .x_plate_ohms = 603, + // .y_plate_ohms = 332, + + /* For a 10.4" touch-screen */ + // .x_plate_ohms = 611, + // .y_plate_ohms = 325, + + .x_plate_ohms = 576, + .y_plate_ohms = 366, + + .pressure_max = 15000, /* generally nonsense on the 7843 */ + .debounce_max = 1, + .debounce_rep = 0, + .debounce_tol = (~0), + .get_pendown_state = ads7843_pendown_state, +}; + +static void __init yl9200_add_device_ts(void) +{ + at91_set_gpio_input(AT91_PIN_PB11, 1); /* Touchscreen interrupt pin */ + at91_set_gpio_input(AT91_PIN_PB10, 1); /* Touchscreen BUSY signal - not used! */ +} +#else +static void __init yl9200_add_device_ts(void) {} +#endif + +/* + * SPI devices + */ +static struct spi_board_info yl9200_spi_devices[] = { +#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) + { /* Touchscreen */ + .modalias = "ads7846", + .chip_select = 0, + .max_speed_hz = 5000 * 26, + .platform_data = &ads_info, + .irq = AT91_PIN_PB11, + }, +#endif + { /* CAN */ + .modalias = "mcp2510", + .chip_select = 1, + .max_speed_hz = 25000 * 26, + .irq = AT91_PIN_PC0, + } +}; + +/* + * LCD / VGA + * + * EPSON S1D13806 FB (discontinued chip) + * EPSON S1D13506 FB + */ +#if defined(CONFIG_FB_S1D13XXX) || defined(CONFIG_FB_S1D13XXX_MODULE) +#include <video/s1d13xxxfb.h> + + +static void __init yl9200_init_video(void) +{ + /* NWAIT Signal */ + at91_set_A_periph(AT91_PIN_PC6, 0); + + /* Initialization of the Static Memory Controller for Chip Select 2 */ + at91_sys_write(AT91_SMC_CSR(2), AT91_SMC_DBW_16 /* 16 bit */ + | AT91_SMC_WSEN | AT91_SMC_NWS_(0x4) /* wait states */ + | AT91_SMC_TDF_(0x100) /* float time */ + ); +} + +static struct s1d13xxxfb_regval yl9200_s1dfb_initregs[] = +{ + {S1DREG_MISC, 0x00}, /* Miscellaneous Register*/ + {S1DREG_COM_DISP_MODE, 0x01}, /* Display Mode Register, LCD only*/ + {S1DREG_GPIO_CNF0, 0x00}, /* General IO Pins Configuration Register*/ + {S1DREG_GPIO_CTL0, 0x00}, /* General IO Pins Control Register*/ + {S1DREG_CLK_CNF, 0x11}, /* Memory Clock Configuration Register*/ + {S1DREG_LCD_CLK_CNF, 0x10}, /* LCD Pixel Clock Configuration Register*/ + {S1DREG_CRT_CLK_CNF, 0x12}, /* CRT/TV Pixel Clock Configuration Register*/ + {S1DREG_MPLUG_CLK_CNF, 0x01}, /* MediaPlug Clock Configuration Register*/ + {S1DREG_CPU2MEM_WST_SEL, 0x02}, /* CPU To Memory Wait State Select Register*/ + {S1DREG_MEM_CNF, 0x00}, /* Memory Configuration Register*/ + {S1DREG_SDRAM_REF_RATE, 0x04}, /* DRAM Refresh Rate Register, MCLK source*/ + {S1DREG_SDRAM_TC0, 0x12}, /* DRAM Timings Control Register 0*/ + {S1DREG_SDRAM_TC1, 0x02}, /* DRAM Timings Control Register 1*/ + {S1DREG_PANEL_TYPE, 0x25}, /* Panel Type Register*/ + {S1DREG_MOD_RATE, 0x00}, /* MOD Rate Register*/ + {S1DREG_LCD_DISP_HWIDTH, 0x4F}, /* LCD Horizontal Display Width Register*/ + {S1DREG_LCD_NDISP_HPER, 0x13}, /* LCD Horizontal Non-Display Period Register*/ + {S1DREG_TFT_FPLINE_START, 0x01}, /* TFT FPLINE Start Position Register*/ + {S1DREG_TFT_FPLINE_PWIDTH, 0x0c}, /* TFT FPLINE Pulse Width Register*/ + {S1DREG_LCD_DISP_VHEIGHT0, 0xDF}, /* LCD Vertical Display Height Register 0*/ + {S1DREG_LCD_DISP_VHEIGHT1, 0x01}, /* LCD Vertical Display Height Register 1*/ + {S1DREG_LCD_NDISP_VPER, 0x2c}, /* LCD Vertical Non-Display Period Register*/ + {S1DREG_TFT_FPFRAME_START, 0x0a}, /* TFT FPFRAME Start Position Register*/ + {S1DREG_TFT_FPFRAME_PWIDTH, 0x02}, /* TFT FPFRAME Pulse Width Register*/ + {S1DREG_LCD_DISP_MODE, 0x05}, /* LCD Display Mode Register*/ + {S1DREG_LCD_MISC, 0x01}, /* LCD Miscellaneous Register*/ + {S1DREG_LCD_DISP_START0, 0x00}, /* LCD Display Start Address Register 0*/ + {S1DREG_LCD_DISP_START1, 0x00}, /* LCD Display Start Address Register 1*/ + {S1DREG_LCD_DISP_START2, 0x00}, /* LCD Display Start Address Register 2*/ + {S1DREG_LCD_MEM_OFF0, 0x80}, /* LCD Memory Address Offset Register 0*/ + {S1DREG_LCD_MEM_OFF1, 0x02}, /* LCD Memory Address Offset Register 1*/ + {S1DREG_LCD_PIX_PAN, 0x03}, /* LCD Pixel Panning Register*/ + {S1DREG_LCD_DISP_FIFO_HTC, 0x00}, /* LCD Display FIFO High Threshold Control Register*/ + {S1DREG_LCD_DISP_FIFO_LTC, 0x00}, /* LCD Display FIFO Low Threshold Control Register*/ + {S1DREG_CRT_DISP_HWIDTH, 0x4F}, /* CRT/TV Horizontal Display Width Register*/ + {S1DREG_CRT_NDISP_HPER, 0x13}, /* CRT/TV Horizontal Non-Display Period Register*/ + {S1DREG_CRT_HRTC_START, 0x01}, /* CRT/TV HRTC Start Position Register*/ + {S1DREG_CRT_HRTC_PWIDTH, 0x0B}, /* CRT/TV HRTC Pulse Width Register*/ + {S1DREG_CRT_DISP_VHEIGHT0, 0xDF}, /* CRT/TV Vertical Display Height Register 0*/ + {S1DREG_CRT_DISP_VHEIGHT1, 0x01}, /* CRT/TV Vertical Display Height Register 1*/ + {S1DREG_CRT_NDISP_VPER, 0x2B}, /* CRT/TV Vertical Non-Display Period Register*/ + {S1DREG_CRT_VRTC_START, 0x09}, /* CRT/TV VRTC Start Position Register*/ + {S1DREG_CRT_VRTC_PWIDTH, 0x01}, /* CRT/TV VRTC Pulse Width Register*/ + {S1DREG_TV_OUT_CTL, 0x18}, /* TV Output Control Register */ + {S1DREG_CRT_DISP_MODE, 0x05}, /* CRT/TV Display Mode Register, 16BPP*/ + {S1DREG_CRT_DISP_START0, 0x00}, /* CRT/TV Display Start Address Register 0*/ + {S1DREG_CRT_DISP_START1, 0x00}, /* CRT/TV Display Start Address Register 1*/ + {S1DREG_CRT_DISP_START2, 0x00}, /* CRT/TV Display Start Address Register 2*/ + {S1DREG_CRT_MEM_OFF0, 0x80}, /* CRT/TV Memory Address Offset Register 0*/ + {S1DREG_CRT_MEM_OFF1, 0x02}, /* CRT/TV Memory Address Offset Register 1*/ + {S1DREG_CRT_PIX_PAN, 0x00}, /* CRT/TV Pixel Panning Register*/ + {S1DREG_CRT_DISP_FIFO_HTC, 0x00}, /* CRT/TV Display FIFO High Threshold Control Register*/ + {S1DREG_CRT_DISP_FIFO_LTC, 0x00}, /* CRT/TV Display FIFO Low Threshold Control Register*/ + {S1DREG_LCD_CUR_CTL, 0x00}, /* LCD Ink/Cursor Control Register*/ + {S1DREG_LCD_CUR_START, 0x01}, /* LCD Ink/Cursor Start Address Register*/ + {S1DREG_LCD_CUR_XPOS0, 0x00}, /* LCD Cursor X Position Register 0*/ + {S1DREG_LCD_CUR_XPOS1, 0x00}, /* LCD Cursor X Position Register 1*/ + {S1DREG_LCD_CUR_YPOS0, 0x00}, /* LCD Cursor Y Position Register 0*/ + {S1DREG_LCD_CUR_YPOS1, 0x00}, /* LCD Cursor Y Position Register 1*/ + {S1DREG_LCD_CUR_BCTL0, 0x00}, /* LCD Ink/Cursor Blue Color 0 Register*/ + {S1DREG_LCD_CUR_GCTL0, 0x00}, /* LCD Ink/Cursor Green Color 0 Register*/ + {S1DREG_LCD_CUR_RCTL0, 0x00}, /* LCD Ink/Cursor Red Color 0 Register*/ + {S1DREG_LCD_CUR_BCTL1, 0x1F}, /* LCD Ink/Cursor Blue Color 1 Register*/ + {S1DREG_LCD_CUR_GCTL1, 0x3F}, /* LCD Ink/Cursor Green Color 1 Register*/ + {S1DREG_LCD_CUR_RCTL1, 0x1F}, /* LCD Ink/Cursor Red Color 1 Register*/ + {S1DREG_LCD_CUR_FIFO_HTC, 0x00}, /* LCD Ink/Cursor FIFO Threshold Register*/ + {S1DREG_CRT_CUR_CTL, 0x00}, /* CRT/TV Ink/Cursor Control Register*/ + {S1DREG_CRT_CUR_START, 0x01}, /* CRT/TV Ink/Cursor Start Address Register*/ + {S1DREG_CRT_CUR_XPOS0, 0x00}, /* CRT/TV Cursor X Position Register 0*/ + {S1DREG_CRT_CUR_XPOS1, 0x00}, /* CRT/TV Cursor X Position Register 1*/ + {S1DREG_CRT_CUR_YPOS0, 0x00}, /* CRT/TV Cursor Y Position Register 0*/ + {S1DREG_CRT_CUR_YPOS1, 0x00}, /* CRT/TV Cursor Y Position Register 1*/ + {S1DREG_CRT_CUR_BCTL0, 0x00}, /* CRT/TV Ink/Cursor Blue Color 0 Register*/ + {S1DREG_CRT_CUR_GCTL0, 0x00}, /* CRT/TV Ink/Cursor Green Color 0 Register*/ + {S1DREG_CRT_CUR_RCTL0, 0x00}, /* CRT/TV Ink/Cursor Red Color 0 Register*/ + {S1DREG_CRT_CUR_BCTL1, 0x1F}, /* CRT/TV Ink/Cursor Blue Color 1 Register*/ + {S1DREG_CRT_CUR_GCTL1, 0x3F}, /* CRT/TV Ink/Cursor Green Color 1 Register*/ + {S1DREG_CRT_CUR_RCTL1, 0x1F}, /* CRT/TV Ink/Cursor Red Color 1 Register*/ + {S1DREG_CRT_CUR_FIFO_HTC, 0x00}, /* CRT/TV Ink/Cursor FIFO Threshold Register*/ + {S1DREG_BBLT_CTL0, 0x00}, /* BitBlt Control Register 0*/ + {S1DREG_BBLT_CTL1, 0x01}, /* BitBlt Control Register 1*/ + {S1DREG_BBLT_CC_EXP, 0x00}, /* BitBlt ROP Code/Color Expansion Register*/ + {S1DREG_BBLT_OP, 0x00}, /* BitBlt Operation Register*/ + {S1DREG_BBLT_SRC_START0, 0x00}, /* BitBlt Source Start Address Register 0*/ + {S1DREG_BBLT_SRC_START1, 0x00}, /* BitBlt Source Start Address Register 1*/ + {S1DREG_BBLT_SRC_START2, 0x00}, /* BitBlt Source Start Address Register 2*/ + {S1DREG_BBLT_DST_START0, 0x00}, /* BitBlt Destination Start Address Register 0*/ + {S1DREG_BBLT_DST_START1, 0x00}, /* BitBlt Destination Start Address Register 1*/ + {S1DREG_BBLT_DST_START2, 0x00}, /* BitBlt Destination Start Address Register 2*/ + {S1DREG_BBLT_MEM_OFF0, 0x00}, /* BitBlt Memory Address Offset Register 0*/ + {S1DREG_BBLT_MEM_OFF1, 0x00}, /* BitBlt Memory Address Offset Register 1*/ + {S1DREG_BBLT_WIDTH0, 0x00}, /* BitBlt Width Register 0*/ + {S1DREG_BBLT_WIDTH1, 0x00}, /* BitBlt Width Register 1*/ + {S1DREG_BBLT_HEIGHT0, 0x00}, /* BitBlt Height Register 0*/ + {S1DREG_BBLT_HEIGHT1, 0x00}, /* BitBlt Height Register 1*/ + {S1DREG_BBLT_BGC0, 0x00}, /* BitBlt Background Color Register 0*/ + {S1DREG_BBLT_BGC1, 0x00}, /* BitBlt Background Color Register 1*/ + {S1DREG_BBLT_FGC0, 0x00}, /* BitBlt Foreground Color Register 0*/ + {S1DREG_BBLT_FGC1, 0x00}, /* BitBlt Foreground Color Register 1*/ + {S1DREG_LKUP_MODE, 0x00}, /* Look-Up Table Mode Register*/ + {S1DREG_LKUP_ADDR, 0x00}, /* Look-Up Table Address Register*/ + {S1DREG_PS_CNF, 0x00}, /* Power Save Configuration Register*/ + {S1DREG_PS_STATUS, 0x00}, /* Power Save Status Register*/ + {S1DREG_CPU2MEM_WDOGT, 0x00}, /* CPU-to-Memory Access Watchdog Timer Register*/ + {S1DREG_COM_DISP_MODE, 0x01}, /* Display Mode Register, LCD only*/ +}; + +static struct s1d13xxxfb_pdata yl9200_s1dfb_pdata = { + .initregs = yl9200_s1dfb_initregs, + .initregssize = ARRAY_SIZE(yl9200_s1dfb_initregs), + .platform_init_video = yl9200_init_video, +}; + +#define YL9200_FB_REG_BASE AT91_CHIPSELECT_7 +#define YL9200_FB_VMEM_BASE YL9200_FB_REG_BASE + SZ_2M +#define YL9200_FB_VMEM_SIZE SZ_2M + +static struct resource yl9200_s1dfb_resource[] = { + [0] = { /* video mem */ + .name = "s1d13xxxfb memory", + .start = YL9200_FB_VMEM_BASE, + .end = YL9200_FB_VMEM_BASE + YL9200_FB_VMEM_SIZE -1, + .flags = IORESOURCE_MEM, + }, + [1] = { /* video registers */ + .name = "s1d13xxxfb registers", + .start = YL9200_FB_REG_BASE, + .end = YL9200_FB_REG_BASE + SZ_512 -1, + .flags = IORESOURCE_MEM, + }, +}; + +static u64 s1dfb_dmamask = DMA_BIT_MASK(32); + +static struct platform_device yl9200_s1dfb_device = { + .name = "s1d13806fb", + .id = -1, + .dev = { + .dma_mask = &s1dfb_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &yl9200_s1dfb_pdata, + }, + .resource = yl9200_s1dfb_resource, + .num_resources = ARRAY_SIZE(yl9200_s1dfb_resource), +}; + +void __init yl9200_add_device_video(void) +{ + platform_device_register(&yl9200_s1dfb_device); +} +#else +void __init yl9200_add_device_video(void) {} +#endif + + +static void __init yl9200_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* Ethernet */ + at91_add_device_eth(&yl9200_eth_data); + /* USB Host */ + at91_add_device_usbh(&yl9200_usbh_data); + /* USB Device */ + at91_add_device_udc(&yl9200_udc_data); + /* I2C */ + at91_add_device_i2c(yl9200_i2c_devices, ARRAY_SIZE(yl9200_i2c_devices)); + /* MMC */ + at91_add_device_mmc(0, &yl9200_mmc_data); + /* NAND */ + at91_add_device_nand(&yl9200_nand_data); + /* NOR Flash */ + platform_device_register(&yl9200_flash); +#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) + /* SPI */ + at91_add_device_spi(yl9200_spi_devices, ARRAY_SIZE(yl9200_spi_devices)); + /* Touchscreen */ + yl9200_add_device_ts(); +#endif + /* LEDs. */ + at91_gpio_leds(yl9200_leds, ARRAY_SIZE(yl9200_leds)); + /* Push Buttons */ + yl9200_add_device_buttons(); + /* VGA */ + yl9200_add_device_video(); +} + +MACHINE_START(YL9200, "uCdragon YL-9200") + /* Maintainer: S.Birtles */ + .timer = &at91rm9200_timer, + .map_io = at91rm9200_map_io, + .init_early = yl9200_init_early, + .init_irq = yl9200_init_irq, + .init_machine = yl9200_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c new file mode 100644 index 00000000..61873f3a --- /dev/null +++ b/arch/arm/mach-at91/clock.c @@ -0,0 +1,778 @@ +/* + * linux/arch/arm/mach-at91/clock.c + * + * Copyright (C) 2005 David Brownell + * Copyright (C) 2005 Ivan Kokshaysky + * + * 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. + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/fs.h> +#include <linux/debugfs.h> +#include <linux/seq_file.h> +#include <linux/list.h> +#include <linux/errno.h> +#include <linux/err.h> +#include <linux/spinlock.h> +#include <linux/delay.h> +#include <linux/clk.h> +#include <linux/io.h> + +#include <mach/hardware.h> +#include <mach/at91_pmc.h> +#include <mach/cpu.h> + +#include "clock.h" +#include "generic.h" + + +/* + * There's a lot more which can be done with clocks, including cpufreq + * integration, slow clock mode support (for system suspend), letting + * PLLB be used at other rates (on boards that don't need USB), etc. + */ + +#define clk_is_primary(x) ((x)->type & CLK_TYPE_PRIMARY) +#define clk_is_programmable(x) ((x)->type & CLK_TYPE_PROGRAMMABLE) +#define clk_is_peripheral(x) ((x)->type & CLK_TYPE_PERIPHERAL) +#define clk_is_sys(x) ((x)->type & CLK_TYPE_SYSTEM) + + +/* + * Chips have some kind of clocks : group them by functionality + */ +#define cpu_has_utmi() ( cpu_is_at91cap9() \ + || cpu_is_at91sam9rl() \ + || cpu_is_at91sam9g45()) + +#define cpu_has_800M_plla() ( cpu_is_at91sam9g20() \ + || cpu_is_at91sam9g45()) + +#define cpu_has_300M_plla() (cpu_is_at91sam9g10()) + +#define cpu_has_pllb() (!(cpu_is_at91sam9rl() \ + || cpu_is_at91sam9g45())) + +#define cpu_has_upll() (cpu_is_at91sam9g45()) + +/* USB host HS & FS */ +#define cpu_has_uhp() (!cpu_is_at91sam9rl()) + +/* USB device FS only */ +#define cpu_has_udpfs() (!(cpu_is_at91sam9rl() \ + || cpu_is_at91sam9g45())) + +static LIST_HEAD(clocks); +static DEFINE_SPINLOCK(clk_lock); + +static u32 at91_pllb_usb_init; + +/* + * Four primary clock sources: two crystal oscillators (32K, main), and + * two PLLs. PLLA usually runs the master clock; and PLLB must run at + * 48 MHz (unless no USB function clocks are needed). The main clock and + * both PLLs are turned off to run in "slow clock mode" (system suspend). + */ +static struct clk clk32k = { + .name = "clk32k", + .rate_hz = AT91_SLOW_CLOCK, + .users = 1, /* always on */ + .id = 0, + .type = CLK_TYPE_PRIMARY, +}; +static struct clk main_clk = { + .name = "main", + .pmc_mask = AT91_PMC_MOSCS, /* in PMC_SR */ + .id = 1, + .type = CLK_TYPE_PRIMARY, +}; +static struct clk plla = { + .name = "plla", + .parent = &main_clk, + .pmc_mask = AT91_PMC_LOCKA, /* in PMC_SR */ + .id = 2, + .type = CLK_TYPE_PRIMARY | CLK_TYPE_PLL, +}; + +static void pllb_mode(struct clk *clk, int is_on) +{ + u32 value; + + if (is_on) { + is_on = AT91_PMC_LOCKB; + value = at91_pllb_usb_init; + } else + value = 0; + + // REVISIT: Add work-around for AT91RM9200 Errata #26 ? + at91_sys_write(AT91_CKGR_PLLBR, value); + + do { + cpu_relax(); + } while ((at91_sys_read(AT91_PMC_SR) & AT91_PMC_LOCKB) != is_on); +} + +static struct clk pllb = { + .name = "pllb", + .parent = &main_clk, + .pmc_mask = AT91_PMC_LOCKB, /* in PMC_SR */ + .mode = pllb_mode, + .id = 3, + .type = CLK_TYPE_PRIMARY | CLK_TYPE_PLL, +}; + +static void pmc_sys_mode(struct clk *clk, int is_on) +{ + if (is_on) + at91_sys_write(AT91_PMC_SCER, clk->pmc_mask); + else + at91_sys_write(AT91_PMC_SCDR, clk->pmc_mask); +} + +static void pmc_uckr_mode(struct clk *clk, int is_on) +{ + unsigned int uckr = at91_sys_read(AT91_CKGR_UCKR); + + if (cpu_is_at91sam9g45()) { + if (is_on) + uckr |= AT91_PMC_BIASEN; + else + uckr &= ~AT91_PMC_BIASEN; + } + + if (is_on) { + is_on = AT91_PMC_LOCKU; + at91_sys_write(AT91_CKGR_UCKR, uckr | clk->pmc_mask); + } else + at91_sys_write(AT91_CKGR_UCKR, uckr & ~(clk->pmc_mask)); + + do { + cpu_relax(); + } while ((at91_sys_read(AT91_PMC_SR) & AT91_PMC_LOCKU) != is_on); +} + +/* USB function clocks (PLLB must be 48 MHz) */ +static struct clk udpck = { + .name = "udpck", + .parent = &pllb, + .mode = pmc_sys_mode, +}; +struct clk utmi_clk = { + .name = "utmi_clk", + .parent = &main_clk, + .pmc_mask = AT91_PMC_UPLLEN, /* in CKGR_UCKR */ + .mode = pmc_uckr_mode, + .type = CLK_TYPE_PLL, +}; +static struct clk uhpck = { + .name = "uhpck", + /*.parent = ... we choose parent at runtime */ + .mode = pmc_sys_mode, +}; + + +/* + * The master clock is divided from the CPU clock (by 1-4). It's used for + * memory, interfaces to on-chip peripherals, the AIC, and sometimes more + * (e.g baud rate generation). It's sourced from one of the primary clocks. + */ +struct clk mck = { + .name = "mck", + .pmc_mask = AT91_PMC_MCKRDY, /* in PMC_SR */ +}; + +static void pmc_periph_mode(struct clk *clk, int is_on) +{ + if (is_on) + at91_sys_write(AT91_PMC_PCER, clk->pmc_mask); + else + at91_sys_write(AT91_PMC_PCDR, clk->pmc_mask); +} + +static struct clk __init *at91_css_to_clk(unsigned long css) +{ + switch (css) { + case AT91_PMC_CSS_SLOW: + return &clk32k; + case AT91_PMC_CSS_MAIN: + return &main_clk; + case AT91_PMC_CSS_PLLA: + return &plla; + case AT91_PMC_CSS_PLLB: + if (cpu_has_upll()) + /* CSS_PLLB == CSS_UPLL */ + return &utmi_clk; + else if (cpu_has_pllb()) + return &pllb; + } + + return NULL; +} + +static void __clk_enable(struct clk *clk) +{ + if (clk->parent) + __clk_enable(clk->parent); + if (clk->users++ == 0 && clk->mode) + clk->mode(clk, 1); +} + +int clk_enable(struct clk *clk) +{ + unsigned long flags; + + spin_lock_irqsave(&clk_lock, flags); + __clk_enable(clk); + spin_unlock_irqrestore(&clk_lock, flags); + return 0; +} +EXPORT_SYMBOL(clk_enable); + +static void __clk_disable(struct clk *clk) +{ + BUG_ON(clk->users == 0); + if (--clk->users == 0 && clk->mode) + clk->mode(clk, 0); + if (clk->parent) + __clk_disable(clk->parent); +} + +void clk_disable(struct clk *clk) +{ + unsigned long flags; + + spin_lock_irqsave(&clk_lock, flags); + __clk_disable(clk); + spin_unlock_irqrestore(&clk_lock, flags); +} +EXPORT_SYMBOL(clk_disable); + +unsigned long clk_get_rate(struct clk *clk) +{ + unsigned long flags; + unsigned long rate; + + spin_lock_irqsave(&clk_lock, flags); + for (;;) { + rate = clk->rate_hz; + if (rate || !clk->parent) + break; + clk = clk->parent; + } + spin_unlock_irqrestore(&clk_lock, flags); + return rate; +} +EXPORT_SYMBOL(clk_get_rate); + +/*------------------------------------------------------------------------*/ + +#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS + +/* + * For now, only the programmable clocks support reparenting (MCK could + * do this too, with care) or rate changing (the PLLs could do this too, + * ditto MCK but that's more for cpufreq). Drivers may reparent to get + * a better rate match; we don't. + */ + +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + unsigned long flags; + unsigned prescale; + unsigned long actual; + unsigned long prev = ULONG_MAX; + + if (!clk_is_programmable(clk)) + return -EINVAL; + spin_lock_irqsave(&clk_lock, flags); + + actual = clk->parent->rate_hz; + for (prescale = 0; prescale < 7; prescale++) { + if (actual > rate) + prev = actual; + + if (actual && actual <= rate) { + if ((prev - rate) < (rate - actual)) { + actual = prev; + prescale--; + } + break; + } + actual >>= 1; + } + + spin_unlock_irqrestore(&clk_lock, flags); + return (prescale < 7) ? actual : -ENOENT; +} +EXPORT_SYMBOL(clk_round_rate); + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + unsigned long flags; + unsigned prescale; + unsigned long actual; + + if (!clk_is_programmable(clk)) + return -EINVAL; + if (clk->users) + return -EBUSY; + spin_lock_irqsave(&clk_lock, flags); + + actual = clk->parent->rate_hz; + for (prescale = 0; prescale < 7; prescale++) { + if (actual && actual <= rate) { + u32 pckr; + + pckr = at91_sys_read(AT91_PMC_PCKR(clk->id)); + pckr &= AT91_PMC_CSS; /* clock selection */ + pckr |= prescale << 2; + at91_sys_write(AT91_PMC_PCKR(clk->id), pckr); + clk->rate_hz = actual; + break; + } + actual >>= 1; + } + + spin_unlock_irqrestore(&clk_lock, flags); + return (prescale < 7) ? actual : -ENOENT; +} +EXPORT_SYMBOL(clk_set_rate); + +struct clk *clk_get_parent(struct clk *clk) +{ + return clk->parent; +} +EXPORT_SYMBOL(clk_get_parent); + +int clk_set_parent(struct clk *clk, struct clk *parent) +{ + unsigned long flags; + + if (clk->users) + return -EBUSY; + if (!clk_is_primary(parent) || !clk_is_programmable(clk)) + return -EINVAL; + + if (cpu_is_at91sam9rl() && parent->id == AT91_PMC_CSS_PLLB) + return -EINVAL; + + spin_lock_irqsave(&clk_lock, flags); + + clk->rate_hz = parent->rate_hz; + clk->parent = parent; + at91_sys_write(AT91_PMC_PCKR(clk->id), parent->id); + + spin_unlock_irqrestore(&clk_lock, flags); + return 0; +} +EXPORT_SYMBOL(clk_set_parent); + +/* establish PCK0..PCKN parentage and rate */ +static void __init init_programmable_clock(struct clk *clk) +{ + struct clk *parent; + u32 pckr; + + pckr = at91_sys_read(AT91_PMC_PCKR(clk->id)); + parent = at91_css_to_clk(pckr & AT91_PMC_CSS); + clk->parent = parent; + clk->rate_hz = parent->rate_hz / (1 << ((pckr & AT91_PMC_PRES) >> 2)); +} + +#endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */ + +/*------------------------------------------------------------------------*/ + +#ifdef CONFIG_DEBUG_FS + +static int at91_clk_show(struct seq_file *s, void *unused) +{ + u32 scsr, pcsr, uckr = 0, sr; + struct clk *clk; + + seq_printf(s, "SCSR = %8x\n", scsr = at91_sys_read(AT91_PMC_SCSR)); + seq_printf(s, "PCSR = %8x\n", pcsr = at91_sys_read(AT91_PMC_PCSR)); + seq_printf(s, "MOR = %8x\n", at91_sys_read(AT91_CKGR_MOR)); + seq_printf(s, "MCFR = %8x\n", at91_sys_read(AT91_CKGR_MCFR)); + seq_printf(s, "PLLA = %8x\n", at91_sys_read(AT91_CKGR_PLLAR)); + if (cpu_has_pllb()) + seq_printf(s, "PLLB = %8x\n", at91_sys_read(AT91_CKGR_PLLBR)); + if (cpu_has_utmi()) + seq_printf(s, "UCKR = %8x\n", uckr = at91_sys_read(AT91_CKGR_UCKR)); + seq_printf(s, "MCKR = %8x\n", at91_sys_read(AT91_PMC_MCKR)); + if (cpu_has_upll()) + seq_printf(s, "USB = %8x\n", at91_sys_read(AT91_PMC_USB)); + seq_printf(s, "SR = %8x\n", sr = at91_sys_read(AT91_PMC_SR)); + + seq_printf(s, "\n"); + + list_for_each_entry(clk, &clocks, node) { + char *state; + + if (clk->mode == pmc_sys_mode) + state = (scsr & clk->pmc_mask) ? "on" : "off"; + else if (clk->mode == pmc_periph_mode) + state = (pcsr & clk->pmc_mask) ? "on" : "off"; + else if (clk->mode == pmc_uckr_mode) + state = (uckr & clk->pmc_mask) ? "on" : "off"; + else if (clk->pmc_mask) + state = (sr & clk->pmc_mask) ? "on" : "off"; + else if (clk == &clk32k || clk == &main_clk) + state = "on"; + else + state = ""; + + seq_printf(s, "%-10s users=%2d %-3s %9ld Hz %s\n", + clk->name, clk->users, state, clk_get_rate(clk), + clk->parent ? clk->parent->name : ""); + } + return 0; +} + +static int at91_clk_open(struct inode *inode, struct file *file) +{ + return single_open(file, at91_clk_show, NULL); +} + +static const struct file_operations at91_clk_operations = { + .open = at91_clk_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int __init at91_clk_debugfs_init(void) +{ + /* /sys/kernel/debug/at91_clk */ + (void) debugfs_create_file("at91_clk", S_IFREG | S_IRUGO, NULL, NULL, &at91_clk_operations); + + return 0; +} +postcore_initcall(at91_clk_debugfs_init); + +#endif + +/*------------------------------------------------------------------------*/ + +/* Register a new clock */ +static void __init at91_clk_add(struct clk *clk) +{ + list_add_tail(&clk->node, &clocks); + + clk->cl.con_id = clk->name; + clk->cl.clk = clk; + clkdev_add(&clk->cl); +} + +int __init clk_register(struct clk *clk) +{ + if (clk_is_peripheral(clk)) { + if (!clk->parent) + clk->parent = &mck; + clk->mode = pmc_periph_mode; + } + else if (clk_is_sys(clk)) { + clk->parent = &mck; + clk->mode = pmc_sys_mode; + } +#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS + else if (clk_is_programmable(clk)) { + clk->mode = pmc_sys_mode; + init_programmable_clock(clk); + } +#endif + + at91_clk_add(clk); + + return 0; +} + +/*------------------------------------------------------------------------*/ + +static u32 __init at91_pll_rate(struct clk *pll, u32 freq, u32 reg) +{ + unsigned mul, div; + + div = reg & 0xff; + mul = (reg >> 16) & 0x7ff; + if (div && mul) { + freq /= div; + freq *= mul + 1; + } else + freq = 0; + + return freq; +} + +static u32 __init at91_usb_rate(struct clk *pll, u32 freq, u32 reg) +{ + if (pll == &pllb && (reg & AT91_PMC_USB96M)) + return freq / 2; + else + return freq; +} + +static unsigned __init at91_pll_calc(unsigned main_freq, unsigned out_freq) +{ + unsigned i, div = 0, mul = 0, diff = 1 << 30; + unsigned ret = (out_freq > 155000000) ? 0xbe00 : 0x3e00; + + /* PLL output max 240 MHz (or 180 MHz per errata) */ + if (out_freq > 240000000) + goto fail; + + for (i = 1; i < 256; i++) { + int diff1; + unsigned input, mul1; + + /* + * PLL input between 1MHz and 32MHz per spec, but lower + * frequences seem necessary in some cases so allow 100K. + * Warning: some newer products need 2MHz min. + */ + input = main_freq / i; + if (cpu_is_at91sam9g20() && input < 2000000) + continue; + if (input < 100000) + continue; + if (input > 32000000) + continue; + + mul1 = out_freq / input; + if (cpu_is_at91sam9g20() && mul > 63) + continue; + if (mul1 > 2048) + continue; + if (mul1 < 2) + goto fail; + + diff1 = out_freq - input * mul1; + if (diff1 < 0) + diff1 = -diff1; + if (diff > diff1) { + diff = diff1; + div = i; + mul = mul1; + if (diff == 0) + break; + } + } + if (i == 256 && diff > (out_freq >> 5)) + goto fail; + return ret | ((mul - 1) << 16) | div; +fail: + return 0; +} + +static struct clk *const standard_pmc_clocks[] __initdata = { + /* four primary clocks */ + &clk32k, + &main_clk, + &plla, + + /* MCK */ + &mck +}; + +/* PLLB generated USB full speed clock init */ +static void __init at91_pllb_usbfs_clock_init(unsigned long main_clock) +{ + /* + * USB clock init: choose 48 MHz PLLB value, + * disable 48MHz clock during usb peripheral suspend. + * + * REVISIT: assumes MCK doesn't derive from PLLB! + */ + uhpck.parent = &pllb; + + at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | AT91_PMC_USB96M; + pllb.rate_hz = at91_pll_rate(&pllb, main_clock, at91_pllb_usb_init); + if (cpu_is_at91rm9200()) { + uhpck.pmc_mask = AT91RM9200_PMC_UHP; + udpck.pmc_mask = AT91RM9200_PMC_UDP; + at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP); + } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || + cpu_is_at91sam9263() || cpu_is_at91sam9g20() || + cpu_is_at91sam9g10()) { + uhpck.pmc_mask = AT91SAM926x_PMC_UHP; + udpck.pmc_mask = AT91SAM926x_PMC_UDP; + } else if (cpu_is_at91cap9()) { + uhpck.pmc_mask = AT91CAP9_PMC_UHP; + } + at91_sys_write(AT91_CKGR_PLLBR, 0); + + udpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init); + uhpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init); +} + +/* UPLL generated USB full speed clock init */ +static void __init at91_upll_usbfs_clock_init(unsigned long main_clock) +{ + /* + * USB clock init: choose 480 MHz from UPLL, + */ + unsigned int usbr = AT91_PMC_USBS_UPLL; + + /* Setup divider by 10 to reach 48 MHz */ + usbr |= ((10 - 1) << 8) & AT91_PMC_OHCIUSBDIV; + + at91_sys_write(AT91_PMC_USB, usbr); + + /* Now set uhpck values */ + uhpck.parent = &utmi_clk; + uhpck.pmc_mask = AT91SAM926x_PMC_UHP; + uhpck.rate_hz = utmi_clk.rate_hz; + uhpck.rate_hz /= 1 + ((at91_sys_read(AT91_PMC_USB) & AT91_PMC_OHCIUSBDIV) >> 8); +} + +int __init at91_clock_init(unsigned long main_clock) +{ + unsigned tmp, freq, mckr; + int i; + int pll_overclock = false; + + /* + * When the bootloader initialized the main oscillator correctly, + * there's no problem using the cycle counter. But if it didn't, + * or when using oscillator bypass mode, we must be told the speed + * of the main clock. + */ + if (!main_clock) { + do { + tmp = at91_sys_read(AT91_CKGR_MCFR); + } while (!(tmp & AT91_PMC_MAINRDY)); + main_clock = (tmp & AT91_PMC_MAINF) * (AT91_SLOW_CLOCK / 16); + } + main_clk.rate_hz = main_clock; + + /* report if PLLA is more than mildly overclocked */ + plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_sys_read(AT91_CKGR_PLLAR)); + if (cpu_has_300M_plla()) { + if (plla.rate_hz > 300000000) + pll_overclock = true; + } else if (cpu_has_800M_plla()) { + if (plla.rate_hz > 800000000) + pll_overclock = true; + } else { + if (plla.rate_hz > 209000000) + pll_overclock = true; + } + if (pll_overclock) + pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000); + + if (cpu_is_at91sam9g45()) { + mckr = at91_sys_read(AT91_PMC_MCKR); + plla.rate_hz /= (1 << ((mckr & AT91_PMC_PLLADIV2) >> 12)); /* plla divisor by 2 */ + } + + if (!cpu_has_pllb() && cpu_has_upll()) { + /* setup UTMI clock as the fourth primary clock + * (instead of pllb) */ + utmi_clk.type |= CLK_TYPE_PRIMARY; + utmi_clk.id = 3; + } + + + /* + * USB HS clock init + */ + if (cpu_has_utmi()) { + /* + * multiplier is hard-wired to 40 + * (obtain the USB High Speed 480 MHz when input is 12 MHz) + */ + utmi_clk.rate_hz = 40 * utmi_clk.parent->rate_hz; + } + + /* + * USB FS clock init + */ + if (cpu_has_pllb()) + at91_pllb_usbfs_clock_init(main_clock); + if (cpu_has_upll()) + /* assumes that we choose UPLL for USB and not PLLA */ + at91_upll_usbfs_clock_init(main_clock); + + /* + * MCK and CPU derive from one of those primary clocks. + * For now, assume this parentage won't change. + */ + mckr = at91_sys_read(AT91_PMC_MCKR); + mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS); + freq = mck.parent->rate_hz; + freq /= (1 << ((mckr & AT91_PMC_PRES) >> 2)); /* prescale */ + if (cpu_is_at91rm9200()) { + mck.rate_hz = freq / (1 + ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ + } else if (cpu_is_at91sam9g20()) { + mck.rate_hz = (mckr & AT91_PMC_MDIV) ? + freq / ((mckr & AT91_PMC_MDIV) >> 7) : freq; /* mdiv ; (x >> 7) = ((x >> 8) * 2) */ + if (mckr & AT91_PMC_PDIV) + freq /= 2; /* processor clock division */ + } else if (cpu_is_at91sam9g45()) { + mck.rate_hz = (mckr & AT91_PMC_MDIV) == AT91SAM9_PMC_MDIV_3 ? + freq / 3 : freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ + } else { + mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ + } + + /* Register the PMC's standard clocks */ + for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++) + at91_clk_add(standard_pmc_clocks[i]); + + if (cpu_has_pllb()) + at91_clk_add(&pllb); + + if (cpu_has_uhp()) + at91_clk_add(&uhpck); + + if (cpu_has_udpfs()) + at91_clk_add(&udpck); + + if (cpu_has_utmi()) + at91_clk_add(&utmi_clk); + + /* MCK and CPU clock are "always on" */ + clk_enable(&mck); + + printk("Clocks: CPU %u MHz, master %u MHz, main %u.%03u MHz\n", + freq / 1000000, (unsigned) mck.rate_hz / 1000000, + (unsigned) main_clock / 1000000, + ((unsigned) main_clock % 1000000) / 1000); + + return 0; +} + +/* + * Several unused clocks may be active. Turn them off. + */ +static int __init at91_clock_reset(void) +{ + unsigned long pcdr = 0; + unsigned long scdr = 0; + struct clk *clk; + + list_for_each_entry(clk, &clocks, node) { + if (clk->users > 0) + continue; + + if (clk->mode == pmc_periph_mode) + pcdr |= clk->pmc_mask; + + if (clk->mode == pmc_sys_mode) + scdr |= clk->pmc_mask; + + pr_debug("Clocks: disable unused %s\n", clk->name); + } + + at91_sys_write(AT91_PMC_PCDR, pcdr); + at91_sys_write(AT91_PMC_SCDR, scdr); + + return 0; +} +late_initcall(at91_clock_reset); diff --git a/arch/arm/mach-at91/clock.h b/arch/arm/mach-at91/clock.h new file mode 100644 index 00000000..c2e63e47 --- /dev/null +++ b/arch/arm/mach-at91/clock.h @@ -0,0 +1,47 @@ +/* + * linux/arch/arm/mach-at91/clock.h + * + * 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/clkdev.h> + +#define CLK_TYPE_PRIMARY 0x1 +#define CLK_TYPE_PLL 0x2 +#define CLK_TYPE_PROGRAMMABLE 0x4 +#define CLK_TYPE_PERIPHERAL 0x8 +#define CLK_TYPE_SYSTEM 0x10 + + +struct clk { + struct list_head node; + const char *name; /* unique clock name */ + struct clk_lookup cl; + unsigned long rate_hz; + struct clk *parent; + u32 pmc_mask; + void (*mode)(struct clk *, int); + unsigned id:3; /* PCK0..4, or 32k/main/a/b */ + unsigned type; /* clock type */ + u16 users; +}; + + +extern int __init clk_register(struct clk *clk); +extern struct clk mck; +extern struct clk utmi_clk; + +#define CLKDEV_CON_ID(_id, _clk) \ + { \ + .con_id = _id, \ + .clk = _clk, \ + } + +#define CLKDEV_CON_DEV_ID(_con_id, _dev_id, _clk) \ + { \ + .con_id = _con_id, \ + .dev_id = _dev_id, \ + .clk = _clk, \ + } diff --git a/arch/arm/mach-at91/cpuidle.c b/arch/arm/mach-at91/cpuidle.c new file mode 100644 index 00000000..1cfeac14 --- /dev/null +++ b/arch/arm/mach-at91/cpuidle.c @@ -0,0 +1,94 @@ +/* + * based on arch/arm/mach-kirkwood/cpuidle.c + * + * CPU idle support for AT91 SoC + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + * + * The cpu idle uses wait-for-interrupt and RAM self refresh in order + * to implement two idle states - + * #1 wait-for-interrupt + * #2 wait-for-interrupt and RAM self refresh + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/cpuidle.h> +#include <asm/proc-fns.h> +#include <linux/io.h> + +#include "pm.h" + +#define AT91_MAX_STATES 2 + +static DEFINE_PER_CPU(struct cpuidle_device, at91_cpuidle_device); + +static struct cpuidle_driver at91_idle_driver = { + .name = "at91_idle", + .owner = THIS_MODULE, +}; + +/* Actual code that puts the SoC in different idle states */ +static int at91_enter_idle(struct cpuidle_device *dev, + struct cpuidle_state *state) +{ + struct timeval before, after; + int idle_time; + u32 saved_lpr; + + local_irq_disable(); + do_gettimeofday(&before); + if (state == &dev->states[0]) + /* Wait for interrupt state */ + cpu_do_idle(); + else if (state == &dev->states[1]) { + asm("b 1f; .align 5; 1:"); + asm("mcr p15, 0, r0, c7, c10, 4"); /* drain write buffer */ + saved_lpr = sdram_selfrefresh_enable(); + cpu_do_idle(); + sdram_selfrefresh_disable(saved_lpr); + } + do_gettimeofday(&after); + local_irq_enable(); + idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + + (after.tv_usec - before.tv_usec); + return idle_time; +} + +/* Initialize CPU idle by registering the idle states */ +static int at91_init_cpuidle(void) +{ + struct cpuidle_device *device; + + cpuidle_register_driver(&at91_idle_driver); + + device = &per_cpu(at91_cpuidle_device, smp_processor_id()); + device->state_count = AT91_MAX_STATES; + + /* Wait for interrupt state */ + device->states[0].enter = at91_enter_idle; + device->states[0].exit_latency = 1; + device->states[0].target_residency = 10000; + device->states[0].flags = CPUIDLE_FLAG_TIME_VALID; + strcpy(device->states[0].name, "WFI"); + strcpy(device->states[0].desc, "Wait for interrupt"); + + /* Wait for interrupt and RAM self refresh state */ + device->states[1].enter = at91_enter_idle; + device->states[1].exit_latency = 10; + device->states[1].target_residency = 10000; + device->states[1].flags = CPUIDLE_FLAG_TIME_VALID; + strcpy(device->states[1].name, "RAM_SR"); + strcpy(device->states[1].desc, "WFI and RAM Self Refresh"); + + if (cpuidle_register_device(device)) { + printk(KERN_ERR "at91_init_cpuidle: Failed registering\n"); + return -EIO; + } + return 0; +} + +device_initcall(at91_init_cpuidle); diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h new file mode 100644 index 00000000..8ff3418f --- /dev/null +++ b/arch/arm/mach-at91/generic.h @@ -0,0 +1,87 @@ +/* + * linux/arch/arm/mach-at91/generic.h + * + * Copyright (C) 2005 David Brownell + * + * 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/clkdev.h> + + /* Map io */ +extern void __init at91rm9200_map_io(void); +extern void __init at91sam9260_map_io(void); +extern void __init at91sam9261_map_io(void); +extern void __init at91sam9263_map_io(void); +extern void __init at91sam9rl_map_io(void); +extern void __init at91sam9g45_map_io(void); +extern void __init at91x40_map_io(void); +extern void __init at91cap9_map_io(void); + + /* Processors */ +extern void __init at91rm9200_set_type(int type); +extern void __init at91rm9200_initialize(unsigned long main_clock); +extern void __init at91sam9260_initialize(unsigned long main_clock); +extern void __init at91sam9261_initialize(unsigned long main_clock); +extern void __init at91sam9263_initialize(unsigned long main_clock); +extern void __init at91sam9rl_initialize(unsigned long main_clock); +extern void __init at91sam9g45_initialize(unsigned long main_clock); +extern void __init at91x40_initialize(unsigned long main_clock); +extern void __init at91cap9_initialize(unsigned long main_clock); + + /* Interrupts */ +extern void __init at91rm9200_init_interrupts(unsigned int priority[]); +extern void __init at91sam9260_init_interrupts(unsigned int priority[]); +extern void __init at91sam9261_init_interrupts(unsigned int priority[]); +extern void __init at91sam9263_init_interrupts(unsigned int priority[]); +extern void __init at91sam9rl_init_interrupts(unsigned int priority[]); +extern void __init at91sam9g45_init_interrupts(unsigned int priority[]); +extern void __init at91x40_init_interrupts(unsigned int priority[]); +extern void __init at91cap9_init_interrupts(unsigned int priority[]); +extern void __init at91_aic_init(unsigned int priority[]); + + /* Timer */ +struct sys_timer; +extern struct sys_timer at91rm9200_timer; +extern struct sys_timer at91sam926x_timer; +extern struct sys_timer at91x40_timer; + + /* Clocks */ +extern int __init at91_clock_init(unsigned long main_clock); +/* + * function to specify the clock of the default console. As we do not + * use the device/driver bus, the dev_name is not intialize. So we need + * to link the clock to a specific con_id only "usart" + */ +extern void __init at91rm9200_set_console_clock(int id); +extern void __init at91sam9260_set_console_clock(int id); +extern void __init at91sam9261_set_console_clock(int id); +extern void __init at91sam9263_set_console_clock(int id); +extern void __init at91sam9rl_set_console_clock(int id); +extern void __init at91sam9g45_set_console_clock(int id); +extern void __init at91cap9_set_console_clock(int id); +struct device; + + /* Power Management */ +extern void at91_irq_suspend(void); +extern void at91_irq_resume(void); + +/* reset */ +extern void at91sam9_alt_reset(void); + + /* GPIO */ +#define AT91RM9200_PQFP 3 /* AT91RM9200 PQFP package has 3 banks */ +#define AT91RM9200_BGA 4 /* AT91RM9200 BGA package has 4 banks */ + +struct at91_gpio_bank { + unsigned short id; /* peripheral ID */ + unsigned long offset; /* offset from system peripheral base */ + struct clk *clock; /* associated clock */ +}; +extern void __init at91_gpio_init(struct at91_gpio_bank *, int nr_banks); +extern void __init at91_gpio_irq_setup(void); + +extern void (*at91_arch_reset)(void); +extern int at91_extern_irq; diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c new file mode 100644 index 00000000..46155282 --- /dev/null +++ b/arch/arm/mach-at91/gpio.c @@ -0,0 +1,632 @@ +/* + * linux/arch/arm/mach-at91/gpio.c + * + * Copyright (C) 2005 HP Labs + * + * 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. + */ + +#include <linux/clk.h> +#include <linux/errno.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/debugfs.h> +#include <linux/seq_file.h> +#include <linux/kernel.h> +#include <linux/list.h> +#include <linux/module.h> +#include <linux/io.h> + +#include <mach/hardware.h> +#include <mach/at91_pio.h> +#include <mach/gpio.h> + +#include <asm/gpio.h> + +#include "generic.h" + +struct at91_gpio_chip { + struct gpio_chip chip; + struct at91_gpio_chip *next; /* Bank sharing same clock */ + struct at91_gpio_bank *bank; /* Bank definition */ + void __iomem *regbase; /* Base of register bank */ +}; + +#define to_at91_gpio_chip(c) container_of(c, struct at91_gpio_chip, chip) + +static void at91_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip); +static void at91_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val); +static int at91_gpiolib_get(struct gpio_chip *chip, unsigned offset); +static int at91_gpiolib_direction_output(struct gpio_chip *chip, + unsigned offset, int val); +static int at91_gpiolib_direction_input(struct gpio_chip *chip, + unsigned offset); + +#define AT91_GPIO_CHIP(name, base_gpio, nr_gpio) \ + { \ + .chip = { \ + .label = name, \ + .direction_input = at91_gpiolib_direction_input, \ + .direction_output = at91_gpiolib_direction_output, \ + .get = at91_gpiolib_get, \ + .set = at91_gpiolib_set, \ + .dbg_show = at91_gpiolib_dbg_show, \ + .base = base_gpio, \ + .ngpio = nr_gpio, \ + }, \ + } + +static struct at91_gpio_chip gpio_chip[] = { + AT91_GPIO_CHIP("A", 0x00 + PIN_BASE, 32), + AT91_GPIO_CHIP("B", 0x20 + PIN_BASE, 32), + AT91_GPIO_CHIP("C", 0x40 + PIN_BASE, 32), + AT91_GPIO_CHIP("D", 0x60 + PIN_BASE, 32), + AT91_GPIO_CHIP("E", 0x80 + PIN_BASE, 32), +}; + +static int gpio_banks; + +static inline void __iomem *pin_to_controller(unsigned pin) +{ + pin -= PIN_BASE; + pin /= 32; + if (likely(pin < gpio_banks)) + return gpio_chip[pin].regbase; + + return NULL; +} + +static inline unsigned pin_to_mask(unsigned pin) +{ + pin -= PIN_BASE; + return 1 << (pin % 32); +} + + +/*--------------------------------------------------------------------------*/ + +/* Not all hardware capabilities are exposed through these calls; they + * only encapsulate the most common features and modes. (So if you + * want to change signals in groups, do it directly.) + * + * Bootloaders will usually handle some of the pin multiplexing setup. + * The intent is certainly that by the time Linux is fully booted, all + * pins should have been fully initialized. These setup calls should + * only be used by board setup routines, or possibly in driver probe(). + * + * For bootloaders doing all that setup, these calls could be inlined + * as NOPs so Linux won't duplicate any setup code + */ + + +/* + * mux the pin to the "GPIO" peripheral role. + */ +int __init_or_module at91_set_GPIO_periph(unsigned pin, int use_pullup) +{ + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); + + if (!pio) + return -EINVAL; + __raw_writel(mask, pio + PIO_IDR); + __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); + __raw_writel(mask, pio + PIO_PER); + return 0; +} +EXPORT_SYMBOL(at91_set_GPIO_periph); + + +/* + * mux the pin to the "A" internal peripheral role. + */ +int __init_or_module at91_set_A_periph(unsigned pin, int use_pullup) +{ + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); + + if (!pio) + return -EINVAL; + + __raw_writel(mask, pio + PIO_IDR); + __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); + __raw_writel(mask, pio + PIO_ASR); + __raw_writel(mask, pio + PIO_PDR); + return 0; +} +EXPORT_SYMBOL(at91_set_A_periph); + + +/* + * mux the pin to the "B" internal peripheral role. + */ +int __init_or_module at91_set_B_periph(unsigned pin, int use_pullup) +{ + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); + + if (!pio) + return -EINVAL; + + __raw_writel(mask, pio + PIO_IDR); + __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); + __raw_writel(mask, pio + PIO_BSR); + __raw_writel(mask, pio + PIO_PDR); + return 0; +} +EXPORT_SYMBOL(at91_set_B_periph); + + +/* + * mux the pin to the gpio controller (instead of "A" or "B" peripheral), and + * configure it for an input. + */ +int __init_or_module at91_set_gpio_input(unsigned pin, int use_pullup) +{ + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); + + if (!pio) + return -EINVAL; + + __raw_writel(mask, pio + PIO_IDR); + __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); + __raw_writel(mask, pio + PIO_ODR); + __raw_writel(mask, pio + PIO_PER); + return 0; +} +EXPORT_SYMBOL(at91_set_gpio_input); + + +/* + * mux the pin to the gpio controller (instead of "A" or "B" peripheral), + * and configure it for an output. + */ +int __init_or_module at91_set_gpio_output(unsigned pin, int value) +{ + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); + + if (!pio) + return -EINVAL; + + __raw_writel(mask, pio + PIO_IDR); + __raw_writel(mask, pio + PIO_PUDR); + __raw_writel(mask, pio + (value ? PIO_SODR : PIO_CODR)); + __raw_writel(mask, pio + PIO_OER); + __raw_writel(mask, pio + PIO_PER); + return 0; +} +EXPORT_SYMBOL(at91_set_gpio_output); + + +/* + * enable/disable the glitch filter; mostly used with IRQ handling. + */ +int __init_or_module at91_set_deglitch(unsigned pin, int is_on) +{ + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); + + if (!pio) + return -EINVAL; + __raw_writel(mask, pio + (is_on ? PIO_IFER : PIO_IFDR)); + return 0; +} +EXPORT_SYMBOL(at91_set_deglitch); + +/* + * enable/disable the multi-driver; This is only valid for output and + * allows the output pin to run as an open collector output. + */ +int __init_or_module at91_set_multi_drive(unsigned pin, int is_on) +{ + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); + + if (!pio) + return -EINVAL; + + __raw_writel(mask, pio + (is_on ? PIO_MDER : PIO_MDDR)); + return 0; +} +EXPORT_SYMBOL(at91_set_multi_drive); + +/* + * assuming the pin is muxed as a gpio output, set its value. + */ +int at91_set_gpio_value(unsigned pin, int value) +{ + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); + + if (!pio) + return -EINVAL; + __raw_writel(mask, pio + (value ? PIO_SODR : PIO_CODR)); + return 0; +} +EXPORT_SYMBOL(at91_set_gpio_value); + + +/* + * read the pin's value (works even if it's not muxed as a gpio). + */ +int at91_get_gpio_value(unsigned pin) +{ + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); + u32 pdsr; + + if (!pio) + return -EINVAL; + pdsr = __raw_readl(pio + PIO_PDSR); + return (pdsr & mask) != 0; +} +EXPORT_SYMBOL(at91_get_gpio_value); + +/*--------------------------------------------------------------------------*/ + +#ifdef CONFIG_PM + +static u32 wakeups[MAX_GPIO_BANKS]; +static u32 backups[MAX_GPIO_BANKS]; + +static int gpio_irq_set_wake(struct irq_data *d, unsigned state) +{ + unsigned mask = pin_to_mask(d->irq); + unsigned bank = (d->irq - PIN_BASE) / 32; + + if (unlikely(bank >= MAX_GPIO_BANKS)) + return -EINVAL; + + if (state) + wakeups[bank] |= mask; + else + wakeups[bank] &= ~mask; + + irq_set_irq_wake(gpio_chip[bank].bank->id, state); + + return 0; +} + +void at91_gpio_suspend(void) +{ + int i; + + for (i = 0; i < gpio_banks; i++) { + void __iomem *pio = gpio_chip[i].regbase; + + backups[i] = __raw_readl(pio + PIO_IMR); + __raw_writel(backups[i], pio + PIO_IDR); + __raw_writel(wakeups[i], pio + PIO_IER); + + if (!wakeups[i]) + clk_disable(gpio_chip[i].bank->clock); + else { +#ifdef CONFIG_PM_DEBUG + printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", 'A'+i, wakeups[i]); +#endif + } + } +} + +void at91_gpio_resume(void) +{ + int i; + + for (i = 0; i < gpio_banks; i++) { + void __iomem *pio = gpio_chip[i].regbase; + + if (!wakeups[i]) + clk_enable(gpio_chip[i].bank->clock); + + __raw_writel(wakeups[i], pio + PIO_IDR); + __raw_writel(backups[i], pio + PIO_IER); + } +} + +#else +#define gpio_irq_set_wake NULL +#endif + + +/* Several AIC controller irqs are dispatched through this GPIO handler. + * To use any AT91_PIN_* as an externally triggered IRQ, first call + * at91_set_gpio_input() then maybe enable its glitch filter. + * Then just request_irq() with the pin ID; it works like any ARM IRQ + * handler, though it always triggers on rising and falling edges. + * + * Alternatively, certain pins may be used directly as IRQ0..IRQ6 after + * configuring them with at91_set_a_periph() or at91_set_b_periph(). + * IRQ0..IRQ6 should be configurable, e.g. level vs edge triggering. + */ + +static void gpio_irq_mask(struct irq_data *d) +{ + void __iomem *pio = pin_to_controller(d->irq); + unsigned mask = pin_to_mask(d->irq); + + if (pio) + __raw_writel(mask, pio + PIO_IDR); +} + +static void gpio_irq_unmask(struct irq_data *d) +{ + void __iomem *pio = pin_to_controller(d->irq); + unsigned mask = pin_to_mask(d->irq); + + if (pio) + __raw_writel(mask, pio + PIO_IER); +} + +static int gpio_irq_type(struct irq_data *d, unsigned type) +{ + switch (type) { + case IRQ_TYPE_NONE: + case IRQ_TYPE_EDGE_BOTH: + return 0; + default: + return -EINVAL; + } +} + +static struct irq_chip gpio_irqchip = { + .name = "GPIO", + .irq_disable = gpio_irq_mask, + .irq_mask = gpio_irq_mask, + .irq_unmask = gpio_irq_unmask, + .irq_set_type = gpio_irq_type, + .irq_set_wake = gpio_irq_set_wake, +}; + +static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) +{ + unsigned pin; + struct irq_data *idata = irq_desc_get_irq_data(desc); + struct irq_chip *chip = irq_data_get_irq_chip(idata); + struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(idata); + void __iomem *pio = at91_gpio->regbase; + u32 isr; + + /* temporarily mask (level sensitive) parent IRQ */ + chip->irq_ack(idata); + for (;;) { + /* Reading ISR acks pending (edge triggered) GPIO interrupts. + * When there none are pending, we're finished unless we need + * to process multiple banks (like ID_PIOCDE on sam9263). + */ + isr = __raw_readl(pio + PIO_ISR) & __raw_readl(pio + PIO_IMR); + if (!isr) { + if (!at91_gpio->next) + break; + at91_gpio = at91_gpio->next; + pio = at91_gpio->regbase; + continue; + } + + pin = at91_gpio->chip.base; + + while (isr) { + if (isr & 1) + generic_handle_irq(pin); + pin++; + isr >>= 1; + } + } + chip->irq_unmask(idata); + /* now it may re-trigger */ +} + +/*--------------------------------------------------------------------------*/ + +#ifdef CONFIG_DEBUG_FS + +static int at91_gpio_show(struct seq_file *s, void *unused) +{ + int bank, j; + + /* print heading */ + seq_printf(s, "Pin\t"); + for (bank = 0; bank < gpio_banks; bank++) { + seq_printf(s, "PIO%c\t", 'A' + bank); + }; + seq_printf(s, "\n\n"); + + /* print pin status */ + for (j = 0; j < 32; j++) { + seq_printf(s, "%i:\t", j); + + for (bank = 0; bank < gpio_banks; bank++) { + unsigned pin = PIN_BASE + (32 * bank) + j; + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); + + if (__raw_readl(pio + PIO_PSR) & mask) + seq_printf(s, "GPIO:%s", __raw_readl(pio + PIO_PDSR) & mask ? "1" : "0"); + else + seq_printf(s, "%s", __raw_readl(pio + PIO_ABSR) & mask ? "B" : "A"); + + seq_printf(s, "\t"); + } + + seq_printf(s, "\n"); + } + + return 0; +} + +static int at91_gpio_open(struct inode *inode, struct file *file) +{ + return single_open(file, at91_gpio_show, NULL); +} + +static const struct file_operations at91_gpio_operations = { + .open = at91_gpio_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int __init at91_gpio_debugfs_init(void) +{ + /* /sys/kernel/debug/at91_gpio */ + (void) debugfs_create_file("at91_gpio", S_IFREG | S_IRUGO, NULL, NULL, &at91_gpio_operations); + return 0; +} +postcore_initcall(at91_gpio_debugfs_init); + +#endif + +/*--------------------------------------------------------------------------*/ + +/* + * This lock class tells lockdep that GPIO irqs are in a different + * category than their parents, so it won't report false recursion. + */ +static struct lock_class_key gpio_lock_class; + +/* + * Called from the processor-specific init to enable GPIO interrupt support. + */ +void __init at91_gpio_irq_setup(void) +{ + unsigned pioc, pin; + struct at91_gpio_chip *this, *prev; + + for (pioc = 0, pin = PIN_BASE, this = gpio_chip, prev = NULL; + pioc++ < gpio_banks; + prev = this, this++) { + unsigned id = this->bank->id; + unsigned i; + + __raw_writel(~0, this->regbase + PIO_IDR); + + for (i = 0, pin = this->chip.base; i < 32; i++, pin++) { + irq_set_lockdep_class(pin, &gpio_lock_class); + + /* + * Can use the "simple" and not "edge" handler since it's + * shorter, and the AIC handles interrupts sanely. + */ + irq_set_chip_and_handler(pin, &gpio_irqchip, + handle_simple_irq); + set_irq_flags(pin, IRQF_VALID); + } + + /* The toplevel handler handles one bank of GPIOs, except + * AT91SAM9263_ID_PIOCDE handles three... PIOC is first in + * the list, so we only set up that handler. + */ + if (prev && prev->next == this) + continue; + + irq_set_chip_data(id, this); + irq_set_chained_handler(id, gpio_irq_handler); + } + pr_info("AT91: %d gpio irqs in %d banks\n", pin - PIN_BASE, gpio_banks); +} + +/* gpiolib support */ +static int at91_gpiolib_direction_input(struct gpio_chip *chip, + unsigned offset) +{ + struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); + void __iomem *pio = at91_gpio->regbase; + unsigned mask = 1 << offset; + + __raw_writel(mask, pio + PIO_ODR); + return 0; +} + +static int at91_gpiolib_direction_output(struct gpio_chip *chip, + unsigned offset, int val) +{ + struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); + void __iomem *pio = at91_gpio->regbase; + unsigned mask = 1 << offset; + + __raw_writel(mask, pio + (val ? PIO_SODR : PIO_CODR)); + __raw_writel(mask, pio + PIO_OER); + return 0; +} + +static int at91_gpiolib_get(struct gpio_chip *chip, unsigned offset) +{ + struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); + void __iomem *pio = at91_gpio->regbase; + unsigned mask = 1 << offset; + u32 pdsr; + + pdsr = __raw_readl(pio + PIO_PDSR); + return (pdsr & mask) != 0; +} + +static void at91_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val) +{ + struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); + void __iomem *pio = at91_gpio->regbase; + unsigned mask = 1 << offset; + + __raw_writel(mask, pio + (val ? PIO_SODR : PIO_CODR)); +} + +static void at91_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) +{ + int i; + + for (i = 0; i < chip->ngpio; i++) { + unsigned pin = chip->base + i; + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); + const char *gpio_label; + + gpio_label = gpiochip_is_requested(chip, i); + if (gpio_label) { + seq_printf(s, "[%s] GPIO%s%d: ", + gpio_label, chip->label, i); + if (__raw_readl(pio + PIO_PSR) & mask) + seq_printf(s, "[gpio] %s\n", + at91_get_gpio_value(pin) ? + "set" : "clear"); + else + seq_printf(s, "[periph %s]\n", + __raw_readl(pio + PIO_ABSR) & + mask ? "B" : "A"); + } + } +} + +/* + * Called from the processor-specific init to enable GPIO pin support. + */ +void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) +{ + unsigned i; + struct at91_gpio_chip *at91_gpio, *last = NULL; + + BUG_ON(nr_banks > MAX_GPIO_BANKS); + + gpio_banks = nr_banks; + + for (i = 0; i < nr_banks; i++) { + at91_gpio = &gpio_chip[i]; + + at91_gpio->bank = &data[i]; + at91_gpio->chip.base = PIN_BASE + i * 32; + at91_gpio->regbase = at91_gpio->bank->offset + + (void __iomem *)AT91_VA_BASE_SYS; + + /* enable PIO controller's clock */ + clk_enable(at91_gpio->bank->clock); + + /* AT91SAM9263_ID_PIOCDE groups PIOC, PIOD, PIOE */ + if (last && last->bank->id == at91_gpio->bank->id) + last->next = at91_gpio; + last = at91_gpio; + + gpiochip_add(&at91_gpio->chip); + } +} diff --git a/arch/arm/mach-at91/include/mach/at91_adc.h b/arch/arm/mach-at91/include/mach/at91_adc.h new file mode 100644 index 00000000..8e7ed5c9 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_adc.h @@ -0,0 +1,61 @@ +/* + * arch/arm/mach-at91/include/mach/at91_adc.h + * + * Copyright (C) SAN People + * + * Analog-to-Digital Converter (ADC) registers. + * Based on AT91SAM9260 datasheet revision D. + * + * 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. + */ + +#ifndef AT91_ADC_H +#define AT91_ADC_H + +#define AT91_ADC_CR 0x00 /* Control Register */ +#define AT91_ADC_SWRST (1 << 0) /* Software Reset */ +#define AT91_ADC_START (1 << 1) /* Start Conversion */ + +#define AT91_ADC_MR 0x04 /* Mode Register */ +#define AT91_ADC_TRGEN (1 << 0) /* Trigger Enable */ +#define AT91_ADC_TRGSEL (7 << 1) /* Trigger Selection */ +#define AT91_ADC_TRGSEL_TC0 (0 << 1) +#define AT91_ADC_TRGSEL_TC1 (1 << 1) +#define AT91_ADC_TRGSEL_TC2 (2 << 1) +#define AT91_ADC_TRGSEL_EXTERNAL (6 << 1) +#define AT91_ADC_LOWRES (1 << 4) /* Low Resolution */ +#define AT91_ADC_SLEEP (1 << 5) /* Sleep Mode */ +#define AT91_ADC_PRESCAL (0x3f << 8) /* Prescalar Rate Selection */ +#define AT91_ADC_PRESCAL_(x) ((x) << 8) +#define AT91_ADC_STARTUP (0x1f << 16) /* Startup Up Time */ +#define AT91_ADC_STARTUP_(x) ((x) << 16) +#define AT91_ADC_SHTIM (0xf << 24) /* Sample & Hold Time */ +#define AT91_ADC_SHTIM_(x) ((x) << 24) + +#define AT91_ADC_CHER 0x10 /* Channel Enable Register */ +#define AT91_ADC_CHDR 0x14 /* Channel Disable Register */ +#define AT91_ADC_CHSR 0x18 /* Channel Status Register */ +#define AT91_ADC_CH(n) (1 << (n)) /* Channel Number */ + +#define AT91_ADC_SR 0x1C /* Status Register */ +#define AT91_ADC_EOC(n) (1 << (n)) /* End of Conversion on Channel N */ +#define AT91_ADC_OVRE(n) (1 << ((n) + 8))/* Overrun Error on Channel N */ +#define AT91_ADC_DRDY (1 << 16) /* Data Ready */ +#define AT91_ADC_GOVRE (1 << 17) /* General Overrun Error */ +#define AT91_ADC_ENDRX (1 << 18) /* End of RX Buffer */ +#define AT91_ADC_RXFUFF (1 << 19) /* RX Buffer Full */ + +#define AT91_ADC_LCDR 0x20 /* Last Converted Data Register */ +#define AT91_ADC_LDATA (0x3ff) + +#define AT91_ADC_IER 0x24 /* Interrupt Enable Register */ +#define AT91_ADC_IDR 0x28 /* Interrupt Disable Register */ +#define AT91_ADC_IMR 0x2C /* Interrupt Mask Register */ + +#define AT91_ADC_CHR(n) (0x30 + ((n) * 4)) /* Channel Data Register N */ +#define AT91_ADC_DATA (0x3ff) + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91_aic.h b/arch/arm/mach-at91/include/mach/at91_aic.h new file mode 100644 index 00000000..03566799 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_aic.h @@ -0,0 +1,53 @@ +/* + * arch/arm/mach-at91/include/mach/at91_aic.h + * + * Copyright (C) 2005 Ivan Kokshaysky + * Copyright (C) SAN People + * + * Advanced Interrupt Controller (AIC) - System peripherals registers. + * Based on AT91RM9200 datasheet revision E. + * + * 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. + */ + +#ifndef AT91_AIC_H +#define AT91_AIC_H + +#define AT91_AIC_SMR(n) (AT91_AIC + ((n) * 4)) /* Source Mode Registers 0-31 */ +#define AT91_AIC_PRIOR (7 << 0) /* Priority Level */ +#define AT91_AIC_SRCTYPE (3 << 5) /* Interrupt Source Type */ +#define AT91_AIC_SRCTYPE_LOW (0 << 5) +#define AT91_AIC_SRCTYPE_FALLING (1 << 5) +#define AT91_AIC_SRCTYPE_HIGH (2 << 5) +#define AT91_AIC_SRCTYPE_RISING (3 << 5) + +#define AT91_AIC_SVR(n) (AT91_AIC + 0x80 + ((n) * 4)) /* Source Vector Registers 0-31 */ +#define AT91_AIC_IVR (AT91_AIC + 0x100) /* Interrupt Vector Register */ +#define AT91_AIC_FVR (AT91_AIC + 0x104) /* Fast Interrupt Vector Register */ +#define AT91_AIC_ISR (AT91_AIC + 0x108) /* Interrupt Status Register */ +#define AT91_AIC_IRQID (0x1f << 0) /* Current Interrupt Identifier */ + +#define AT91_AIC_IPR (AT91_AIC + 0x10c) /* Interrupt Pending Register */ +#define AT91_AIC_IMR (AT91_AIC + 0x110) /* Interrupt Mask Register */ +#define AT91_AIC_CISR (AT91_AIC + 0x114) /* Core Interrupt Status Register */ +#define AT91_AIC_NFIQ (1 << 0) /* nFIQ Status */ +#define AT91_AIC_NIRQ (1 << 1) /* nIRQ Status */ + +#define AT91_AIC_IECR (AT91_AIC + 0x120) /* Interrupt Enable Command Register */ +#define AT91_AIC_IDCR (AT91_AIC + 0x124) /* Interrupt Disable Command Register */ +#define AT91_AIC_ICCR (AT91_AIC + 0x128) /* Interrupt Clear Command Register */ +#define AT91_AIC_ISCR (AT91_AIC + 0x12c) /* Interrupt Set Command Register */ +#define AT91_AIC_EOICR (AT91_AIC + 0x130) /* End of Interrupt Command Register */ +#define AT91_AIC_SPU (AT91_AIC + 0x134) /* Spurious Interrupt Vector Register */ +#define AT91_AIC_DCR (AT91_AIC + 0x138) /* Debug Control Register */ +#define AT91_AIC_DCR_PROT (1 << 0) /* Protection Mode */ +#define AT91_AIC_DCR_GMSK (1 << 1) /* General Mask */ + +#define AT91_AIC_FFER (AT91_AIC + 0x140) /* Fast Forcing Enable Register [SAM9 only] */ +#define AT91_AIC_FFDR (AT91_AIC + 0x144) /* Fast Forcing Disable Register [SAM9 only] */ +#define AT91_AIC_FFSR (AT91_AIC + 0x148) /* Fast Forcing Status Register [SAM9 only] */ + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91_dbgu.h b/arch/arm/mach-at91/include/mach/at91_dbgu.h new file mode 100644 index 00000000..6dcaa771 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_dbgu.h @@ -0,0 +1,66 @@ +/* + * arch/arm/mach-at91/include/mach/at91_dbgu.h + * + * Copyright (C) 2005 Ivan Kokshaysky + * Copyright (C) SAN People + * + * Debug Unit (DBGU) - System peripherals registers. + * Based on AT91RM9200 datasheet revision E. + * + * 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. + */ + +#ifndef AT91_DBGU_H +#define AT91_DBGU_H + +#ifdef AT91_DBGU +#define AT91_DBGU_CR (AT91_DBGU + 0x00) /* Control Register */ +#define AT91_DBGU_MR (AT91_DBGU + 0x04) /* Mode Register */ +#define AT91_DBGU_IER (AT91_DBGU + 0x08) /* Interrupt Enable Register */ +#define AT91_DBGU_TXRDY (1 << 1) /* Transmitter Ready */ +#define AT91_DBGU_TXEMPTY (1 << 9) /* Transmitter Empty */ +#define AT91_DBGU_IDR (AT91_DBGU + 0x0c) /* Interrupt Disable Register */ +#define AT91_DBGU_IMR (AT91_DBGU + 0x10) /* Interrupt Mask Register */ +#define AT91_DBGU_SR (AT91_DBGU + 0x14) /* Status Register */ +#define AT91_DBGU_RHR (AT91_DBGU + 0x18) /* Receiver Holding Register */ +#define AT91_DBGU_THR (AT91_DBGU + 0x1c) /* Transmitter Holding Register */ +#define AT91_DBGU_BRGR (AT91_DBGU + 0x20) /* Baud Rate Generator Register */ + +#define AT91_DBGU_CIDR (AT91_DBGU + 0x40) /* Chip ID Register */ +#define AT91_DBGU_EXID (AT91_DBGU + 0x44) /* Chip ID Extension Register */ +#define AT91_DBGU_FNR (AT91_DBGU + 0x48) /* Force NTRST Register [SAM9 only] */ +#define AT91_DBGU_FNTRST (1 << 0) /* Force NTRST */ + +#endif /* AT91_DBGU */ + +/* + * Some AT91 parts that don't have full DEBUG units still support the ID + * and extensions register. + */ +#define AT91_CIDR_VERSION (0x1f << 0) /* Version of the Device */ +#define AT91_CIDR_EPROC (7 << 5) /* Embedded Processor */ +#define AT91_CIDR_NVPSIZ (0xf << 8) /* Nonvolatile Program Memory Size */ +#define AT91_CIDR_NVPSIZ2 (0xf << 12) /* Second Nonvolatile Program Memory Size */ +#define AT91_CIDR_SRAMSIZ (0xf << 16) /* Internal SRAM Size */ +#define AT91_CIDR_SRAMSIZ_1K (1 << 16) +#define AT91_CIDR_SRAMSIZ_2K (2 << 16) +#define AT91_CIDR_SRAMSIZ_112K (4 << 16) +#define AT91_CIDR_SRAMSIZ_4K (5 << 16) +#define AT91_CIDR_SRAMSIZ_80K (6 << 16) +#define AT91_CIDR_SRAMSIZ_160K (7 << 16) +#define AT91_CIDR_SRAMSIZ_8K (8 << 16) +#define AT91_CIDR_SRAMSIZ_16K (9 << 16) +#define AT91_CIDR_SRAMSIZ_32K (10 << 16) +#define AT91_CIDR_SRAMSIZ_64K (11 << 16) +#define AT91_CIDR_SRAMSIZ_128K (12 << 16) +#define AT91_CIDR_SRAMSIZ_256K (13 << 16) +#define AT91_CIDR_SRAMSIZ_96K (14 << 16) +#define AT91_CIDR_SRAMSIZ_512K (15 << 16) +#define AT91_CIDR_ARCH (0xff << 20) /* Architecture Identifier */ +#define AT91_CIDR_NVPTYP (7 << 28) /* Nonvolatile Program Memory Type */ +#define AT91_CIDR_EXT (1 << 31) /* Extension Flag */ + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91_mci.h b/arch/arm/mach-at91/include/mach/at91_mci.h new file mode 100644 index 00000000..02182c16 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_mci.h @@ -0,0 +1,115 @@ +/* + * arch/arm/mach-at91/include/mach/at91_mci.h + * + * Copyright (C) 2005 Ivan Kokshaysky + * Copyright (C) SAN People + * + * MultiMedia Card Interface (MCI) registers. + * Based on AT91RM9200 datasheet revision F. + * + * 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. + */ + +#ifndef AT91_MCI_H +#define AT91_MCI_H + +#define AT91_MCI_CR 0x00 /* Control Register */ +#define AT91_MCI_MCIEN (1 << 0) /* Multi-Media Interface Enable */ +#define AT91_MCI_MCIDIS (1 << 1) /* Multi-Media Interface Disable */ +#define AT91_MCI_PWSEN (1 << 2) /* Power Save Mode Enable */ +#define AT91_MCI_PWSDIS (1 << 3) /* Power Save Mode Disable */ +#define AT91_MCI_SWRST (1 << 7) /* Software Reset */ + +#define AT91_MCI_MR 0x04 /* Mode Register */ +#define AT91_MCI_CLKDIV (0xff << 0) /* Clock Divider */ +#define AT91_MCI_PWSDIV (7 << 8) /* Power Saving Divider */ +#define AT91_MCI_RDPROOF (1 << 11) /* Read Proof Enable [SAM926[03] only] */ +#define AT91_MCI_WRPROOF (1 << 12) /* Write Proof Enable [SAM926[03] only] */ +#define AT91_MCI_PDCFBYTE (1 << 13) /* PDC Force Byte Transfer [SAM926[03] only] */ +#define AT91_MCI_PDCPADV (1 << 14) /* PDC Padding Value */ +#define AT91_MCI_PDCMODE (1 << 15) /* PDC-orientated Mode */ +#define AT91_MCI_BLKLEN (0xfff << 18) /* Data Block Length */ + +#define AT91_MCI_DTOR 0x08 /* Data Timeout Register */ +#define AT91_MCI_DTOCYC (0xf << 0) /* Data Timeout Cycle Number */ +#define AT91_MCI_DTOMUL (7 << 4) /* Data Timeout Multiplier */ +#define AT91_MCI_DTOMUL_1 (0 << 4) +#define AT91_MCI_DTOMUL_16 (1 << 4) +#define AT91_MCI_DTOMUL_128 (2 << 4) +#define AT91_MCI_DTOMUL_256 (3 << 4) +#define AT91_MCI_DTOMUL_1K (4 << 4) +#define AT91_MCI_DTOMUL_4K (5 << 4) +#define AT91_MCI_DTOMUL_64K (6 << 4) +#define AT91_MCI_DTOMUL_1M (7 << 4) + +#define AT91_MCI_SDCR 0x0c /* SD Card Register */ +#define AT91_MCI_SDCSEL (3 << 0) /* SD Card Selector */ +#define AT91_MCI_SDCBUS (1 << 7) /* 1-bit or 4-bit bus */ + +#define AT91_MCI_ARGR 0x10 /* Argument Register */ + +#define AT91_MCI_CMDR 0x14 /* Command Register */ +#define AT91_MCI_CMDNB (0x3f << 0) /* Command Number */ +#define AT91_MCI_RSPTYP (3 << 6) /* Response Type */ +#define AT91_MCI_RSPTYP_NONE (0 << 6) +#define AT91_MCI_RSPTYP_48 (1 << 6) +#define AT91_MCI_RSPTYP_136 (2 << 6) +#define AT91_MCI_SPCMD (7 << 8) /* Special Command */ +#define AT91_MCI_SPCMD_NONE (0 << 8) +#define AT91_MCI_SPCMD_INIT (1 << 8) +#define AT91_MCI_SPCMD_SYNC (2 << 8) +#define AT91_MCI_SPCMD_ICMD (4 << 8) +#define AT91_MCI_SPCMD_IRESP (5 << 8) +#define AT91_MCI_OPDCMD (1 << 11) /* Open Drain Command */ +#define AT91_MCI_MAXLAT (1 << 12) /* Max Latency for Command to Response */ +#define AT91_MCI_TRCMD (3 << 16) /* Transfer Command */ +#define AT91_MCI_TRCMD_NONE (0 << 16) +#define AT91_MCI_TRCMD_START (1 << 16) +#define AT91_MCI_TRCMD_STOP (2 << 16) +#define AT91_MCI_TRDIR (1 << 18) /* Transfer Direction */ +#define AT91_MCI_TRTYP (3 << 19) /* Transfer Type */ +#define AT91_MCI_TRTYP_BLOCK (0 << 19) +#define AT91_MCI_TRTYP_MULTIPLE (1 << 19) +#define AT91_MCI_TRTYP_STREAM (2 << 19) +#define AT91_MCI_TRTYP_SDIO_BYTE (4 << 19) +#define AT91_MCI_TRTYP_SDIO_BLOCK (5 << 19) + +#define AT91_MCI_BLKR 0x18 /* Block Register */ +#define AT91_MCI_BLKR_BCNT(n) ((0xffff & (n)) << 0) /* Block count */ +#define AT91_MCI_BLKR_BLKLEN(n) ((0xffff & (n)) << 16) /* Block length */ + +#define AT91_MCI_RSPR(n) (0x20 + ((n) * 4)) /* Response Registers 0-3 */ +#define AT91_MCR_RDR 0x30 /* Receive Data Register */ +#define AT91_MCR_TDR 0x34 /* Transmit Data Register */ + +#define AT91_MCI_SR 0x40 /* Status Register */ +#define AT91_MCI_CMDRDY (1 << 0) /* Command Ready */ +#define AT91_MCI_RXRDY (1 << 1) /* Receiver Ready */ +#define AT91_MCI_TXRDY (1 << 2) /* Transmit Ready */ +#define AT91_MCI_BLKE (1 << 3) /* Data Block Ended */ +#define AT91_MCI_DTIP (1 << 4) /* Data Transfer in Progress */ +#define AT91_MCI_NOTBUSY (1 << 5) /* Data Not Busy */ +#define AT91_MCI_ENDRX (1 << 6) /* End of RX Buffer */ +#define AT91_MCI_ENDTX (1 << 7) /* End fo TX Buffer */ +#define AT91_MCI_SDIOIRQA (1 << 8) /* SDIO Interrupt for Slot A */ +#define AT91_MCI_SDIOIRQB (1 << 9) /* SDIO Interrupt for Slot B */ +#define AT91_MCI_RXBUFF (1 << 14) /* RX Buffer Full */ +#define AT91_MCI_TXBUFE (1 << 15) /* TX Buffer Empty */ +#define AT91_MCI_RINDE (1 << 16) /* Response Index Error */ +#define AT91_MCI_RDIRE (1 << 17) /* Response Direction Error */ +#define AT91_MCI_RCRCE (1 << 18) /* Response CRC Error */ +#define AT91_MCI_RENDE (1 << 19) /* Response End Bit Error */ +#define AT91_MCI_RTOE (1 << 20) /* Response Time-out Error */ +#define AT91_MCI_DCRCE (1 << 21) /* Data CRC Error */ +#define AT91_MCI_DTOE (1 << 22) /* Data Time-out Error */ +#define AT91_MCI_OVRE (1 << 30) /* Overrun */ +#define AT91_MCI_UNRE (1 << 31) /* Underrun */ + +#define AT91_MCI_IER 0x44 /* Interrupt Enable Register */ +#define AT91_MCI_IDR 0x48 /* Interrupt Disable Register */ +#define AT91_MCI_IMR 0x4c /* Interrupt Mask Register */ + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91_pio.h b/arch/arm/mach-at91/include/mach/at91_pio.h new file mode 100644 index 00000000..c6a31bf8 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_pio.h @@ -0,0 +1,49 @@ +/* + * arch/arm/mach-at91/include/mach/at91_pio.h + * + * Copyright (C) 2005 Ivan Kokshaysky + * Copyright (C) SAN People + * + * Parallel I/O Controller (PIO) - System peripherals registers. + * Based on AT91RM9200 datasheet revision E. + * + * 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. + */ + +#ifndef AT91_PIO_H +#define AT91_PIO_H + +#define PIO_PER 0x00 /* Enable Register */ +#define PIO_PDR 0x04 /* Disable Register */ +#define PIO_PSR 0x08 /* Status Register */ +#define PIO_OER 0x10 /* Output Enable Register */ +#define PIO_ODR 0x14 /* Output Disable Register */ +#define PIO_OSR 0x18 /* Output Status Register */ +#define PIO_IFER 0x20 /* Glitch Input Filter Enable */ +#define PIO_IFDR 0x24 /* Glitch Input Filter Disable */ +#define PIO_IFSR 0x28 /* Glitch Input Filter Status */ +#define PIO_SODR 0x30 /* Set Output Data Register */ +#define PIO_CODR 0x34 /* Clear Output Data Register */ +#define PIO_ODSR 0x38 /* Output Data Status Register */ +#define PIO_PDSR 0x3c /* Pin Data Status Register */ +#define PIO_IER 0x40 /* Interrupt Enable Register */ +#define PIO_IDR 0x44 /* Interrupt Disable Register */ +#define PIO_IMR 0x48 /* Interrupt Mask Register */ +#define PIO_ISR 0x4c /* Interrupt Status Register */ +#define PIO_MDER 0x50 /* Multi-driver Enable Register */ +#define PIO_MDDR 0x54 /* Multi-driver Disable Register */ +#define PIO_MDSR 0x58 /* Multi-driver Status Register */ +#define PIO_PUDR 0x60 /* Pull-up Disable Register */ +#define PIO_PUER 0x64 /* Pull-up Enable Register */ +#define PIO_PUSR 0x68 /* Pull-up Status Register */ +#define PIO_ASR 0x70 /* Peripheral A Select Register */ +#define PIO_BSR 0x74 /* Peripheral B Select Register */ +#define PIO_ABSR 0x78 /* AB Status Register */ +#define PIO_OWER 0xa0 /* Output Write Enable Register */ +#define PIO_OWDR 0xa4 /* Output Write Disable Register */ +#define PIO_OWSR 0xa8 /* Output Write Status Register */ + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91_pit.h b/arch/arm/mach-at91/include/mach/at91_pit.h new file mode 100644 index 00000000..974d0bd0 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_pit.h @@ -0,0 +1,32 @@ +/* + * arch/arm/mach-at91/include/mach/at91_pit.h + * + * Copyright (C) 2007 Andrew Victor + * Copyright (C) 2007 Atmel Corporation. + * + * Periodic Interval Timer (PIT) - System peripherals regsters. + * Based on AT91SAM9261 datasheet revision D. + * + * 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. + */ + +#ifndef AT91_PIT_H +#define AT91_PIT_H + +#define AT91_PIT_MR (AT91_PIT + 0x00) /* Mode Register */ +#define AT91_PIT_PITIEN (1 << 25) /* Timer Interrupt Enable */ +#define AT91_PIT_PITEN (1 << 24) /* Timer Enabled */ +#define AT91_PIT_PIV (0xfffff) /* Periodic Interval Value */ + +#define AT91_PIT_SR (AT91_PIT + 0x04) /* Status Register */ +#define AT91_PIT_PITS (1 << 0) /* Timer Status */ + +#define AT91_PIT_PIVR (AT91_PIT + 0x08) /* Periodic Interval Value Register */ +#define AT91_PIT_PIIR (AT91_PIT + 0x0c) /* Periodic Interval Image Register */ +#define AT91_PIT_PICNT (0xfff << 20) /* Interval Counter */ +#define AT91_PIT_CPIV (0xfffff) /* Inverval Value */ + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91_pmc.h b/arch/arm/mach-at91/include/mach/at91_pmc.h new file mode 100644 index 00000000..e46f93e3 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_pmc.h @@ -0,0 +1,133 @@ +/* + * arch/arm/mach-at91/include/mach/at91_pmc.h + * + * Copyright (C) 2005 Ivan Kokshaysky + * Copyright (C) SAN People + * + * Power Management Controller (PMC) - System peripherals registers. + * Based on AT91RM9200 datasheet revision E. + * + * 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. + */ + +#ifndef AT91_PMC_H +#define AT91_PMC_H + +#define AT91_PMC_SCER (AT91_PMC + 0x00) /* System Clock Enable Register */ +#define AT91_PMC_SCDR (AT91_PMC + 0x04) /* System Clock Disable Register */ + +#define AT91_PMC_SCSR (AT91_PMC + 0x08) /* System Clock Status Register */ +#define AT91_PMC_PCK (1 << 0) /* Processor Clock */ +#define AT91RM9200_PMC_UDP (1 << 1) /* USB Devcice Port Clock [AT91RM9200 only] */ +#define AT91RM9200_PMC_MCKUDP (1 << 2) /* USB Device Port Master Clock Automatic Disable on Suspend [AT91RM9200 only] */ +#define AT91CAP9_PMC_DDR (1 << 2) /* DDR Clock [CAP9 revC & some SAM9 only] */ +#define AT91RM9200_PMC_UHP (1 << 4) /* USB Host Port Clock [AT91RM9200 only] */ +#define AT91SAM926x_PMC_UHP (1 << 6) /* USB Host Port Clock [AT91SAM926x only] */ +#define AT91CAP9_PMC_UHP (1 << 6) /* USB Host Port Clock [AT91CAP9 only] */ +#define AT91SAM926x_PMC_UDP (1 << 7) /* USB Devcice Port Clock [AT91SAM926x only] */ +#define AT91_PMC_PCK0 (1 << 8) /* Programmable Clock 0 */ +#define AT91_PMC_PCK1 (1 << 9) /* Programmable Clock 1 */ +#define AT91_PMC_PCK2 (1 << 10) /* Programmable Clock 2 */ +#define AT91_PMC_PCK3 (1 << 11) /* Programmable Clock 3 */ +#define AT91_PMC_PCK4 (1 << 12) /* Programmable Clock 4 [AT572D940HF only] */ +#define AT91_PMC_HCK0 (1 << 16) /* AHB Clock (USB host) [AT91SAM9261 only] */ +#define AT91_PMC_HCK1 (1 << 17) /* AHB Clock (LCD) [AT91SAM9261 only] */ + +#define AT91_PMC_PCER (AT91_PMC + 0x10) /* Peripheral Clock Enable Register */ +#define AT91_PMC_PCDR (AT91_PMC + 0x14) /* Peripheral Clock Disable Register */ +#define AT91_PMC_PCSR (AT91_PMC + 0x18) /* Peripheral Clock Status Register */ + +#define AT91_CKGR_UCKR (AT91_PMC + 0x1C) /* UTMI Clock Register [some SAM9, CAP9] */ +#define AT91_PMC_UPLLEN (1 << 16) /* UTMI PLL Enable */ +#define AT91_PMC_UPLLCOUNT (0xf << 20) /* UTMI PLL Start-up Time */ +#define AT91_PMC_BIASEN (1 << 24) /* UTMI BIAS Enable */ +#define AT91_PMC_BIASCOUNT (0xf << 28) /* UTMI BIAS Start-up Time */ + +#define AT91_CKGR_MOR (AT91_PMC + 0x20) /* Main Oscillator Register [not on SAM9RL] */ +#define AT91_PMC_MOSCEN (1 << 0) /* Main Oscillator Enable */ +#define AT91_PMC_OSCBYPASS (1 << 1) /* Oscillator Bypass [SAM9x, CAP9] */ +#define AT91_PMC_OSCOUNT (0xff << 8) /* Main Oscillator Start-up Time */ + +#define AT91_CKGR_MCFR (AT91_PMC + 0x24) /* Main Clock Frequency Register */ +#define AT91_PMC_MAINF (0xffff << 0) /* Main Clock Frequency */ +#define AT91_PMC_MAINRDY (1 << 16) /* Main Clock Ready */ + +#define AT91_CKGR_PLLAR (AT91_PMC + 0x28) /* PLL A Register */ +#define AT91_CKGR_PLLBR (AT91_PMC + 0x2c) /* PLL B Register */ +#define AT91_PMC_DIV (0xff << 0) /* Divider */ +#define AT91_PMC_PLLCOUNT (0x3f << 8) /* PLL Counter */ +#define AT91_PMC_OUT (3 << 14) /* PLL Clock Frequency Range */ +#define AT91_PMC_MUL (0x7ff << 16) /* PLL Multiplier */ +#define AT91_PMC_USBDIV (3 << 28) /* USB Divisor (PLLB only) */ +#define AT91_PMC_USBDIV_1 (0 << 28) +#define AT91_PMC_USBDIV_2 (1 << 28) +#define AT91_PMC_USBDIV_4 (2 << 28) +#define AT91_PMC_USB96M (1 << 28) /* Divider by 2 Enable (PLLB only) */ + +#define AT91_PMC_MCKR (AT91_PMC + 0x30) /* Master Clock Register */ +#define AT91_PMC_CSS (3 << 0) /* Master Clock Selection */ +#define AT91_PMC_CSS_SLOW (0 << 0) +#define AT91_PMC_CSS_MAIN (1 << 0) +#define AT91_PMC_CSS_PLLA (2 << 0) +#define AT91_PMC_CSS_PLLB (3 << 0) +#define AT91_PMC_CSS_UPLL (3 << 0) /* [some SAM9 only] */ +#define AT91_PMC_PRES (7 << 2) /* Master Clock Prescaler */ +#define AT91_PMC_PRES_1 (0 << 2) +#define AT91_PMC_PRES_2 (1 << 2) +#define AT91_PMC_PRES_4 (2 << 2) +#define AT91_PMC_PRES_8 (3 << 2) +#define AT91_PMC_PRES_16 (4 << 2) +#define AT91_PMC_PRES_32 (5 << 2) +#define AT91_PMC_PRES_64 (6 << 2) +#define AT91_PMC_MDIV (3 << 8) /* Master Clock Division */ +#define AT91RM9200_PMC_MDIV_1 (0 << 8) /* [AT91RM9200 only] */ +#define AT91RM9200_PMC_MDIV_2 (1 << 8) +#define AT91RM9200_PMC_MDIV_3 (2 << 8) +#define AT91RM9200_PMC_MDIV_4 (3 << 8) +#define AT91SAM9_PMC_MDIV_1 (0 << 8) /* [SAM9,CAP9 only] */ +#define AT91SAM9_PMC_MDIV_2 (1 << 8) +#define AT91SAM9_PMC_MDIV_4 (2 << 8) +#define AT91SAM9_PMC_MDIV_6 (3 << 8) /* [some SAM9 only] */ +#define AT91SAM9_PMC_MDIV_3 (3 << 8) /* [some SAM9 only] */ +#define AT91_PMC_PDIV (1 << 12) /* Processor Clock Division [some SAM9 only] */ +#define AT91_PMC_PDIV_1 (0 << 12) +#define AT91_PMC_PDIV_2 (1 << 12) +#define AT91_PMC_PLLADIV2 (1 << 12) /* PLLA divisor by 2 [some SAM9 only] */ +#define AT91_PMC_PLLADIV2_OFF (0 << 12) +#define AT91_PMC_PLLADIV2_ON (1 << 12) + +#define AT91_PMC_USB (AT91_PMC + 0x38) /* USB Clock Register [some SAM9 only] */ +#define AT91_PMC_USBS (0x1 << 0) /* USB OHCI Input clock selection */ +#define AT91_PMC_USBS_PLLA (0 << 0) +#define AT91_PMC_USBS_UPLL (1 << 0) +#define AT91_PMC_OHCIUSBDIV (0xF << 8) /* Divider for USB OHCI Clock */ + +#define AT91_PMC_PCKR(n) (AT91_PMC + 0x40 + ((n) * 4)) /* Programmable Clock 0-N Registers */ +#define AT91_PMC_CSSMCK (0x1 << 8) /* CSS or Master Clock Selection */ +#define AT91_PMC_CSSMCK_CSS (0 << 8) +#define AT91_PMC_CSSMCK_MCK (1 << 8) + +#define AT91_PMC_IER (AT91_PMC + 0x60) /* Interrupt Enable Register */ +#define AT91_PMC_IDR (AT91_PMC + 0x64) /* Interrupt Disable Register */ +#define AT91_PMC_SR (AT91_PMC + 0x68) /* Status Register */ +#define AT91_PMC_MOSCS (1 << 0) /* MOSCS Flag */ +#define AT91_PMC_LOCKA (1 << 1) /* PLLA Lock */ +#define AT91_PMC_LOCKB (1 << 2) /* PLLB Lock */ +#define AT91_PMC_MCKRDY (1 << 3) /* Master Clock */ +#define AT91_PMC_LOCKU (1 << 6) /* UPLL Lock [some SAM9, AT91CAP9 only] */ +#define AT91_PMC_OSCSEL (1 << 7) /* Slow Clock Oscillator [AT91CAP9 revC only] */ +#define AT91_PMC_PCK0RDY (1 << 8) /* Programmable Clock 0 */ +#define AT91_PMC_PCK1RDY (1 << 9) /* Programmable Clock 1 */ +#define AT91_PMC_PCK2RDY (1 << 10) /* Programmable Clock 2 */ +#define AT91_PMC_PCK3RDY (1 << 11) /* Programmable Clock 3 */ +#define AT91_PMC_IMR (AT91_PMC + 0x6c) /* Interrupt Mask Register */ + +#define AT91_PMC_PROT (AT91_PMC + 0xe4) /* Protect Register [AT91CAP9 revC only] */ +#define AT91_PMC_PROTKEY 0x504d4301 /* Activation Code */ + +#define AT91_PMC_VER (AT91_PMC + 0xfc) /* PMC Module Version [AT91CAP9 only] */ + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91_rstc.h b/arch/arm/mach-at91/include/mach/at91_rstc.h new file mode 100644 index 00000000..cbd2bf05 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_rstc.h @@ -0,0 +1,41 @@ +/* + * arch/arm/mach-at91/include/mach/at91_rstc.h + * + * Copyright (C) 2007 Andrew Victor + * Copyright (C) 2007 Atmel Corporation. + * + * Reset Controller (RSTC) - System peripherals regsters. + * Based on AT91SAM9261 datasheet revision D. + * + * 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. + */ + +#ifndef AT91_RSTC_H +#define AT91_RSTC_H + +#define AT91_RSTC_CR (AT91_RSTC + 0x00) /* Reset Controller Control Register */ +#define AT91_RSTC_PROCRST (1 << 0) /* Processor Reset */ +#define AT91_RSTC_PERRST (1 << 2) /* Peripheral Reset */ +#define AT91_RSTC_EXTRST (1 << 3) /* External Reset */ +#define AT91_RSTC_KEY (0xa5 << 24) /* KEY Password */ + +#define AT91_RSTC_SR (AT91_RSTC + 0x04) /* Reset Controller Status Register */ +#define AT91_RSTC_URSTS (1 << 0) /* User Reset Status */ +#define AT91_RSTC_RSTTYP (7 << 8) /* Reset Type */ +#define AT91_RSTC_RSTTYP_GENERAL (0 << 8) +#define AT91_RSTC_RSTTYP_WAKEUP (1 << 8) +#define AT91_RSTC_RSTTYP_WATCHDOG (2 << 8) +#define AT91_RSTC_RSTTYP_SOFTWARE (3 << 8) +#define AT91_RSTC_RSTTYP_USER (4 << 8) +#define AT91_RSTC_NRSTL (1 << 16) /* NRST Pin Level */ +#define AT91_RSTC_SRCMP (1 << 17) /* Software Reset Command in Progress */ + +#define AT91_RSTC_MR (AT91_RSTC + 0x08) /* Reset Controller Mode Register */ +#define AT91_RSTC_URSTEN (1 << 0) /* User Reset Enable */ +#define AT91_RSTC_URSTIEN (1 << 4) /* User Reset Interrupt Enable */ +#define AT91_RSTC_ERSTL (0xf << 8) /* External Reset Length */ + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91_rtc.h b/arch/arm/mach-at91/include/mach/at91_rtc.h new file mode 100644 index 00000000..e56f4701 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_rtc.h @@ -0,0 +1,75 @@ +/* + * arch/arm/mach-at91/include/mach/at91_rtc.h + * + * Copyright (C) 2005 Ivan Kokshaysky + * Copyright (C) SAN People + * + * Real Time Clock (RTC) - System peripheral registers. + * Based on AT91RM9200 datasheet revision E. + * + * 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. + */ + +#ifndef AT91_RTC_H +#define AT91_RTC_H + +#define AT91_RTC_CR (AT91_RTC + 0x00) /* Control Register */ +#define AT91_RTC_UPDTIM (1 << 0) /* Update Request Time Register */ +#define AT91_RTC_UPDCAL (1 << 1) /* Update Request Calendar Register */ +#define AT91_RTC_TIMEVSEL (3 << 8) /* Time Event Selection */ +#define AT91_RTC_TIMEVSEL_MINUTE (0 << 8) +#define AT91_RTC_TIMEVSEL_HOUR (1 << 8) +#define AT91_RTC_TIMEVSEL_DAY24 (2 << 8) +#define AT91_RTC_TIMEVSEL_DAY12 (3 << 8) +#define AT91_RTC_CALEVSEL (3 << 16) /* Calendar Event Selection */ +#define AT91_RTC_CALEVSEL_WEEK (0 << 16) +#define AT91_RTC_CALEVSEL_MONTH (1 << 16) +#define AT91_RTC_CALEVSEL_YEAR (2 << 16) + +#define AT91_RTC_MR (AT91_RTC + 0x04) /* Mode Register */ +#define AT91_RTC_HRMOD (1 << 0) /* 12/24 Hour Mode */ + +#define AT91_RTC_TIMR (AT91_RTC + 0x08) /* Time Register */ +#define AT91_RTC_SEC (0x7f << 0) /* Current Second */ +#define AT91_RTC_MIN (0x7f << 8) /* Current Minute */ +#define AT91_RTC_HOUR (0x3f << 16) /* Current Hour */ +#define AT91_RTC_AMPM (1 << 22) /* Ante Meridiem Post Meridiem Indicator */ + +#define AT91_RTC_CALR (AT91_RTC + 0x0c) /* Calendar Register */ +#define AT91_RTC_CENT (0x7f << 0) /* Current Century */ +#define AT91_RTC_YEAR (0xff << 8) /* Current Year */ +#define AT91_RTC_MONTH (0x1f << 16) /* Current Month */ +#define AT91_RTC_DAY (7 << 21) /* Current Day */ +#define AT91_RTC_DATE (0x3f << 24) /* Current Date */ + +#define AT91_RTC_TIMALR (AT91_RTC + 0x10) /* Time Alarm Register */ +#define AT91_RTC_SECEN (1 << 7) /* Second Alarm Enable */ +#define AT91_RTC_MINEN (1 << 15) /* Minute Alarm Enable */ +#define AT91_RTC_HOUREN (1 << 23) /* Hour Alarm Enable */ + +#define AT91_RTC_CALALR (AT91_RTC + 0x14) /* Calendar Alarm Register */ +#define AT91_RTC_MTHEN (1 << 23) /* Month Alarm Enable */ +#define AT91_RTC_DATEEN (1 << 31) /* Date Alarm Enable */ + +#define AT91_RTC_SR (AT91_RTC + 0x18) /* Status Register */ +#define AT91_RTC_ACKUPD (1 << 0) /* Acknowledge for Update */ +#define AT91_RTC_ALARM (1 << 1) /* Alarm Flag */ +#define AT91_RTC_SECEV (1 << 2) /* Second Event */ +#define AT91_RTC_TIMEV (1 << 3) /* Time Event */ +#define AT91_RTC_CALEV (1 << 4) /* Calendar Event */ + +#define AT91_RTC_SCCR (AT91_RTC + 0x1c) /* Status Clear Command Register */ +#define AT91_RTC_IER (AT91_RTC + 0x20) /* Interrupt Enable Register */ +#define AT91_RTC_IDR (AT91_RTC + 0x24) /* Interrupt Disable Register */ +#define AT91_RTC_IMR (AT91_RTC + 0x28) /* Interrupt Mask Register */ + +#define AT91_RTC_VER (AT91_RTC + 0x2c) /* Valid Entry Register */ +#define AT91_RTC_NVTIM (1 << 0) /* Non valid Time */ +#define AT91_RTC_NVCAL (1 << 1) /* Non valid Calendar */ +#define AT91_RTC_NVTIMALR (1 << 2) /* Non valid Time Alarm */ +#define AT91_RTC_NVCALALR (1 << 3) /* Non valid Calendar Alarm */ + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91_rtt.h b/arch/arm/mach-at91/include/mach/at91_rtt.h new file mode 100644 index 00000000..7ec75de8 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_rtt.h @@ -0,0 +1,35 @@ +/* + * arch/arm/mach-at91/include/mach/at91_rtt.h + * + * Copyright (C) 2007 Andrew Victor + * Copyright (C) 2007 Atmel Corporation. + * + * Real-time Timer (RTT) - System peripherals regsters. + * Based on AT91SAM9261 datasheet revision D. + * + * 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. + */ + +#ifndef AT91_RTT_H +#define AT91_RTT_H + +#define AT91_RTT_MR 0x00 /* Real-time Mode Register */ +#define AT91_RTT_RTPRES (0xffff << 0) /* Real-time Timer Prescaler Value */ +#define AT91_RTT_ALMIEN (1 << 16) /* Alarm Interrupt Enable */ +#define AT91_RTT_RTTINCIEN (1 << 17) /* Real Time Timer Increment Interrupt Enable */ +#define AT91_RTT_RTTRST (1 << 18) /* Real Time Timer Restart */ + +#define AT91_RTT_AR 0x04 /* Real-time Alarm Register */ +#define AT91_RTT_ALMV (0xffffffff) /* Alarm Value */ + +#define AT91_RTT_VR 0x08 /* Real-time Value Register */ +#define AT91_RTT_CRTV (0xffffffff) /* Current Real-time Value */ + +#define AT91_RTT_SR 0x0c /* Real-time Status Register */ +#define AT91_RTT_ALMS (1 << 0) /* Real-time Alarm Status */ +#define AT91_RTT_RTTINC (1 << 1) /* Real-time Timer Increment */ + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91_shdwc.h b/arch/arm/mach-at91/include/mach/at91_shdwc.h new file mode 100644 index 00000000..c4ce07e8 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_shdwc.h @@ -0,0 +1,38 @@ +/* + * arch/arm/mach-at91/include/mach/at91_shdwc.h + * + * Copyright (C) 2007 Andrew Victor + * Copyright (C) 2007 Atmel Corporation. + * + * Shutdown Controller (SHDWC) - System peripherals regsters. + * Based on AT91SAM9261 datasheet revision D. + * + * 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. + */ + +#ifndef AT91_SHDWC_H +#define AT91_SHDWC_H + +#define AT91_SHDW_CR (AT91_SHDWC + 0x00) /* Shut Down Control Register */ +#define AT91_SHDW_SHDW (1 << 0) /* Shut Down command */ +#define AT91_SHDW_KEY (0xa5 << 24) /* KEY Password */ + +#define AT91_SHDW_MR (AT91_SHDWC + 0x04) /* Shut Down Mode Register */ +#define AT91_SHDW_WKMODE0 (3 << 0) /* Wake-up 0 Mode Selection */ +#define AT91_SHDW_WKMODE0_NONE 0 +#define AT91_SHDW_WKMODE0_HIGH 1 +#define AT91_SHDW_WKMODE0_LOW 2 +#define AT91_SHDW_WKMODE0_ANYLEVEL 3 +#define AT91_SHDW_CPTWK0 (0xf << 4) /* Counter On Wake Up 0 */ +#define AT91_SHDW_CPTWK0_(x) ((x) << 4) +#define AT91_SHDW_RTTWKEN (1 << 16) /* Real Time Timer Wake-up Enable */ + +#define AT91_SHDW_SR (AT91_SHDWC + 0x08) /* Shut Down Status Register */ +#define AT91_SHDW_WAKEUP0 (1 << 0) /* Wake-up 0 Status */ +#define AT91_SHDW_RTTWK (1 << 16) /* Real-time Timer Wake-up */ +#define AT91_SHDW_RTCWK (1 << 17) /* Real-time Clock Wake-up [SAM9RL] */ + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91_spi.h b/arch/arm/mach-at91/include/mach/at91_spi.h new file mode 100644 index 00000000..2f6ba0c5 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_spi.h @@ -0,0 +1,81 @@ +/* + * arch/arm/mach-at91/include/mach/at91_spi.h + * + * Copyright (C) 2005 Ivan Kokshaysky + * Copyright (C) SAN People + * + * Serial Peripheral Interface (SPI) registers. + * Based on AT91RM9200 datasheet revision E. + * + * 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. + */ + +#ifndef AT91_SPI_H +#define AT91_SPI_H + +#define AT91_SPI_CR 0x00 /* Control Register */ +#define AT91_SPI_SPIEN (1 << 0) /* SPI Enable */ +#define AT91_SPI_SPIDIS (1 << 1) /* SPI Disable */ +#define AT91_SPI_SWRST (1 << 7) /* SPI Software Reset */ +#define AT91_SPI_LASTXFER (1 << 24) /* Last Transfer [SAM9261 only] */ + +#define AT91_SPI_MR 0x04 /* Mode Register */ +#define AT91_SPI_MSTR (1 << 0) /* Master/Slave Mode */ +#define AT91_SPI_PS (1 << 1) /* Peripheral Select */ +#define AT91_SPI_PS_FIXED (0 << 1) +#define AT91_SPI_PS_VARIABLE (1 << 1) +#define AT91_SPI_PCSDEC (1 << 2) /* Chip Select Decode */ +#define AT91_SPI_DIV32 (1 << 3) /* Clock Selection [AT91RM9200 only] */ +#define AT91_SPI_MODFDIS (1 << 4) /* Mode Fault Detection */ +#define AT91_SPI_LLB (1 << 7) /* Local Loopback Enable */ +#define AT91_SPI_PCS (0xf << 16) /* Peripheral Chip Select */ +#define AT91_SPI_DLYBCS (0xff << 24) /* Delay Between Chip Selects */ + +#define AT91_SPI_RDR 0x08 /* Receive Data Register */ +#define AT91_SPI_RD (0xffff << 0) /* Receive Data */ +#define AT91_SPI_PCS (0xf << 16) /* Peripheral Chip Select */ + +#define AT91_SPI_TDR 0x0c /* Transmit Data Register */ +#define AT91_SPI_TD (0xffff << 0) /* Transmit Data */ +#define AT91_SPI_PCS (0xf << 16) /* Peripheral Chip Select */ +#define AT91_SPI_LASTXFER (1 << 24) /* Last Transfer [SAM9261 only] */ + +#define AT91_SPI_SR 0x10 /* Status Register */ +#define AT91_SPI_RDRF (1 << 0) /* Receive Data Register Full */ +#define AT91_SPI_TDRE (1 << 1) /* Transmit Data Register Full */ +#define AT91_SPI_MODF (1 << 2) /* Mode Fault Error */ +#define AT91_SPI_OVRES (1 << 3) /* Overrun Error Status */ +#define AT91_SPI_ENDRX (1 << 4) /* End of RX buffer */ +#define AT91_SPI_ENDTX (1 << 5) /* End of TX buffer */ +#define AT91_SPI_RXBUFF (1 << 6) /* RX Buffer Full */ +#define AT91_SPI_TXBUFE (1 << 7) /* TX Buffer Empty */ +#define AT91_SPI_NSSR (1 << 8) /* NSS Rising [SAM9261 only] */ +#define AT91_SPI_TXEMPTY (1 << 9) /* Transmission Register Empty [SAM9261 only] */ +#define AT91_SPI_SPIENS (1 << 16) /* SPI Enable Status */ + +#define AT91_SPI_IER 0x14 /* Interrupt Enable Register */ +#define AT91_SPI_IDR 0x18 /* Interrupt Disable Register */ +#define AT91_SPI_IMR 0x1c /* Interrupt Mask Register */ + +#define AT91_SPI_CSR(n) (0x30 + ((n) * 4)) /* Chip Select Registers 0-3 */ +#define AT91_SPI_CPOL (1 << 0) /* Clock Polarity */ +#define AT91_SPI_NCPHA (1 << 1) /* Clock Phase */ +#define AT91_SPI_CSAAT (1 << 3) /* Chip Select Active After Transfer [SAM9261 only] */ +#define AT91_SPI_BITS (0xf << 4) /* Bits Per Transfer */ +#define AT91_SPI_BITS_8 (0 << 4) +#define AT91_SPI_BITS_9 (1 << 4) +#define AT91_SPI_BITS_10 (2 << 4) +#define AT91_SPI_BITS_11 (3 << 4) +#define AT91_SPI_BITS_12 (4 << 4) +#define AT91_SPI_BITS_13 (5 << 4) +#define AT91_SPI_BITS_14 (6 << 4) +#define AT91_SPI_BITS_15 (7 << 4) +#define AT91_SPI_BITS_16 (8 << 4) +#define AT91_SPI_SCBR (0xff << 8) /* Serial Clock Baud Rate */ +#define AT91_SPI_DLYBS (0xff << 16) /* Delay before SPCK */ +#define AT91_SPI_DLYBCT (0xff << 24) /* Delay between Consecutive Transfers */ + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91_ssc.h b/arch/arm/mach-at91/include/mach/at91_ssc.h new file mode 100644 index 00000000..a81114c1 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_ssc.h @@ -0,0 +1,106 @@ +/* + * arch/arm/mach-at91/include/mach/at91_ssc.h + * + * Copyright (C) SAN People + * + * Serial Synchronous Controller (SSC) registers. + * Based on AT91RM9200 datasheet revision E. + * + * 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. + */ + +#ifndef AT91_SSC_H +#define AT91_SSC_H + +#define AT91_SSC_CR 0x00 /* Control Register */ +#define AT91_SSC_RXEN (1 << 0) /* Receive Enable */ +#define AT91_SSC_RXDIS (1 << 1) /* Receive Disable */ +#define AT91_SSC_TXEN (1 << 8) /* Transmit Enable */ +#define AT91_SSC_TXDIS (1 << 9) /* Transmit Disable */ +#define AT91_SSC_SWRST (1 << 15) /* Software Reset */ + +#define AT91_SSC_CMR 0x04 /* Clock Mode Register */ +#define AT91_SSC_CMR_DIV (0xfff << 0) /* Clock Divider */ + +#define AT91_SSC_RCMR 0x10 /* Receive Clock Mode Register */ +#define AT91_SSC_CKS (3 << 0) /* Clock Selection */ +#define AT91_SSC_CKS_DIV (0 << 0) +#define AT91_SSC_CKS_CLOCK (1 << 0) +#define AT91_SSC_CKS_PIN (2 << 0) +#define AT91_SSC_CKO (7 << 2) /* Clock Output Mode Selection */ +#define AT91_SSC_CKO_NONE (0 << 2) +#define AT91_SSC_CKO_CONTINUOUS (1 << 2) +#define AT91_SSC_CKI (1 << 5) /* Clock Inversion */ +#define AT91_SSC_CKI_FALLING (0 << 5) +#define AT91_SSC_CK_RISING (1 << 5) +#define AT91_SSC_CKG (1 << 6) /* Receive Clock Gating Selection [AT91SAM9261 only] */ +#define AT91_SSC_CKG_NONE (0 << 6) +#define AT91_SSC_CKG_RFLOW (1 << 6) +#define AT91_SSC_CKG_RFHIGH (2 << 6) +#define AT91_SSC_START (0xf << 8) /* Start Selection */ +#define AT91_SSC_START_CONTINUOUS (0 << 8) +#define AT91_SSC_START_TX_RX (1 << 8) +#define AT91_SSC_START_LOW_RF (2 << 8) +#define AT91_SSC_START_HIGH_RF (3 << 8) +#define AT91_SSC_START_FALLING_RF (4 << 8) +#define AT91_SSC_START_RISING_RF (5 << 8) +#define AT91_SSC_START_LEVEL_RF (6 << 8) +#define AT91_SSC_START_EDGE_RF (7 << 8) +#define AT91_SSC_STOP (1 << 12) /* Receive Stop Selection [AT91SAM9261 only] */ +#define AT91_SSC_STTDLY (0xff << 16) /* Start Delay */ +#define AT91_SSC_PERIOD (0xff << 24) /* Period Divider Selection */ + +#define AT91_SSC_RFMR 0x14 /* Receive Frame Mode Register */ +#define AT91_SSC_DATALEN (0x1f << 0) /* Data Length */ +#define AT91_SSC_LOOP (1 << 5) /* Loop Mode */ +#define AT91_SSC_MSBF (1 << 7) /* Most Significant Bit First */ +#define AT91_SSC_DATNB (0xf << 8) /* Data Number per Frame */ +#define AT91_SSC_FSLEN (0xf << 16) /* Frame Sync Length */ +#define AT91_SSC_FSOS (7 << 20) /* Frame Sync Output Selection */ +#define AT91_SSC_FSOS_NONE (0 << 20) +#define AT91_SSC_FSOS_NEGATIVE (1 << 20) +#define AT91_SSC_FSOS_POSITIVE (2 << 20) +#define AT91_SSC_FSOS_LOW (3 << 20) +#define AT91_SSC_FSOS_HIGH (4 << 20) +#define AT91_SSC_FSOS_TOGGLE (5 << 20) +#define AT91_SSC_FSEDGE (1 << 24) /* Frame Sync Edge Detection */ +#define AT91_SSC_FSEDGE_POSITIVE (0 << 24) +#define AT91_SSC_FSEDGE_NEGATIVE (1 << 24) + +#define AT91_SSC_TCMR 0x18 /* Transmit Clock Mode Register */ +#define AT91_SSC_TFMR 0x1c /* Transmit Fram Mode Register */ +#define AT91_SSC_DATDEF (1 << 5) /* Data Default Value */ +#define AT91_SSC_FSDEN (1 << 23) /* Frame Sync Data Enable */ + +#define AT91_SSC_RHR 0x20 /* Receive Holding Register */ +#define AT91_SSC_THR 0x24 /* Transmit Holding Register */ +#define AT91_SSC_RSHR 0x30 /* Receive Sync Holding Register */ +#define AT91_SSC_TSHR 0x34 /* Transmit Sync Holding Register */ + +#define AT91_SSC_RC0R 0x38 /* Receive Compare 0 Register [AT91SAM9261 only] */ +#define AT91_SSC_RC1R 0x3c /* Receive Compare 1 Register [AT91SAM9261 only] */ + +#define AT91_SSC_SR 0x40 /* Status Register */ +#define AT91_SSC_TXRDY (1 << 0) /* Transmit Ready */ +#define AT91_SSC_TXEMPTY (1 << 1) /* Transmit Empty */ +#define AT91_SSC_ENDTX (1 << 2) /* End of Transmission */ +#define AT91_SSC_TXBUFE (1 << 3) /* Transmit Buffer Empty */ +#define AT91_SSC_RXRDY (1 << 4) /* Receive Ready */ +#define AT91_SSC_OVRUN (1 << 5) /* Receive Overrun */ +#define AT91_SSC_ENDRX (1 << 6) /* End of Reception */ +#define AT91_SSC_RXBUFF (1 << 7) /* Receive Buffer Full */ +#define AT91_SSC_CP0 (1 << 8) /* Compare 0 [AT91SAM9261 only] */ +#define AT91_SSC_CP1 (1 << 9) /* Compare 1 [AT91SAM9261 only] */ +#define AT91_SSC_TXSYN (1 << 10) /* Transmit Sync */ +#define AT91_SSC_RXSYN (1 << 11) /* Receive Sync */ +#define AT91_SSC_TXENA (1 << 16) /* Transmit Enable */ +#define AT91_SSC_RXENA (1 << 17) /* Receive Enable */ + +#define AT91_SSC_IER 0x44 /* Interrupt Enable Register */ +#define AT91_SSC_IDR 0x48 /* Interrupt Disable Register */ +#define AT91_SSC_IMR 0x4c /* Interrupt Mask Register */ + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91_st.h b/arch/arm/mach-at91/include/mach/at91_st.h new file mode 100644 index 00000000..8847173e --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_st.h @@ -0,0 +1,49 @@ +/* + * arch/arm/mach-at91/include/mach/at91_st.h + * + * Copyright (C) 2005 Ivan Kokshaysky + * Copyright (C) SAN People + * + * System Timer (ST) - System peripherals registers. + * Based on AT91RM9200 datasheet revision E. + * + * 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. + */ + +#ifndef AT91_ST_H +#define AT91_ST_H + +#define AT91_ST_CR (AT91_ST + 0x00) /* Control Register */ +#define AT91_ST_WDRST (1 << 0) /* Watchdog Timer Restart */ + +#define AT91_ST_PIMR (AT91_ST + 0x04) /* Period Interval Mode Register */ +#define AT91_ST_PIV (0xffff << 0) /* Period Interval Value */ + +#define AT91_ST_WDMR (AT91_ST + 0x08) /* Watchdog Mode Register */ +#define AT91_ST_WDV (0xffff << 0) /* Watchdog Counter Value */ +#define AT91_ST_RSTEN (1 << 16) /* Reset Enable */ +#define AT91_ST_EXTEN (1 << 17) /* External Signal Assertion Enable */ + +#define AT91_ST_RTMR (AT91_ST + 0x0c) /* Real-time Mode Register */ +#define AT91_ST_RTPRES (0xffff << 0) /* Real-time Prescalar Value */ + +#define AT91_ST_SR (AT91_ST + 0x10) /* Status Register */ +#define AT91_ST_PITS (1 << 0) /* Period Interval Timer Status */ +#define AT91_ST_WDOVF (1 << 1) /* Watchdog Overflow */ +#define AT91_ST_RTTINC (1 << 2) /* Real-time Timer Increment */ +#define AT91_ST_ALMS (1 << 3) /* Alarm Status */ + +#define AT91_ST_IER (AT91_ST + 0x14) /* Interrupt Enable Register */ +#define AT91_ST_IDR (AT91_ST + 0x18) /* Interrupt Disable Register */ +#define AT91_ST_IMR (AT91_ST + 0x1c) /* Interrupt Mask Register */ + +#define AT91_ST_RTAR (AT91_ST + 0x20) /* Real-time Alarm Register */ +#define AT91_ST_ALMV (0xfffff << 0) /* Alarm Value */ + +#define AT91_ST_CRTR (AT91_ST + 0x24) /* Current Real-time Register */ +#define AT91_ST_CRTV (0xfffff << 0) /* Current Real-Time Value */ + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91_tc.h b/arch/arm/mach-at91/include/mach/at91_tc.h new file mode 100644 index 00000000..46a317fd --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_tc.h @@ -0,0 +1,146 @@ +/* + * arch/arm/mach-at91/include/mach/at91_tc.h + * + * Copyright (C) SAN People + * + * Timer/Counter Unit (TC) registers. + * Based on AT91RM9200 datasheet revision E. + * + * 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. + */ + +#ifndef AT91_TC_H +#define AT91_TC_H + +#define AT91_TC_BCR 0xc0 /* TC Block Control Register */ +#define AT91_TC_SYNC (1 << 0) /* Synchro Command */ + +#define AT91_TC_BMR 0xc4 /* TC Block Mode Register */ +#define AT91_TC_TC0XC0S (3 << 0) /* External Clock Signal 0 Selection */ +#define AT91_TC_TC0XC0S_TCLK0 (0 << 0) +#define AT91_TC_TC0XC0S_NONE (1 << 0) +#define AT91_TC_TC0XC0S_TIOA1 (2 << 0) +#define AT91_TC_TC0XC0S_TIOA2 (3 << 0) +#define AT91_TC_TC1XC1S (3 << 2) /* External Clock Signal 1 Selection */ +#define AT91_TC_TC1XC1S_TCLK1 (0 << 2) +#define AT91_TC_TC1XC1S_NONE (1 << 2) +#define AT91_TC_TC1XC1S_TIOA0 (2 << 2) +#define AT91_TC_TC1XC1S_TIOA2 (3 << 2) +#define AT91_TC_TC2XC2S (3 << 4) /* External Clock Signal 2 Selection */ +#define AT91_TC_TC2XC2S_TCLK2 (0 << 4) +#define AT91_TC_TC2XC2S_NONE (1 << 4) +#define AT91_TC_TC2XC2S_TIOA0 (2 << 4) +#define AT91_TC_TC2XC2S_TIOA1 (3 << 4) + + +#define AT91_TC_CCR 0x00 /* Channel Control Register */ +#define AT91_TC_CLKEN (1 << 0) /* Counter Clock Enable Command */ +#define AT91_TC_CLKDIS (1 << 1) /* Counter CLock Disable Command */ +#define AT91_TC_SWTRG (1 << 2) /* Software Trigger Command */ + +#define AT91_TC_CMR 0x04 /* Channel Mode Register */ +#define AT91_TC_TCCLKS (7 << 0) /* Capture/Waveform Mode: Clock Selection */ +#define AT91_TC_TIMER_CLOCK1 (0 << 0) +#define AT91_TC_TIMER_CLOCK2 (1 << 0) +#define AT91_TC_TIMER_CLOCK3 (2 << 0) +#define AT91_TC_TIMER_CLOCK4 (3 << 0) +#define AT91_TC_TIMER_CLOCK5 (4 << 0) +#define AT91_TC_XC0 (5 << 0) +#define AT91_TC_XC1 (6 << 0) +#define AT91_TC_XC2 (7 << 0) +#define AT91_TC_CLKI (1 << 3) /* Capture/Waveform Mode: Clock Invert */ +#define AT91_TC_BURST (3 << 4) /* Capture/Waveform Mode: Burst Signal Selection */ +#define AT91_TC_LDBSTOP (1 << 6) /* Capture Mode: Counter Clock Stopped with TB Loading */ +#define AT91_TC_LDBDIS (1 << 7) /* Capture Mode: Counter Clock Disable with RB Loading */ +#define AT91_TC_ETRGEDG (3 << 8) /* Capture Mode: External Trigger Edge Selection */ +#define AT91_TC_ABETRG (1 << 10) /* Capture Mode: TIOA or TIOB External Trigger Selection */ +#define AT91_TC_CPCTRG (1 << 14) /* Capture Mode: RC Compare Trigger Enable */ +#define AT91_TC_WAVE (1 << 15) /* Capture/Waveform mode */ +#define AT91_TC_LDRA (3 << 16) /* Capture Mode: RA Loading Selection */ +#define AT91_TC_LDRB (3 << 18) /* Capture Mode: RB Loading Selection */ + +#define AT91_TC_CPCSTOP (1 << 6) /* Waveform Mode: Counter Clock Stopped with RC Compare */ +#define AT91_TC_CPCDIS (1 << 7) /* Waveform Mode: Counter Clock Disable with RC Compare */ +#define AT91_TC_EEVTEDG (3 << 8) /* Waveform Mode: External Event Edge Selection */ +#define AT91_TC_EEVTEDG_NONE (0 << 8) +#define AT91_TC_EEVTEDG_RISING (1 << 8) +#define AT91_TC_EEVTEDG_FALLING (2 << 8) +#define AT91_TC_EEVTEDG_BOTH (3 << 8) +#define AT91_TC_EEVT (3 << 10) /* Waveform Mode: External Event Selection */ +#define AT91_TC_EEVT_TIOB (0 << 10) +#define AT91_TC_EEVT_XC0 (1 << 10) +#define AT91_TC_EEVT_XC1 (2 << 10) +#define AT91_TC_EEVT_XC2 (3 << 10) +#define AT91_TC_ENETRG (1 << 12) /* Waveform Mode: External Event Trigger Enable */ +#define AT91_TC_WAVESEL (3 << 13) /* Waveform Mode: Waveform Selection */ +#define AT91_TC_WAVESEL_UP (0 << 13) +#define AT91_TC_WAVESEL_UP_AUTO (2 << 13) +#define AT91_TC_WAVESEL_UPDOWN (1 << 13) +#define AT91_TC_WAVESEL_UPDOWN_AUTO (3 << 13) +#define AT91_TC_ACPA (3 << 16) /* Waveform Mode: RA Compare Effect on TIOA */ +#define AT91_TC_ACPA_NONE (0 << 16) +#define AT91_TC_ACPA_SET (1 << 16) +#define AT91_TC_ACPA_CLEAR (2 << 16) +#define AT91_TC_ACPA_TOGGLE (3 << 16) +#define AT91_TC_ACPC (3 << 18) /* Waveform Mode: RC Compre Effect on TIOA */ +#define AT91_TC_ACPC_NONE (0 << 18) +#define AT91_TC_ACPC_SET (1 << 18) +#define AT91_TC_ACPC_CLEAR (2 << 18) +#define AT91_TC_ACPC_TOGGLE (3 << 18) +#define AT91_TC_AEEVT (3 << 20) /* Waveform Mode: External Event Effect on TIOA */ +#define AT91_TC_AEEVT_NONE (0 << 20) +#define AT91_TC_AEEVT_SET (1 << 20) +#define AT91_TC_AEEVT_CLEAR (2 << 20) +#define AT91_TC_AEEVT_TOGGLE (3 << 20) +#define AT91_TC_ASWTRG (3 << 22) /* Waveform Mode: Software Trigger Effect on TIOA */ +#define AT91_TC_ASWTRG_NONE (0 << 22) +#define AT91_TC_ASWTRG_SET (1 << 22) +#define AT91_TC_ASWTRG_CLEAR (2 << 22) +#define AT91_TC_ASWTRG_TOGGLE (3 << 22) +#define AT91_TC_BCPB (3 << 24) /* Waveform Mode: RB Compare Effect on TIOB */ +#define AT91_TC_BCPB_NONE (0 << 24) +#define AT91_TC_BCPB_SET (1 << 24) +#define AT91_TC_BCPB_CLEAR (2 << 24) +#define AT91_TC_BCPB_TOGGLE (3 << 24) +#define AT91_TC_BCPC (3 << 26) /* Waveform Mode: RC Compare Effect on TIOB */ +#define AT91_TC_BCPC_NONE (0 << 26) +#define AT91_TC_BCPC_SET (1 << 26) +#define AT91_TC_BCPC_CLEAR (2 << 26) +#define AT91_TC_BCPC_TOGGLE (3 << 26) +#define AT91_TC_BEEVT (3 << 28) /* Waveform Mode: External Event Effect on TIOB */ +#define AT91_TC_BEEVT_NONE (0 << 28) +#define AT91_TC_BEEVT_SET (1 << 28) +#define AT91_TC_BEEVT_CLEAR (2 << 28) +#define AT91_TC_BEEVT_TOGGLE (3 << 28) +#define AT91_TC_BSWTRG (3 << 30) /* Waveform Mode: Software Trigger Effect on TIOB */ +#define AT91_TC_BSWTRG_NONE (0 << 30) +#define AT91_TC_BSWTRG_SET (1 << 30) +#define AT91_TC_BSWTRG_CLEAR (2 << 30) +#define AT91_TC_BSWTRG_TOGGLE (3 << 30) + +#define AT91_TC_CV 0x10 /* Counter Value */ +#define AT91_TC_RA 0x14 /* Register A */ +#define AT91_TC_RB 0x18 /* Register B */ +#define AT91_TC_RC 0x1c /* Register C */ + +#define AT91_TC_SR 0x20 /* Status Register */ +#define AT91_TC_COVFS (1 << 0) /* Counter Overflow Status */ +#define AT91_TC_LOVRS (1 << 1) /* Load Overrun Status */ +#define AT91_TC_CPAS (1 << 2) /* RA Compare Status */ +#define AT91_TC_CPBS (1 << 3) /* RB Compare Status */ +#define AT91_TC_CPCS (1 << 4) /* RC Compare Status */ +#define AT91_TC_LDRAS (1 << 5) /* RA Loading Status */ +#define AT91_TC_LDRBS (1 << 6) /* RB Loading Status */ +#define AT91_TC_ETRGS (1 << 7) /* External Trigger Status */ +#define AT91_TC_CLKSTA (1 << 16) /* Clock Enabling Status */ +#define AT91_TC_MTIOA (1 << 17) /* TIOA Mirror */ +#define AT91_TC_MTIOB (1 << 18) /* TIOB Mirror */ + +#define AT91_TC_IER 0x24 /* Interrupt Enable Register */ +#define AT91_TC_IDR 0x28 /* Interrupt Disable Register */ +#define AT91_TC_IMR 0x2c /* Interrupt Mask Register */ + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91_twi.h b/arch/arm/mach-at91/include/mach/at91_twi.h new file mode 100644 index 00000000..bb2880f6 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_twi.h @@ -0,0 +1,68 @@ +/* + * arch/arm/mach-at91/include/mach/at91_twi.h + * + * Copyright (C) 2005 Ivan Kokshaysky + * Copyright (C) SAN People + * + * Two-wire Interface (TWI) registers. + * Based on AT91RM9200 datasheet revision E. + * + * 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. + */ + +#ifndef AT91_TWI_H +#define AT91_TWI_H + +#define AT91_TWI_CR 0x00 /* Control Register */ +#define AT91_TWI_START (1 << 0) /* Send a Start Condition */ +#define AT91_TWI_STOP (1 << 1) /* Send a Stop Condition */ +#define AT91_TWI_MSEN (1 << 2) /* Master Transfer Enable */ +#define AT91_TWI_MSDIS (1 << 3) /* Master Transfer Disable */ +#define AT91_TWI_SVEN (1 << 4) /* Slave Transfer Enable [SAM9260 only] */ +#define AT91_TWI_SVDIS (1 << 5) /* Slave Transfer Disable [SAM9260 only] */ +#define AT91_TWI_SWRST (1 << 7) /* Software Reset */ + +#define AT91_TWI_MMR 0x04 /* Master Mode Register */ +#define AT91_TWI_IADRSZ (3 << 8) /* Internal Device Address Size */ +#define AT91_TWI_IADRSZ_NO (0 << 8) +#define AT91_TWI_IADRSZ_1 (1 << 8) +#define AT91_TWI_IADRSZ_2 (2 << 8) +#define AT91_TWI_IADRSZ_3 (3 << 8) +#define AT91_TWI_MREAD (1 << 12) /* Master Read Direction */ +#define AT91_TWI_DADR (0x7f << 16) /* Device Address */ + +#define AT91_TWI_SMR 0x08 /* Slave Mode Register [SAM9260 only] */ +#define AT91_TWI_SADR (0x7f << 16) /* Slave Address */ + +#define AT91_TWI_IADR 0x0c /* Internal Address Register */ + +#define AT91_TWI_CWGR 0x10 /* Clock Waveform Generator Register */ +#define AT91_TWI_CLDIV (0xff << 0) /* Clock Low Divisor */ +#define AT91_TWI_CHDIV (0xff << 8) /* Clock High Divisor */ +#define AT91_TWI_CKDIV (7 << 16) /* Clock Divider */ + +#define AT91_TWI_SR 0x20 /* Status Register */ +#define AT91_TWI_TXCOMP (1 << 0) /* Transmission Complete */ +#define AT91_TWI_RXRDY (1 << 1) /* Receive Holding Register Ready */ +#define AT91_TWI_TXRDY (1 << 2) /* Transmit Holding Register Ready */ +#define AT91_TWI_SVREAD (1 << 3) /* Slave Read [SAM9260 only] */ +#define AT91_TWI_SVACC (1 << 4) /* Slave Access [SAM9260 only] */ +#define AT91_TWI_GACC (1 << 5) /* General Call Access [SAM9260 only] */ +#define AT91_TWI_OVRE (1 << 6) /* Overrun Error [AT91RM9200 only] */ +#define AT91_TWI_UNRE (1 << 7) /* Underrun Error [AT91RM9200 only] */ +#define AT91_TWI_NACK (1 << 8) /* Not Acknowledged */ +#define AT91_TWI_ARBLST (1 << 9) /* Arbitration Lost [SAM9260 only] */ +#define AT91_TWI_SCLWS (1 << 10) /* Clock Wait State [SAM9260 only] */ +#define AT91_TWI_EOSACC (1 << 11) /* End of Slave Address [SAM9260 only] */ + +#define AT91_TWI_IER 0x24 /* Interrupt Enable Register */ +#define AT91_TWI_IDR 0x28 /* Interrupt Disable Register */ +#define AT91_TWI_IMR 0x2c /* Interrupt Mask Register */ +#define AT91_TWI_RHR 0x30 /* Receive Holding Register */ +#define AT91_TWI_THR 0x34 /* Transmit Holding Register */ + +#endif + diff --git a/arch/arm/mach-at91/include/mach/at91_wdt.h b/arch/arm/mach-at91/include/mach/at91_wdt.h new file mode 100644 index 00000000..fecc2e9f --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_wdt.h @@ -0,0 +1,37 @@ +/* + * arch/arm/mach-at91/include/mach/at91_wdt.h + * + * Copyright (C) 2007 Andrew Victor + * Copyright (C) 2007 Atmel Corporation. + * + * Watchdog Timer (WDT) - System peripherals regsters. + * Based on AT91SAM9261 datasheet revision D. + * + * 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. + */ + +#ifndef AT91_WDT_H +#define AT91_WDT_H + +#define AT91_WDT_CR (AT91_WDT + 0x00) /* Watchdog Control Register */ +#define AT91_WDT_WDRSTT (1 << 0) /* Restart */ +#define AT91_WDT_KEY (0xa5 << 24) /* KEY Password */ + +#define AT91_WDT_MR (AT91_WDT + 0x04) /* Watchdog Mode Register */ +#define AT91_WDT_WDV (0xfff << 0) /* Counter Value */ +#define AT91_WDT_WDFIEN (1 << 12) /* Fault Interrupt Enable */ +#define AT91_WDT_WDRSTEN (1 << 13) /* Reset Processor */ +#define AT91_WDT_WDRPROC (1 << 14) /* Timer Restart */ +#define AT91_WDT_WDDIS (1 << 15) /* Watchdog Disable */ +#define AT91_WDT_WDD (0xfff << 16) /* Delta Value */ +#define AT91_WDT_WDDBGHLT (1 << 28) /* Debug Halt */ +#define AT91_WDT_WDIDLEHLT (1 << 29) /* Idle Halt */ + +#define AT91_WDT_SR (AT91_WDT + 0x08) /* Watchdog Status Register */ +#define AT91_WDT_WDUNF (1 << 0) /* Watchdog Underflow */ +#define AT91_WDT_WDERR (1 << 1) /* Watchdog Error */ + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h new file mode 100644 index 00000000..66599384 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91cap9.h @@ -0,0 +1,124 @@ +/* + * arch/arm/mach-at91/include/mach/at91cap9.h + * + * Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com> + * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com> + * Copyright (C) 2007 Atmel Corporation. + * + * Common definitions. + * Based on AT91CAP9 datasheet revision B (Preliminary). + * + * 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. + */ + +#ifndef AT91CAP9_H +#define AT91CAP9_H + +/* + * Peripheral identifiers/interrupts. + */ +#define AT91CAP9_ID_PIOABCD 2 /* Parallel IO Controller A, B, C and D */ +#define AT91CAP9_ID_MPB0 3 /* MP Block Peripheral 0 */ +#define AT91CAP9_ID_MPB1 4 /* MP Block Peripheral 1 */ +#define AT91CAP9_ID_MPB2 5 /* MP Block Peripheral 2 */ +#define AT91CAP9_ID_MPB3 6 /* MP Block Peripheral 3 */ +#define AT91CAP9_ID_MPB4 7 /* MP Block Peripheral 4 */ +#define AT91CAP9_ID_US0 8 /* USART 0 */ +#define AT91CAP9_ID_US1 9 /* USART 1 */ +#define AT91CAP9_ID_US2 10 /* USART 2 */ +#define AT91CAP9_ID_MCI0 11 /* Multimedia Card Interface 0 */ +#define AT91CAP9_ID_MCI1 12 /* Multimedia Card Interface 1 */ +#define AT91CAP9_ID_CAN 13 /* CAN */ +#define AT91CAP9_ID_TWI 14 /* Two-Wire Interface */ +#define AT91CAP9_ID_SPI0 15 /* Serial Peripheral Interface 0 */ +#define AT91CAP9_ID_SPI1 16 /* Serial Peripheral Interface 0 */ +#define AT91CAP9_ID_SSC0 17 /* Serial Synchronous Controller 0 */ +#define AT91CAP9_ID_SSC1 18 /* Serial Synchronous Controller 1 */ +#define AT91CAP9_ID_AC97C 19 /* AC97 Controller */ +#define AT91CAP9_ID_TCB 20 /* Timer Counter 0, 1 and 2 */ +#define AT91CAP9_ID_PWMC 21 /* Pulse Width Modulation Controller */ +#define AT91CAP9_ID_EMAC 22 /* Ethernet */ +#define AT91CAP9_ID_AESTDES 23 /* Advanced Encryption Standard, Triple DES */ +#define AT91CAP9_ID_ADC 24 /* Analog-to-Digital Converter */ +#define AT91CAP9_ID_ISI 25 /* Image Sensor Interface */ +#define AT91CAP9_ID_LCDC 26 /* LCD Controller */ +#define AT91CAP9_ID_DMA 27 /* DMA Controller */ +#define AT91CAP9_ID_UDPHS 28 /* USB High Speed Device Port */ +#define AT91CAP9_ID_UHP 29 /* USB Host Port */ +#define AT91CAP9_ID_IRQ0 30 /* Advanced Interrupt Controller (IRQ0) */ +#define AT91CAP9_ID_IRQ1 31 /* Advanced Interrupt Controller (IRQ1) */ + +/* + * User Peripheral physical base addresses. + */ +#define AT91CAP9_BASE_UDPHS 0xfff78000 +#define AT91CAP9_BASE_TCB0 0xfff7c000 +#define AT91CAP9_BASE_TC0 0xfff7c000 +#define AT91CAP9_BASE_TC1 0xfff7c040 +#define AT91CAP9_BASE_TC2 0xfff7c080 +#define AT91CAP9_BASE_MCI0 0xfff80000 +#define AT91CAP9_BASE_MCI1 0xfff84000 +#define AT91CAP9_BASE_TWI 0xfff88000 +#define AT91CAP9_BASE_US0 0xfff8c000 +#define AT91CAP9_BASE_US1 0xfff90000 +#define AT91CAP9_BASE_US2 0xfff94000 +#define AT91CAP9_BASE_SSC0 0xfff98000 +#define AT91CAP9_BASE_SSC1 0xfff9c000 +#define AT91CAP9_BASE_AC97C 0xfffa0000 +#define AT91CAP9_BASE_SPI0 0xfffa4000 +#define AT91CAP9_BASE_SPI1 0xfffa8000 +#define AT91CAP9_BASE_CAN 0xfffac000 +#define AT91CAP9_BASE_PWMC 0xfffb8000 +#define AT91CAP9_BASE_EMAC 0xfffbc000 +#define AT91CAP9_BASE_ADC 0xfffc0000 +#define AT91CAP9_BASE_ISI 0xfffc4000 +#define AT91_BASE_SYS 0xffffe200 + +/* + * System Peripherals (offset from AT91_BASE_SYS) + */ +#define AT91_ECC (0xffffe200 - AT91_BASE_SYS) +#define AT91_BCRAMC (0xffffe400 - AT91_BASE_SYS) +#define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS) +#define AT91_SMC (0xffffe800 - AT91_BASE_SYS) +#define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS) +#define AT91_CCFG (0xffffeb10 - AT91_BASE_SYS) +#define AT91_DMA (0xffffec00 - AT91_BASE_SYS) +#define AT91_DBGU (0xffffee00 - AT91_BASE_SYS) +#define AT91_AIC (0xfffff000 - AT91_BASE_SYS) +#define AT91_PIOA (0xfffff200 - AT91_BASE_SYS) +#define AT91_PIOB (0xfffff400 - AT91_BASE_SYS) +#define AT91_PIOC (0xfffff600 - AT91_BASE_SYS) +#define AT91_PIOD (0xfffff800 - AT91_BASE_SYS) +#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) +#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) +#define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) +#define AT91_RTT (0xfffffd20 - AT91_BASE_SYS) +#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS) +#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) +#define AT91_GPBR (cpu_is_at91cap9_revB() ? \ + (0xfffffd50 - AT91_BASE_SYS) : \ + (0xfffffd60 - AT91_BASE_SYS)) + +#define AT91_USART0 AT91CAP9_BASE_US0 +#define AT91_USART1 AT91CAP9_BASE_US1 +#define AT91_USART2 AT91CAP9_BASE_US2 + + +/* + * Internal Memory. + */ +#define AT91CAP9_SRAM_BASE 0x00100000 /* Internal SRAM base address */ +#define AT91CAP9_SRAM_SIZE (32 * SZ_1K) /* Internal SRAM size (32Kb) */ + +#define AT91CAP9_ROM_BASE 0x00400000 /* Internal ROM base address */ +#define AT91CAP9_ROM_SIZE (32 * SZ_1K) /* Internal ROM size (32Kb) */ + +#define AT91CAP9_LCDC_BASE 0x00500000 /* LCD Controller */ +#define AT91CAP9_UDPHS_FIFO 0x00600000 /* USB High Speed Device Port */ +#define AT91CAP9_UHP_BASE 0x00700000 /* USB Host controller */ + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h b/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h new file mode 100644 index 00000000..976f4a6c --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h @@ -0,0 +1,108 @@ +/* + * arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h + * + * (C) 2008 Andrew Victor + * + * DDR/SDR Controller (DDRSDRC) - System peripherals registers. + * Based on AT91CAP9 datasheet revision B. + * + * 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. + */ + +#ifndef AT91CAP9_DDRSDR_H +#define AT91CAP9_DDRSDR_H + +#define AT91_DDRSDRC_MR 0x00 /* Mode Register */ +#define AT91_DDRSDRC_MODE (0xf << 0) /* Command Mode */ +#define AT91_DDRSDRC_MODE_NORMAL 0 +#define AT91_DDRSDRC_MODE_NOP 1 +#define AT91_DDRSDRC_MODE_PRECHARGE 2 +#define AT91_DDRSDRC_MODE_LMR 3 +#define AT91_DDRSDRC_MODE_REFRESH 4 +#define AT91_DDRSDRC_MODE_EXT_LMR 5 +#define AT91_DDRSDRC_MODE_DEEP 6 + +#define AT91_DDRSDRC_RTR 0x04 /* Refresh Timer Register */ +#define AT91_DDRSDRC_COUNT (0xfff << 0) /* Refresh Timer Counter */ + +#define AT91_DDRSDRC_CR 0x08 /* Configuration Register */ +#define AT91_DDRSDRC_NC (3 << 0) /* Number of Column Bits */ +#define AT91_DDRSDRC_NC_SDR8 (0 << 0) +#define AT91_DDRSDRC_NC_SDR9 (1 << 0) +#define AT91_DDRSDRC_NC_SDR10 (2 << 0) +#define AT91_DDRSDRC_NC_SDR11 (3 << 0) +#define AT91_DDRSDRC_NC_DDR9 (0 << 0) +#define AT91_DDRSDRC_NC_DDR10 (1 << 0) +#define AT91_DDRSDRC_NC_DDR11 (2 << 0) +#define AT91_DDRSDRC_NC_DDR12 (3 << 0) +#define AT91_DDRSDRC_NR (3 << 2) /* Number of Row Bits */ +#define AT91_DDRSDRC_NR_11 (0 << 2) +#define AT91_DDRSDRC_NR_12 (1 << 2) +#define AT91_DDRSDRC_NR_13 (2 << 2) +#define AT91_DDRSDRC_CAS (7 << 4) /* CAS Latency */ +#define AT91_DDRSDRC_CAS_2 (2 << 4) +#define AT91_DDRSDRC_CAS_3 (3 << 4) +#define AT91_DDRSDRC_CAS_25 (6 << 4) +#define AT91_DDRSDRC_DLL (1 << 7) /* Reset DLL */ +#define AT91_DDRSDRC_DICDS (1 << 8) /* Output impedance control */ + +#define AT91_DDRSDRC_T0PR 0x0C /* Timing 0 Register */ +#define AT91_DDRSDRC_TRAS (0xf << 0) /* Active to Precharge delay */ +#define AT91_DDRSDRC_TRCD (0xf << 4) /* Row to Column delay */ +#define AT91_DDRSDRC_TWR (0xf << 8) /* Write recovery delay */ +#define AT91_DDRSDRC_TRC (0xf << 12) /* Row cycle delay */ +#define AT91_DDRSDRC_TRP (0xf << 16) /* Row precharge delay */ +#define AT91_DDRSDRC_TRRD (0xf << 20) /* Active BankA to BankB */ +#define AT91_DDRSDRC_TWTR (1 << 24) /* Internal Write to Read delay */ +#define AT91_DDRSDRC_TMRD (0xf << 28) /* Load mode to active/refresh delay */ + +#define AT91_DDRSDRC_T1PR 0x10 /* Timing 1 Register */ +#define AT91_DDRSDRC_TRFC (0x1f << 0) /* Row Cycle Delay */ +#define AT91_DDRSDRC_TXSNR (0xff << 8) /* Exit self-refresh to non-read */ +#define AT91_DDRSDRC_TXSRD (0xff << 16) /* Exit self-refresh to read */ +#define AT91_DDRSDRC_TXP (0xf << 24) /* Exit power-down delay */ + +#define AT91_DDRSDRC_LPR 0x18 /* Low Power Register */ +#define AT91_DDRSDRC_LPCB (3 << 0) /* Low-power Configurations */ +#define AT91_DDRSDRC_LPCB_DISABLE 0 +#define AT91_DDRSDRC_LPCB_SELF_REFRESH 1 +#define AT91_DDRSDRC_LPCB_POWER_DOWN 2 +#define AT91_DDRSDRC_LPCB_DEEP_POWER_DOWN 3 +#define AT91_DDRSDRC_CLKFR (1 << 2) /* Clock Frozen */ +#define AT91_DDRSDRC_PASR (7 << 4) /* Partial Array Self Refresh */ +#define AT91_DDRSDRC_TCSR (3 << 8) /* Temperature Compensated Self Refresh */ +#define AT91_DDRSDRC_DS (3 << 10) /* Drive Strength */ +#define AT91_DDRSDRC_TIMEOUT (3 << 12) /* Time to define when Low Power Mode is enabled */ +#define AT91_DDRSDRC_TIMEOUT_0_CLK_CYCLES (0 << 12) +#define AT91_DDRSDRC_TIMEOUT_64_CLK_CYCLES (1 << 12) +#define AT91_DDRSDRC_TIMEOUT_128_CLK_CYCLES (2 << 12) + +#define AT91_DDRSDRC_MDR 0x1C /* Memory Device Register */ +#define AT91_DDRSDRC_MD (3 << 0) /* Memory Device Type */ +#define AT91_DDRSDRC_MD_SDR 0 +#define AT91_DDRSDRC_MD_LOW_POWER_SDR 1 +#define AT91_DDRSDRC_MD_DDR 2 +#define AT91_DDRSDRC_MD_LOW_POWER_DDR 3 + +#define AT91_DDRSDRC_DLLR 0x20 /* DLL Information Register */ +#define AT91_DDRSDRC_MDINC (1 << 0) /* Master Delay increment */ +#define AT91_DDRSDRC_MDDEC (1 << 1) /* Master Delay decrement */ +#define AT91_DDRSDRC_MDOVF (1 << 2) /* Master Delay Overflow */ +#define AT91_DDRSDRC_SDCOVF (1 << 3) /* Slave Delay Correction Overflow */ +#define AT91_DDRSDRC_SDCUDF (1 << 4) /* Slave Delay Correction Underflow */ +#define AT91_DDRSDRC_SDERF (1 << 5) /* Slave Delay Correction error */ +#define AT91_DDRSDRC_MDVAL (0xff << 8) /* Master Delay value */ +#define AT91_DDRSDRC_SDVAL (0xff << 16) /* Slave Delay value */ +#define AT91_DDRSDRC_SDCVAL (0xff << 24) /* Slave Delay Correction value */ + +/* Register access macros */ +#define at91_ramc_read(num, reg) \ + at91_sys_read(AT91_DDRSDRC##num + reg) +#define at91_ramc_write(num, reg, value) \ + at91_sys_write(AT91_DDRSDRC##num + reg, value) + + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91cap9_matrix.h b/arch/arm/mach-at91/include/mach/at91cap9_matrix.h new file mode 100644 index 00000000..4b9d4aff --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91cap9_matrix.h @@ -0,0 +1,137 @@ +/* + * arch/arm/mach-at91/include/mach/at91cap9_matrix.h + * + * Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com> + * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com> + * Copyright (C) 2006 Atmel Corporation. + * + * Memory Controllers (MATRIX, EBI) - System peripherals registers. + * Based on AT91CAP9 datasheet revision B (Preliminary). + * + * 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. + */ + +#ifndef AT91CAP9_MATRIX_H +#define AT91CAP9_MATRIX_H + +#define AT91_MATRIX_MCFG0 (AT91_MATRIX + 0x00) /* Master Configuration Register 0 */ +#define AT91_MATRIX_MCFG1 (AT91_MATRIX + 0x04) /* Master Configuration Register 1 */ +#define AT91_MATRIX_MCFG2 (AT91_MATRIX + 0x08) /* Master Configuration Register 2 */ +#define AT91_MATRIX_MCFG3 (AT91_MATRIX + 0x0C) /* Master Configuration Register 3 */ +#define AT91_MATRIX_MCFG4 (AT91_MATRIX + 0x10) /* Master Configuration Register 4 */ +#define AT91_MATRIX_MCFG5 (AT91_MATRIX + 0x14) /* Master Configuration Register 5 */ +#define AT91_MATRIX_MCFG6 (AT91_MATRIX + 0x18) /* Master Configuration Register 6 */ +#define AT91_MATRIX_MCFG7 (AT91_MATRIX + 0x1C) /* Master Configuration Register 7 */ +#define AT91_MATRIX_MCFG8 (AT91_MATRIX + 0x20) /* Master Configuration Register 8 */ +#define AT91_MATRIX_MCFG9 (AT91_MATRIX + 0x24) /* Master Configuration Register 9 */ +#define AT91_MATRIX_MCFG10 (AT91_MATRIX + 0x28) /* Master Configuration Register 10 */ +#define AT91_MATRIX_MCFG11 (AT91_MATRIX + 0x2C) /* Master Configuration Register 11 */ +#define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */ +#define AT91_MATRIX_ULBT_INFINITE (0 << 0) +#define AT91_MATRIX_ULBT_SINGLE (1 << 0) +#define AT91_MATRIX_ULBT_FOUR (2 << 0) +#define AT91_MATRIX_ULBT_EIGHT (3 << 0) +#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0) + +#define AT91_MATRIX_SCFG0 (AT91_MATRIX + 0x40) /* Slave Configuration Register 0 */ +#define AT91_MATRIX_SCFG1 (AT91_MATRIX + 0x44) /* Slave Configuration Register 1 */ +#define AT91_MATRIX_SCFG2 (AT91_MATRIX + 0x48) /* Slave Configuration Register 2 */ +#define AT91_MATRIX_SCFG3 (AT91_MATRIX + 0x4C) /* Slave Configuration Register 3 */ +#define AT91_MATRIX_SCFG4 (AT91_MATRIX + 0x50) /* Slave Configuration Register 4 */ +#define AT91_MATRIX_SCFG5 (AT91_MATRIX + 0x54) /* Slave Configuration Register 5 */ +#define AT91_MATRIX_SCFG6 (AT91_MATRIX + 0x58) /* Slave Configuration Register 6 */ +#define AT91_MATRIX_SCFG7 (AT91_MATRIX + 0x5C) /* Slave Configuration Register 7 */ +#define AT91_MATRIX_SCFG8 (AT91_MATRIX + 0x60) /* Slave Configuration Register 8 */ +#define AT91_MATRIX_SCFG9 (AT91_MATRIX + 0x64) /* Slave Configuration Register 9 */ +#define AT91_MATRIX_SLOT_CYCLE (0xff << 0) /* Maximum Number of Allowed Cycles for a Burst */ +#define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */ +#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) +#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16) +#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16) +#define AT91_MATRIX_FIXED_DEFMSTR (0xf << 18) /* Fixed Index of Default Master */ +#define AT91_MATRIX_ARBT (3 << 24) /* Arbitration Type */ +#define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24) +#define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24) + +#define AT91_MATRIX_PRAS0 (AT91_MATRIX + 0x80) /* Priority Register A for Slave 0 */ +#define AT91_MATRIX_PRBS0 (AT91_MATRIX + 0x84) /* Priority Register B for Slave 0 */ +#define AT91_MATRIX_PRAS1 (AT91_MATRIX + 0x88) /* Priority Register A for Slave 1 */ +#define AT91_MATRIX_PRBS1 (AT91_MATRIX + 0x8C) /* Priority Register B for Slave 1 */ +#define AT91_MATRIX_PRAS2 (AT91_MATRIX + 0x90) /* Priority Register A for Slave 2 */ +#define AT91_MATRIX_PRBS2 (AT91_MATRIX + 0x94) /* Priority Register B for Slave 2 */ +#define AT91_MATRIX_PRAS3 (AT91_MATRIX + 0x98) /* Priority Register A for Slave 3 */ +#define AT91_MATRIX_PRBS3 (AT91_MATRIX + 0x9C) /* Priority Register B for Slave 3 */ +#define AT91_MATRIX_PRAS4 (AT91_MATRIX + 0xA0) /* Priority Register A for Slave 4 */ +#define AT91_MATRIX_PRBS4 (AT91_MATRIX + 0xA4) /* Priority Register B for Slave 4 */ +#define AT91_MATRIX_PRAS5 (AT91_MATRIX + 0xA8) /* Priority Register A for Slave 5 */ +#define AT91_MATRIX_PRBS5 (AT91_MATRIX + 0xAC) /* Priority Register B for Slave 5 */ +#define AT91_MATRIX_PRAS6 (AT91_MATRIX + 0xB0) /* Priority Register A for Slave 6 */ +#define AT91_MATRIX_PRBS6 (AT91_MATRIX + 0xB4) /* Priority Register B for Slave 6 */ +#define AT91_MATRIX_PRAS7 (AT91_MATRIX + 0xB8) /* Priority Register A for Slave 7 */ +#define AT91_MATRIX_PRBS7 (AT91_MATRIX + 0xBC) /* Priority Register B for Slave 7 */ +#define AT91_MATRIX_PRAS8 (AT91_MATRIX + 0xC0) /* Priority Register A for Slave 8 */ +#define AT91_MATRIX_PRBS8 (AT91_MATRIX + 0xC4) /* Priority Register B for Slave 8 */ +#define AT91_MATRIX_PRAS9 (AT91_MATRIX + 0xC8) /* Priority Register A for Slave 9 */ +#define AT91_MATRIX_PRBS9 (AT91_MATRIX + 0xCC) /* Priority Register B for Slave 9 */ +#define AT91_MATRIX_M0PR (3 << 0) /* Master 0 Priority */ +#define AT91_MATRIX_M1PR (3 << 4) /* Master 1 Priority */ +#define AT91_MATRIX_M2PR (3 << 8) /* Master 2 Priority */ +#define AT91_MATRIX_M3PR (3 << 12) /* Master 3 Priority */ +#define AT91_MATRIX_M4PR (3 << 16) /* Master 4 Priority */ +#define AT91_MATRIX_M5PR (3 << 20) /* Master 5 Priority */ +#define AT91_MATRIX_M6PR (3 << 24) /* Master 6 Priority */ +#define AT91_MATRIX_M7PR (3 << 28) /* Master 7 Priority */ +#define AT91_MATRIX_M8PR (3 << 0) /* Master 8 Priority (in Register B) */ +#define AT91_MATRIX_M9PR (3 << 4) /* Master 9 Priority (in Register B) */ +#define AT91_MATRIX_M10PR (3 << 8) /* Master 10 Priority (in Register B) */ +#define AT91_MATRIX_M11PR (3 << 12) /* Master 11 Priority (in Register B) */ + +#define AT91_MATRIX_MRCR (AT91_MATRIX + 0x100) /* Master Remap Control Register */ +#define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */ +#define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */ +#define AT91_MATRIX_RCB2 (1 << 2) +#define AT91_MATRIX_RCB3 (1 << 3) +#define AT91_MATRIX_RCB4 (1 << 4) +#define AT91_MATRIX_RCB5 (1 << 5) +#define AT91_MATRIX_RCB6 (1 << 6) +#define AT91_MATRIX_RCB7 (1 << 7) +#define AT91_MATRIX_RCB8 (1 << 8) +#define AT91_MATRIX_RCB9 (1 << 9) +#define AT91_MATRIX_RCB10 (1 << 10) +#define AT91_MATRIX_RCB11 (1 << 11) + +#define AT91_MPBS0_SFR (AT91_MATRIX + 0x114) /* MPBlock Slave 0 Special Function Register */ +#define AT91_MPBS1_SFR (AT91_MATRIX + 0x11C) /* MPBlock Slave 1 Special Function Register */ + +#define AT91_MATRIX_UDPHS (AT91_MATRIX + 0x118) /* USBHS Special Function Register [AT91CAP9 only] */ +#define AT91_MATRIX_SELECT_UDPHS (0 << 31) /* select High Speed UDP */ +#define AT91_MATRIX_SELECT_UDP (1 << 31) /* select standard UDP */ +#define AT91_MATRIX_UDPHS_BYPASS_LOCK (1 << 30) /* bypass lock bit */ + +#define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x120) /* EBI Chip Select Assignment Register */ +#define AT91_MATRIX_EBI_CS1A (1 << 1) /* Chip Select 1 Assignment */ +#define AT91_MATRIX_EBI_CS1A_SMC (0 << 1) +#define AT91_MATRIX_EBI_CS1A_BCRAMC (1 << 1) +#define AT91_MATRIX_EBI_CS3A (1 << 3) /* Chip Select 3 Assignment */ +#define AT91_MATRIX_EBI_CS3A_SMC (0 << 3) +#define AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA (1 << 3) +#define AT91_MATRIX_EBI_CS4A (1 << 4) /* Chip Select 4 Assignment */ +#define AT91_MATRIX_EBI_CS4A_SMC (0 << 4) +#define AT91_MATRIX_EBI_CS4A_SMC_CF1 (1 << 4) +#define AT91_MATRIX_EBI_CS5A (1 << 5) /* Chip Select 5 Assignment */ +#define AT91_MATRIX_EBI_CS5A_SMC (0 << 5) +#define AT91_MATRIX_EBI_CS5A_SMC_CF2 (1 << 5) +#define AT91_MATRIX_EBI_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */ +#define AT91_MATRIX_EBI_DQSPDC (1 << 9) /* Data Qualifier Strobe Pull-Down Configuration */ +#define AT91_MATRIX_EBI_VDDIOMSEL (1 << 16) /* Memory voltage selection */ +#define AT91_MATRIX_EBI_VDDIOMSEL_1_8V (0 << 16) +#define AT91_MATRIX_EBI_VDDIOMSEL_3_3V (1 << 16) + +#define AT91_MPBS2_SFR (AT91_MATRIX + 0x12C) /* MPBlock Slave 2 Special Function Register */ +#define AT91_MPBS3_SFR (AT91_MATRIX + 0x130) /* MPBlock Slave 3 Special Function Register */ +#define AT91_APB_SFR (AT91_MATRIX + 0x134) /* APB Bridge Special Function Register */ + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91rm9200.h b/arch/arm/mach-at91/include/mach/at91rm9200.h new file mode 100644 index 00000000..99e0f8d0 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91rm9200.h @@ -0,0 +1,113 @@ +/* + * arch/arm/mach-at91/include/mach/at91rm9200.h + * + * Copyright (C) 2005 Ivan Kokshaysky + * Copyright (C) SAN People + * + * Common definitions. + * Based on AT91RM9200 datasheet revision E. + * + * 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. + */ + +#ifndef AT91RM9200_H +#define AT91RM9200_H + +/* + * Peripheral identifiers/interrupts. + */ +#define AT91RM9200_ID_PIOA 2 /* Parallel IO Controller A */ +#define AT91RM9200_ID_PIOB 3 /* Parallel IO Controller B */ +#define AT91RM9200_ID_PIOC 4 /* Parallel IO Controller C */ +#define AT91RM9200_ID_PIOD 5 /* Parallel IO Controller D */ +#define AT91RM9200_ID_US0 6 /* USART 0 */ +#define AT91RM9200_ID_US1 7 /* USART 1 */ +#define AT91RM9200_ID_US2 8 /* USART 2 */ +#define AT91RM9200_ID_US3 9 /* USART 3 */ +#define AT91RM9200_ID_MCI 10 /* Multimedia Card Interface */ +#define AT91RM9200_ID_UDP 11 /* USB Device Port */ +#define AT91RM9200_ID_TWI 12 /* Two-Wire Interface */ +#define AT91RM9200_ID_SPI 13 /* Serial Peripheral Interface */ +#define AT91RM9200_ID_SSC0 14 /* Serial Synchronous Controller 0 */ +#define AT91RM9200_ID_SSC1 15 /* Serial Synchronous Controller 1 */ +#define AT91RM9200_ID_SSC2 16 /* Serial Synchronous Controller 2 */ +#define AT91RM9200_ID_TC0 17 /* Timer Counter 0 */ +#define AT91RM9200_ID_TC1 18 /* Timer Counter 1 */ +#define AT91RM9200_ID_TC2 19 /* Timer Counter 2 */ +#define AT91RM9200_ID_TC3 20 /* Timer Counter 3 */ +#define AT91RM9200_ID_TC4 21 /* Timer Counter 4 */ +#define AT91RM9200_ID_TC5 22 /* Timer Counter 5 */ +#define AT91RM9200_ID_UHP 23 /* USB Host port */ +#define AT91RM9200_ID_EMAC 24 /* Ethernet MAC */ +#define AT91RM9200_ID_IRQ0 25 /* Advanced Interrupt Controller (IRQ0) */ +#define AT91RM9200_ID_IRQ1 26 /* Advanced Interrupt Controller (IRQ1) */ +#define AT91RM9200_ID_IRQ2 27 /* Advanced Interrupt Controller (IRQ2) */ +#define AT91RM9200_ID_IRQ3 28 /* Advanced Interrupt Controller (IRQ3) */ +#define AT91RM9200_ID_IRQ4 29 /* Advanced Interrupt Controller (IRQ4) */ +#define AT91RM9200_ID_IRQ5 30 /* Advanced Interrupt Controller (IRQ5) */ +#define AT91RM9200_ID_IRQ6 31 /* Advanced Interrupt Controller (IRQ6) */ + + +/* + * Peripheral physical base addresses. + */ +#define AT91RM9200_BASE_TCB0 0xfffa0000 +#define AT91RM9200_BASE_TC0 0xfffa0000 +#define AT91RM9200_BASE_TC1 0xfffa0040 +#define AT91RM9200_BASE_TC2 0xfffa0080 +#define AT91RM9200_BASE_TCB1 0xfffa4000 +#define AT91RM9200_BASE_TC3 0xfffa4000 +#define AT91RM9200_BASE_TC4 0xfffa4040 +#define AT91RM9200_BASE_TC5 0xfffa4080 +#define AT91RM9200_BASE_UDP 0xfffb0000 +#define AT91RM9200_BASE_MCI 0xfffb4000 +#define AT91RM9200_BASE_TWI 0xfffb8000 +#define AT91RM9200_BASE_EMAC 0xfffbc000 +#define AT91RM9200_BASE_US0 0xfffc0000 +#define AT91RM9200_BASE_US1 0xfffc4000 +#define AT91RM9200_BASE_US2 0xfffc8000 +#define AT91RM9200_BASE_US3 0xfffcc000 +#define AT91RM9200_BASE_SSC0 0xfffd0000 +#define AT91RM9200_BASE_SSC1 0xfffd4000 +#define AT91RM9200_BASE_SSC2 0xfffd8000 +#define AT91RM9200_BASE_SPI 0xfffe0000 +#define AT91_BASE_SYS 0xfffff000 + + +/* + * System Peripherals (offset from AT91_BASE_SYS) + */ +#define AT91_AIC (0xfffff000 - AT91_BASE_SYS) /* Advanced Interrupt Controller */ +#define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) /* Debug Unit */ +#define AT91_PIOA (0xfffff400 - AT91_BASE_SYS) /* PIO Controller A */ +#define AT91_PIOB (0xfffff600 - AT91_BASE_SYS) /* PIO Controller B */ +#define AT91_PIOC (0xfffff800 - AT91_BASE_SYS) /* PIO Controller C */ +#define AT91_PIOD (0xfffffa00 - AT91_BASE_SYS) /* PIO Controller D */ +#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) /* Power Management Controller */ +#define AT91_ST (0xfffffd00 - AT91_BASE_SYS) /* System Timer */ +#define AT91_RTC (0xfffffe00 - AT91_BASE_SYS) /* Real-Time Clock */ +#define AT91_MC (0xffffff00 - AT91_BASE_SYS) /* Memory Controllers */ + +#define AT91_USART0 AT91RM9200_BASE_US0 +#define AT91_USART1 AT91RM9200_BASE_US1 +#define AT91_USART2 AT91RM9200_BASE_US2 +#define AT91_USART3 AT91RM9200_BASE_US3 + +#define AT91_MATRIX 0 /* not supported */ + +/* + * Internal Memory. + */ +#define AT91RM9200_ROM_BASE 0x00100000 /* Internal ROM base address */ +#define AT91RM9200_ROM_SIZE SZ_128K /* Internal ROM size (128Kb) */ + +#define AT91RM9200_SRAM_BASE 0x00200000 /* Internal SRAM base address */ +#define AT91RM9200_SRAM_SIZE SZ_16K /* Internal SRAM size (16Kb) */ + +#define AT91RM9200_UHP_BASE 0x00300000 /* USB Host controller */ + + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91rm9200_emac.h b/arch/arm/mach-at91/include/mach/at91rm9200_emac.h new file mode 100644 index 00000000..b8260cd8 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91rm9200_emac.h @@ -0,0 +1,138 @@ +/* + * arch/arm/mach-at91/include/mach/at91rm9200_emac.h + * + * Copyright (C) 2005 Ivan Kokshaysky + * Copyright (C) SAN People + * + * Ethernet MAC registers. + * Based on AT91RM9200 datasheet revision E. + * + * 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. + */ + +#ifndef AT91RM9200_EMAC_H +#define AT91RM9200_EMAC_H + +#define AT91_EMAC_CTL 0x00 /* Control Register */ +#define AT91_EMAC_LB (1 << 0) /* Loopback */ +#define AT91_EMAC_LBL (1 << 1) /* Loopback Local */ +#define AT91_EMAC_RE (1 << 2) /* Receive Enable */ +#define AT91_EMAC_TE (1 << 3) /* Transmit Enable */ +#define AT91_EMAC_MPE (1 << 4) /* Management Port Enable */ +#define AT91_EMAC_CSR (1 << 5) /* Clear Statistics Registers */ +#define AT91_EMAC_INCSTAT (1 << 6) /* Increment Statistics Registers */ +#define AT91_EMAC_WES (1 << 7) /* Write Enable for Statistics Registers */ +#define AT91_EMAC_BP (1 << 8) /* Back Pressure */ + +#define AT91_EMAC_CFG 0x04 /* Configuration Register */ +#define AT91_EMAC_SPD (1 << 0) /* Speed */ +#define AT91_EMAC_FD (1 << 1) /* Full Duplex */ +#define AT91_EMAC_BR (1 << 2) /* Bit Rate */ +#define AT91_EMAC_CAF (1 << 4) /* Copy All Frames */ +#define AT91_EMAC_NBC (1 << 5) /* No Broadcast */ +#define AT91_EMAC_MTI (1 << 6) /* Multicast Hash Enable */ +#define AT91_EMAC_UNI (1 << 7) /* Unicast Hash Enable */ +#define AT91_EMAC_BIG (1 << 8) /* Receive 1522 Bytes */ +#define AT91_EMAC_EAE (1 << 9) /* External Address Match Enable */ +#define AT91_EMAC_CLK (3 << 10) /* MDC Clock Divisor */ +#define AT91_EMAC_CLK_DIV8 (0 << 10) +#define AT91_EMAC_CLK_DIV16 (1 << 10) +#define AT91_EMAC_CLK_DIV32 (2 << 10) +#define AT91_EMAC_CLK_DIV64 (3 << 10) +#define AT91_EMAC_RTY (1 << 12) /* Retry Test */ +#define AT91_EMAC_RMII (1 << 13) /* Reduce MII (RMII) */ + +#define AT91_EMAC_SR 0x08 /* Status Register */ +#define AT91_EMAC_SR_LINK (1 << 0) /* Link */ +#define AT91_EMAC_SR_MDIO (1 << 1) /* MDIO pin */ +#define AT91_EMAC_SR_IDLE (1 << 2) /* PHY idle */ + +#define AT91_EMAC_TAR 0x0c /* Transmit Address Register */ + +#define AT91_EMAC_TCR 0x10 /* Transmit Control Register */ +#define AT91_EMAC_LEN (0x7ff << 0) /* Transmit Frame Length */ +#define AT91_EMAC_NCRC (1 << 15) /* No CRC */ + +#define AT91_EMAC_TSR 0x14 /* Transmit Status Register */ +#define AT91_EMAC_TSR_OVR (1 << 0) /* Transmit Buffer Overrun */ +#define AT91_EMAC_TSR_COL (1 << 1) /* Collision Occurred */ +#define AT91_EMAC_TSR_RLE (1 << 2) /* Retry Limit Exceeded */ +#define AT91_EMAC_TSR_IDLE (1 << 3) /* Transmitter Idle */ +#define AT91_EMAC_TSR_BNQ (1 << 4) /* Transmit Buffer not Queued */ +#define AT91_EMAC_TSR_COMP (1 << 5) /* Transmit Complete */ +#define AT91_EMAC_TSR_UND (1 << 6) /* Transmit Underrun */ + +#define AT91_EMAC_RBQP 0x18 /* Receive Buffer Queue Pointer */ + +#define AT91_EMAC_RSR 0x20 /* Receive Status Register */ +#define AT91_EMAC_RSR_BNA (1 << 0) /* Buffer Not Available */ +#define AT91_EMAC_RSR_REC (1 << 1) /* Frame Received */ +#define AT91_EMAC_RSR_OVR (1 << 2) /* RX Overrun */ + +#define AT91_EMAC_ISR 0x24 /* Interrupt Status Register */ +#define AT91_EMAC_DONE (1 << 0) /* Management Done */ +#define AT91_EMAC_RCOM (1 << 1) /* Receive Complete */ +#define AT91_EMAC_RBNA (1 << 2) /* Receive Buffer Not Available */ +#define AT91_EMAC_TOVR (1 << 3) /* Transmit Buffer Overrun */ +#define AT91_EMAC_TUND (1 << 4) /* Transmit Buffer Underrun */ +#define AT91_EMAC_RTRY (1 << 5) /* Retry Limit */ +#define AT91_EMAC_TBRE (1 << 6) /* Transmit Buffer Register Empty */ +#define AT91_EMAC_TCOM (1 << 7) /* Transmit Complete */ +#define AT91_EMAC_TIDLE (1 << 8) /* Transmit Idle */ +#define AT91_EMAC_LINK (1 << 9) /* Link */ +#define AT91_EMAC_ROVR (1 << 10) /* RX Overrun */ +#define AT91_EMAC_ABT (1 << 11) /* Abort */ + +#define AT91_EMAC_IER 0x28 /* Interrupt Enable Register */ +#define AT91_EMAC_IDR 0x2c /* Interrupt Disable Register */ +#define AT91_EMAC_IMR 0x30 /* Interrupt Mask Register */ + +#define AT91_EMAC_MAN 0x34 /* PHY Maintenance Register */ +#define AT91_EMAC_DATA (0xffff << 0) /* MDIO Data */ +#define AT91_EMAC_REGA (0x1f << 18) /* MDIO Register */ +#define AT91_EMAC_PHYA (0x1f << 23) /* MDIO PHY Address */ +#define AT91_EMAC_RW (3 << 28) /* Read/Write operation */ +#define AT91_EMAC_RW_W (1 << 28) +#define AT91_EMAC_RW_R (2 << 28) +#define AT91_EMAC_MAN_802_3 0x40020000 /* IEEE 802.3 value */ + +/* + * Statistics Registers. + */ +#define AT91_EMAC_FRA 0x40 /* Frames Transmitted OK */ +#define AT91_EMAC_SCOL 0x44 /* Single Collision Frame */ +#define AT91_EMAC_MCOL 0x48 /* Multiple Collision Frame */ +#define AT91_EMAC_OK 0x4c /* Frames Received OK */ +#define AT91_EMAC_SEQE 0x50 /* Frame Check Sequence Error */ +#define AT91_EMAC_ALE 0x54 /* Alignmemt Error */ +#define AT91_EMAC_DTE 0x58 /* Deffered Transmission Frame */ +#define AT91_EMAC_LCOL 0x5c /* Late Collision */ +#define AT91_EMAC_ECOL 0x60 /* Excessive Collision */ +#define AT91_EMAC_TUE 0x64 /* Transmit Underrun Error */ +#define AT91_EMAC_CSE 0x68 /* Carrier Sense Error */ +#define AT91_EMAC_DRFC 0x6c /* Discard RX Frame */ +#define AT91_EMAC_ROV 0x70 /* Receive Overrun */ +#define AT91_EMAC_CDE 0x74 /* Code Error */ +#define AT91_EMAC_ELR 0x78 /* Excessive Length Error */ +#define AT91_EMAC_RJB 0x7c /* Receive Jabber */ +#define AT91_EMAC_USF 0x80 /* Undersize Frame */ +#define AT91_EMAC_SQEE 0x84 /* SQE Test Error */ + +/* + * Address Registers. + */ +#define AT91_EMAC_HSL 0x90 /* Hash Address Low [31:0] */ +#define AT91_EMAC_HSH 0x94 /* Hash Address High [63:32] */ +#define AT91_EMAC_SA1L 0x98 /* Specific Address 1 Low, bytes 0-3 */ +#define AT91_EMAC_SA1H 0x9c /* Specific Address 1 High, bytes 4-5 */ +#define AT91_EMAC_SA2L 0xa0 /* Specific Address 2 Low, bytes 0-3 */ +#define AT91_EMAC_SA2H 0xa4 /* Specific Address 2 High, bytes 4-5 */ +#define AT91_EMAC_SA3L 0xa8 /* Specific Address 3 Low, bytes 0-3 */ +#define AT91_EMAC_SA3H 0xac /* Specific Address 3 High, bytes 4-5 */ +#define AT91_EMAC_SA4L 0xb0 /* Specific Address 4 Low, bytes 0-3 */ +#define AT91_EMAC_SA4H 0xb4 /* Specific Address 4 High, bytes 4-5 */ + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91rm9200_mc.h b/arch/arm/mach-at91/include/mach/at91rm9200_mc.h new file mode 100644 index 00000000..d34e4ed8 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91rm9200_mc.h @@ -0,0 +1,160 @@ +/* + * arch/arm/mach-at91/include/mach/at91rm9200_mc.h + * + * Copyright (C) 2005 Ivan Kokshaysky + * Copyright (C) SAN People + * + * Memory Controllers (MC, EBI, SMC, SDRAMC, BFC) - System peripherals registers. + * Based on AT91RM9200 datasheet revision E. + * + * 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. + */ + +#ifndef AT91RM9200_MC_H +#define AT91RM9200_MC_H + +/* Memory Controller */ +#define AT91_MC_RCR (AT91_MC + 0x00) /* MC Remap Control Register */ +#define AT91_MC_RCB (1 << 0) /* Remap Command Bit */ + +#define AT91_MC_ASR (AT91_MC + 0x04) /* MC Abort Status Register */ +#define AT91_MC_UNADD (1 << 0) /* Undefined Address Abort Status */ +#define AT91_MC_MISADD (1 << 1) /* Misaligned Address Abort Status */ +#define AT91_MC_ABTSZ (3 << 8) /* Abort Size Status */ +#define AT91_MC_ABTSZ_BYTE (0 << 8) +#define AT91_MC_ABTSZ_HALFWORD (1 << 8) +#define AT91_MC_ABTSZ_WORD (2 << 8) +#define AT91_MC_ABTTYP (3 << 10) /* Abort Type Status */ +#define AT91_MC_ABTTYP_DATAREAD (0 << 10) +#define AT91_MC_ABTTYP_DATAWRITE (1 << 10) +#define AT91_MC_ABTTYP_FETCH (2 << 10) +#define AT91_MC_MST0 (1 << 16) /* ARM920T Abort Source */ +#define AT91_MC_MST1 (1 << 17) /* PDC Abort Source */ +#define AT91_MC_MST2 (1 << 18) /* UHP Abort Source */ +#define AT91_MC_MST3 (1 << 19) /* EMAC Abort Source */ +#define AT91_MC_SVMST0 (1 << 24) /* Saved ARM920T Abort Source */ +#define AT91_MC_SVMST1 (1 << 25) /* Saved PDC Abort Source */ +#define AT91_MC_SVMST2 (1 << 26) /* Saved UHP Abort Source */ +#define AT91_MC_SVMST3 (1 << 27) /* Saved EMAC Abort Source */ + +#define AT91_MC_AASR (AT91_MC + 0x08) /* MC Abort Address Status Register */ + +#define AT91_MC_MPR (AT91_MC + 0x0c) /* MC Master Priority Register */ +#define AT91_MPR_MSTP0 (7 << 0) /* ARM920T Priority */ +#define AT91_MPR_MSTP1 (7 << 4) /* PDC Priority */ +#define AT91_MPR_MSTP2 (7 << 8) /* UHP Priority */ +#define AT91_MPR_MSTP3 (7 << 12) /* EMAC Priority */ + +/* External Bus Interface (EBI) registers */ +#define AT91_EBI_CSA (AT91_MC + 0x60) /* Chip Select Assignment Register */ +#define AT91_EBI_CS0A (1 << 0) /* Chip Select 0 Assignment */ +#define AT91_EBI_CS0A_SMC (0 << 0) +#define AT91_EBI_CS0A_BFC (1 << 0) +#define AT91_EBI_CS1A (1 << 1) /* Chip Select 1 Assignment */ +#define AT91_EBI_CS1A_SMC (0 << 1) +#define AT91_EBI_CS1A_SDRAMC (1 << 1) +#define AT91_EBI_CS3A (1 << 3) /* Chip Select 2 Assignment */ +#define AT91_EBI_CS3A_SMC (0 << 3) +#define AT91_EBI_CS3A_SMC_SMARTMEDIA (1 << 3) +#define AT91_EBI_CS4A (1 << 4) /* Chip Select 3 Assignment */ +#define AT91_EBI_CS4A_SMC (0 << 4) +#define AT91_EBI_CS4A_SMC_COMPACTFLASH (1 << 4) +#define AT91_EBI_CFGR (AT91_MC + 0x64) /* Configuration Register */ +#define AT91_EBI_DBPUC (1 << 0) /* Data Bus Pull-Up Configuration */ + +/* Static Memory Controller (SMC) registers */ +#define AT91_SMC_CSR(n) (AT91_MC + 0x70 + ((n) * 4))/* SMC Chip Select Register */ +#define AT91_SMC_NWS (0x7f << 0) /* Number of Wait States */ +#define AT91_SMC_NWS_(x) ((x) << 0) +#define AT91_SMC_WSEN (1 << 7) /* Wait State Enable */ +#define AT91_SMC_TDF (0xf << 8) /* Data Float Time */ +#define AT91_SMC_TDF_(x) ((x) << 8) +#define AT91_SMC_BAT (1 << 12) /* Byte Access Type */ +#define AT91_SMC_DBW (3 << 13) /* Data Bus Width */ +#define AT91_SMC_DBW_16 (1 << 13) +#define AT91_SMC_DBW_8 (2 << 13) +#define AT91_SMC_DPR (1 << 15) /* Data Read Protocol */ +#define AT91_SMC_ACSS (3 << 16) /* Address to Chip Select Setup */ +#define AT91_SMC_ACSS_STD (0 << 16) +#define AT91_SMC_ACSS_1 (1 << 16) +#define AT91_SMC_ACSS_2 (2 << 16) +#define AT91_SMC_ACSS_3 (3 << 16) +#define AT91_SMC_RWSETUP (7 << 24) /* Read & Write Signal Time Setup */ +#define AT91_SMC_RWSETUP_(x) ((x) << 24) +#define AT91_SMC_RWHOLD (7 << 28) /* Read & Write Signal Hold Time */ +#define AT91_SMC_RWHOLD_(x) ((x) << 28) + +/* SDRAM Controller registers */ +#define AT91_SDRAMC_MR (AT91_MC + 0x90) /* Mode Register */ +#define AT91_SDRAMC_MODE (0xf << 0) /* Command Mode */ +#define AT91_SDRAMC_MODE_NORMAL (0 << 0) +#define AT91_SDRAMC_MODE_NOP (1 << 0) +#define AT91_SDRAMC_MODE_PRECHARGE (2 << 0) +#define AT91_SDRAMC_MODE_LMR (3 << 0) +#define AT91_SDRAMC_MODE_REFRESH (4 << 0) +#define AT91_SDRAMC_DBW (1 << 4) /* Data Bus Width */ +#define AT91_SDRAMC_DBW_32 (0 << 4) +#define AT91_SDRAMC_DBW_16 (1 << 4) + +#define AT91_SDRAMC_TR (AT91_MC + 0x94) /* Refresh Timer Register */ +#define AT91_SDRAMC_COUNT (0xfff << 0) /* Refresh Timer Count */ + +#define AT91_SDRAMC_CR (AT91_MC + 0x98) /* Configuration Register */ +#define AT91_SDRAMC_NC (3 << 0) /* Number of Column Bits */ +#define AT91_SDRAMC_NC_8 (0 << 0) +#define AT91_SDRAMC_NC_9 (1 << 0) +#define AT91_SDRAMC_NC_10 (2 << 0) +#define AT91_SDRAMC_NC_11 (3 << 0) +#define AT91_SDRAMC_NR (3 << 2) /* Number of Row Bits */ +#define AT91_SDRAMC_NR_11 (0 << 2) +#define AT91_SDRAMC_NR_12 (1 << 2) +#define AT91_SDRAMC_NR_13 (2 << 2) +#define AT91_SDRAMC_NB (1 << 4) /* Number of Banks */ +#define AT91_SDRAMC_NB_2 (0 << 4) +#define AT91_SDRAMC_NB_4 (1 << 4) +#define AT91_SDRAMC_CAS (3 << 5) /* CAS Latency */ +#define AT91_SDRAMC_CAS_2 (2 << 5) +#define AT91_SDRAMC_TWR (0xf << 7) /* Write Recovery Delay */ +#define AT91_SDRAMC_TRC (0xf << 11) /* Row Cycle Delay */ +#define AT91_SDRAMC_TRP (0xf << 15) /* Row Precharge Delay */ +#define AT91_SDRAMC_TRCD (0xf << 19) /* Row to Column Delay */ +#define AT91_SDRAMC_TRAS (0xf << 23) /* Active to Precharge Delay */ +#define AT91_SDRAMC_TXSR (0xf << 27) /* Exit Self Refresh to Active Delay */ + +#define AT91_SDRAMC_SRR (AT91_MC + 0x9c) /* Self Refresh Register */ +#define AT91_SDRAMC_LPR (AT91_MC + 0xa0) /* Low Power Register */ +#define AT91_SDRAMC_IER (AT91_MC + 0xa4) /* Interrupt Enable Register */ +#define AT91_SDRAMC_IDR (AT91_MC + 0xa8) /* Interrupt Disable Register */ +#define AT91_SDRAMC_IMR (AT91_MC + 0xac) /* Interrupt Mask Register */ +#define AT91_SDRAMC_ISR (AT91_MC + 0xb0) /* Interrupt Status Register */ + +/* Burst Flash Controller register */ +#define AT91_BFC_MR (AT91_MC + 0xc0) /* Mode Register */ +#define AT91_BFC_BFCOM (3 << 0) /* Burst Flash Controller Operating Mode */ +#define AT91_BFC_BFCOM_DISABLED (0 << 0) +#define AT91_BFC_BFCOM_ASYNC (1 << 0) +#define AT91_BFC_BFCOM_BURST (2 << 0) +#define AT91_BFC_BFCC (3 << 2) /* Burst Flash Controller Clock */ +#define AT91_BFC_BFCC_MCK (1 << 2) +#define AT91_BFC_BFCC_DIV2 (2 << 2) +#define AT91_BFC_BFCC_DIV4 (3 << 2) +#define AT91_BFC_AVL (0xf << 4) /* Address Valid Latency */ +#define AT91_BFC_PAGES (7 << 8) /* Page Size */ +#define AT91_BFC_PAGES_NO_PAGE (0 << 8) +#define AT91_BFC_PAGES_16 (1 << 8) +#define AT91_BFC_PAGES_32 (2 << 8) +#define AT91_BFC_PAGES_64 (3 << 8) +#define AT91_BFC_PAGES_128 (4 << 8) +#define AT91_BFC_PAGES_256 (5 << 8) +#define AT91_BFC_PAGES_512 (6 << 8) +#define AT91_BFC_PAGES_1024 (7 << 8) +#define AT91_BFC_OEL (3 << 12) /* Output Enable Latency */ +#define AT91_BFC_BAAEN (1 << 16) /* Burst Address Advance Enable */ +#define AT91_BFC_BFOEH (1 << 17) /* Burst Flash Output Enable Handling */ +#define AT91_BFC_MUXEN (1 << 18) /* Multiplexed Bus Enable */ +#define AT91_BFC_RDYEN (1 << 19) /* Ready Enable Mode */ + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h b/arch/arm/mach-at91/include/mach/at91sam9260.h new file mode 100644 index 00000000..8b6bf835 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9260.h @@ -0,0 +1,136 @@ +/* + * arch/arm/mach-at91/include/mach/at91sam9260.h + * + * (C) 2006 Andrew Victor + * + * Common definitions. + * Based on AT91SAM9260 datasheet revision A (Preliminary). + * + * Includes also definitions for AT91SAM9XE and AT91SAM9G families + * + * 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. + */ + +#ifndef AT91SAM9260_H +#define AT91SAM9260_H + +/* + * Peripheral identifiers/interrupts. + */ +#define AT91SAM9260_ID_PIOA 2 /* Parallel IO Controller A */ +#define AT91SAM9260_ID_PIOB 3 /* Parallel IO Controller B */ +#define AT91SAM9260_ID_PIOC 4 /* Parallel IO Controller C */ +#define AT91SAM9260_ID_ADC 5 /* Analog-to-Digital Converter */ +#define AT91SAM9260_ID_US0 6 /* USART 0 */ +#define AT91SAM9260_ID_US1 7 /* USART 1 */ +#define AT91SAM9260_ID_US2 8 /* USART 2 */ +#define AT91SAM9260_ID_MCI 9 /* Multimedia Card Interface */ +#define AT91SAM9260_ID_UDP 10 /* USB Device Port */ +#define AT91SAM9260_ID_TWI 11 /* Two-Wire Interface */ +#define AT91SAM9260_ID_SPI0 12 /* Serial Peripheral Interface 0 */ +#define AT91SAM9260_ID_SPI1 13 /* Serial Peripheral Interface 1 */ +#define AT91SAM9260_ID_SSC 14 /* Serial Synchronous Controller */ +#define AT91SAM9260_ID_TC0 17 /* Timer Counter 0 */ +#define AT91SAM9260_ID_TC1 18 /* Timer Counter 1 */ +#define AT91SAM9260_ID_TC2 19 /* Timer Counter 2 */ +#define AT91SAM9260_ID_UHP 20 /* USB Host port */ +#define AT91SAM9260_ID_EMAC 21 /* Ethernet */ +#define AT91SAM9260_ID_ISI 22 /* Image Sensor Interface */ +#define AT91SAM9260_ID_US3 23 /* USART 3 */ +#define AT91SAM9260_ID_US4 24 /* USART 4 */ +#define AT91SAM9260_ID_US5 25 /* USART 5 */ +#define AT91SAM9260_ID_TC3 26 /* Timer Counter 3 */ +#define AT91SAM9260_ID_TC4 27 /* Timer Counter 4 */ +#define AT91SAM9260_ID_TC5 28 /* Timer Counter 5 */ +#define AT91SAM9260_ID_IRQ0 29 /* Advanced Interrupt Controller (IRQ0) */ +#define AT91SAM9260_ID_IRQ1 30 /* Advanced Interrupt Controller (IRQ1) */ +#define AT91SAM9260_ID_IRQ2 31 /* Advanced Interrupt Controller (IRQ2) */ + + +/* + * User Peripheral physical base addresses. + */ +#define AT91SAM9260_BASE_TCB0 0xfffa0000 +#define AT91SAM9260_BASE_TC0 0xfffa0000 +#define AT91SAM9260_BASE_TC1 0xfffa0040 +#define AT91SAM9260_BASE_TC2 0xfffa0080 +#define AT91SAM9260_BASE_UDP 0xfffa4000 +#define AT91SAM9260_BASE_MCI 0xfffa8000 +#define AT91SAM9260_BASE_TWI 0xfffac000 +#define AT91SAM9260_BASE_US0 0xfffb0000 +#define AT91SAM9260_BASE_US1 0xfffb4000 +#define AT91SAM9260_BASE_US2 0xfffb8000 +#define AT91SAM9260_BASE_SSC 0xfffbc000 +#define AT91SAM9260_BASE_ISI 0xfffc0000 +#define AT91SAM9260_BASE_EMAC 0xfffc4000 +#define AT91SAM9260_BASE_SPI0 0xfffc8000 +#define AT91SAM9260_BASE_SPI1 0xfffcc000 +#define AT91SAM9260_BASE_US3 0xfffd0000 +#define AT91SAM9260_BASE_US4 0xfffd4000 +#define AT91SAM9260_BASE_US5 0xfffd8000 +#define AT91SAM9260_BASE_TCB1 0xfffdc000 +#define AT91SAM9260_BASE_TC3 0xfffdc000 +#define AT91SAM9260_BASE_TC4 0xfffdc040 +#define AT91SAM9260_BASE_TC5 0xfffdc080 +#define AT91SAM9260_BASE_ADC 0xfffe0000 +#define AT91_BASE_SYS 0xffffe800 + +/* + * System Peripherals (offset from AT91_BASE_SYS) + */ +#define AT91_ECC (0xffffe800 - AT91_BASE_SYS) +#define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) +#define AT91_SMC (0xffffec00 - AT91_BASE_SYS) +#define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) +#define AT91_CCFG (0xffffef10 - AT91_BASE_SYS) +#define AT91_AIC (0xfffff000 - AT91_BASE_SYS) +#define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) +#define AT91_PIOA (0xfffff400 - AT91_BASE_SYS) +#define AT91_PIOB (0xfffff600 - AT91_BASE_SYS) +#define AT91_PIOC (0xfffff800 - AT91_BASE_SYS) +#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) +#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) +#define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) +#define AT91_RTT (0xfffffd20 - AT91_BASE_SYS) +#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS) +#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) +#define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) + +#define AT91_USART0 AT91SAM9260_BASE_US0 +#define AT91_USART1 AT91SAM9260_BASE_US1 +#define AT91_USART2 AT91SAM9260_BASE_US2 +#define AT91_USART3 AT91SAM9260_BASE_US3 +#define AT91_USART4 AT91SAM9260_BASE_US4 +#define AT91_USART5 AT91SAM9260_BASE_US5 + + +/* + * Internal Memory. + */ +#define AT91SAM9260_ROM_BASE 0x00100000 /* Internal ROM base address */ +#define AT91SAM9260_ROM_SIZE SZ_32K /* Internal ROM size (32Kb) */ + +#define AT91SAM9260_SRAM0_BASE 0x00200000 /* Internal SRAM 0 base address */ +#define AT91SAM9260_SRAM0_SIZE SZ_4K /* Internal SRAM 0 size (4Kb) */ +#define AT91SAM9260_SRAM1_BASE 0x00300000 /* Internal SRAM 1 base address */ +#define AT91SAM9260_SRAM1_SIZE SZ_4K /* Internal SRAM 1 size (4Kb) */ + +#define AT91SAM9260_UHP_BASE 0x00500000 /* USB Host controller */ + +#define AT91SAM9XE_FLASH_BASE 0x00200000 /* Internal FLASH base address */ +#define AT91SAM9XE_SRAM_BASE 0x00300000 /* Internal SRAM base address */ + +#define AT91SAM9G20_ROM_BASE 0x00100000 /* Internal ROM base address */ +#define AT91SAM9G20_ROM_SIZE SZ_32K /* Internal ROM size (32Kb) */ + +#define AT91SAM9G20_SRAM0_BASE 0x00200000 /* Internal SRAM 0 base address */ +#define AT91SAM9G20_SRAM0_SIZE SZ_16K /* Internal SRAM 0 size (16Kb) */ +#define AT91SAM9G20_SRAM1_BASE 0x00300000 /* Internal SRAM 1 base address */ +#define AT91SAM9G20_SRAM1_SIZE SZ_16K /* Internal SRAM 1 size (16Kb) */ + +#define AT91SAM9G20_UHP_BASE 0x00500000 /* USB Host controller */ + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9260_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9260_matrix.h new file mode 100644 index 00000000..020f02ed --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9260_matrix.h @@ -0,0 +1,80 @@ +/* + * arch/arm/mach-at91/include/mach/at91sam9260_matrix.h + * + * Copyright (C) 2007 Atmel Corporation. + * + * Memory Controllers (MATRIX, EBI) - System peripherals registers. + * Based on AT91SAM9260 datasheet revision B. + * + * 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. + */ + +#ifndef AT91SAM9260_MATRIX_H +#define AT91SAM9260_MATRIX_H + +#define AT91_MATRIX_MCFG0 (AT91_MATRIX + 0x00) /* Master Configuration Register 0 */ +#define AT91_MATRIX_MCFG1 (AT91_MATRIX + 0x04) /* Master Configuration Register 1 */ +#define AT91_MATRIX_MCFG2 (AT91_MATRIX + 0x08) /* Master Configuration Register 2 */ +#define AT91_MATRIX_MCFG3 (AT91_MATRIX + 0x0C) /* Master Configuration Register 3 */ +#define AT91_MATRIX_MCFG4 (AT91_MATRIX + 0x10) /* Master Configuration Register 4 */ +#define AT91_MATRIX_MCFG5 (AT91_MATRIX + 0x14) /* Master Configuration Register 5 */ +#define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */ +#define AT91_MATRIX_ULBT_INFINITE (0 << 0) +#define AT91_MATRIX_ULBT_SINGLE (1 << 0) +#define AT91_MATRIX_ULBT_FOUR (2 << 0) +#define AT91_MATRIX_ULBT_EIGHT (3 << 0) +#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0) + +#define AT91_MATRIX_SCFG0 (AT91_MATRIX + 0x40) /* Slave Configuration Register 0 */ +#define AT91_MATRIX_SCFG1 (AT91_MATRIX + 0x44) /* Slave Configuration Register 1 */ +#define AT91_MATRIX_SCFG2 (AT91_MATRIX + 0x48) /* Slave Configuration Register 2 */ +#define AT91_MATRIX_SCFG3 (AT91_MATRIX + 0x4C) /* Slave Configuration Register 3 */ +#define AT91_MATRIX_SCFG4 (AT91_MATRIX + 0x50) /* Slave Configuration Register 4 */ +#define AT91_MATRIX_SLOT_CYCLE (0xff << 0) /* Maximum Number of Allowed Cycles for a Burst */ +#define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */ +#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) +#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16) +#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16) +#define AT91_MATRIX_FIXED_DEFMSTR (7 << 18) /* Fixed Index of Default Master */ +#define AT91_MATRIX_ARBT (3 << 24) /* Arbitration Type */ +#define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24) +#define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24) + +#define AT91_MATRIX_PRAS0 (AT91_MATRIX + 0x80) /* Priority Register A for Slave 0 */ +#define AT91_MATRIX_PRAS1 (AT91_MATRIX + 0x88) /* Priority Register A for Slave 1 */ +#define AT91_MATRIX_PRAS2 (AT91_MATRIX + 0x90) /* Priority Register A for Slave 2 */ +#define AT91_MATRIX_PRAS3 (AT91_MATRIX + 0x98) /* Priority Register A for Slave 3 */ +#define AT91_MATRIX_PRAS4 (AT91_MATRIX + 0xA0) /* Priority Register A for Slave 4 */ +#define AT91_MATRIX_M0PR (3 << 0) /* Master 0 Priority */ +#define AT91_MATRIX_M1PR (3 << 4) /* Master 1 Priority */ +#define AT91_MATRIX_M2PR (3 << 8) /* Master 2 Priority */ +#define AT91_MATRIX_M3PR (3 << 12) /* Master 3 Priority */ +#define AT91_MATRIX_M4PR (3 << 16) /* Master 4 Priority */ +#define AT91_MATRIX_M5PR (3 << 20) /* Master 5 Priority */ + +#define AT91_MATRIX_MRCR (AT91_MATRIX + 0x100) /* Master Remap Control Register */ +#define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */ +#define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */ + +#define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x11C) /* EBI Chip Select Assignment Register */ +#define AT91_MATRIX_CS1A (1 << 1) /* Chip Select 1 Assignment */ +#define AT91_MATRIX_CS1A_SMC (0 << 1) +#define AT91_MATRIX_CS1A_SDRAMC (1 << 1) +#define AT91_MATRIX_CS3A (1 << 3) /* Chip Select 3 Assignment */ +#define AT91_MATRIX_CS3A_SMC (0 << 3) +#define AT91_MATRIX_CS3A_SMC_SMARTMEDIA (1 << 3) +#define AT91_MATRIX_CS4A (1 << 4) /* Chip Select 4 Assignment */ +#define AT91_MATRIX_CS4A_SMC (0 << 4) +#define AT91_MATRIX_CS4A_SMC_CF1 (1 << 4) +#define AT91_MATRIX_CS5A (1 << 5) /* Chip Select 5 Assignment */ +#define AT91_MATRIX_CS5A_SMC (0 << 5) +#define AT91_MATRIX_CS5A_SMC_CF2 (1 << 5) +#define AT91_MATRIX_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */ +#define AT91_MATRIX_VDDIOMSEL (1 << 16) /* Memory voltage selection */ +#define AT91_MATRIX_VDDIOMSEL_1_8V (0 << 16) +#define AT91_MATRIX_VDDIOMSEL_3_3V (1 << 16) + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9261.h b/arch/arm/mach-at91/include/mach/at91sam9261.h new file mode 100644 index 00000000..eafbddaf --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9261.h @@ -0,0 +1,106 @@ +/* + * arch/arm/mach-at91/include/mach/at91sam9261.h + * + * Copyright (C) SAN People + * + * Common definitions. + * Based on AT91SAM9261 datasheet revision E. (Preliminary) + * + * 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. + */ + +#ifndef AT91SAM9261_H +#define AT91SAM9261_H + +/* + * Peripheral identifiers/interrupts. + */ +#define AT91SAM9261_ID_PIOA 2 /* Parallel IO Controller A */ +#define AT91SAM9261_ID_PIOB 3 /* Parallel IO Controller B */ +#define AT91SAM9261_ID_PIOC 4 /* Parallel IO Controller C */ +#define AT91SAM9261_ID_US0 6 /* USART 0 */ +#define AT91SAM9261_ID_US1 7 /* USART 1 */ +#define AT91SAM9261_ID_US2 8 /* USART 2 */ +#define AT91SAM9261_ID_MCI 9 /* Multimedia Card Interface */ +#define AT91SAM9261_ID_UDP 10 /* USB Device Port */ +#define AT91SAM9261_ID_TWI 11 /* Two-Wire Interface */ +#define AT91SAM9261_ID_SPI0 12 /* Serial Peripheral Interface 0 */ +#define AT91SAM9261_ID_SPI1 13 /* Serial Peripheral Interface 1 */ +#define AT91SAM9261_ID_SSC0 14 /* Serial Synchronous Controller 0 */ +#define AT91SAM9261_ID_SSC1 15 /* Serial Synchronous Controller 1 */ +#define AT91SAM9261_ID_SSC2 16 /* Serial Synchronous Controller 2 */ +#define AT91SAM9261_ID_TC0 17 /* Timer Counter 0 */ +#define AT91SAM9261_ID_TC1 18 /* Timer Counter 1 */ +#define AT91SAM9261_ID_TC2 19 /* Timer Counter 2 */ +#define AT91SAM9261_ID_UHP 20 /* USB Host port */ +#define AT91SAM9261_ID_LCDC 21 /* LDC Controller */ +#define AT91SAM9261_ID_IRQ0 29 /* Advanced Interrupt Controller (IRQ0) */ +#define AT91SAM9261_ID_IRQ1 30 /* Advanced Interrupt Controller (IRQ1) */ +#define AT91SAM9261_ID_IRQ2 31 /* Advanced Interrupt Controller (IRQ2) */ + + +/* + * User Peripheral physical base addresses. + */ +#define AT91SAM9261_BASE_TCB0 0xfffa0000 +#define AT91SAM9261_BASE_TC0 0xfffa0000 +#define AT91SAM9261_BASE_TC1 0xfffa0040 +#define AT91SAM9261_BASE_TC2 0xfffa0080 +#define AT91SAM9261_BASE_UDP 0xfffa4000 +#define AT91SAM9261_BASE_MCI 0xfffa8000 +#define AT91SAM9261_BASE_TWI 0xfffac000 +#define AT91SAM9261_BASE_US0 0xfffb0000 +#define AT91SAM9261_BASE_US1 0xfffb4000 +#define AT91SAM9261_BASE_US2 0xfffb8000 +#define AT91SAM9261_BASE_SSC0 0xfffbc000 +#define AT91SAM9261_BASE_SSC1 0xfffc0000 +#define AT91SAM9261_BASE_SSC2 0xfffc4000 +#define AT91SAM9261_BASE_SPI0 0xfffc8000 +#define AT91SAM9261_BASE_SPI1 0xfffcc000 +#define AT91_BASE_SYS 0xffffea00 + + +/* + * System Peripherals (offset from AT91_BASE_SYS) + */ +#define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) +#define AT91_SMC (0xffffec00 - AT91_BASE_SYS) +#define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) +#define AT91_AIC (0xfffff000 - AT91_BASE_SYS) +#define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) +#define AT91_PIOA (0xfffff400 - AT91_BASE_SYS) +#define AT91_PIOB (0xfffff600 - AT91_BASE_SYS) +#define AT91_PIOC (0xfffff800 - AT91_BASE_SYS) +#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) +#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) +#define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) +#define AT91_RTT (0xfffffd20 - AT91_BASE_SYS) +#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS) +#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) +#define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) + +#define AT91_USART0 AT91SAM9261_BASE_US0 +#define AT91_USART1 AT91SAM9261_BASE_US1 +#define AT91_USART2 AT91SAM9261_BASE_US2 + + +/* + * Internal Memory. + */ +#define AT91SAM9261_SRAM_BASE 0x00300000 /* Internal SRAM base address */ +#define AT91SAM9261_SRAM_SIZE 0x00028000 /* Internal SRAM size (160Kb) */ + +#define AT91SAM9G10_SRAM_BASE AT91SAM9261_SRAM_BASE /* Internal SRAM base address */ +#define AT91SAM9G10_SRAM_SIZE 0x00004000 /* Internal SRAM size (16Kb) */ + +#define AT91SAM9261_ROM_BASE 0x00400000 /* Internal ROM base address */ +#define AT91SAM9261_ROM_SIZE SZ_32K /* Internal ROM size (32Kb) */ + +#define AT91SAM9261_UHP_BASE 0x00500000 /* USB Host controller */ +#define AT91SAM9261_LCDC_BASE 0x00600000 /* LDC controller */ + + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9261_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9261_matrix.h new file mode 100644 index 00000000..69c65019 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9261_matrix.h @@ -0,0 +1,64 @@ +/* + * arch/arm/mach-at91/include/mach/at91sam9261_matrix.h + * + * Copyright (C) 2007 Atmel Corporation. + * + * Memory Controllers (MATRIX, EBI) - System peripherals registers. + * Based on AT91SAM9261 datasheet revision D. + * + * 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. + */ + +#ifndef AT91SAM9261_MATRIX_H +#define AT91SAM9261_MATRIX_H + +#define AT91_MATRIX_MCFG (AT91_MATRIX + 0x00) /* Master Configuration Register */ +#define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */ +#define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */ + +#define AT91_MATRIX_SCFG0 (AT91_MATRIX + 0x04) /* Slave Configuration Register 0 */ +#define AT91_MATRIX_SCFG1 (AT91_MATRIX + 0x08) /* Slave Configuration Register 1 */ +#define AT91_MATRIX_SCFG2 (AT91_MATRIX + 0x0C) /* Slave Configuration Register 2 */ +#define AT91_MATRIX_SCFG3 (AT91_MATRIX + 0x10) /* Slave Configuration Register 3 */ +#define AT91_MATRIX_SCFG4 (AT91_MATRIX + 0x14) /* Slave Configuration Register 4 */ +#define AT91_MATRIX_SLOT_CYCLE (0xff << 0) /* Maximum Number of Allowed Cycles for a Burst */ +#define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */ +#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) +#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16) +#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16) +#define AT91_MATRIX_FIXED_DEFMSTR (7 << 18) /* Fixed Index of Default Master */ + +#define AT91_MATRIX_TCR (AT91_MATRIX + 0x24) /* TCM Configuration Register */ +#define AT91_MATRIX_ITCM_SIZE (0xf << 0) /* Size of ITCM enabled memory block */ +#define AT91_MATRIX_ITCM_0 (0 << 0) +#define AT91_MATRIX_ITCM_16 (5 << 0) +#define AT91_MATRIX_ITCM_32 (6 << 0) +#define AT91_MATRIX_ITCM_64 (7 << 0) +#define AT91_MATRIX_DTCM_SIZE (0xf << 4) /* Size of DTCM enabled memory block */ +#define AT91_MATRIX_DTCM_0 (0 << 4) +#define AT91_MATRIX_DTCM_16 (5 << 4) +#define AT91_MATRIX_DTCM_32 (6 << 4) +#define AT91_MATRIX_DTCM_64 (7 << 4) + +#define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x30) /* EBI Chip Select Assignment Register */ +#define AT91_MATRIX_CS1A (1 << 1) /* Chip Select 1 Assignment */ +#define AT91_MATRIX_CS1A_SMC (0 << 1) +#define AT91_MATRIX_CS1A_SDRAMC (1 << 1) +#define AT91_MATRIX_CS3A (1 << 3) /* Chip Select 3 Assignment */ +#define AT91_MATRIX_CS3A_SMC (0 << 3) +#define AT91_MATRIX_CS3A_SMC_SMARTMEDIA (1 << 3) +#define AT91_MATRIX_CS4A (1 << 4) /* Chip Select 4 Assignment */ +#define AT91_MATRIX_CS4A_SMC (0 << 4) +#define AT91_MATRIX_CS4A_SMC_CF1 (1 << 4) +#define AT91_MATRIX_CS5A (1 << 5) /* Chip Select 5 Assignment */ +#define AT91_MATRIX_CS5A_SMC (0 << 5) +#define AT91_MATRIX_CS5A_SMC_CF2 (1 << 5) +#define AT91_MATRIX_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */ + +#define AT91_MATRIX_USBPUCR (AT91_MATRIX + 0x34) /* USB Pad Pull-Up Control Register */ +#define AT91_MATRIX_USBPUCR_PUON (1 << 30) /* USB Device PAD Pull-up Enable */ + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9263.h b/arch/arm/mach-at91/include/mach/at91sam9263.h new file mode 100644 index 00000000..e2d34821 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9263.h @@ -0,0 +1,125 @@ +/* + * arch/arm/mach-at91/include/mach/at91sam9263.h + * + * (C) 2007 Atmel Corporation. + * + * Common definitions. + * Based on AT91SAM9263 datasheet revision B (Preliminary). + * + * 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. + */ + +#ifndef AT91SAM9263_H +#define AT91SAM9263_H + +/* + * Peripheral identifiers/interrupts. + */ +#define AT91SAM9263_ID_PIOA 2 /* Parallel IO Controller A */ +#define AT91SAM9263_ID_PIOB 3 /* Parallel IO Controller B */ +#define AT91SAM9263_ID_PIOCDE 4 /* Parallel IO Controller C, D and E */ +#define AT91SAM9263_ID_US0 7 /* USART 0 */ +#define AT91SAM9263_ID_US1 8 /* USART 1 */ +#define AT91SAM9263_ID_US2 9 /* USART 2 */ +#define AT91SAM9263_ID_MCI0 10 /* Multimedia Card Interface 0 */ +#define AT91SAM9263_ID_MCI1 11 /* Multimedia Card Interface 1 */ +#define AT91SAM9263_ID_CAN 12 /* CAN */ +#define AT91SAM9263_ID_TWI 13 /* Two-Wire Interface */ +#define AT91SAM9263_ID_SPI0 14 /* Serial Peripheral Interface 0 */ +#define AT91SAM9263_ID_SPI1 15 /* Serial Peripheral Interface 1 */ +#define AT91SAM9263_ID_SSC0 16 /* Serial Synchronous Controller 0 */ +#define AT91SAM9263_ID_SSC1 17 /* Serial Synchronous Controller 1 */ +#define AT91SAM9263_ID_AC97C 18 /* AC97 Controller */ +#define AT91SAM9263_ID_TCB 19 /* Timer Counter 0, 1 and 2 */ +#define AT91SAM9263_ID_PWMC 20 /* Pulse Width Modulation Controller */ +#define AT91SAM9263_ID_EMAC 21 /* Ethernet */ +#define AT91SAM9263_ID_2DGE 23 /* 2D Graphic Engine */ +#define AT91SAM9263_ID_UDP 24 /* USB Device Port */ +#define AT91SAM9263_ID_ISI 25 /* Image Sensor Interface */ +#define AT91SAM9263_ID_LCDC 26 /* LCD Controller */ +#define AT91SAM9263_ID_DMA 27 /* DMA Controller */ +#define AT91SAM9263_ID_UHP 29 /* USB Host port */ +#define AT91SAM9263_ID_IRQ0 30 /* Advanced Interrupt Controller (IRQ0) */ +#define AT91SAM9263_ID_IRQ1 31 /* Advanced Interrupt Controller (IRQ1) */ + + +/* + * User Peripheral physical base addresses. + */ +#define AT91SAM9263_BASE_UDP 0xfff78000 +#define AT91SAM9263_BASE_TCB0 0xfff7c000 +#define AT91SAM9263_BASE_TC0 0xfff7c000 +#define AT91SAM9263_BASE_TC1 0xfff7c040 +#define AT91SAM9263_BASE_TC2 0xfff7c080 +#define AT91SAM9263_BASE_MCI0 0xfff80000 +#define AT91SAM9263_BASE_MCI1 0xfff84000 +#define AT91SAM9263_BASE_TWI 0xfff88000 +#define AT91SAM9263_BASE_US0 0xfff8c000 +#define AT91SAM9263_BASE_US1 0xfff90000 +#define AT91SAM9263_BASE_US2 0xfff94000 +#define AT91SAM9263_BASE_SSC0 0xfff98000 +#define AT91SAM9263_BASE_SSC1 0xfff9c000 +#define AT91SAM9263_BASE_AC97C 0xfffa0000 +#define AT91SAM9263_BASE_SPI0 0xfffa4000 +#define AT91SAM9263_BASE_SPI1 0xfffa8000 +#define AT91SAM9263_BASE_CAN 0xfffac000 +#define AT91SAM9263_BASE_PWMC 0xfffb8000 +#define AT91SAM9263_BASE_EMAC 0xfffbc000 +#define AT91SAM9263_BASE_ISI 0xfffc4000 +#define AT91SAM9263_BASE_2DGE 0xfffc8000 +#define AT91_BASE_SYS 0xffffe000 + +/* + * System Peripherals (offset from AT91_BASE_SYS) + */ +#define AT91_ECC0 (0xffffe000 - AT91_BASE_SYS) +#define AT91_SDRAMC0 (0xffffe200 - AT91_BASE_SYS) +#define AT91_SMC0 (0xffffe400 - AT91_BASE_SYS) +#define AT91_ECC1 (0xffffe600 - AT91_BASE_SYS) +#define AT91_SDRAMC1 (0xffffe800 - AT91_BASE_SYS) +#define AT91_SMC1 (0xffffea00 - AT91_BASE_SYS) +#define AT91_MATRIX (0xffffec00 - AT91_BASE_SYS) +#define AT91_CCFG (0xffffed10 - AT91_BASE_SYS) +#define AT91_DBGU (0xffffee00 - AT91_BASE_SYS) +#define AT91_AIC (0xfffff000 - AT91_BASE_SYS) +#define AT91_PIOA (0xfffff200 - AT91_BASE_SYS) +#define AT91_PIOB (0xfffff400 - AT91_BASE_SYS) +#define AT91_PIOC (0xfffff600 - AT91_BASE_SYS) +#define AT91_PIOD (0xfffff800 - AT91_BASE_SYS) +#define AT91_PIOE (0xfffffa00 - AT91_BASE_SYS) +#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) +#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) +#define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) +#define AT91_RTT0 (0xfffffd20 - AT91_BASE_SYS) +#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS) +#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) +#define AT91_RTT1 (0xfffffd50 - AT91_BASE_SYS) +#define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) + +#define AT91_USART0 AT91SAM9263_BASE_US0 +#define AT91_USART1 AT91SAM9263_BASE_US1 +#define AT91_USART2 AT91SAM9263_BASE_US2 + +#define AT91_SMC AT91_SMC0 + +/* + * Internal Memory. + */ +#define AT91SAM9263_SRAM0_BASE 0x00300000 /* Internal SRAM 0 base address */ +#define AT91SAM9263_SRAM0_SIZE (80 * SZ_1K) /* Internal SRAM 0 size (80Kb) */ + +#define AT91SAM9263_ROM_BASE 0x00400000 /* Internal ROM base address */ +#define AT91SAM9263_ROM_SIZE SZ_128K /* Internal ROM size (128Kb) */ + +#define AT91SAM9263_SRAM1_BASE 0x00500000 /* Internal SRAM 1 base address */ +#define AT91SAM9263_SRAM1_SIZE SZ_16K /* Internal SRAM 1 size (16Kb) */ + +#define AT91SAM9263_LCDC_BASE 0x00700000 /* LCD Controller */ +#define AT91SAM9263_DMAC_BASE 0x00800000 /* DMA Controller */ +#define AT91SAM9263_UHP_BASE 0x00a00000 /* USB Host controller */ + + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9263_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9263_matrix.h new file mode 100644 index 00000000..9b3efd3e --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9263_matrix.h @@ -0,0 +1,129 @@ +/* + * arch/arm/mach-at91/include/mach/at91sam9263_matrix.h + * + * Copyright (C) 2006 Atmel Corporation. + * + * Memory Controllers (MATRIX, EBI) - System peripherals registers. + * Based on AT91SAM9263 datasheet revision B (Preliminary). + * + * 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. + */ + +#ifndef AT91SAM9263_MATRIX_H +#define AT91SAM9263_MATRIX_H + +#define AT91_MATRIX_MCFG0 (AT91_MATRIX + 0x00) /* Master Configuration Register 0 */ +#define AT91_MATRIX_MCFG1 (AT91_MATRIX + 0x04) /* Master Configuration Register 1 */ +#define AT91_MATRIX_MCFG2 (AT91_MATRIX + 0x08) /* Master Configuration Register 2 */ +#define AT91_MATRIX_MCFG3 (AT91_MATRIX + 0x0C) /* Master Configuration Register 3 */ +#define AT91_MATRIX_MCFG4 (AT91_MATRIX + 0x10) /* Master Configuration Register 4 */ +#define AT91_MATRIX_MCFG5 (AT91_MATRIX + 0x14) /* Master Configuration Register 5 */ +#define AT91_MATRIX_MCFG6 (AT91_MATRIX + 0x18) /* Master Configuration Register 6 */ +#define AT91_MATRIX_MCFG7 (AT91_MATRIX + 0x1C) /* Master Configuration Register 7 */ +#define AT91_MATRIX_MCFG8 (AT91_MATRIX + 0x20) /* Master Configuration Register 8 */ +#define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */ +#define AT91_MATRIX_ULBT_INFINITE (0 << 0) +#define AT91_MATRIX_ULBT_SINGLE (1 << 0) +#define AT91_MATRIX_ULBT_FOUR (2 << 0) +#define AT91_MATRIX_ULBT_EIGHT (3 << 0) +#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0) + +#define AT91_MATRIX_SCFG0 (AT91_MATRIX + 0x40) /* Slave Configuration Register 0 */ +#define AT91_MATRIX_SCFG1 (AT91_MATRIX + 0x44) /* Slave Configuration Register 1 */ +#define AT91_MATRIX_SCFG2 (AT91_MATRIX + 0x48) /* Slave Configuration Register 2 */ +#define AT91_MATRIX_SCFG3 (AT91_MATRIX + 0x4C) /* Slave Configuration Register 3 */ +#define AT91_MATRIX_SCFG4 (AT91_MATRIX + 0x50) /* Slave Configuration Register 4 */ +#define AT91_MATRIX_SCFG5 (AT91_MATRIX + 0x54) /* Slave Configuration Register 5 */ +#define AT91_MATRIX_SCFG6 (AT91_MATRIX + 0x58) /* Slave Configuration Register 6 */ +#define AT91_MATRIX_SCFG7 (AT91_MATRIX + 0x5C) /* Slave Configuration Register 7 */ +#define AT91_MATRIX_SLOT_CYCLE (0xff << 0) /* Maximum Number of Allowed Cycles for a Burst */ +#define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */ +#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) +#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16) +#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16) +#define AT91_MATRIX_FIXED_DEFMSTR (0xf << 18) /* Fixed Index of Default Master */ +#define AT91_MATRIX_ARBT (3 << 24) /* Arbitration Type */ +#define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24) +#define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24) + +#define AT91_MATRIX_PRAS0 (AT91_MATRIX + 0x80) /* Priority Register A for Slave 0 */ +#define AT91_MATRIX_PRBS0 (AT91_MATRIX + 0x84) /* Priority Register B for Slave 0 */ +#define AT91_MATRIX_PRAS1 (AT91_MATRIX + 0x88) /* Priority Register A for Slave 1 */ +#define AT91_MATRIX_PRBS1 (AT91_MATRIX + 0x8C) /* Priority Register B for Slave 1 */ +#define AT91_MATRIX_PRAS2 (AT91_MATRIX + 0x90) /* Priority Register A for Slave 2 */ +#define AT91_MATRIX_PRBS2 (AT91_MATRIX + 0x94) /* Priority Register B for Slave 2 */ +#define AT91_MATRIX_PRAS3 (AT91_MATRIX + 0x98) /* Priority Register A for Slave 3 */ +#define AT91_MATRIX_PRBS3 (AT91_MATRIX + 0x9C) /* Priority Register B for Slave 3 */ +#define AT91_MATRIX_PRAS4 (AT91_MATRIX + 0xA0) /* Priority Register A for Slave 4 */ +#define AT91_MATRIX_PRBS4 (AT91_MATRIX + 0xA4) /* Priority Register B for Slave 4 */ +#define AT91_MATRIX_PRAS5 (AT91_MATRIX + 0xA8) /* Priority Register A for Slave 5 */ +#define AT91_MATRIX_PRBS5 (AT91_MATRIX + 0xAC) /* Priority Register B for Slave 5 */ +#define AT91_MATRIX_PRAS6 (AT91_MATRIX + 0xB0) /* Priority Register A for Slave 6 */ +#define AT91_MATRIX_PRBS6 (AT91_MATRIX + 0xB4) /* Priority Register B for Slave 6 */ +#define AT91_MATRIX_PRAS7 (AT91_MATRIX + 0xB8) /* Priority Register A for Slave 7 */ +#define AT91_MATRIX_PRBS7 (AT91_MATRIX + 0xBC) /* Priority Register B for Slave 7 */ +#define AT91_MATRIX_M0PR (3 << 0) /* Master 0 Priority */ +#define AT91_MATRIX_M1PR (3 << 4) /* Master 1 Priority */ +#define AT91_MATRIX_M2PR (3 << 8) /* Master 2 Priority */ +#define AT91_MATRIX_M3PR (3 << 12) /* Master 3 Priority */ +#define AT91_MATRIX_M4PR (3 << 16) /* Master 4 Priority */ +#define AT91_MATRIX_M5PR (3 << 20) /* Master 5 Priority */ +#define AT91_MATRIX_M6PR (3 << 24) /* Master 6 Priority */ +#define AT91_MATRIX_M7PR (3 << 28) /* Master 7 Priority */ +#define AT91_MATRIX_M8PR (3 << 0) /* Master 8 Priority (in Register B) */ + +#define AT91_MATRIX_MRCR (AT91_MATRIX + 0x100) /* Master Remap Control Register */ +#define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */ +#define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */ +#define AT91_MATRIX_RCB2 (1 << 2) +#define AT91_MATRIX_RCB3 (1 << 3) +#define AT91_MATRIX_RCB4 (1 << 4) +#define AT91_MATRIX_RCB5 (1 << 5) +#define AT91_MATRIX_RCB6 (1 << 6) +#define AT91_MATRIX_RCB7 (1 << 7) +#define AT91_MATRIX_RCB8 (1 << 8) + +#define AT91_MATRIX_TCMR (AT91_MATRIX + 0x114) /* TCM Configuration Register */ +#define AT91_MATRIX_ITCM_SIZE (0xf << 0) /* Size of ITCM enabled memory block */ +#define AT91_MATRIX_ITCM_0 (0 << 0) +#define AT91_MATRIX_ITCM_16 (5 << 0) +#define AT91_MATRIX_ITCM_32 (6 << 0) +#define AT91_MATRIX_DTCM_SIZE (0xf << 4) /* Size of DTCM enabled memory block */ +#define AT91_MATRIX_DTCM_0 (0 << 4) +#define AT91_MATRIX_DTCM_16 (5 << 4) +#define AT91_MATRIX_DTCM_32 (6 << 4) + +#define AT91_MATRIX_EBI0CSA (AT91_MATRIX + 0x120) /* EBI0 Chip Select Assignment Register */ +#define AT91_MATRIX_EBI0_CS1A (1 << 1) /* Chip Select 1 Assignment */ +#define AT91_MATRIX_EBI0_CS1A_SMC (0 << 1) +#define AT91_MATRIX_EBI0_CS1A_SDRAMC (1 << 1) +#define AT91_MATRIX_EBI0_CS3A (1 << 3) /* Chip Select 3 Assignment */ +#define AT91_MATRIX_EBI0_CS3A_SMC (0 << 3) +#define AT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA (1 << 3) +#define AT91_MATRIX_EBI0_CS4A (1 << 4) /* Chip Select 4 Assignment */ +#define AT91_MATRIX_EBI0_CS4A_SMC (0 << 4) +#define AT91_MATRIX_EBI0_CS4A_SMC_CF1 (1 << 4) +#define AT91_MATRIX_EBI0_CS5A (1 << 5) /* Chip Select 5 Assignment */ +#define AT91_MATRIX_EBI0_CS5A_SMC (0 << 5) +#define AT91_MATRIX_EBI0_CS5A_SMC_CF2 (1 << 5) +#define AT91_MATRIX_EBI0_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */ +#define AT91_MATRIX_EBI0_VDDIOMSEL (1 << 16) /* Memory voltage selection */ +#define AT91_MATRIX_EBI0_VDDIOMSEL_1_8V (0 << 16) +#define AT91_MATRIX_EBI0_VDDIOMSEL_3_3V (1 << 16) + +#define AT91_MATRIX_EBI1CSA (AT91_MATRIX + 0x124) /* EBI1 Chip Select Assignment Register */ +#define AT91_MATRIX_EBI1_CS1A (1 << 1) /* Chip Select 1 Assignment */ +#define AT91_MATRIX_EBI1_CS1A_SMC (0 << 1) +#define AT91_MATRIX_EBI1_CS1A_SDRAMC (1 << 1) +#define AT91_MATRIX_EBI1_CS2A (1 << 3) /* Chip Select 3 Assignment */ +#define AT91_MATRIX_EBI1_CS2A_SMC (0 << 3) +#define AT91_MATRIX_EBI1_CS2A_SMC_SMARTMEDIA (1 << 3) +#define AT91_MATRIX_EBI1_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */ +#define AT91_MATRIX_EBI1_VDDIOMSEL (1 << 16) /* Memory voltage selection */ +#define AT91_MATRIX_EBI1_VDDIOMSEL_1_8V (0 << 16) +#define AT91_MATRIX_EBI1_VDDIOMSEL_3_3V (1 << 16) + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h b/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h new file mode 100644 index 00000000..d27b15ba --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h @@ -0,0 +1,130 @@ +/* + * Header file for the Atmel DDR/SDR SDRAM Controller + * + * Copyright (C) 2010 Atmel Corporation + * Nicolas Ferre <nicolas.ferre@atmel.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. + */ +#ifndef AT91SAM9_DDRSDR_H +#define AT91SAM9_DDRSDR_H + +#define AT91_DDRSDRC_MR 0x00 /* Mode Register */ +#define AT91_DDRSDRC_MODE (0x7 << 0) /* Command Mode */ +#define AT91_DDRSDRC_MODE_NORMAL 0 +#define AT91_DDRSDRC_MODE_NOP 1 +#define AT91_DDRSDRC_MODE_PRECHARGE 2 +#define AT91_DDRSDRC_MODE_LMR 3 +#define AT91_DDRSDRC_MODE_REFRESH 4 +#define AT91_DDRSDRC_MODE_EXT_LMR 5 +#define AT91_DDRSDRC_MODE_DEEP 6 + +#define AT91_DDRSDRC_RTR 0x04 /* Refresh Timer Register */ +#define AT91_DDRSDRC_COUNT (0xfff << 0) /* Refresh Timer Counter */ + +#define AT91_DDRSDRC_CR 0x08 /* Configuration Register */ +#define AT91_DDRSDRC_NC (3 << 0) /* Number of Column Bits */ +#define AT91_DDRSDRC_NC_SDR8 (0 << 0) +#define AT91_DDRSDRC_NC_SDR9 (1 << 0) +#define AT91_DDRSDRC_NC_SDR10 (2 << 0) +#define AT91_DDRSDRC_NC_SDR11 (3 << 0) +#define AT91_DDRSDRC_NC_DDR9 (0 << 0) +#define AT91_DDRSDRC_NC_DDR10 (1 << 0) +#define AT91_DDRSDRC_NC_DDR11 (2 << 0) +#define AT91_DDRSDRC_NC_DDR12 (3 << 0) +#define AT91_DDRSDRC_NR (3 << 2) /* Number of Row Bits */ +#define AT91_DDRSDRC_NR_11 (0 << 2) +#define AT91_DDRSDRC_NR_12 (1 << 2) +#define AT91_DDRSDRC_NR_13 (2 << 2) +#define AT91_DDRSDRC_NR_14 (3 << 2) +#define AT91_DDRSDRC_CAS (7 << 4) /* CAS Latency */ +#define AT91_DDRSDRC_CAS_2 (2 << 4) +#define AT91_DDRSDRC_CAS_3 (3 << 4) +#define AT91_DDRSDRC_CAS_25 (6 << 4) +#define AT91_DDRSDRC_RST_DLL (1 << 7) /* Reset DLL */ +#define AT91_DDRSDRC_DICDS (1 << 8) /* Output impedance control */ +#define AT91_DDRSDRC_DIS_DLL (1 << 9) /* Disable DLL */ +#define AT91_DDRSDRC_OCD (1 << 12) /* Off-Chip Driver */ +#define AT91_DDRSDRC_DQMS (1 << 16) /* Mask Data is Shared */ +#define AT91_DDRSDRC_ACTBST (1 << 18) /* Active Bank X to Burst Stop Read Access Bank Y */ + +#define AT91_DDRSDRC_T0PR 0x0C /* Timing 0 Register */ +#define AT91_DDRSDRC_TRAS (0xf << 0) /* Active to Precharge delay */ +#define AT91_DDRSDRC_TRCD (0xf << 4) /* Row to Column delay */ +#define AT91_DDRSDRC_TWR (0xf << 8) /* Write recovery delay */ +#define AT91_DDRSDRC_TRC (0xf << 12) /* Row cycle delay */ +#define AT91_DDRSDRC_TRP (0xf << 16) /* Row precharge delay */ +#define AT91_DDRSDRC_TRRD (0xf << 20) /* Active BankA to BankB */ +#define AT91_DDRSDRC_TWTR (0x7 << 24) /* Internal Write to Read delay */ +#define AT91_DDRSDRC_RED_WRRD (0x1 << 27) /* Reduce Write to Read Delay */ +#define AT91_DDRSDRC_TMRD (0xf << 28) /* Load mode to active/refresh delay */ + +#define AT91_DDRSDRC_T1PR 0x10 /* Timing 1 Register */ +#define AT91_DDRSDRC_TRFC (0x1f << 0) /* Row Cycle Delay */ +#define AT91_DDRSDRC_TXSNR (0xff << 8) /* Exit self-refresh to non-read */ +#define AT91_DDRSDRC_TXSRD (0xff << 16) /* Exit self-refresh to read */ +#define AT91_DDRSDRC_TXP (0xf << 24) /* Exit power-down delay */ + +#define AT91_DDRSDRC_T2PR 0x14 /* Timing 2 Register */ +#define AT91_DDRSDRC_TXARD (0xf << 0) /* Exit active power down delay to read command in mode "Fast Exit" */ +#define AT91_DDRSDRC_TXARDS (0xf << 4) /* Exit active power down delay to read command in mode "Slow Exit" */ +#define AT91_DDRSDRC_TRPA (0xf << 8) /* Row Precharge All delay */ +#define AT91_DDRSDRC_TRTP (0x7 << 12) /* Read to Precharge delay */ + +#define AT91_DDRSDRC_LPR 0x1C /* Low Power Register */ +#define AT91_DDRSDRC_LPCB (3 << 0) /* Low-power Configurations */ +#define AT91_DDRSDRC_LPCB_DISABLE 0 +#define AT91_DDRSDRC_LPCB_SELF_REFRESH 1 +#define AT91_DDRSDRC_LPCB_POWER_DOWN 2 +#define AT91_DDRSDRC_LPCB_DEEP_POWER_DOWN 3 +#define AT91_DDRSDRC_CLKFR (1 << 2) /* Clock Frozen */ +#define AT91_DDRSDRC_PASR (7 << 4) /* Partial Array Self Refresh */ +#define AT91_DDRSDRC_TCSR (3 << 8) /* Temperature Compensated Self Refresh */ +#define AT91_DDRSDRC_DS (3 << 10) /* Drive Strength */ +#define AT91_DDRSDRC_TIMEOUT (3 << 12) /* Time to define when Low Power Mode is enabled */ +#define AT91_DDRSDRC_TIMEOUT_0_CLK_CYCLES (0 << 12) +#define AT91_DDRSDRC_TIMEOUT_64_CLK_CYCLES (1 << 12) +#define AT91_DDRSDRC_TIMEOUT_128_CLK_CYCLES (2 << 12) +#define AT91_DDRSDRC_APDE (1 << 16) /* Active power down exit time */ +#define AT91_DDRSDRC_UPD_MR (3 << 20) /* Update load mode register and extended mode register */ + +#define AT91_DDRSDRC_MDR 0x20 /* Memory Device Register */ +#define AT91_DDRSDRC_MD (3 << 0) /* Memory Device Type */ +#define AT91_DDRSDRC_MD_SDR 0 +#define AT91_DDRSDRC_MD_LOW_POWER_SDR 1 +#define AT91_DDRSDRC_MD_LOW_POWER_DDR 3 +#define AT91_DDRSDRC_MD_DDR2 6 +#define AT91_DDRSDRC_DBW (1 << 4) /* Data Bus Width */ +#define AT91_DDRSDRC_DBW_32BITS (0 << 4) +#define AT91_DDRSDRC_DBW_16BITS (1 << 4) + +#define AT91_DDRSDRC_DLL 0x24 /* DLL Information Register */ +#define AT91_DDRSDRC_MDINC (1 << 0) /* Master Delay increment */ +#define AT91_DDRSDRC_MDDEC (1 << 1) /* Master Delay decrement */ +#define AT91_DDRSDRC_MDOVF (1 << 2) /* Master Delay Overflow */ +#define AT91_DDRSDRC_MDVAL (0xff << 8) /* Master Delay value */ + +#define AT91_DDRSDRC_HS 0x2C /* High Speed Register */ +#define AT91_DDRSDRC_DIS_ATCP_RD (1 << 2) /* Anticip read access is disabled */ + +#define AT91_DDRSDRC_DELAY(n) (0x30 + (0x4 * (n))) /* Delay I/O Register n */ + +#define AT91_DDRSDRC_WPMR 0xE4 /* Write Protect Mode Register */ +#define AT91_DDRSDRC_WP (1 << 0) /* Write protect enable */ +#define AT91_DDRSDRC_WPKEY (0xffffff << 8) /* Write protect key */ +#define AT91_DDRSDRC_KEY (0x444452 << 8) /* Write protect key = "DDR" */ + +#define AT91_DDRSDRC_WPSR 0xE8 /* Write Protect Status Register */ +#define AT91_DDRSDRC_WPVS (1 << 0) /* Write protect violation status */ +#define AT91_DDRSDRC_WPVSRC (0xffff << 8) /* Write protect violation source */ + +/* Register access macros */ +#define at91_ramc_read(num, reg) \ + at91_sys_read(AT91_DDRSDRC##num + reg) +#define at91_ramc_write(num, reg, value) \ + at91_sys_write(AT91_DDRSDRC##num + reg, value) + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h b/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h new file mode 100644 index 00000000..100f5a59 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h @@ -0,0 +1,91 @@ +/* + * arch/arm/mach-at91/include/mach/at91sam9_sdramc.h + * + * Copyright (C) 2007 Andrew Victor + * Copyright (C) 2007 Atmel Corporation. + * + * SDRAM Controllers (SDRAMC) - System peripherals registers. + * Based on AT91SAM9261 datasheet revision D. + * + * 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. + */ + +#ifndef AT91SAM9_SDRAMC_H +#define AT91SAM9_SDRAMC_H + +/* SDRAM Controller (SDRAMC) registers */ +#define AT91_SDRAMC_MR 0x00 /* SDRAM Controller Mode Register */ +#define AT91_SDRAMC_MODE (0xf << 0) /* Command Mode */ +#define AT91_SDRAMC_MODE_NORMAL 0 +#define AT91_SDRAMC_MODE_NOP 1 +#define AT91_SDRAMC_MODE_PRECHARGE 2 +#define AT91_SDRAMC_MODE_LMR 3 +#define AT91_SDRAMC_MODE_REFRESH 4 +#define AT91_SDRAMC_MODE_EXT_LMR 5 +#define AT91_SDRAMC_MODE_DEEP 6 + +#define AT91_SDRAMC_TR 0x04 /* SDRAM Controller Refresh Timer Register */ +#define AT91_SDRAMC_COUNT (0xfff << 0) /* Refresh Timer Counter */ + +#define AT91_SDRAMC_CR 0x08 /* SDRAM Controller Configuration Register */ +#define AT91_SDRAMC_NC (3 << 0) /* Number of Column Bits */ +#define AT91_SDRAMC_NC_8 (0 << 0) +#define AT91_SDRAMC_NC_9 (1 << 0) +#define AT91_SDRAMC_NC_10 (2 << 0) +#define AT91_SDRAMC_NC_11 (3 << 0) +#define AT91_SDRAMC_NR (3 << 2) /* Number of Row Bits */ +#define AT91_SDRAMC_NR_11 (0 << 2) +#define AT91_SDRAMC_NR_12 (1 << 2) +#define AT91_SDRAMC_NR_13 (2 << 2) +#define AT91_SDRAMC_NB (1 << 4) /* Number of Banks */ +#define AT91_SDRAMC_NB_2 (0 << 4) +#define AT91_SDRAMC_NB_4 (1 << 4) +#define AT91_SDRAMC_CAS (3 << 5) /* CAS Latency */ +#define AT91_SDRAMC_CAS_1 (1 << 5) +#define AT91_SDRAMC_CAS_2 (2 << 5) +#define AT91_SDRAMC_CAS_3 (3 << 5) +#define AT91_SDRAMC_DBW (1 << 7) /* Data Bus Width */ +#define AT91_SDRAMC_DBW_32 (0 << 7) +#define AT91_SDRAMC_DBW_16 (1 << 7) +#define AT91_SDRAMC_TWR (0xf << 8) /* Write Recovery Delay */ +#define AT91_SDRAMC_TRC (0xf << 12) /* Row Cycle Delay */ +#define AT91_SDRAMC_TRP (0xf << 16) /* Row Precharge Delay */ +#define AT91_SDRAMC_TRCD (0xf << 20) /* Row to Column Delay */ +#define AT91_SDRAMC_TRAS (0xf << 24) /* Active to Precharge Delay */ +#define AT91_SDRAMC_TXSR (0xf << 28) /* Exit Self Refresh to Active Delay */ + +#define AT91_SDRAMC_LPR 0x10 /* SDRAM Controller Low Power Register */ +#define AT91_SDRAMC_LPCB (3 << 0) /* Low-power Configurations */ +#define AT91_SDRAMC_LPCB_DISABLE 0 +#define AT91_SDRAMC_LPCB_SELF_REFRESH 1 +#define AT91_SDRAMC_LPCB_POWER_DOWN 2 +#define AT91_SDRAMC_LPCB_DEEP_POWER_DOWN 3 +#define AT91_SDRAMC_PASR (7 << 4) /* Partial Array Self Refresh */ +#define AT91_SDRAMC_TCSR (3 << 8) /* Temperature Compensated Self Refresh */ +#define AT91_SDRAMC_DS (3 << 10) /* Drive Strength */ +#define AT91_SDRAMC_TIMEOUT (3 << 12) /* Time to define when Low Power Mode is enabled */ +#define AT91_SDRAMC_TIMEOUT_0_CLK_CYCLES (0 << 12) +#define AT91_SDRAMC_TIMEOUT_64_CLK_CYCLES (1 << 12) +#define AT91_SDRAMC_TIMEOUT_128_CLK_CYCLES (2 << 12) + +#define AT91_SDRAMC_IER 0x14 /* SDRAM Controller Interrupt Enable Register */ +#define AT91_SDRAMC_IDR 0x18 /* SDRAM Controller Interrupt Disable Register */ +#define AT91_SDRAMC_IMR 0x1C /* SDRAM Controller Interrupt Mask Register */ +#define AT91_SDRAMC_ISR 0x20 /* SDRAM Controller Interrupt Status Register */ +#define AT91_SDRAMC_RES (1 << 0) /* Refresh Error Status */ + +#define AT91_SDRAMC_MDR 0x24 /* SDRAM Memory Device Register */ +#define AT91_SDRAMC_MD (3 << 0) /* Memory Device Type */ +#define AT91_SDRAMC_MD_SDRAM 0 +#define AT91_SDRAMC_MD_LOW_POWER_SDRAM 1 + +/* Register access macros */ +#define at91_ramc_read(num, reg) \ + at91_sys_read(AT91_SDRAMC##num + reg) +#define at91_ramc_write(num, reg, value) \ + at91_sys_write(AT91_SDRAMC##num + reg, value) + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9_smc.h b/arch/arm/mach-at91/include/mach/at91sam9_smc.h new file mode 100644 index 00000000..57de6207 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9_smc.h @@ -0,0 +1,76 @@ +/* + * arch/arm/mach-at91/include/mach/at91sam9_smc.h + * + * Copyright (C) 2007 Andrew Victor + * Copyright (C) 2007 Atmel Corporation. + * + * Static Memory Controllers (SMC) - System peripherals registers. + * Based on AT91SAM9261 datasheet revision D. + * + * 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. + */ + +#ifndef AT91SAM9_SMC_H +#define AT91SAM9_SMC_H + +#define AT91_SMC_SETUP(n) (AT91_SMC + 0x00 + ((n)*0x10)) /* Setup Register for CS n */ +#define AT91_SMC_NWESETUP (0x3f << 0) /* NWE Setup Length */ +#define AT91_SMC_NWESETUP_(x) ((x) << 0) +#define AT91_SMC_NCS_WRSETUP (0x3f << 8) /* NCS Setup Length in Write Access */ +#define AT91_SMC_NCS_WRSETUP_(x) ((x) << 8) +#define AT91_SMC_NRDSETUP (0x3f << 16) /* NRD Setup Length */ +#define AT91_SMC_NRDSETUP_(x) ((x) << 16) +#define AT91_SMC_NCS_RDSETUP (0x3f << 24) /* NCS Setup Length in Read Access */ +#define AT91_SMC_NCS_RDSETUP_(x) ((x) << 24) + +#define AT91_SMC_PULSE(n) (AT91_SMC + 0x04 + ((n)*0x10)) /* Pulse Register for CS n */ +#define AT91_SMC_NWEPULSE (0x7f << 0) /* NWE Pulse Length */ +#define AT91_SMC_NWEPULSE_(x) ((x) << 0) +#define AT91_SMC_NCS_WRPULSE (0x7f << 8) /* NCS Pulse Length in Write Access */ +#define AT91_SMC_NCS_WRPULSE_(x)((x) << 8) +#define AT91_SMC_NRDPULSE (0x7f << 16) /* NRD Pulse Length */ +#define AT91_SMC_NRDPULSE_(x) ((x) << 16) +#define AT91_SMC_NCS_RDPULSE (0x7f << 24) /* NCS Pulse Length in Read Access */ +#define AT91_SMC_NCS_RDPULSE_(x)((x) << 24) + +#define AT91_SMC_CYCLE(n) (AT91_SMC + 0x08 + ((n)*0x10)) /* Cycle Register for CS n */ +#define AT91_SMC_NWECYCLE (0x1ff << 0 ) /* Total Write Cycle Length */ +#define AT91_SMC_NWECYCLE_(x) ((x) << 0) +#define AT91_SMC_NRDCYCLE (0x1ff << 16) /* Total Read Cycle Length */ +#define AT91_SMC_NRDCYCLE_(x) ((x) << 16) + +#define AT91_SMC_MODE(n) (AT91_SMC + 0x0c + ((n)*0x10)) /* Mode Register for CS n */ +#define AT91_SMC_READMODE (1 << 0) /* Read Mode */ +#define AT91_SMC_WRITEMODE (1 << 1) /* Write Mode */ +#define AT91_SMC_EXNWMODE (3 << 4) /* NWAIT Mode */ +#define AT91_SMC_EXNWMODE_DISABLE (0 << 4) +#define AT91_SMC_EXNWMODE_FROZEN (2 << 4) +#define AT91_SMC_EXNWMODE_READY (3 << 4) +#define AT91_SMC_BAT (1 << 8) /* Byte Access Type */ +#define AT91_SMC_BAT_SELECT (0 << 8) +#define AT91_SMC_BAT_WRITE (1 << 8) +#define AT91_SMC_DBW (3 << 12) /* Data Bus Width */ +#define AT91_SMC_DBW_8 (0 << 12) +#define AT91_SMC_DBW_16 (1 << 12) +#define AT91_SMC_DBW_32 (2 << 12) +#define AT91_SMC_TDF (0xf << 16) /* Data Float Time. */ +#define AT91_SMC_TDF_(x) ((x) << 16) +#define AT91_SMC_TDFMODE (1 << 20) /* TDF Optimization - Enabled */ +#define AT91_SMC_PMEN (1 << 24) /* Page Mode Enabled */ +#define AT91_SMC_PS (3 << 28) /* Page Size */ +#define AT91_SMC_PS_4 (0 << 28) +#define AT91_SMC_PS_8 (1 << 28) +#define AT91_SMC_PS_16 (2 << 28) +#define AT91_SMC_PS_32 (3 << 28) + +#if defined(AT91_SMC1) /* The AT91SAM9263 has 2 Static Memory contollers */ +#define AT91_SMC1_SETUP(n) (AT91_SMC1 + 0x00 + ((n)*0x10)) /* Setup Register for CS n */ +#define AT91_SMC1_PULSE(n) (AT91_SMC1 + 0x04 + ((n)*0x10)) /* Pulse Register for CS n */ +#define AT91_SMC1_CYCLE(n) (AT91_SMC1 + 0x08 + ((n)*0x10)) /* Cycle Register for CS n */ +#define AT91_SMC1_MODE(n) (AT91_SMC1 + 0x0c + ((n)*0x10)) /* Mode Register for CS n */ +#endif + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h new file mode 100644 index 00000000..659304aa --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h @@ -0,0 +1,151 @@ +/* + * Chip-specific header file for the AT91SAM9G45 family + * + * Copyright (C) 2008-2009 Atmel Corporation. + * + * Common definitions. + * Based on AT91SAM9G45 preliminary datasheet. + * + * 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. + */ + +#ifndef AT91SAM9G45_H +#define AT91SAM9G45_H + +/* + * Peripheral identifiers/interrupts. + */ +#define AT91SAM9G45_ID_PIOA 2 /* Parallel I/O Controller A */ +#define AT91SAM9G45_ID_PIOB 3 /* Parallel I/O Controller B */ +#define AT91SAM9G45_ID_PIOC 4 /* Parallel I/O Controller C */ +#define AT91SAM9G45_ID_PIODE 5 /* Parallel I/O Controller D and E */ +#define AT91SAM9G45_ID_TRNG 6 /* True Random Number Generator */ +#define AT91SAM9G45_ID_US0 7 /* USART 0 */ +#define AT91SAM9G45_ID_US1 8 /* USART 1 */ +#define AT91SAM9G45_ID_US2 9 /* USART 2 */ +#define AT91SAM9G45_ID_US3 10 /* USART 3 */ +#define AT91SAM9G45_ID_MCI0 11 /* High Speed Multimedia Card Interface 0 */ +#define AT91SAM9G45_ID_TWI0 12 /* Two-Wire Interface 0 */ +#define AT91SAM9G45_ID_TWI1 13 /* Two-Wire Interface 1 */ +#define AT91SAM9G45_ID_SPI0 14 /* Serial Peripheral Interface 0 */ +#define AT91SAM9G45_ID_SPI1 15 /* Serial Peripheral Interface 1 */ +#define AT91SAM9G45_ID_SSC0 16 /* Synchronous Serial Controller 0 */ +#define AT91SAM9G45_ID_SSC1 17 /* Synchronous Serial Controller 1 */ +#define AT91SAM9G45_ID_TCB 18 /* Timer Counter 0, 1, 2, 3, 4 and 5 */ +#define AT91SAM9G45_ID_PWMC 19 /* Pulse Width Modulation Controller */ +#define AT91SAM9G45_ID_TSC 20 /* Touch Screen ADC Controller */ +#define AT91SAM9G45_ID_DMA 21 /* DMA Controller */ +#define AT91SAM9G45_ID_UHPHS 22 /* USB Host High Speed */ +#define AT91SAM9G45_ID_LCDC 23 /* LCD Controller */ +#define AT91SAM9G45_ID_AC97C 24 /* AC97 Controller */ +#define AT91SAM9G45_ID_EMAC 25 /* Ethernet MAC */ +#define AT91SAM9G45_ID_ISI 26 /* Image Sensor Interface */ +#define AT91SAM9G45_ID_UDPHS 27 /* USB Device High Speed */ +#define AT91SAM9G45_ID_AESTDESSHA 28 /* AES + T-DES + SHA */ +#define AT91SAM9G45_ID_MCI1 29 /* High Speed Multimedia Card Interface 1 */ +#define AT91SAM9G45_ID_VDEC 30 /* Video Decoder */ +#define AT91SAM9G45_ID_IRQ0 31 /* Advanced Interrupt Controller */ + +/* + * User Peripheral physical base addresses. + */ +#define AT91SAM9G45_BASE_UDPHS 0xfff78000 +#define AT91SAM9G45_BASE_TCB0 0xfff7c000 +#define AT91SAM9G45_BASE_TC0 0xfff7c000 +#define AT91SAM9G45_BASE_TC1 0xfff7c040 +#define AT91SAM9G45_BASE_TC2 0xfff7c080 +#define AT91SAM9G45_BASE_MCI0 0xfff80000 +#define AT91SAM9G45_BASE_TWI0 0xfff84000 +#define AT91SAM9G45_BASE_TWI1 0xfff88000 +#define AT91SAM9G45_BASE_US0 0xfff8c000 +#define AT91SAM9G45_BASE_US1 0xfff90000 +#define AT91SAM9G45_BASE_US2 0xfff94000 +#define AT91SAM9G45_BASE_US3 0xfff98000 +#define AT91SAM9G45_BASE_SSC0 0xfff9c000 +#define AT91SAM9G45_BASE_SSC1 0xfffa0000 +#define AT91SAM9G45_BASE_SPI0 0xfffa4000 +#define AT91SAM9G45_BASE_SPI1 0xfffa8000 +#define AT91SAM9G45_BASE_AC97C 0xfffac000 +#define AT91SAM9G45_BASE_TSC 0xfffb0000 +#define AT91SAM9G45_BASE_ISI 0xfffb4000 +#define AT91SAM9G45_BASE_PWMC 0xfffb8000 +#define AT91SAM9G45_BASE_EMAC 0xfffbc000 +#define AT91SAM9G45_BASE_AES 0xfffc0000 +#define AT91SAM9G45_BASE_TDES 0xfffc4000 +#define AT91SAM9G45_BASE_SHA 0xfffc8000 +#define AT91SAM9G45_BASE_TRNG 0xfffcc000 +#define AT91SAM9G45_BASE_MCI1 0xfffd0000 +#define AT91SAM9G45_BASE_TCB1 0xfffd4000 +#define AT91SAM9G45_BASE_TC3 0xfffd4000 +#define AT91SAM9G45_BASE_TC4 0xfffd4040 +#define AT91SAM9G45_BASE_TC5 0xfffd4080 +#define AT91_BASE_SYS 0xffffe200 + +/* + * System Peripherals (offset from AT91_BASE_SYS) + */ +#define AT91_ECC (0xffffe200 - AT91_BASE_SYS) +#define AT91_DDRSDRC1 (0xffffe400 - AT91_BASE_SYS) +#define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS) +#define AT91_SMC (0xffffe800 - AT91_BASE_SYS) +#define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS) +#define AT91_DMA (0xffffec00 - AT91_BASE_SYS) +#define AT91_DBGU (0xffffee00 - AT91_BASE_SYS) +#define AT91_AIC (0xfffff000 - AT91_BASE_SYS) +#define AT91_PIOA (0xfffff200 - AT91_BASE_SYS) +#define AT91_PIOB (0xfffff400 - AT91_BASE_SYS) +#define AT91_PIOC (0xfffff600 - AT91_BASE_SYS) +#define AT91_PIOD (0xfffff800 - AT91_BASE_SYS) +#define AT91_PIOE (0xfffffa00 - AT91_BASE_SYS) +#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) +#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) +#define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) +#define AT91_RTT (0xfffffd20 - AT91_BASE_SYS) +#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS) +#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) +#define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) +#define AT91_RTC (0xfffffdb0 - AT91_BASE_SYS) + +#define AT91_USART0 AT91SAM9G45_BASE_US0 +#define AT91_USART1 AT91SAM9G45_BASE_US1 +#define AT91_USART2 AT91SAM9G45_BASE_US2 +#define AT91_USART3 AT91SAM9G45_BASE_US3 + +/* + * Internal Memory. + */ +#define AT91SAM9G45_SRAM_BASE 0x00300000 /* Internal SRAM base address */ +#define AT91SAM9G45_SRAM_SIZE SZ_64K /* Internal SRAM size (64Kb) */ + +#define AT91SAM9G45_ROM_BASE 0x00400000 /* Internal ROM base address */ +#define AT91SAM9G45_ROM_SIZE SZ_64K /* Internal ROM size (64Kb) */ + +#define AT91SAM9G45_LCDC_BASE 0x00500000 /* LCD Controller */ +#define AT91SAM9G45_UDPHS_FIFO 0x00600000 /* USB Device HS controller */ +#define AT91SAM9G45_OHCI_BASE 0x00700000 /* USB Host controller (OHCI) */ +#define AT91SAM9G45_EHCI_BASE 0x00800000 /* USB Host controller (EHCI) */ +#define AT91SAM9G45_VDEC_BASE 0x00900000 /* Video Decoder Controller */ + +#define CONSISTENT_DMA_SIZE SZ_4M + +/* + * DMA peripheral identifiers + * for hardware handshaking interface + */ +#define AT_DMA_ID_MCI0 0 +#define AT_DMA_ID_SPI0_TX 1 +#define AT_DMA_ID_SPI0_RX 2 +#define AT_DMA_ID_SPI1_TX 3 +#define AT_DMA_ID_SPI1_RX 4 +#define AT_DMA_ID_SSC0_TX 5 +#define AT_DMA_ID_SSC0_RX 6 +#define AT_DMA_ID_SSC1_TX 7 +#define AT_DMA_ID_SSC1_RX 8 +#define AT_DMA_ID_AC97_TX 9 +#define AT_DMA_ID_AC97_RX 10 +#define AT_DMA_ID_MCI1 13 + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9g45_matrix.h new file mode 100644 index 00000000..c972d60e --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9g45_matrix.h @@ -0,0 +1,153 @@ +/* + * Matrix-centric header file for the AT91SAM9G45 family + * + * Copyright (C) 2008-2009 Atmel Corporation. + * + * Memory Controllers (MATRIX, EBI) - System peripherals registers. + * Based on AT91SAM9G45 preliminary datasheet. + * + * 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. + */ + +#ifndef AT91SAM9G45_MATRIX_H +#define AT91SAM9G45_MATRIX_H + +#define AT91_MATRIX_MCFG0 (AT91_MATRIX + 0x00) /* Master Configuration Register 0 */ +#define AT91_MATRIX_MCFG1 (AT91_MATRIX + 0x04) /* Master Configuration Register 1 */ +#define AT91_MATRIX_MCFG2 (AT91_MATRIX + 0x08) /* Master Configuration Register 2 */ +#define AT91_MATRIX_MCFG3 (AT91_MATRIX + 0x0C) /* Master Configuration Register 3 */ +#define AT91_MATRIX_MCFG4 (AT91_MATRIX + 0x10) /* Master Configuration Register 4 */ +#define AT91_MATRIX_MCFG5 (AT91_MATRIX + 0x14) /* Master Configuration Register 5 */ +#define AT91_MATRIX_MCFG6 (AT91_MATRIX + 0x18) /* Master Configuration Register 6 */ +#define AT91_MATRIX_MCFG7 (AT91_MATRIX + 0x1C) /* Master Configuration Register 7 */ +#define AT91_MATRIX_MCFG8 (AT91_MATRIX + 0x20) /* Master Configuration Register 8 */ +#define AT91_MATRIX_MCFG9 (AT91_MATRIX + 0x24) /* Master Configuration Register 9 */ +#define AT91_MATRIX_MCFG10 (AT91_MATRIX + 0x28) /* Master Configuration Register 10 */ +#define AT91_MATRIX_MCFG11 (AT91_MATRIX + 0x2C) /* Master Configuration Register 11 */ +#define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */ +#define AT91_MATRIX_ULBT_INFINITE (0 << 0) +#define AT91_MATRIX_ULBT_SINGLE (1 << 0) +#define AT91_MATRIX_ULBT_FOUR (2 << 0) +#define AT91_MATRIX_ULBT_EIGHT (3 << 0) +#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0) +#define AT91_MATRIX_ULBT_THIRTYTWO (5 << 0) +#define AT91_MATRIX_ULBT_SIXTYFOUR (6 << 0) +#define AT91_MATRIX_ULBT_128 (7 << 0) + +#define AT91_MATRIX_SCFG0 (AT91_MATRIX + 0x40) /* Slave Configuration Register 0 */ +#define AT91_MATRIX_SCFG1 (AT91_MATRIX + 0x44) /* Slave Configuration Register 1 */ +#define AT91_MATRIX_SCFG2 (AT91_MATRIX + 0x48) /* Slave Configuration Register 2 */ +#define AT91_MATRIX_SCFG3 (AT91_MATRIX + 0x4C) /* Slave Configuration Register 3 */ +#define AT91_MATRIX_SCFG4 (AT91_MATRIX + 0x50) /* Slave Configuration Register 4 */ +#define AT91_MATRIX_SCFG5 (AT91_MATRIX + 0x54) /* Slave Configuration Register 5 */ +#define AT91_MATRIX_SCFG6 (AT91_MATRIX + 0x58) /* Slave Configuration Register 6 */ +#define AT91_MATRIX_SCFG7 (AT91_MATRIX + 0x5C) /* Slave Configuration Register 7 */ +#define AT91_MATRIX_SLOT_CYCLE (0x1ff << 0) /* Maximum Number of Allowed Cycles for a Burst */ +#define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */ +#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) +#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16) +#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16) +#define AT91_MATRIX_FIXED_DEFMSTR (0xf << 18) /* Fixed Index of Default Master */ + +#define AT91_MATRIX_PRAS0 (AT91_MATRIX + 0x80) /* Priority Register A for Slave 0 */ +#define AT91_MATRIX_PRBS0 (AT91_MATRIX + 0x84) /* Priority Register B for Slave 0 */ +#define AT91_MATRIX_PRAS1 (AT91_MATRIX + 0x88) /* Priority Register A for Slave 1 */ +#define AT91_MATRIX_PRBS1 (AT91_MATRIX + 0x8C) /* Priority Register B for Slave 1 */ +#define AT91_MATRIX_PRAS2 (AT91_MATRIX + 0x90) /* Priority Register A for Slave 2 */ +#define AT91_MATRIX_PRBS2 (AT91_MATRIX + 0x94) /* Priority Register B for Slave 2 */ +#define AT91_MATRIX_PRAS3 (AT91_MATRIX + 0x98) /* Priority Register A for Slave 3 */ +#define AT91_MATRIX_PRBS3 (AT91_MATRIX + 0x9C) /* Priority Register B for Slave 3 */ +#define AT91_MATRIX_PRAS4 (AT91_MATRIX + 0xA0) /* Priority Register A for Slave 4 */ +#define AT91_MATRIX_PRBS4 (AT91_MATRIX + 0xA4) /* Priority Register B for Slave 4 */ +#define AT91_MATRIX_PRAS5 (AT91_MATRIX + 0xA8) /* Priority Register A for Slave 5 */ +#define AT91_MATRIX_PRBS5 (AT91_MATRIX + 0xAC) /* Priority Register B for Slave 5 */ +#define AT91_MATRIX_PRAS6 (AT91_MATRIX + 0xB0) /* Priority Register A for Slave 6 */ +#define AT91_MATRIX_PRBS6 (AT91_MATRIX + 0xB4) /* Priority Register B for Slave 6 */ +#define AT91_MATRIX_PRAS7 (AT91_MATRIX + 0xB8) /* Priority Register A for Slave 7 */ +#define AT91_MATRIX_PRBS7 (AT91_MATRIX + 0xBC) /* Priority Register B for Slave 7 */ +#define AT91_MATRIX_M0PR (3 << 0) /* Master 0 Priority */ +#define AT91_MATRIX_M1PR (3 << 4) /* Master 1 Priority */ +#define AT91_MATRIX_M2PR (3 << 8) /* Master 2 Priority */ +#define AT91_MATRIX_M3PR (3 << 12) /* Master 3 Priority */ +#define AT91_MATRIX_M4PR (3 << 16) /* Master 4 Priority */ +#define AT91_MATRIX_M5PR (3 << 20) /* Master 5 Priority */ +#define AT91_MATRIX_M6PR (3 << 24) /* Master 6 Priority */ +#define AT91_MATRIX_M7PR (3 << 28) /* Master 7 Priority */ +#define AT91_MATRIX_M8PR (3 << 0) /* Master 8 Priority (in Register B) */ +#define AT91_MATRIX_M9PR (3 << 4) /* Master 9 Priority (in Register B) */ +#define AT91_MATRIX_M10PR (3 << 8) /* Master 10 Priority (in Register B) */ +#define AT91_MATRIX_M11PR (3 << 12) /* Master 11 Priority (in Register B) */ + +#define AT91_MATRIX_MRCR (AT91_MATRIX + 0x100) /* Master Remap Control Register */ +#define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */ +#define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */ +#define AT91_MATRIX_RCB2 (1 << 2) +#define AT91_MATRIX_RCB3 (1 << 3) +#define AT91_MATRIX_RCB4 (1 << 4) +#define AT91_MATRIX_RCB5 (1 << 5) +#define AT91_MATRIX_RCB6 (1 << 6) +#define AT91_MATRIX_RCB7 (1 << 7) +#define AT91_MATRIX_RCB8 (1 << 8) +#define AT91_MATRIX_RCB9 (1 << 9) +#define AT91_MATRIX_RCB10 (1 << 10) +#define AT91_MATRIX_RCB11 (1 << 11) + +#define AT91_MATRIX_TCMR (AT91_MATRIX + 0x110) /* TCM Configuration Register */ +#define AT91_MATRIX_ITCM_SIZE (0xf << 0) /* Size of ITCM enabled memory block */ +#define AT91_MATRIX_ITCM_0 (0 << 0) +#define AT91_MATRIX_ITCM_32 (6 << 0) +#define AT91_MATRIX_DTCM_SIZE (0xf << 4) /* Size of DTCM enabled memory block */ +#define AT91_MATRIX_DTCM_0 (0 << 4) +#define AT91_MATRIX_DTCM_32 (6 << 4) +#define AT91_MATRIX_DTCM_64 (7 << 4) +#define AT91_MATRIX_TCM_NWS (0x1 << 11) /* Wait state TCM register */ +#define AT91_MATRIX_TCM_NO_WS (0x0 << 11) +#define AT91_MATRIX_TCM_ONE_WS (0x1 << 11) + +#define AT91_MATRIX_VIDEO (AT91_MATRIX + 0x118) /* Video Mode Configuration Register */ +#define AT91C_VDEC_SEL (0x1 << 0) /* Video Mode Selection */ +#define AT91C_VDEC_SEL_OFF (0 << 0) +#define AT91C_VDEC_SEL_ON (1 << 0) + +#define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x128) /* EBI Chip Select Assignment Register */ +#define AT91_MATRIX_EBI_CS1A (1 << 1) /* Chip Select 1 Assignment */ +#define AT91_MATRIX_EBI_CS1A_SMC (0 << 1) +#define AT91_MATRIX_EBI_CS1A_SDRAMC (1 << 1) +#define AT91_MATRIX_EBI_CS3A (1 << 3) /* Chip Select 3 Assignment */ +#define AT91_MATRIX_EBI_CS3A_SMC (0 << 3) +#define AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA (1 << 3) +#define AT91_MATRIX_EBI_CS4A (1 << 4) /* Chip Select 4 Assignment */ +#define AT91_MATRIX_EBI_CS4A_SMC (0 << 4) +#define AT91_MATRIX_EBI_CS4A_SMC_CF0 (1 << 4) +#define AT91_MATRIX_EBI_CS5A (1 << 5) /* Chip Select 5 Assignment */ +#define AT91_MATRIX_EBI_CS5A_SMC (0 << 5) +#define AT91_MATRIX_EBI_CS5A_SMC_CF1 (1 << 5) +#define AT91_MATRIX_EBI_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */ +#define AT91_MATRIX_EBI_DBPU_ON (0 << 8) +#define AT91_MATRIX_EBI_DBPU_OFF (1 << 8) +#define AT91_MATRIX_EBI_VDDIOMSEL (1 << 16) /* Memory voltage selection */ +#define AT91_MATRIX_EBI_VDDIOMSEL_1_8V (0 << 16) +#define AT91_MATRIX_EBI_VDDIOMSEL_3_3V (1 << 16) +#define AT91_MATRIX_EBI_EBI_IOSR (1 << 17) /* EBI I/O slew rate selection */ +#define AT91_MATRIX_EBI_EBI_IOSR_REDUCED (0 << 17) +#define AT91_MATRIX_EBI_EBI_IOSR_NORMAL (1 << 17) +#define AT91_MATRIX_EBI_DDR_IOSR (1 << 18) /* DDR2 dedicated port I/O slew rate selection */ +#define AT91_MATRIX_EBI_DDR_IOSR_REDUCED (0 << 18) +#define AT91_MATRIX_EBI_DDR_IOSR_NORMAL (1 << 18) + +#define AT91_MATRIX_WPMR (AT91_MATRIX + 0x1E4) /* Write Protect Mode Register */ +#define AT91_MATRIX_WPMR_WPEN (1 << 0) /* Write Protect ENable */ +#define AT91_MATRIX_WPMR_WP_WPDIS (0 << 0) +#define AT91_MATRIX_WPMR_WP_WPEN (1 << 0) +#define AT91_MATRIX_WPMR_WPKEY (0xFFFFFF << 8) /* Write Protect KEY */ + +#define AT91_MATRIX_WPSR (AT91_MATRIX + 0x1E8) /* Write Protect Status Register */ +#define AT91_MATRIX_WPSR_WPVS (1 << 0) /* Write Protect Violation Status */ +#define AT91_MATRIX_WPSR_NO_WPV (0 << 0) +#define AT91_MATRIX_WPSR_WPV (1 << 0) +#define AT91_MATRIX_WPSR_WPVSRC (0xFFFF << 8) /* Write Protect Violation Source */ + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h new file mode 100644 index 00000000..41dbbe61 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h @@ -0,0 +1,113 @@ +/* + * arch/arm/mach-at91/include/mach/at91sam9260.h + * + * Copyright (C) 2007 Atmel Corporation + * + * Common definitions. + * Based on AT91SAM9RL datasheet revision A. (Preliminary) + * + * 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. + */ + +#ifndef AT91SAM9RL_H +#define AT91SAM9RL_H + +/* + * Peripheral identifiers/interrupts. + */ +#define AT91SAM9RL_ID_PIOA 2 /* Parallel IO Controller A */ +#define AT91SAM9RL_ID_PIOB 3 /* Parallel IO Controller B */ +#define AT91SAM9RL_ID_PIOC 4 /* Parallel IO Controller C */ +#define AT91SAM9RL_ID_PIOD 5 /* Parallel IO Controller D */ +#define AT91SAM9RL_ID_US0 6 /* USART 0 */ +#define AT91SAM9RL_ID_US1 7 /* USART 1 */ +#define AT91SAM9RL_ID_US2 8 /* USART 2 */ +#define AT91SAM9RL_ID_US3 9 /* USART 3 */ +#define AT91SAM9RL_ID_MCI 10 /* Multimedia Card Interface */ +#define AT91SAM9RL_ID_TWI0 11 /* TWI 0 */ +#define AT91SAM9RL_ID_TWI1 12 /* TWI 1 */ +#define AT91SAM9RL_ID_SPI 13 /* Serial Peripheral Interface */ +#define AT91SAM9RL_ID_SSC0 14 /* Serial Synchronous Controller 0 */ +#define AT91SAM9RL_ID_SSC1 15 /* Serial Synchronous Controller 1 */ +#define AT91SAM9RL_ID_TC0 16 /* Timer Counter 0 */ +#define AT91SAM9RL_ID_TC1 17 /* Timer Counter 1 */ +#define AT91SAM9RL_ID_TC2 18 /* Timer Counter 2 */ +#define AT91SAM9RL_ID_PWMC 19 /* Pulse Width Modulation Controller */ +#define AT91SAM9RL_ID_TSC 20 /* Touch Screen Controller */ +#define AT91SAM9RL_ID_DMA 21 /* DMA Controller */ +#define AT91SAM9RL_ID_UDPHS 22 /* USB Device HS */ +#define AT91SAM9RL_ID_LCDC 23 /* LCD Controller */ +#define AT91SAM9RL_ID_AC97C 24 /* AC97 Controller */ +#define AT91SAM9RL_ID_IRQ0 31 /* Advanced Interrupt Controller (IRQ0) */ + + +/* + * User Peripheral physical base addresses. + */ +#define AT91SAM9RL_BASE_TCB0 0xfffa0000 +#define AT91SAM9RL_BASE_TC0 0xfffa0000 +#define AT91SAM9RL_BASE_TC1 0xfffa0040 +#define AT91SAM9RL_BASE_TC2 0xfffa0080 +#define AT91SAM9RL_BASE_MCI 0xfffa4000 +#define AT91SAM9RL_BASE_TWI0 0xfffa8000 +#define AT91SAM9RL_BASE_TWI1 0xfffac000 +#define AT91SAM9RL_BASE_US0 0xfffb0000 +#define AT91SAM9RL_BASE_US1 0xfffb4000 +#define AT91SAM9RL_BASE_US2 0xfffb8000 +#define AT91SAM9RL_BASE_US3 0xfffbc000 +#define AT91SAM9RL_BASE_SSC0 0xfffc0000 +#define AT91SAM9RL_BASE_SSC1 0xfffc4000 +#define AT91SAM9RL_BASE_PWMC 0xfffc8000 +#define AT91SAM9RL_BASE_SPI 0xfffcc000 +#define AT91SAM9RL_BASE_TSC 0xfffd0000 +#define AT91SAM9RL_BASE_UDPHS 0xfffd4000 +#define AT91SAM9RL_BASE_AC97C 0xfffd8000 +#define AT91_BASE_SYS 0xffffc000 + + +/* + * System Peripherals (offset from AT91_BASE_SYS) + */ +#define AT91_DMA (0xffffe600 - AT91_BASE_SYS) +#define AT91_ECC (0xffffe800 - AT91_BASE_SYS) +#define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) +#define AT91_SMC (0xffffec00 - AT91_BASE_SYS) +#define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) +#define AT91_CCFG (0xffffef10 - AT91_BASE_SYS) +#define AT91_AIC (0xfffff000 - AT91_BASE_SYS) +#define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) +#define AT91_PIOA (0xfffff400 - AT91_BASE_SYS) +#define AT91_PIOB (0xfffff600 - AT91_BASE_SYS) +#define AT91_PIOC (0xfffff800 - AT91_BASE_SYS) +#define AT91_PIOD (0xfffffa00 - AT91_BASE_SYS) +#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) +#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) +#define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) +#define AT91_RTT (0xfffffd20 - AT91_BASE_SYS) +#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS) +#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) +#define AT91_SCKCR (0xfffffd50 - AT91_BASE_SYS) +#define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) +#define AT91_RTC (0xfffffe00 - AT91_BASE_SYS) + +#define AT91_USART0 AT91SAM9RL_BASE_US0 +#define AT91_USART1 AT91SAM9RL_BASE_US1 +#define AT91_USART2 AT91SAM9RL_BASE_US2 +#define AT91_USART3 AT91SAM9RL_BASE_US3 + + +/* + * Internal Memory. + */ +#define AT91SAM9RL_SRAM_BASE 0x00300000 /* Internal SRAM base address */ +#define AT91SAM9RL_SRAM_SIZE SZ_16K /* Internal SRAM size (16Kb) */ + +#define AT91SAM9RL_ROM_BASE 0x00400000 /* Internal ROM base address */ +#define AT91SAM9RL_ROM_SIZE (2 * SZ_16K) /* Internal ROM size (32Kb) */ + +#define AT91SAM9RL_LCDC_BASE 0x00500000 /* LCD Controller */ +#define AT91SAM9RL_UDPHS_FIFO 0x00600000 /* USB Device HS controller */ + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9rl_matrix.h new file mode 100644 index 00000000..5f914907 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9rl_matrix.h @@ -0,0 +1,96 @@ +/* + * arch/arm/mach-at91/include/mach/at91sam9rl_matrix.h + * + * Copyright (C) 2007 Atmel Corporation + * + * Memory Controllers (MATRIX, EBI) - System peripherals registers. + * Based on AT91SAM9RL datasheet revision A. (Preliminary) + * + * 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. + */ + +#ifndef AT91SAM9RL_MATRIX_H +#define AT91SAM9RL_MATRIX_H + +#define AT91_MATRIX_MCFG0 (AT91_MATRIX + 0x00) /* Master Configuration Register 0 */ +#define AT91_MATRIX_MCFG1 (AT91_MATRIX + 0x04) /* Master Configuration Register 1 */ +#define AT91_MATRIX_MCFG2 (AT91_MATRIX + 0x08) /* Master Configuration Register 2 */ +#define AT91_MATRIX_MCFG3 (AT91_MATRIX + 0x0C) /* Master Configuration Register 3 */ +#define AT91_MATRIX_MCFG4 (AT91_MATRIX + 0x10) /* Master Configuration Register 4 */ +#define AT91_MATRIX_MCFG5 (AT91_MATRIX + 0x14) /* Master Configuration Register 5 */ +#define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */ +#define AT91_MATRIX_ULBT_INFINITE (0 << 0) +#define AT91_MATRIX_ULBT_SINGLE (1 << 0) +#define AT91_MATRIX_ULBT_FOUR (2 << 0) +#define AT91_MATRIX_ULBT_EIGHT (3 << 0) +#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0) + +#define AT91_MATRIX_SCFG0 (AT91_MATRIX + 0x40) /* Slave Configuration Register 0 */ +#define AT91_MATRIX_SCFG1 (AT91_MATRIX + 0x44) /* Slave Configuration Register 1 */ +#define AT91_MATRIX_SCFG2 (AT91_MATRIX + 0x48) /* Slave Configuration Register 2 */ +#define AT91_MATRIX_SCFG3 (AT91_MATRIX + 0x4C) /* Slave Configuration Register 3 */ +#define AT91_MATRIX_SCFG4 (AT91_MATRIX + 0x50) /* Slave Configuration Register 4 */ +#define AT91_MATRIX_SCFG5 (AT91_MATRIX + 0x54) /* Slave Configuration Register 5 */ +#define AT91_MATRIX_SLOT_CYCLE (0xff << 0) /* Maximum Number of Allowed Cycles for a Burst */ +#define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */ +#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) +#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16) +#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16) +#define AT91_MATRIX_FIXED_DEFMSTR (0xf << 18) /* Fixed Index of Default Master */ +#define AT91_MATRIX_ARBT (3 << 24) /* Arbitration Type */ +#define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24) +#define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24) + +#define AT91_MATRIX_PRAS0 (AT91_MATRIX + 0x80) /* Priority Register A for Slave 0 */ +#define AT91_MATRIX_PRAS1 (AT91_MATRIX + 0x88) /* Priority Register A for Slave 1 */ +#define AT91_MATRIX_PRAS2 (AT91_MATRIX + 0x90) /* Priority Register A for Slave 2 */ +#define AT91_MATRIX_PRAS3 (AT91_MATRIX + 0x98) /* Priority Register A for Slave 3 */ +#define AT91_MATRIX_PRAS4 (AT91_MATRIX + 0xA0) /* Priority Register A for Slave 4 */ +#define AT91_MATRIX_PRAS5 (AT91_MATRIX + 0xA8) /* Priority Register A for Slave 5 */ +#define AT91_MATRIX_M0PR (3 << 0) /* Master 0 Priority */ +#define AT91_MATRIX_M1PR (3 << 4) /* Master 1 Priority */ +#define AT91_MATRIX_M2PR (3 << 8) /* Master 2 Priority */ +#define AT91_MATRIX_M3PR (3 << 12) /* Master 3 Priority */ +#define AT91_MATRIX_M4PR (3 << 16) /* Master 4 Priority */ +#define AT91_MATRIX_M5PR (3 << 20) /* Master 5 Priority */ + +#define AT91_MATRIX_MRCR (AT91_MATRIX + 0x100) /* Master Remap Control Register */ +#define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */ +#define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */ +#define AT91_MATRIX_RCB2 (1 << 2) +#define AT91_MATRIX_RCB3 (1 << 3) +#define AT91_MATRIX_RCB4 (1 << 4) +#define AT91_MATRIX_RCB5 (1 << 5) + +#define AT91_MATRIX_TCMR (AT91_MATRIX + 0x114) /* TCM Configuration Register */ +#define AT91_MATRIX_ITCM_SIZE (0xf << 0) /* Size of ITCM enabled memory block */ +#define AT91_MATRIX_ITCM_0 (0 << 0) +#define AT91_MATRIX_ITCM_16 (5 << 0) +#define AT91_MATRIX_ITCM_32 (6 << 0) +#define AT91_MATRIX_DTCM_SIZE (0xf << 4) /* Size of DTCM enabled memory block */ +#define AT91_MATRIX_DTCM_0 (0 << 4) +#define AT91_MATRIX_DTCM_16 (5 << 4) +#define AT91_MATRIX_DTCM_32 (6 << 4) + +#define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x120) /* EBI0 Chip Select Assignment Register */ +#define AT91_MATRIX_CS1A (1 << 1) /* Chip Select 1 Assignment */ +#define AT91_MATRIX_CS1A_SMC (0 << 1) +#define AT91_MATRIX_CS1A_SDRAMC (1 << 1) +#define AT91_MATRIX_CS3A (1 << 3) /* Chip Select 3 Assignment */ +#define AT91_MATRIX_CS3A_SMC (0 << 3) +#define AT91_MATRIX_CS3A_SMC_SMARTMEDIA (1 << 3) +#define AT91_MATRIX_CS4A (1 << 4) /* Chip Select 4 Assignment */ +#define AT91_MATRIX_CS4A_SMC (0 << 4) +#define AT91_MATRIX_CS4A_SMC_CF1 (1 << 4) +#define AT91_MATRIX_CS5A (1 << 5) /* Chip Select 5 Assignment */ +#define AT91_MATRIX_CS5A_SMC (0 << 5) +#define AT91_MATRIX_CS5A_SMC_CF2 (1 << 5) +#define AT91_MATRIX_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */ +#define AT91_MATRIX_VDDIOMSEL (1 << 16) /* Memory voltage selection */ +#define AT91_MATRIX_VDDIOMSEL_1_8V (0 << 16) +#define AT91_MATRIX_VDDIOMSEL_3_3V (1 << 16) + + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91x40.h b/arch/arm/mach-at91/include/mach/at91x40.h new file mode 100644 index 00000000..a152ff87 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91x40.h @@ -0,0 +1,59 @@ +/* + * arch/arm/mach-at91/include/mach/at91x40.h + * + * (C) Copyright 2007, Greg Ungerer <gerg@snapgear.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. + */ + +#ifndef AT91X40_H +#define AT91X40_H + +/* + * IRQ list. + */ +#define AT91X40_ID_USART0 2 /* USART port 0 */ +#define AT91X40_ID_USART1 3 /* USART port 1 */ +#define AT91X40_ID_TC0 4 /* Timer/Counter 0 */ +#define AT91X40_ID_TC1 5 /* Timer/Counter 1*/ +#define AT91X40_ID_TC2 6 /* Timer/Counter 2*/ +#define AT91X40_ID_WD 7 /* Watchdog? */ +#define AT91X40_ID_PIOA 8 /* Parallel IO Controller A */ + +#define AT91X40_ID_IRQ0 16 /* External IRQ 0 */ +#define AT91X40_ID_IRQ1 17 /* External IRQ 1 */ +#define AT91X40_ID_IRQ2 18 /* External IRQ 2 */ + +/* + * System Peripherals (offset from AT91_BASE_SYS) + */ +#define AT91_BASE_SYS 0xffc00000 + +#define AT91_EBI (0xffe00000 - AT91_BASE_SYS) /* External Bus Interface */ +#define AT91_SF (0xfff00000 - AT91_BASE_SYS) /* Special Function */ +#define AT91_USART1 (0xfffcc000 - AT91_BASE_SYS) /* USART 1 */ +#define AT91_USART0 (0xfffd0000 - AT91_BASE_SYS) /* USART 0 */ +#define AT91_TC (0xfffe0000 - AT91_BASE_SYS) /* Timer Counter */ +#define AT91_PIOA (0xffff0000 - AT91_BASE_SYS) /* PIO Controller A */ +#define AT91_PS (0xffff4000 - AT91_BASE_SYS) /* Power Save */ +#define AT91_WD (0xffff8000 - AT91_BASE_SYS) /* Watchdog Timer */ +#define AT91_AIC (0xfffff000 - AT91_BASE_SYS) /* Advanced Interrupt Controller */ + +/* + * The AT91x40 series doesn't have a debug unit like the other AT91 parts. + * But it does have a chip identify register and extension ID, so define at + * least these here. + */ +#define AT91_DBGU_CIDR (AT91_SF + 0) /* CIDR in PS segment */ +#define AT91_DBGU_EXID (AT91_SF + 4) /* EXID in PS segment */ + +/* + * Support defines for the simple Power Controller module. + */ +#define AT91_PS_CR (AT91_PS + 0) /* PS Control register */ +#define AT91_PS_CR_CPU (1 << 0) /* CPU clock disable bit */ + +#endif /* AT91X40_H */ diff --git a/arch/arm/mach-at91/include/mach/at_hdmac.h b/arch/arm/mach-at91/include/mach/at_hdmac.h new file mode 100644 index 00000000..187cb583 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at_hdmac.h @@ -0,0 +1,102 @@ +/* + * Header file for the Atmel AHB DMA Controller driver + * + * Copyright (C) 2008 Atmel Corporation + * + * 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. + */ +#ifndef AT_HDMAC_H +#define AT_HDMAC_H + +#include <linux/dmaengine.h> + +/** + * struct at_dma_platform_data - Controller configuration parameters + * @nr_channels: Number of channels supported by hardware (max 8) + * @cap_mask: dma_capability flags supported by the platform + */ +struct at_dma_platform_data { + unsigned int nr_channels; + dma_cap_mask_t cap_mask; +}; + +/** + * enum at_dma_slave_width - DMA slave register access width. + * @AT_DMA_SLAVE_WIDTH_8BIT: Do 8-bit slave register accesses + * @AT_DMA_SLAVE_WIDTH_16BIT: Do 16-bit slave register accesses + * @AT_DMA_SLAVE_WIDTH_32BIT: Do 32-bit slave register accesses + */ +enum at_dma_slave_width { + AT_DMA_SLAVE_WIDTH_8BIT = 0, + AT_DMA_SLAVE_WIDTH_16BIT, + AT_DMA_SLAVE_WIDTH_32BIT, +}; + +/** + * struct at_dma_slave - Controller-specific information about a slave + * @dma_dev: required DMA master device + * @tx_reg: physical address of data register used for + * memory-to-peripheral transfers + * @rx_reg: physical address of data register used for + * peripheral-to-memory transfers + * @reg_width: peripheral register width + * @cfg: Platform-specific initializer for the CFG register + * @ctrla: Platform-specific initializer for the CTRLA register + */ +struct at_dma_slave { + struct device *dma_dev; + dma_addr_t tx_reg; + dma_addr_t rx_reg; + enum at_dma_slave_width reg_width; + u32 cfg; + u32 ctrla; +}; + + +/* Platform-configurable bits in CFG */ +#define ATC_SRC_PER(h) (0xFU & (h)) /* Channel src rq associated with periph handshaking ifc h */ +#define ATC_DST_PER(h) ((0xFU & (h)) << 4) /* Channel dst rq associated with periph handshaking ifc h */ +#define ATC_SRC_REP (0x1 << 8) /* Source Replay Mod */ +#define ATC_SRC_H2SEL (0x1 << 9) /* Source Handshaking Mod */ +#define ATC_SRC_H2SEL_SW (0x0 << 9) +#define ATC_SRC_H2SEL_HW (0x1 << 9) +#define ATC_DST_REP (0x1 << 12) /* Destination Replay Mod */ +#define ATC_DST_H2SEL (0x1 << 13) /* Destination Handshaking Mod */ +#define ATC_DST_H2SEL_SW (0x0 << 13) +#define ATC_DST_H2SEL_HW (0x1 << 13) +#define ATC_SOD (0x1 << 16) /* Stop On Done */ +#define ATC_LOCK_IF (0x1 << 20) /* Interface Lock */ +#define ATC_LOCK_B (0x1 << 21) /* AHB Bus Lock */ +#define ATC_LOCK_IF_L (0x1 << 22) /* Master Interface Arbiter Lock */ +#define ATC_LOCK_IF_L_CHUNK (0x0 << 22) +#define ATC_LOCK_IF_L_BUFFER (0x1 << 22) +#define ATC_AHB_PROT_MASK (0x7 << 24) /* AHB Protection */ +#define ATC_FIFOCFG_MASK (0x3 << 28) /* FIFO Request Configuration */ +#define ATC_FIFOCFG_LARGESTBURST (0x0 << 28) +#define ATC_FIFOCFG_HALFFIFO (0x1 << 28) +#define ATC_FIFOCFG_ENOUGHSPACE (0x2 << 28) + +/* Platform-configurable bits in CTRLA */ +#define ATC_SCSIZE_MASK (0x7 << 16) /* Source Chunk Transfer Size */ +#define ATC_SCSIZE_1 (0x0 << 16) +#define ATC_SCSIZE_4 (0x1 << 16) +#define ATC_SCSIZE_8 (0x2 << 16) +#define ATC_SCSIZE_16 (0x3 << 16) +#define ATC_SCSIZE_32 (0x4 << 16) +#define ATC_SCSIZE_64 (0x5 << 16) +#define ATC_SCSIZE_128 (0x6 << 16) +#define ATC_SCSIZE_256 (0x7 << 16) +#define ATC_DCSIZE_MASK (0x7 << 20) /* Destination Chunk Transfer Size */ +#define ATC_DCSIZE_1 (0x0 << 20) +#define ATC_DCSIZE_4 (0x1 << 20) +#define ATC_DCSIZE_8 (0x2 << 20) +#define ATC_DCSIZE_16 (0x3 << 20) +#define ATC_DCSIZE_32 (0x4 << 20) +#define ATC_DCSIZE_64 (0x5 << 20) +#define ATC_DCSIZE_128 (0x6 << 20) +#define ATC_DCSIZE_256 (0x7 << 20) + +#endif /* AT_HDMAC_H */ diff --git a/arch/arm/mach-at91/include/mach/atmel-mci.h b/arch/arm/mach-at91/include/mach/atmel-mci.h new file mode 100644 index 00000000..998cb0c0 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/atmel-mci.h @@ -0,0 +1,24 @@ +#ifndef __MACH_ATMEL_MCI_H +#define __MACH_ATMEL_MCI_H + +#include <mach/at_hdmac.h> + +/** + * struct mci_dma_data - DMA data for MCI interface + */ +struct mci_dma_data { + struct at_dma_slave sdata; +}; + +/* accessor macros */ +#define slave_data_ptr(s) (&(s)->sdata) +#define find_slave_dev(s) ((s)->sdata.dma_dev) + +#define setup_dma_addr(s, t, r) do { \ + if (s) { \ + (s)->sdata.tx_reg = (t); \ + (s)->sdata.rx_reg = (r); \ + } \ +} while (0) + +#endif /* __MACH_ATMEL_MCI_H */ diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h new file mode 100644 index 00000000..ed544a0d --- /dev/null +++ b/arch/arm/mach-at91/include/mach/board.h @@ -0,0 +1,210 @@ +/* + * arch/arm/mach-at91/include/mach/board.h + * + * Copyright (C) 2005 HP Labs + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * These are data structures found in platform_device.dev.platform_data, + * and describing board-specific data needed by drivers. For example, + * which pin is used for a given GPIO role. + * + * In 2.6, drivers should strongly avoid board-specific knowledge so + * that supporting new boards normally won't require driver patches. + * Most board-specific knowledge should be in arch/.../board-*.c files. + */ + +#ifndef __ASM_ARCH_BOARD_H +#define __ASM_ARCH_BOARD_H + +#include <linux/mtd/partitions.h> +#include <linux/device.h> +#include <linux/i2c.h> +#include <linux/leds.h> +#include <linux/spi/spi.h> +#include <linux/usb/atmel_usba_udc.h> +#include <linux/atmel-mci.h> +#include <sound/atmel-ac97c.h> +#include <linux/serial.h> + + /* USB Device */ +struct at91_udc_data { + u8 vbus_pin; /* high == host powering us */ + u8 vbus_active_low; /* vbus polarity */ + u8 vbus_polled; /* Use polling, not interrupt */ + u8 pullup_pin; /* active == D+ pulled up */ + u8 pullup_active_low; /* true == pullup_pin is active low */ +}; +extern void __init at91_add_device_udc(struct at91_udc_data *data); + + /* USB High Speed Device */ +extern void __init at91_add_device_usba(struct usba_platform_data *data); + + /* Compact Flash */ +struct at91_cf_data { + u8 irq_pin; /* I/O IRQ */ + u8 det_pin; /* Card detect */ + u8 vcc_pin; /* power switching */ + u8 rst_pin; /* card reset */ + u8 chipselect; /* EBI Chip Select number */ + u8 flags; +#define AT91_CF_TRUE_IDE 0x01 +#define AT91_IDE_SWAP_A0_A2 0x02 +}; +extern void __init at91_add_device_cf(struct at91_cf_data *data); + + /* MMC / SD */ + /* at91_mci platform config */ +struct at91_mmc_data { + u8 det_pin; /* card detect IRQ */ + unsigned slot_b:1; /* uses Slot B */ + unsigned wire4:1; /* (SD) supports DAT0..DAT3 */ + u8 wp_pin; /* (SD) writeprotect detect */ + u8 vcc_pin; /* power switching (high == on) */ +}; +extern void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data); + + /* atmel-mci platform config */ +extern void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data); + + /* Ethernet (EMAC & MACB) */ +struct at91_eth_data { + u32 phy_mask; + u8 phy_irq_pin; /* PHY IRQ */ + u8 is_rmii; /* using RMII interface? */ +}; +extern void __init at91_add_device_eth(struct at91_eth_data *data); + +#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91SAM9G20) || defined(CONFIG_ARCH_AT91CAP9) \ + || defined(CONFIG_ARCH_AT91SAM9G45) +#define eth_platform_data at91_eth_data +#endif + + /* USB Host */ +struct at91_usbh_data { + u8 ports; /* number of ports on root hub */ + u8 vbus_pin[2]; /* port power-control pin */ +}; +extern void __init at91_add_device_usbh(struct at91_usbh_data *data); +extern void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data); +extern void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data); + + /* NAND / SmartMedia */ +struct atmel_nand_data { + u8 enable_pin; /* chip enable */ + u8 det_pin; /* card detect */ + u8 rdy_pin; /* ready/busy */ + u8 rdy_pin_active_low; /* rdy_pin value is inverted */ + u8 ale; /* address line number connected to ALE */ + u8 cle; /* address line number connected to CLE */ + u8 bus_width_16; /* buswidth is 16 bit */ + struct mtd_partition* (*partition_info)(int, int*); +}; +extern void __init at91_add_device_nand(struct atmel_nand_data *data); + + /* I2C*/ +#if defined(CONFIG_ARCH_AT91SAM9G45) +extern void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices); +#else +extern void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices); +#endif + + /* SPI */ +extern void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices); + + /* Serial */ +#define ATMEL_UART_CTS 0x01 +#define ATMEL_UART_RTS 0x02 +#define ATMEL_UART_DSR 0x04 +#define ATMEL_UART_DTR 0x08 +#define ATMEL_UART_DCD 0x10 +#define ATMEL_UART_RI 0x20 + +extern void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins); +extern void __init at91_set_serial_console(unsigned portnr); + +extern struct platform_device *atmel_default_console_device; + +struct atmel_uart_data { + int num; /* port num */ + short use_dma_tx; /* use transmit DMA? */ + short use_dma_rx; /* use receive DMA? */ + void __iomem *regs; /* virt. base address, if any */ + struct serial_rs485 rs485; /* rs485 settings */ +}; +extern void __init at91_add_device_serial(void); + +/* + * PWM + */ +#define AT91_PWM0 0 +#define AT91_PWM1 1 +#define AT91_PWM2 2 +#define AT91_PWM3 3 + +extern void __init at91_add_device_pwm(u32 mask); + +/* + * SSC -- accessed through ssc_request(id). Drivers don't bind to SSC + * platform devices. Their SSC ID is part of their configuration data, + * along with information about which SSC signals they should use. + */ +#define ATMEL_SSC_TK 0x01 +#define ATMEL_SSC_TF 0x02 +#define ATMEL_SSC_TD 0x04 +#define ATMEL_SSC_TX (ATMEL_SSC_TK | ATMEL_SSC_TF | ATMEL_SSC_TD) + +#define ATMEL_SSC_RK 0x10 +#define ATMEL_SSC_RF 0x20 +#define ATMEL_SSC_RD 0x40 +#define ATMEL_SSC_RX (ATMEL_SSC_RK | ATMEL_SSC_RF | ATMEL_SSC_RD) + +extern void __init at91_add_device_ssc(unsigned id, unsigned pins); + + /* LCD Controller */ +struct atmel_lcdfb_info; +extern void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data); + + /* AC97 */ +extern void __init at91_add_device_ac97(struct ac97c_platform_data *data); + + /* ISI */ +extern void __init at91_add_device_isi(void); + + /* Touchscreen Controller */ +struct at91_tsadcc_data { + unsigned int adc_clock; + u8 pendet_debounce; + u8 ts_sample_hold_time; +}; +extern void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data); + +/* CAN */ +struct at91_can_data { + void (*transceiver_switch)(int on); +}; +extern void __init at91_add_device_can(struct at91_can_data *data); + + /* LEDs */ +extern void __init at91_init_leds(u8 cpu_led, u8 timer_led); +extern void __init at91_gpio_leds(struct gpio_led *leds, int nr); +extern void __init at91_pwm_leds(struct gpio_led *leds, int nr); + +/* FIXME: this needs a better location, but gets stuff building again */ +extern int at91_suspend_entering_slow_clock(void); + +#endif diff --git a/arch/arm/mach-at91/include/mach/clkdev.h b/arch/arm/mach-at91/include/mach/clkdev.h new file mode 100644 index 00000000..04b37a89 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/clkdev.h @@ -0,0 +1,7 @@ +#ifndef __ASM_MACH_CLKDEV_H +#define __ASM_MACH_CLKDEV_H + +#define __clk_get(clk) ({ 1; }) +#define __clk_put(clk) do { } while (0) + +#endif diff --git a/arch/arm/mach-at91/include/mach/cpu.h b/arch/arm/mach-at91/include/mach/cpu.h new file mode 100644 index 00000000..df966c2b --- /dev/null +++ b/arch/arm/mach-at91/include/mach/cpu.h @@ -0,0 +1,195 @@ +/* + * arch/arm/mach-at91/include/mach/cpu.h + * + * Copyright (C) 2006 SAN People + * + * 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. + * + */ + +#ifndef __ASM_ARCH_CPU_H +#define __ASM_ARCH_CPU_H + +#include <mach/hardware.h> +#include <mach/at91_dbgu.h> + + +#define ARCH_ID_AT91RM9200 0x09290780 +#define ARCH_ID_AT91SAM9260 0x019803a0 +#define ARCH_ID_AT91SAM9261 0x019703a0 +#define ARCH_ID_AT91SAM9263 0x019607a0 +#define ARCH_ID_AT91SAM9G10 0x019903a0 +#define ARCH_ID_AT91SAM9G20 0x019905a0 +#define ARCH_ID_AT91SAM9RL64 0x019b03a0 +#define ARCH_ID_AT91SAM9G45 0x819b05a0 +#define ARCH_ID_AT91SAM9G45MRL 0x819b05a2 /* aka 9G45-ES2 & non ES lots */ +#define ARCH_ID_AT91SAM9G45ES 0x819b05a1 /* 9G45-ES (Engineering Sample) */ +#define ARCH_ID_AT91SAM9X5 0x819a05a0 +#define ARCH_ID_AT91CAP9 0x039A03A0 + +#define ARCH_ID_AT91SAM9XE128 0x329973a0 +#define ARCH_ID_AT91SAM9XE256 0x329a93a0 +#define ARCH_ID_AT91SAM9XE512 0x329aa3a0 + +#define ARCH_ID_AT91M40800 0x14080044 +#define ARCH_ID_AT91R40807 0x44080746 +#define ARCH_ID_AT91M40807 0x14080745 +#define ARCH_ID_AT91R40008 0x44000840 + +static inline unsigned long at91_cpu_identify(void) +{ + return (at91_sys_read(AT91_DBGU_CIDR) & ~AT91_CIDR_VERSION); +} + +static inline unsigned long at91_cpu_fully_identify(void) +{ + return at91_sys_read(AT91_DBGU_CIDR); +} + +#define ARCH_EXID_AT91SAM9M11 0x00000001 +#define ARCH_EXID_AT91SAM9M10 0x00000002 +#define ARCH_EXID_AT91SAM9G46 0x00000003 +#define ARCH_EXID_AT91SAM9G45 0x00000004 + +#define ARCH_EXID_AT91SAM9G15 0x00000000 +#define ARCH_EXID_AT91SAM9G35 0x00000001 +#define ARCH_EXID_AT91SAM9X35 0x00000002 +#define ARCH_EXID_AT91SAM9G25 0x00000003 +#define ARCH_EXID_AT91SAM9X25 0x00000004 + +static inline unsigned long at91_exid_identify(void) +{ + return at91_sys_read(AT91_DBGU_EXID); +} + + +#define ARCH_FAMILY_AT91X92 0x09200000 +#define ARCH_FAMILY_AT91SAM9 0x01900000 +#define ARCH_FAMILY_AT91SAM9XE 0x02900000 + +static inline unsigned long at91_arch_identify(void) +{ + return (at91_sys_read(AT91_DBGU_CIDR) & AT91_CIDR_ARCH); +} + +#ifdef CONFIG_ARCH_AT91CAP9 +#include <mach/at91_pmc.h> + +#define ARCH_REVISION_CAP9_B 0x399 +#define ARCH_REVISION_CAP9_C 0x601 + +static inline unsigned long at91cap9_rev_identify(void) +{ + return (at91_sys_read(AT91_PMC_VER)); +} +#endif + +#ifdef CONFIG_ARCH_AT91RM9200 +extern int rm9200_type; +#define ARCH_REVISON_9200_BGA (0 << 0) +#define ARCH_REVISON_9200_PQFP (1 << 0) +#define cpu_is_at91rm9200() (at91_cpu_identify() == ARCH_ID_AT91RM9200) +#define cpu_is_at91rm9200_bga() (!cpu_is_at91rm9200_pqfp()) +#define cpu_is_at91rm9200_pqfp() (cpu_is_at91rm9200() && rm9200_type & ARCH_REVISON_9200_PQFP) +#else +#define cpu_is_at91rm9200() (0) +#define cpu_is_at91rm9200_bga() (0) +#define cpu_is_at91rm9200_pqfp() (0) +#endif + +#ifdef CONFIG_ARCH_AT91SAM9260 +#define cpu_is_at91sam9xe() (at91_arch_identify() == ARCH_FAMILY_AT91SAM9XE) +#define cpu_is_at91sam9260() ((at91_cpu_identify() == ARCH_ID_AT91SAM9260) || cpu_is_at91sam9xe()) +#else +#define cpu_is_at91sam9xe() (0) +#define cpu_is_at91sam9260() (0) +#endif + +#ifdef CONFIG_ARCH_AT91SAM9G20 +#define cpu_is_at91sam9g20() (at91_cpu_identify() == ARCH_ID_AT91SAM9G20) +#else +#define cpu_is_at91sam9g20() (0) +#endif + +#ifdef CONFIG_ARCH_AT91SAM9261 +#define cpu_is_at91sam9261() (at91_cpu_identify() == ARCH_ID_AT91SAM9261) +#else +#define cpu_is_at91sam9261() (0) +#endif + +#ifdef CONFIG_ARCH_AT91SAM9G10 +#define cpu_is_at91sam9g10() ((at91_cpu_identify() & ~AT91_CIDR_EXT) == ARCH_ID_AT91SAM9G10) +#else +#define cpu_is_at91sam9g10() (0) +#endif + +#ifdef CONFIG_ARCH_AT91SAM9263 +#define cpu_is_at91sam9263() (at91_cpu_identify() == ARCH_ID_AT91SAM9263) +#else +#define cpu_is_at91sam9263() (0) +#endif + +#ifdef CONFIG_ARCH_AT91SAM9RL +#define cpu_is_at91sam9rl() (at91_cpu_identify() == ARCH_ID_AT91SAM9RL64) +#else +#define cpu_is_at91sam9rl() (0) +#endif + +#ifdef CONFIG_ARCH_AT91SAM9G45 +#define cpu_is_at91sam9g45() (at91_cpu_identify() == ARCH_ID_AT91SAM9G45) +#define cpu_is_at91sam9g45es() (at91_cpu_fully_identify() == ARCH_ID_AT91SAM9G45ES) +#define cpu_is_at91sam9m10() (cpu_is_at91sam9g45() && \ + (at91_exid_identify() == ARCH_EXID_AT91SAM9M10)) +#define cpu_is_at91sam9m46() (cpu_is_at91sam9g45() && \ + (at91_exid_identify() == ARCH_EXID_AT91SAM9G46)) +#define cpu_is_at91sam9m11() (cpu_is_at91sam9g45() && \ + (at91_exid_identify() == ARCH_EXID_AT91SAM9M11)) +#else +#define cpu_is_at91sam9g45() (0) +#define cpu_is_at91sam9g45es() (0) +#define cpu_is_at91sam9m10() (0) +#define cpu_is_at91sam9g46() (0) +#define cpu_is_at91sam9m11() (0) +#endif + +#ifdef CONFIG_ARCH_AT91SAM9X5 +#define cpu_is_at91sam9x5() (at91_cpu_identify() == ARCH_ID_AT91SAM9X5) +#define cpu_is_at91sam9g15() (cpu_is_at91sam9x5() && \ + (at91_exid_identify() == ARCH_EXID_AT91SAM9G15)) +#define cpu_is_at91sam9g35() (cpu_is_at91sam9x5() && \ + (at91_exid_identify() == ARCH_EXID_AT91SAM9G35)) +#define cpu_is_at91sam9x35() (cpu_is_at91sam9x5() && \ + (at91_exid_identify() == ARCH_EXID_AT91SAM9X35)) +#define cpu_is_at91sam9g25() (cpu_is_at91sam9x5() && \ + (at91_exid_identify() == ARCH_EXID_AT91SAM9G25)) +#define cpu_is_at91sam9x25() (cpu_is_at91sam9x5() && \ + (at91_exid_identify() == ARCH_EXID_AT91SAM9X25)) +#else +#define cpu_is_at91sam9x5() (0) +#define cpu_is_at91sam9g15() (0) +#define cpu_is_at91sam9g35() (0) +#define cpu_is_at91sam9x35() (0) +#define cpu_is_at91sam9g25() (0) +#define cpu_is_at91sam9x25() (0) +#endif + +#ifdef CONFIG_ARCH_AT91CAP9 +#define cpu_is_at91cap9() (at91_cpu_identify() == ARCH_ID_AT91CAP9) +#define cpu_is_at91cap9_revB() (at91cap9_rev_identify() == ARCH_REVISION_CAP9_B) +#define cpu_is_at91cap9_revC() (at91cap9_rev_identify() == ARCH_REVISION_CAP9_C) +#else +#define cpu_is_at91cap9() (0) +#define cpu_is_at91cap9_revB() (0) +#define cpu_is_at91cap9_revC() (0) +#endif + +/* + * Since this is ARM, we will never run on any AVR32 CPU. But these + * definitions may reduce clutter in common drivers. + */ +#define cpu_is_at32ap7000() (0) + +#endif diff --git a/arch/arm/mach-at91/include/mach/debug-macro.S b/arch/arm/mach-at91/include/mach/debug-macro.S new file mode 100644 index 00000000..0f959faf --- /dev/null +++ b/arch/arm/mach-at91/include/mach/debug-macro.S @@ -0,0 +1,37 @@ +/* + * arch/arm/mach-at91/include/mach/debug-macro.S + * + * Copyright (C) 2003-2005 SAN People + * + * Debugging macro include header + * + * 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 <mach/hardware.h> +#include <mach/at91_dbgu.h> + + .macro addruart, rp, rv + ldr \rp, =(AT91_BASE_SYS + AT91_DBGU) @ System peripherals (phys address) + ldr \rv, =(AT91_VA_BASE_SYS + AT91_DBGU) @ System peripherals (virt address) + .endm + + .macro senduart,rd,rx + strb \rd, [\rx, #(AT91_DBGU_THR - AT91_DBGU)] @ Write to Transmitter Holding Register + .endm + + .macro waituart,rd,rx +1001: ldr \rd, [\rx, #(AT91_DBGU_SR - AT91_DBGU)] @ Read Status Register + tst \rd, #AT91_DBGU_TXRDY @ DBGU_TXRDY = 1 when ready to transmit + beq 1001b + .endm + + .macro busyuart,rd,rx +1001: ldr \rd, [\rx, #(AT91_DBGU_SR - AT91_DBGU)] @ Read Status Register + tst \rd, #AT91_DBGU_TXEMPTY @ DBGU_TXEMPTY = 1 when transmission complete + beq 1001b + .endm + diff --git a/arch/arm/mach-at91/include/mach/entry-macro.S b/arch/arm/mach-at91/include/mach/entry-macro.S new file mode 100644 index 00000000..7ab68f97 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/entry-macro.S @@ -0,0 +1,32 @@ +/* + * arch/arm/mach-at91/include/mach/entry-macro.S + * + * Copyright (C) 2003-2005 SAN People + * + * Low-level IRQ helper macros for AT91RM9200 platforms + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include <mach/hardware.h> +#include <mach/at91_aic.h> + + .macro disable_fiq + .endm + + .macro get_irqnr_preamble, base, tmp + ldr \base, =(AT91_VA_BASE_SYS + AT91_AIC) @ base virtual address of AIC peripheral + .endm + + .macro arch_ret_to_user, tmp1, tmp2 + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + ldr \irqnr, [\base, #(AT91_AIC_IVR - AT91_AIC)] @ read IRQ vector register: de-asserts nIRQ to processor (and clears interrupt) + ldr \irqstat, [\base, #(AT91_AIC_ISR - AT91_AIC)] @ read interrupt source number + teq \irqstat, #0 @ ISR is 0 when no current interrupt, or spurious interrupt + streq \tmp, [\base, #(AT91_AIC_EOICR - AT91_AIC)] @ not going to be handled further, then ACK it now. + .endm + diff --git a/arch/arm/mach-at91/include/mach/gpio.h b/arch/arm/mach-at91/include/mach/gpio.h new file mode 100644 index 00000000..056dc667 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/gpio.h @@ -0,0 +1,228 @@ +/* + * arch/arm/mach-at91/include/mach/gpio.h + * + * Copyright (C) 2005 HP Labs + * + * 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. + * + */ + +#ifndef __ASM_ARCH_AT91RM9200_GPIO_H +#define __ASM_ARCH_AT91RM9200_GPIO_H + +#include <linux/kernel.h> +#include <asm/irq.h> + +#define PIN_BASE NR_AIC_IRQS + +#define MAX_GPIO_BANKS 5 +#define NR_BUILTIN_GPIO (PIN_BASE + (MAX_GPIO_BANKS * 32)) + +/* these pin numbers double as IRQ numbers, like AT91xxx_ID_* values */ + +#define AT91_PIN_PA0 (PIN_BASE + 0x00 + 0) +#define AT91_PIN_PA1 (PIN_BASE + 0x00 + 1) +#define AT91_PIN_PA2 (PIN_BASE + 0x00 + 2) +#define AT91_PIN_PA3 (PIN_BASE + 0x00 + 3) +#define AT91_PIN_PA4 (PIN_BASE + 0x00 + 4) +#define AT91_PIN_PA5 (PIN_BASE + 0x00 + 5) +#define AT91_PIN_PA6 (PIN_BASE + 0x00 + 6) +#define AT91_PIN_PA7 (PIN_BASE + 0x00 + 7) +#define AT91_PIN_PA8 (PIN_BASE + 0x00 + 8) +#define AT91_PIN_PA9 (PIN_BASE + 0x00 + 9) +#define AT91_PIN_PA10 (PIN_BASE + 0x00 + 10) +#define AT91_PIN_PA11 (PIN_BASE + 0x00 + 11) +#define AT91_PIN_PA12 (PIN_BASE + 0x00 + 12) +#define AT91_PIN_PA13 (PIN_BASE + 0x00 + 13) +#define AT91_PIN_PA14 (PIN_BASE + 0x00 + 14) +#define AT91_PIN_PA15 (PIN_BASE + 0x00 + 15) +#define AT91_PIN_PA16 (PIN_BASE + 0x00 + 16) +#define AT91_PIN_PA17 (PIN_BASE + 0x00 + 17) +#define AT91_PIN_PA18 (PIN_BASE + 0x00 + 18) +#define AT91_PIN_PA19 (PIN_BASE + 0x00 + 19) +#define AT91_PIN_PA20 (PIN_BASE + 0x00 + 20) +#define AT91_PIN_PA21 (PIN_BASE + 0x00 + 21) +#define AT91_PIN_PA22 (PIN_BASE + 0x00 + 22) +#define AT91_PIN_PA23 (PIN_BASE + 0x00 + 23) +#define AT91_PIN_PA24 (PIN_BASE + 0x00 + 24) +#define AT91_PIN_PA25 (PIN_BASE + 0x00 + 25) +#define AT91_PIN_PA26 (PIN_BASE + 0x00 + 26) +#define AT91_PIN_PA27 (PIN_BASE + 0x00 + 27) +#define AT91_PIN_PA28 (PIN_BASE + 0x00 + 28) +#define AT91_PIN_PA29 (PIN_BASE + 0x00 + 29) +#define AT91_PIN_PA30 (PIN_BASE + 0x00 + 30) +#define AT91_PIN_PA31 (PIN_BASE + 0x00 + 31) + +#define AT91_PIN_PB0 (PIN_BASE + 0x20 + 0) +#define AT91_PIN_PB1 (PIN_BASE + 0x20 + 1) +#define AT91_PIN_PB2 (PIN_BASE + 0x20 + 2) +#define AT91_PIN_PB3 (PIN_BASE + 0x20 + 3) +#define AT91_PIN_PB4 (PIN_BASE + 0x20 + 4) +#define AT91_PIN_PB5 (PIN_BASE + 0x20 + 5) +#define AT91_PIN_PB6 (PIN_BASE + 0x20 + 6) +#define AT91_PIN_PB7 (PIN_BASE + 0x20 + 7) +#define AT91_PIN_PB8 (PIN_BASE + 0x20 + 8) +#define AT91_PIN_PB9 (PIN_BASE + 0x20 + 9) +#define AT91_PIN_PB10 (PIN_BASE + 0x20 + 10) +#define AT91_PIN_PB11 (PIN_BASE + 0x20 + 11) +#define AT91_PIN_PB12 (PIN_BASE + 0x20 + 12) +#define AT91_PIN_PB13 (PIN_BASE + 0x20 + 13) +#define AT91_PIN_PB14 (PIN_BASE + 0x20 + 14) +#define AT91_PIN_PB15 (PIN_BASE + 0x20 + 15) +#define AT91_PIN_PB16 (PIN_BASE + 0x20 + 16) +#define AT91_PIN_PB17 (PIN_BASE + 0x20 + 17) +#define AT91_PIN_PB18 (PIN_BASE + 0x20 + 18) +#define AT91_PIN_PB19 (PIN_BASE + 0x20 + 19) +#define AT91_PIN_PB20 (PIN_BASE + 0x20 + 20) +#define AT91_PIN_PB21 (PIN_BASE + 0x20 + 21) +#define AT91_PIN_PB22 (PIN_BASE + 0x20 + 22) +#define AT91_PIN_PB23 (PIN_BASE + 0x20 + 23) +#define AT91_PIN_PB24 (PIN_BASE + 0x20 + 24) +#define AT91_PIN_PB25 (PIN_BASE + 0x20 + 25) +#define AT91_PIN_PB26 (PIN_BASE + 0x20 + 26) +#define AT91_PIN_PB27 (PIN_BASE + 0x20 + 27) +#define AT91_PIN_PB28 (PIN_BASE + 0x20 + 28) +#define AT91_PIN_PB29 (PIN_BASE + 0x20 + 29) +#define AT91_PIN_PB30 (PIN_BASE + 0x20 + 30) +#define AT91_PIN_PB31 (PIN_BASE + 0x20 + 31) + +#define AT91_PIN_PC0 (PIN_BASE + 0x40 + 0) +#define AT91_PIN_PC1 (PIN_BASE + 0x40 + 1) +#define AT91_PIN_PC2 (PIN_BASE + 0x40 + 2) +#define AT91_PIN_PC3 (PIN_BASE + 0x40 + 3) +#define AT91_PIN_PC4 (PIN_BASE + 0x40 + 4) +#define AT91_PIN_PC5 (PIN_BASE + 0x40 + 5) +#define AT91_PIN_PC6 (PIN_BASE + 0x40 + 6) +#define AT91_PIN_PC7 (PIN_BASE + 0x40 + 7) +#define AT91_PIN_PC8 (PIN_BASE + 0x40 + 8) +#define AT91_PIN_PC9 (PIN_BASE + 0x40 + 9) +#define AT91_PIN_PC10 (PIN_BASE + 0x40 + 10) +#define AT91_PIN_PC11 (PIN_BASE + 0x40 + 11) +#define AT91_PIN_PC12 (PIN_BASE + 0x40 + 12) +#define AT91_PIN_PC13 (PIN_BASE + 0x40 + 13) +#define AT91_PIN_PC14 (PIN_BASE + 0x40 + 14) +#define AT91_PIN_PC15 (PIN_BASE + 0x40 + 15) +#define AT91_PIN_PC16 (PIN_BASE + 0x40 + 16) +#define AT91_PIN_PC17 (PIN_BASE + 0x40 + 17) +#define AT91_PIN_PC18 (PIN_BASE + 0x40 + 18) +#define AT91_PIN_PC19 (PIN_BASE + 0x40 + 19) +#define AT91_PIN_PC20 (PIN_BASE + 0x40 + 20) +#define AT91_PIN_PC21 (PIN_BASE + 0x40 + 21) +#define AT91_PIN_PC22 (PIN_BASE + 0x40 + 22) +#define AT91_PIN_PC23 (PIN_BASE + 0x40 + 23) +#define AT91_PIN_PC24 (PIN_BASE + 0x40 + 24) +#define AT91_PIN_PC25 (PIN_BASE + 0x40 + 25) +#define AT91_PIN_PC26 (PIN_BASE + 0x40 + 26) +#define AT91_PIN_PC27 (PIN_BASE + 0x40 + 27) +#define AT91_PIN_PC28 (PIN_BASE + 0x40 + 28) +#define AT91_PIN_PC29 (PIN_BASE + 0x40 + 29) +#define AT91_PIN_PC30 (PIN_BASE + 0x40 + 30) +#define AT91_PIN_PC31 (PIN_BASE + 0x40 + 31) + +#define AT91_PIN_PD0 (PIN_BASE + 0x60 + 0) +#define AT91_PIN_PD1 (PIN_BASE + 0x60 + 1) +#define AT91_PIN_PD2 (PIN_BASE + 0x60 + 2) +#define AT91_PIN_PD3 (PIN_BASE + 0x60 + 3) +#define AT91_PIN_PD4 (PIN_BASE + 0x60 + 4) +#define AT91_PIN_PD5 (PIN_BASE + 0x60 + 5) +#define AT91_PIN_PD6 (PIN_BASE + 0x60 + 6) +#define AT91_PIN_PD7 (PIN_BASE + 0x60 + 7) +#define AT91_PIN_PD8 (PIN_BASE + 0x60 + 8) +#define AT91_PIN_PD9 (PIN_BASE + 0x60 + 9) +#define AT91_PIN_PD10 (PIN_BASE + 0x60 + 10) +#define AT91_PIN_PD11 (PIN_BASE + 0x60 + 11) +#define AT91_PIN_PD12 (PIN_BASE + 0x60 + 12) +#define AT91_PIN_PD13 (PIN_BASE + 0x60 + 13) +#define AT91_PIN_PD14 (PIN_BASE + 0x60 + 14) +#define AT91_PIN_PD15 (PIN_BASE + 0x60 + 15) +#define AT91_PIN_PD16 (PIN_BASE + 0x60 + 16) +#define AT91_PIN_PD17 (PIN_BASE + 0x60 + 17) +#define AT91_PIN_PD18 (PIN_BASE + 0x60 + 18) +#define AT91_PIN_PD19 (PIN_BASE + 0x60 + 19) +#define AT91_PIN_PD20 (PIN_BASE + 0x60 + 20) +#define AT91_PIN_PD21 (PIN_BASE + 0x60 + 21) +#define AT91_PIN_PD22 (PIN_BASE + 0x60 + 22) +#define AT91_PIN_PD23 (PIN_BASE + 0x60 + 23) +#define AT91_PIN_PD24 (PIN_BASE + 0x60 + 24) +#define AT91_PIN_PD25 (PIN_BASE + 0x60 + 25) +#define AT91_PIN_PD26 (PIN_BASE + 0x60 + 26) +#define AT91_PIN_PD27 (PIN_BASE + 0x60 + 27) +#define AT91_PIN_PD28 (PIN_BASE + 0x60 + 28) +#define AT91_PIN_PD29 (PIN_BASE + 0x60 + 29) +#define AT91_PIN_PD30 (PIN_BASE + 0x60 + 30) +#define AT91_PIN_PD31 (PIN_BASE + 0x60 + 31) + +#define AT91_PIN_PE0 (PIN_BASE + 0x80 + 0) +#define AT91_PIN_PE1 (PIN_BASE + 0x80 + 1) +#define AT91_PIN_PE2 (PIN_BASE + 0x80 + 2) +#define AT91_PIN_PE3 (PIN_BASE + 0x80 + 3) +#define AT91_PIN_PE4 (PIN_BASE + 0x80 + 4) +#define AT91_PIN_PE5 (PIN_BASE + 0x80 + 5) +#define AT91_PIN_PE6 (PIN_BASE + 0x80 + 6) +#define AT91_PIN_PE7 (PIN_BASE + 0x80 + 7) +#define AT91_PIN_PE8 (PIN_BASE + 0x80 + 8) +#define AT91_PIN_PE9 (PIN_BASE + 0x80 + 9) +#define AT91_PIN_PE10 (PIN_BASE + 0x80 + 10) +#define AT91_PIN_PE11 (PIN_BASE + 0x80 + 11) +#define AT91_PIN_PE12 (PIN_BASE + 0x80 + 12) +#define AT91_PIN_PE13 (PIN_BASE + 0x80 + 13) +#define AT91_PIN_PE14 (PIN_BASE + 0x80 + 14) +#define AT91_PIN_PE15 (PIN_BASE + 0x80 + 15) +#define AT91_PIN_PE16 (PIN_BASE + 0x80 + 16) +#define AT91_PIN_PE17 (PIN_BASE + 0x80 + 17) +#define AT91_PIN_PE18 (PIN_BASE + 0x80 + 18) +#define AT91_PIN_PE19 (PIN_BASE + 0x80 + 19) +#define AT91_PIN_PE20 (PIN_BASE + 0x80 + 20) +#define AT91_PIN_PE21 (PIN_BASE + 0x80 + 21) +#define AT91_PIN_PE22 (PIN_BASE + 0x80 + 22) +#define AT91_PIN_PE23 (PIN_BASE + 0x80 + 23) +#define AT91_PIN_PE24 (PIN_BASE + 0x80 + 24) +#define AT91_PIN_PE25 (PIN_BASE + 0x80 + 25) +#define AT91_PIN_PE26 (PIN_BASE + 0x80 + 26) +#define AT91_PIN_PE27 (PIN_BASE + 0x80 + 27) +#define AT91_PIN_PE28 (PIN_BASE + 0x80 + 28) +#define AT91_PIN_PE29 (PIN_BASE + 0x80 + 29) +#define AT91_PIN_PE30 (PIN_BASE + 0x80 + 30) +#define AT91_PIN_PE31 (PIN_BASE + 0x80 + 31) + +#ifndef __ASSEMBLY__ +/* setup setup routines, called from board init or driver probe() */ +extern int __init_or_module at91_set_GPIO_periph(unsigned pin, int use_pullup); +extern int __init_or_module at91_set_A_periph(unsigned pin, int use_pullup); +extern int __init_or_module at91_set_B_periph(unsigned pin, int use_pullup); +extern int __init_or_module at91_set_gpio_input(unsigned pin, int use_pullup); +extern int __init_or_module at91_set_gpio_output(unsigned pin, int value); +extern int __init_or_module at91_set_deglitch(unsigned pin, int is_on); +extern int __init_or_module at91_set_multi_drive(unsigned pin, int is_on); + +/* callable at any time */ +extern int at91_set_gpio_value(unsigned pin, int value); +extern int at91_get_gpio_value(unsigned pin); + +/* callable only from core power-management code */ +extern void at91_gpio_suspend(void); +extern void at91_gpio_resume(void); + +/*-------------------------------------------------------------------------*/ + +/* wrappers for "new style" GPIO calls. the old AT91-specific ones should + * eventually be removed (along with this errno.h inclusion), and the + * gpio request/free calls should probably be implemented. + */ + +#include <asm/errno.h> +#include <asm-generic/gpio.h> /* cansleep wrappers */ + +#define gpio_get_value __gpio_get_value +#define gpio_set_value __gpio_set_value +#define gpio_cansleep __gpio_cansleep + +#define gpio_to_irq(gpio) (gpio) +#define irq_to_gpio(irq) (irq) + +#endif /* __ASSEMBLY__ */ + +#endif diff --git a/arch/arm/mach-at91/include/mach/gsia18s.h b/arch/arm/mach-at91/include/mach/gsia18s.h new file mode 100644 index 00000000..307c1949 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/gsia18s.h @@ -0,0 +1,33 @@ +/* Buttons */ +#define GPIO_TRIG_NET_IN AT91_PIN_PB21 +#define GPIO_CARD_UNMOUNT_0 AT91_PIN_PB13 +#define GPIO_CARD_UNMOUNT_1 AT91_PIN_PB12 +#define GPIO_KEY_POWER AT91_PIN_PA25 + +/* PCF8574 0x20 GPIO - U1 on the GS_IA18-CB_V3 board */ +#define GS_IA18_S_PCF_GPIO_BASE0 NR_BUILTIN_GPIO +#define PCF_GPIO_HDC_POWER (GS_IA18_S_PCF_GPIO_BASE0 + 0) +#define PCF_GPIO_WIFI_SETUP (GS_IA18_S_PCF_GPIO_BASE0 + 1) +#define PCF_GPIO_WIFI_ENABLE (GS_IA18_S_PCF_GPIO_BASE0 + 2) +#define PCF_GPIO_WIFI_RESET (GS_IA18_S_PCF_GPIO_BASE0 + 3) +#define PCF_GPIO_ETH_DETECT 4 /* this is a GPI */ +#define PCF_GPIO_GPS_SETUP (GS_IA18_S_PCF_GPIO_BASE0 + 5) +#define PCF_GPIO_GPS_STANDBY (GS_IA18_S_PCF_GPIO_BASE0 + 6) +#define PCF_GPIO_GPS_POWER (GS_IA18_S_PCF_GPIO_BASE0 + 7) + +/* PCF8574 0x22 GPIO - U1 on the GS_2G_OPT1-A_V0 board (Alarm) */ +#define GS_IA18_S_PCF_GPIO_BASE1 (GS_IA18_S_PCF_GPIO_BASE0 + 8) +#define PCF_GPIO_ALARM1 (GS_IA18_S_PCF_GPIO_BASE1 + 0) +#define PCF_GPIO_ALARM2 (GS_IA18_S_PCF_GPIO_BASE1 + 1) +#define PCF_GPIO_ALARM3 (GS_IA18_S_PCF_GPIO_BASE1 + 2) +#define PCF_GPIO_ALARM4 (GS_IA18_S_PCF_GPIO_BASE1 + 3) +/* bits 4, 5, 6 not used */ +#define PCF_GPIO_ALARM_V_RELAY_ON (GS_IA18_S_PCF_GPIO_BASE1 + 7) + +/* PCF8574 0x24 GPIO U1 on the GS_2G-OPT23-A_V0 board (Modem) */ +#define GS_IA18_S_PCF_GPIO_BASE2 (GS_IA18_S_PCF_GPIO_BASE1 + 8) +#define PCF_GPIO_MODEM_POWER (GS_IA18_S_PCF_GPIO_BASE2 + 0) +#define PCF_GPIO_MODEM_RESET (GS_IA18_S_PCF_GPIO_BASE2 + 3) +/* bits 1, 2, 4, 5 not used */ +#define PCF_GPIO_TRX_RESET (GS_IA18_S_PCF_GPIO_BASE2 + 6) +/* bit 7 not used */ diff --git a/arch/arm/mach-at91/include/mach/hardware.h b/arch/arm/mach-at91/include/mach/hardware.h new file mode 100644 index 00000000..1008b9fb --- /dev/null +++ b/arch/arm/mach-at91/include/mach/hardware.h @@ -0,0 +1,93 @@ +/* + * arch/arm/mach-at91/include/mach/hardware.h + * + * Copyright (C) 2003 SAN People + * Copyright (C) 2003 ATMEL + * + * 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. + * + */ + +#ifndef __ASM_ARCH_HARDWARE_H +#define __ASM_ARCH_HARDWARE_H + +#include <asm/sizes.h> + +#if defined(CONFIG_ARCH_AT91RM9200) +#include <mach/at91rm9200.h> +#elif defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20) +#include <mach/at91sam9260.h> +#elif defined(CONFIG_ARCH_AT91SAM9261) || defined(CONFIG_ARCH_AT91SAM9G10) +#include <mach/at91sam9261.h> +#elif defined(CONFIG_ARCH_AT91SAM9263) +#include <mach/at91sam9263.h> +#elif defined(CONFIG_ARCH_AT91SAM9RL) +#include <mach/at91sam9rl.h> +#elif defined(CONFIG_ARCH_AT91SAM9G45) +#include <mach/at91sam9g45.h> +#elif defined(CONFIG_ARCH_AT91CAP9) +#include <mach/at91cap9.h> +#elif defined(CONFIG_ARCH_AT91X40) +#include <mach/at91x40.h> +#else +#error "Unsupported AT91 processor" +#endif + + +/* + * Peripheral identifiers/interrupts. + */ +#define AT91_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ +#define AT91_ID_SYS 1 /* System Peripherals */ + +#ifdef CONFIG_MMU +/* + * Remap the peripherals from address 0xFFF78000 .. 0xFFFFFFFF + * to 0xFEF78000 .. 0xFF000000. (544Kb) + */ +#define AT91_IO_PHYS_BASE 0xFFF78000 +#define AT91_IO_VIRT_BASE (0xFF000000 - AT91_IO_SIZE) +#else +/* + * Identity mapping for the non MMU case. + */ +#define AT91_IO_PHYS_BASE AT91_BASE_SYS +#define AT91_IO_VIRT_BASE AT91_IO_PHYS_BASE +#endif + +#define AT91_IO_SIZE (0xFFFFFFFF - AT91_IO_PHYS_BASE + 1) + + /* Convert a physical IO address to virtual IO address */ +#define AT91_IO_P2V(x) ((x) - AT91_IO_PHYS_BASE + AT91_IO_VIRT_BASE) + +/* + * Virtual to Physical Address mapping for IO devices. + */ +#define AT91_VA_BASE_SYS AT91_IO_P2V(AT91_BASE_SYS) +#define AT91_VA_BASE_EMAC AT91_IO_P2V(AT91RM9200_BASE_EMAC) + + /* Internal SRAM is mapped below the IO devices */ +#define AT91_SRAM_MAX SZ_1M +#define AT91_VIRT_BASE (AT91_IO_VIRT_BASE - AT91_SRAM_MAX) + +/* Serial ports */ +#define ATMEL_MAX_UART 7 /* 6 USART3's and one DBGU port (SAM9260) */ + +/* External Memory Map */ +#define AT91_CHIPSELECT_0 0x10000000 +#define AT91_CHIPSELECT_1 0x20000000 +#define AT91_CHIPSELECT_2 0x30000000 +#define AT91_CHIPSELECT_3 0x40000000 +#define AT91_CHIPSELECT_4 0x50000000 +#define AT91_CHIPSELECT_5 0x60000000 +#define AT91_CHIPSELECT_6 0x70000000 +#define AT91_CHIPSELECT_7 0x80000000 + +/* Clocks */ +#define AT91_SLOW_CLOCK 32768 /* slow clock */ + + +#endif diff --git a/arch/arm/mach-at91/include/mach/io.h b/arch/arm/mach-at91/include/mach/io.h new file mode 100644 index 00000000..0b0cccc4 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/io.h @@ -0,0 +1,48 @@ +/* + * arch/arm/mach-at91/include/mach/io.h + * + * Copyright (C) 2003 SAN People + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ASM_ARCH_IO_H +#define __ASM_ARCH_IO_H + +#define IO_SPACE_LIMIT 0xFFFFFFFF + +#define __io(a) __typesafe_io(a) +#define __mem_pci(a) (a) + + +#ifndef __ASSEMBLY__ + +static inline unsigned int at91_sys_read(unsigned int reg_offset) +{ + void __iomem *addr = (void __iomem *)AT91_VA_BASE_SYS; + + return __raw_readl(addr + reg_offset); +} + +static inline void at91_sys_write(unsigned int reg_offset, unsigned long value) +{ + void __iomem *addr = (void __iomem *)AT91_VA_BASE_SYS; + + __raw_writel(value, addr + reg_offset); +} + +#endif + +#endif diff --git a/arch/arm/mach-at91/include/mach/irqs.h b/arch/arm/mach-at91/include/mach/irqs.h new file mode 100644 index 00000000..36bd55f3 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/irqs.h @@ -0,0 +1,48 @@ +/* + * arch/arm/mach-at91/include/mach/irqs.h + * + * Copyright (C) 2004 SAN People + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ASM_ARCH_IRQS_H +#define __ASM_ARCH_IRQS_H + +#include <linux/io.h> +#include <mach/at91_aic.h> + +#define NR_AIC_IRQS 32 + + +/* + * Acknowledge interrupt with AIC after interrupt has been handled. + * (by kernel/irq.c) + */ +#define irq_finish(irq) do { at91_sys_write(AT91_AIC_EOICR, 0); } while (0) + + +/* + * IRQ interrupt symbols are the AT91xxx_ID_* symbols + * for IRQs handled directly through the AIC, or else the AT91_PIN_* + * symbols in gpio.h for ones handled indirectly as GPIOs. + * We make provision for 5 banks of GPIO. + */ +#define NR_IRQS (NR_AIC_IRQS + (5 * 32)) + +/* FIQ is AIC source 0. */ +#define FIQ_START AT91_ID_FIQ + +#endif diff --git a/arch/arm/mach-at91/include/mach/memory.h b/arch/arm/mach-at91/include/mach/memory.h new file mode 100644 index 00000000..401c207f --- /dev/null +++ b/arch/arm/mach-at91/include/mach/memory.h @@ -0,0 +1,26 @@ +/* + * arch/arm/mach-at91/include/mach/memory.h + * + * Copyright (C) 2004 SAN People + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ASM_ARCH_MEMORY_H +#define __ASM_ARCH_MEMORY_H + +#include <mach/hardware.h> + +#endif diff --git a/arch/arm/mach-at91/include/mach/stamp9g20.h b/arch/arm/mach-at91/include/mach/stamp9g20.h new file mode 100644 index 00000000..f62c0abc --- /dev/null +++ b/arch/arm/mach-at91/include/mach/stamp9g20.h @@ -0,0 +1,7 @@ +#ifndef __MACH_STAMP9G20_H +#define __MACH_STAMP9G20_H + +void stamp9g20_init_early(void); +void stamp9g20_board_init(void); + +#endif diff --git a/arch/arm/mach-at91/include/mach/system.h b/arch/arm/mach-at91/include/mach/system.h new file mode 100644 index 00000000..36af14bc --- /dev/null +++ b/arch/arm/mach-at91/include/mach/system.h @@ -0,0 +1,59 @@ +/* + * arch/arm/mach-at91/include/mach/system.h + * + * Copyright (C) 2003 SAN People + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ASM_ARCH_SYSTEM_H +#define __ASM_ARCH_SYSTEM_H + +#include <mach/hardware.h> +#include <mach/at91_st.h> +#include <mach/at91_dbgu.h> +#include <mach/at91_pmc.h> + +static inline void arch_idle(void) +{ + /* + * Disable the processor clock. The processor will be automatically + * re-enabled by an interrupt or by a reset. + */ +#ifdef AT91_PS + at91_sys_write(AT91_PS_CR, AT91_PS_CR_CPU); +#else + at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK); +#endif +#ifndef CONFIG_CPU_ARM920T + /* + * Set the processor (CP15) into 'Wait for Interrupt' mode. + * Post-RM9200 processors need this in conjunction with the above + * to save power when idle. + */ + cpu_do_idle(); +#endif +} + +void (*at91_arch_reset)(void); + +static inline void arch_reset(char mode, const char *cmd) +{ + /* call the CPU-specific reset function */ + if (at91_arch_reset) + (at91_arch_reset)(); +} + +#endif diff --git a/arch/arm/mach-at91/include/mach/system_rev.h b/arch/arm/mach-at91/include/mach/system_rev.h new file mode 100644 index 00000000..8f486604 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/system_rev.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * + * Under GPLv2 only + */ + +#ifndef __ARCH_SYSTEM_REV_H__ +#define __ARCH_SYSTEM_REV_H__ + +/* + * board revision encoding + * mach specific + * the 16-31 bit are reserved for at91 generic information + * + * bit 31: + * 0 => nand 8 bit + * 1 => nand 16 bit + */ +#define BOARD_HAVE_NAND_16BIT (1 << 31) +static inline int board_have_nand_16bit(void) +{ + return system_rev & BOARD_HAVE_NAND_16BIT; +} + +#endif /* __ARCH_SYSTEM_REV_H__ */ diff --git a/arch/arm/mach-at91/include/mach/timex.h b/arch/arm/mach-at91/include/mach/timex.h new file mode 100644 index 00000000..31ac2d97 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/timex.h @@ -0,0 +1,87 @@ +/* + * arch/arm/mach-at91/include/mach/timex.h + * + * Copyright (C) 2003 SAN People + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ASM_ARCH_TIMEX_H +#define __ASM_ARCH_TIMEX_H + +#include <mach/hardware.h> + +#if defined(CONFIG_ARCH_AT91RM9200) + +#define CLOCK_TICK_RATE (AT91_SLOW_CLOCK) + +#elif defined(CONFIG_ARCH_AT91SAM9260) + +#if defined(CONFIG_MACH_USB_A9260) || defined(CONFIG_MACH_QIL_A9260) +#define AT91SAM9_MASTER_CLOCK 90000000 +#else +#define AT91SAM9_MASTER_CLOCK 99300000 +#endif + +#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) + +#elif defined(CONFIG_ARCH_AT91SAM9261) + +#define AT91SAM9_MASTER_CLOCK 99300000 +#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) + +#elif defined(CONFIG_ARCH_AT91SAM9G10) + +#define AT91SAM9_MASTER_CLOCK 133000000 +#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) + +#elif defined(CONFIG_ARCH_AT91SAM9263) + +#if defined(CONFIG_MACH_USB_A9263) +#define AT91SAM9_MASTER_CLOCK 90000000 +#else +#define AT91SAM9_MASTER_CLOCK 99959500 +#endif + +#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) + +#elif defined(CONFIG_ARCH_AT91SAM9RL) + +#define AT91SAM9_MASTER_CLOCK 100000000 +#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) + +#elif defined(CONFIG_ARCH_AT91SAM9G20) + +#define AT91SAM9_MASTER_CLOCK 132096000 +#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) + +#elif defined(CONFIG_ARCH_AT91SAM9G45) + +#define AT91SAM9_MASTER_CLOCK 133333333 +#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) + +#elif defined(CONFIG_ARCH_AT91CAP9) + +#define AT91CAP9_MASTER_CLOCK 100000000 +#define CLOCK_TICK_RATE (AT91CAP9_MASTER_CLOCK/16) + +#elif defined(CONFIG_ARCH_AT91X40) + +#define AT91X40_MASTER_CLOCK 40000000 +#define CLOCK_TICK_RATE (AT91X40_MASTER_CLOCK) + +#endif + +#endif diff --git a/arch/arm/mach-at91/include/mach/uncompress.h b/arch/arm/mach-at91/include/mach/uncompress.h new file mode 100644 index 00000000..18bdcdeb --- /dev/null +++ b/arch/arm/mach-at91/include/mach/uncompress.h @@ -0,0 +1,76 @@ +/* + * arch/arm/mach-at91/include/mach/uncompress.h + * + * Copyright (C) 2003 SAN People + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ASM_ARCH_UNCOMPRESS_H +#define __ASM_ARCH_UNCOMPRESS_H + +#include <linux/io.h> +#include <linux/atmel_serial.h> + +#if defined(CONFIG_AT91_EARLY_DBGU) +#define UART_OFFSET (AT91_DBGU + AT91_BASE_SYS) +#elif defined(CONFIG_AT91_EARLY_USART0) +#define UART_OFFSET AT91_USART0 +#elif defined(CONFIG_AT91_EARLY_USART1) +#define UART_OFFSET AT91_USART1 +#elif defined(CONFIG_AT91_EARLY_USART2) +#define UART_OFFSET AT91_USART2 +#elif defined(CONFIG_AT91_EARLY_USART3) +#define UART_OFFSET AT91_USART3 +#elif defined(CONFIG_AT91_EARLY_USART4) +#define UART_OFFSET AT91_USART4 +#elif defined(CONFIG_AT91_EARLY_USART5) +#define UART_OFFSET AT91_USART5 +#endif + +/* + * The following code assumes the serial port has already been + * initialized by the bootloader. If you didn't setup a port in + * your bootloader then nothing will appear (which might be desired). + * + * This does not append a newline + */ +static void putc(int c) +{ +#ifdef UART_OFFSET + void __iomem *sys = (void __iomem *) UART_OFFSET; /* physical address */ + + while (!(__raw_readl(sys + ATMEL_US_CSR) & ATMEL_US_TXRDY)) + barrier(); + __raw_writel(c, sys + ATMEL_US_THR); +#endif +} + +static inline void flush(void) +{ +#ifdef UART_OFFSET + void __iomem *sys = (void __iomem *) UART_OFFSET; /* physical address */ + + /* wait for transmission to complete */ + while (!(__raw_readl(sys + ATMEL_US_CSR) & ATMEL_US_TXEMPTY)) + barrier(); +#endif +} + +#define arch_decomp_setup() + +#define arch_decomp_wdog() + +#endif diff --git a/arch/arm/mach-at91/include/mach/vmalloc.h b/arch/arm/mach-at91/include/mach/vmalloc.h new file mode 100644 index 00000000..8eb459f3 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/vmalloc.h @@ -0,0 +1,26 @@ +/* + * arch/arm/mach-at91/include/mach/vmalloc.h + * + * Copyright (C) 2003 SAN People + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ASM_ARCH_VMALLOC_H +#define __ASM_ARCH_VMALLOC_H + +#define VMALLOC_END (AT91_VIRT_BASE & PGDIR_MASK) + +#endif diff --git a/arch/arm/mach-at91/irq.c b/arch/arm/mach-at91/irq.c new file mode 100644 index 00000000..9665265e --- /dev/null +++ b/arch/arm/mach-at91/irq.c @@ -0,0 +1,166 @@ +/* + * linux/arch/arm/mach-at91/irq.c + * + * Copyright (C) 2004 SAN People + * Copyright (C) 2004 ATMEL + * Copyright (C) Rick Bronson + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/mm.h> +#include <linux/types.h> + +#include <mach/hardware.h> +#include <asm/irq.h> +#include <asm/setup.h> + +#include <asm/mach/arch.h> +#include <asm/mach/irq.h> +#include <asm/mach/map.h> + + +static void at91_aic_mask_irq(struct irq_data *d) +{ + /* Disable interrupt on AIC */ + at91_sys_write(AT91_AIC_IDCR, 1 << d->irq); +} + +static void at91_aic_unmask_irq(struct irq_data *d) +{ + /* Enable interrupt on AIC */ + at91_sys_write(AT91_AIC_IECR, 1 << d->irq); +} + +unsigned int at91_extern_irq; + +#define is_extern_irq(irq) ((1 << (irq)) & at91_extern_irq) + +static int at91_aic_set_type(struct irq_data *d, unsigned type) +{ + unsigned int smr, srctype; + + switch (type) { + case IRQ_TYPE_LEVEL_HIGH: + srctype = AT91_AIC_SRCTYPE_HIGH; + break; + case IRQ_TYPE_EDGE_RISING: + srctype = AT91_AIC_SRCTYPE_RISING; + break; + case IRQ_TYPE_LEVEL_LOW: + if ((d->irq == AT91_ID_FIQ) || is_extern_irq(d->irq)) /* only supported on external interrupts */ + srctype = AT91_AIC_SRCTYPE_LOW; + else + return -EINVAL; + break; + case IRQ_TYPE_EDGE_FALLING: + if ((d->irq == AT91_ID_FIQ) || is_extern_irq(d->irq)) /* only supported on external interrupts */ + srctype = AT91_AIC_SRCTYPE_FALLING; + else + return -EINVAL; + break; + default: + return -EINVAL; + } + + smr = at91_sys_read(AT91_AIC_SMR(d->irq)) & ~AT91_AIC_SRCTYPE; + at91_sys_write(AT91_AIC_SMR(d->irq), smr | srctype); + return 0; +} + +#ifdef CONFIG_PM + +static u32 wakeups; +static u32 backups; + +static int at91_aic_set_wake(struct irq_data *d, unsigned value) +{ + if (unlikely(d->irq >= 32)) + return -EINVAL; + + if (value) + wakeups |= (1 << d->irq); + else + wakeups &= ~(1 << d->irq); + + return 0; +} + +void at91_irq_suspend(void) +{ + backups = at91_sys_read(AT91_AIC_IMR); + at91_sys_write(AT91_AIC_IDCR, backups); + at91_sys_write(AT91_AIC_IECR, wakeups); +} + +void at91_irq_resume(void) +{ + at91_sys_write(AT91_AIC_IDCR, wakeups); + at91_sys_write(AT91_AIC_IECR, backups); +} + +#else +#define at91_aic_set_wake NULL +#endif + +static struct irq_chip at91_aic_chip = { + .name = "AIC", + .irq_ack = at91_aic_mask_irq, + .irq_mask = at91_aic_mask_irq, + .irq_unmask = at91_aic_unmask_irq, + .irq_set_type = at91_aic_set_type, + .irq_set_wake = at91_aic_set_wake, +}; + +/* + * Initialize the AIC interrupt controller. + */ +void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS]) +{ + unsigned int i; + + /* + * The IVR is used by macro get_irqnr_and_base to read and verify. + * The irq number is NR_AIC_IRQS when a spurious interrupt has occurred. + */ + for (i = 0; i < NR_AIC_IRQS; i++) { + /* Put irq number in Source Vector Register: */ + at91_sys_write(AT91_AIC_SVR(i), i); + /* Active Low interrupt, with the specified priority */ + at91_sys_write(AT91_AIC_SMR(i), AT91_AIC_SRCTYPE_LOW | priority[i]); + + irq_set_chip_and_handler(i, &at91_aic_chip, handle_level_irq); + set_irq_flags(i, IRQF_VALID | IRQF_PROBE); + + /* Perform 8 End Of Interrupt Command to make sure AIC will not Lock out nIRQ */ + if (i < 8) + at91_sys_write(AT91_AIC_EOICR, 0); + } + + /* + * Spurious Interrupt ID in Spurious Vector Register is NR_AIC_IRQS + * When there is no current interrupt, the IRQ Vector Register reads the value stored in AIC_SPU + */ + at91_sys_write(AT91_AIC_SPU, NR_AIC_IRQS); + + /* No debugging in AIC: Debug (Protect) Control Register */ + at91_sys_write(AT91_AIC_DCR, 0); + + /* Disable and clear all interrupts initially */ + at91_sys_write(AT91_AIC_IDCR, 0xFFFFFFFF); + at91_sys_write(AT91_AIC_ICCR, 0xFFFFFFFF); +} diff --git a/arch/arm/mach-at91/leds.c b/arch/arm/mach-at91/leds.c new file mode 100644 index 00000000..0415a839 --- /dev/null +++ b/arch/arm/mach-at91/leds.c @@ -0,0 +1,197 @@ +/* + * LED driver for Atmel AT91-based boards. + * + * Copyright (C) SAN People (Pty) Ltd + * + * 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. +*/ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/platform_device.h> + +#include <mach/board.h> +#include <mach/gpio.h> + + +/* ------------------------------------------------------------------------- */ + +#if defined(CONFIG_NEW_LEDS) + +/* + * New cross-platform LED support. + */ + +static struct gpio_led_platform_data led_data; + +static struct platform_device at91_gpio_leds_device = { + .name = "leds-gpio", + .id = -1, + .dev.platform_data = &led_data, +}; + +void __init at91_gpio_leds(struct gpio_led *leds, int nr) +{ + int i; + + if (!nr) + return; + + for (i = 0; i < nr; i++) + at91_set_gpio_output(leds[i].gpio, leds[i].active_low); + + led_data.leds = leds; + led_data.num_leds = nr; + platform_device_register(&at91_gpio_leds_device); +} + +#else +void __init at91_gpio_leds(struct gpio_led *leds, int nr) {} +#endif + + +/* ------------------------------------------------------------------------- */ + +#if defined (CONFIG_LEDS_ATMEL_PWM) + +/* + * PWM Leds + */ + +static struct gpio_led_platform_data pwm_led_data; + +static struct platform_device at91_pwm_leds_device = { + .name = "leds-atmel-pwm", + .id = -1, + .dev.platform_data = &pwm_led_data, +}; + +void __init at91_pwm_leds(struct gpio_led *leds, int nr) +{ + int i; + u32 pwm_mask = 0; + + if (!nr) + return; + + for (i = 0; i < nr; i++) + pwm_mask |= (1 << leds[i].gpio); + + pwm_led_data.leds = leds; + pwm_led_data.num_leds = nr; + + at91_add_device_pwm(pwm_mask); + platform_device_register(&at91_pwm_leds_device); +} +#else +void __init at91_pwm_leds(struct gpio_led *leds, int nr){} +#endif + + +/* ------------------------------------------------------------------------- */ + +#if defined(CONFIG_LEDS) + +#include <asm/leds.h> + +/* + * Old ARM-specific LED framework; not fully functional when generic time is + * in use. + */ + +static u8 at91_leds_cpu; +static u8 at91_leds_timer; + +static inline void at91_led_on(unsigned int led) +{ + at91_set_gpio_value(led, 0); +} + +static inline void at91_led_off(unsigned int led) +{ + at91_set_gpio_value(led, 1); +} + +static inline void at91_led_toggle(unsigned int led) +{ + unsigned long is_off = at91_get_gpio_value(led); + if (is_off) + at91_led_on(led); + else + at91_led_off(led); +} + + +/* + * Handle LED events. + */ +static void at91_leds_event(led_event_t evt) +{ + unsigned long flags; + + local_irq_save(flags); + + switch(evt) { + case led_start: /* System startup */ + at91_led_on(at91_leds_cpu); + break; + + case led_stop: /* System stop / suspend */ + at91_led_off(at91_leds_cpu); + break; + +#ifdef CONFIG_LEDS_TIMER + case led_timer: /* Every 50 timer ticks */ + at91_led_toggle(at91_leds_timer); + break; +#endif + +#ifdef CONFIG_LEDS_CPU + case led_idle_start: /* Entering idle state */ + at91_led_off(at91_leds_cpu); + break; + + case led_idle_end: /* Exit idle state */ + at91_led_on(at91_leds_cpu); + break; +#endif + + default: + break; + } + + local_irq_restore(flags); +} + + +static int __init leds_init(void) +{ + if (!at91_leds_timer || !at91_leds_cpu) + return -ENODEV; + + leds_event = at91_leds_event; + + leds_event(led_start); + return 0; +} + +__initcall(leds_init); + + +void __init at91_init_leds(u8 cpu_led, u8 timer_led) +{ + /* Enable GPIO to access the LEDs */ + at91_set_gpio_output(cpu_led, 1); + at91_set_gpio_output(timer_led, 1); + + at91_leds_cpu = cpu_led; + at91_leds_timer = timer_led; +} + +#else +void __init at91_init_leds(u8 cpu_led, u8 timer_led) {} +#endif diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c new file mode 100644 index 00000000..ea53f4d9 --- /dev/null +++ b/arch/arm/mach-at91/pm.c @@ -0,0 +1,329 @@ +/* + * arch/arm/mach-at91/pm.c + * AT91 Power Management + * + * Copyright (C) 2005 David Brownell + * + * 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. + */ + +#include <linux/suspend.h> +#include <linux/sched.h> +#include <linux/proc_fs.h> +#include <linux/interrupt.h> +#include <linux/sysfs.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/io.h> + +#include <asm/irq.h> +#include <asm/atomic.h> +#include <asm/mach/time.h> +#include <asm/mach/irq.h> + +#include <mach/at91_pmc.h> +#include <mach/gpio.h> +#include <mach/cpu.h> + +#include "generic.h" +#include "pm.h" + +/* + * Show the reason for the previous system reset. + */ +#if defined(AT91_SHDWC) + +#include <mach/at91_rstc.h> +#include <mach/at91_shdwc.h> + +static void __init show_reset_status(void) +{ + static char reset[] __initdata = "reset"; + + static char general[] __initdata = "general"; + static char wakeup[] __initdata = "wakeup"; + static char watchdog[] __initdata = "watchdog"; + static char software[] __initdata = "software"; + static char user[] __initdata = "user"; + static char unknown[] __initdata = "unknown"; + + static char signal[] __initdata = "signal"; + static char rtc[] __initdata = "rtc"; + static char rtt[] __initdata = "rtt"; + static char restore[] __initdata = "power-restored"; + + char *reason, *r2 = reset; + u32 reset_type, wake_type; + + reset_type = at91_sys_read(AT91_RSTC_SR) & AT91_RSTC_RSTTYP; + wake_type = at91_sys_read(AT91_SHDW_SR); + + switch (reset_type) { + case AT91_RSTC_RSTTYP_GENERAL: + reason = general; + break; + case AT91_RSTC_RSTTYP_WAKEUP: + /* board-specific code enabled the wakeup sources */ + reason = wakeup; + + /* "wakeup signal" */ + if (wake_type & AT91_SHDW_WAKEUP0) + r2 = signal; + else { + r2 = reason; + if (wake_type & AT91_SHDW_RTTWK) /* rtt wakeup */ + reason = rtt; + else if (wake_type & AT91_SHDW_RTCWK) /* rtc wakeup */ + reason = rtc; + else if (wake_type == 0) /* power-restored wakeup */ + reason = restore; + else /* unknown wakeup */ + reason = unknown; + } + break; + case AT91_RSTC_RSTTYP_WATCHDOG: + reason = watchdog; + break; + case AT91_RSTC_RSTTYP_SOFTWARE: + reason = software; + break; + case AT91_RSTC_RSTTYP_USER: + reason = user; + break; + default: + reason = unknown; + break; + } + pr_info("AT91: Starting after %s %s\n", reason, r2); +} +#else +static void __init show_reset_status(void) {} +#endif + + +static int at91_pm_valid_state(suspend_state_t state) +{ + switch (state) { + case PM_SUSPEND_ON: + case PM_SUSPEND_STANDBY: + case PM_SUSPEND_MEM: + return 1; + + default: + return 0; + } +} + + +static suspend_state_t target_state; + +/* + * Called after processes are frozen, but before we shutdown devices. + */ +static int at91_pm_begin(suspend_state_t state) +{ + target_state = state; + return 0; +} + +/* + * Verify that all the clocks are correct before entering + * slow-clock mode. + */ +static int at91_pm_verify_clocks(void) +{ + unsigned long scsr; + int i; + + scsr = at91_sys_read(AT91_PMC_SCSR); + + /* USB must not be using PLLB */ + if (cpu_is_at91rm9200()) { + if ((scsr & (AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP)) != 0) { + pr_err("AT91: PM - Suspend-to-RAM with USB still active\n"); + return 0; + } + } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263() + || cpu_is_at91sam9g20() || cpu_is_at91sam9g10()) { + if ((scsr & (AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP)) != 0) { + pr_err("AT91: PM - Suspend-to-RAM with USB still active\n"); + return 0; + } + } else if (cpu_is_at91cap9()) { + if ((scsr & AT91CAP9_PMC_UHP) != 0) { + pr_err("AT91: PM - Suspend-to-RAM with USB still active\n"); + return 0; + } + } + +#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS + /* PCK0..PCK3 must be disabled, or configured to use clk32k */ + for (i = 0; i < 4; i++) { + u32 css; + + if ((scsr & (AT91_PMC_PCK0 << i)) == 0) + continue; + + css = at91_sys_read(AT91_PMC_PCKR(i)) & AT91_PMC_CSS; + if (css != AT91_PMC_CSS_SLOW) { + pr_err("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css); + return 0; + } + } +#endif + + return 1; +} + +/* + * Call this from platform driver suspend() to see how deeply to suspend. + * For example, some controllers (like OHCI) need one of the PLL clocks + * in order to act as a wakeup source, and those are not available when + * going into slow clock mode. + * + * REVISIT: generalize as clk_will_be_available(clk)? Other platforms have + * the very same problem (but not using at91 main_clk), and it'd be better + * to add one generic API rather than lots of platform-specific ones. + */ +int at91_suspend_entering_slow_clock(void) +{ + return (target_state == PM_SUSPEND_MEM); +} +EXPORT_SYMBOL(at91_suspend_entering_slow_clock); + + +static void (*slow_clock)(void); + +#ifdef CONFIG_AT91_SLOW_CLOCK +extern void at91_slow_clock(void); +extern u32 at91_slow_clock_sz; +#endif + + +static int at91_pm_enter(suspend_state_t state) +{ + u32 saved_lpr; + at91_gpio_suspend(); + at91_irq_suspend(); + + pr_debug("AT91: PM - wake mask %08x, pm state %d\n", + /* remember all the always-wake irqs */ + (at91_sys_read(AT91_PMC_PCSR) + | (1 << AT91_ID_FIQ) + | (1 << AT91_ID_SYS) + | (at91_extern_irq)) + & at91_sys_read(AT91_AIC_IMR), + state); + + switch (state) { + /* + * Suspend-to-RAM is like STANDBY plus slow clock mode, so + * drivers must suspend more deeply: only the master clock + * controller may be using the main oscillator. + */ + case PM_SUSPEND_MEM: + /* + * Ensure that clocks are in a valid state. + */ + if (!at91_pm_verify_clocks()) + goto error; + + /* + * Enter slow clock mode by switching over to clk32k and + * turning off the main oscillator; reverse on wakeup. + */ + if (slow_clock) { +#ifdef CONFIG_AT91_SLOW_CLOCK + /* copy slow_clock handler to SRAM, and call it */ + memcpy(slow_clock, at91_slow_clock, at91_slow_clock_sz); +#endif + slow_clock(); + break; + } else { + pr_info("AT91: PM - no slow clock mode enabled ...\n"); + /* FALLTHROUGH leaving master clock alone */ + } + + /* + * STANDBY mode has *all* drivers suspended; ignores irqs not + * marked as 'wakeup' event sources; and reduces DRAM power. + * But otherwise it's identical to PM_SUSPEND_ON: cpu idle, and + * nothing fancy done with main or cpu clocks. + */ + case PM_SUSPEND_STANDBY: + /* + * NOTE: the Wait-for-Interrupt instruction needs to be + * in icache so no SDRAM accesses are needed until the + * wakeup IRQ occurs and self-refresh is terminated. + * For ARM 926 based chips, this requirement is weaker + * as at91sam9 can access a RAM in self-refresh mode. + */ + asm volatile ( "mov r0, #0\n\t" + "b 1f\n\t" + ".align 5\n\t" + "1: mcr p15, 0, r0, c7, c10, 4\n\t" + : /* no output */ + : /* no input */ + : "r0"); + saved_lpr = sdram_selfrefresh_enable(); + wait_for_interrupt_enable(); + sdram_selfrefresh_disable(saved_lpr); + break; + + case PM_SUSPEND_ON: + cpu_do_idle(); + break; + + default: + pr_debug("AT91: PM - bogus suspend state %d\n", state); + goto error; + } + + pr_debug("AT91: PM - wakeup %08x\n", + at91_sys_read(AT91_AIC_IPR) & at91_sys_read(AT91_AIC_IMR)); + +error: + target_state = PM_SUSPEND_ON; + at91_irq_resume(); + at91_gpio_resume(); + return 0; +} + +/* + * Called right prior to thawing processes. + */ +static void at91_pm_end(void) +{ + target_state = PM_SUSPEND_ON; +} + + +static const struct platform_suspend_ops at91_pm_ops = { + .valid = at91_pm_valid_state, + .begin = at91_pm_begin, + .enter = at91_pm_enter, + .end = at91_pm_end, +}; + +static int __init at91_pm_init(void) +{ +#ifdef CONFIG_AT91_SLOW_CLOCK + slow_clock = (void *) (AT91_IO_VIRT_BASE - at91_slow_clock_sz); +#endif + + pr_info("AT91: Power Management%s\n", (slow_clock ? " (with slow clock mode)" : "")); + +#ifdef CONFIG_ARCH_AT91RM9200 + /* AT91RM9200 SDRAM low-power mode cannot be used with self-refresh. */ + at91_sys_write(AT91_SDRAMC_LPR, 0); +#endif + + suspend_set_ops(&at91_pm_ops); + + show_reset_status(); + return 0; +} +arch_initcall(at91_pm_init); diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h new file mode 100644 index 00000000..ce9a2069 --- /dev/null +++ b/arch/arm/mach-at91/pm.h @@ -0,0 +1,107 @@ +#ifdef CONFIG_ARCH_AT91RM9200 +#include <mach/at91rm9200_mc.h> + +/* + * The AT91RM9200 goes into self-refresh mode with this command, and will + * terminate self-refresh automatically on the next SDRAM access. + * + * Self-refresh mode is exited as soon as a memory access is made, but we don't + * know for sure when that happens. However, we need to restore the low-power + * mode if it was enabled before going idle. Restoring low-power mode while + * still in self-refresh is "not recommended", but seems to work. + */ + +static inline u32 sdram_selfrefresh_enable(void) +{ + u32 saved_lpr = at91_sys_read(AT91_SDRAMC_LPR); + + at91_sys_write(AT91_SDRAMC_LPR, 0); + at91_sys_write(AT91_SDRAMC_SRR, 1); + return saved_lpr; +} + +#define sdram_selfrefresh_disable(saved_lpr) at91_sys_write(AT91_SDRAMC_LPR, saved_lpr) +#define wait_for_interrupt_enable() asm volatile ("mcr p15, 0, %0, c7, c0, 4" \ + : : "r" (0)) + +#elif defined(CONFIG_ARCH_AT91CAP9) +#include <mach/at91cap9_ddrsdr.h> + + +static inline u32 sdram_selfrefresh_enable(void) +{ + u32 saved_lpr, lpr; + + saved_lpr = at91_ramc_read(0, AT91_DDRSDRC_LPR); + + lpr = saved_lpr & ~AT91_DDRSDRC_LPCB; + at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr | AT91_DDRSDRC_LPCB_SELF_REFRESH); + return saved_lpr; +} + +#define sdram_selfrefresh_disable(saved_lpr) at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr) +#define wait_for_interrupt_enable() cpu_do_idle() + +#elif defined(CONFIG_ARCH_AT91SAM9G45) +#include <mach/at91sam9_ddrsdr.h> + +/* We manage both DDRAM/SDRAM controllers, we need more than one value to + * remember. + */ +static u32 saved_lpr1; + +static inline u32 sdram_selfrefresh_enable(void) +{ + /* Those tow values allow us to delay self-refresh activation + * to the maximum. */ + u32 lpr0, lpr1; + u32 saved_lpr0; + + saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR); + lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB; + lpr1 |= AT91_DDRSDRC_LPCB_SELF_REFRESH; + + saved_lpr0 = at91_ramc_read(0, AT91_DDRSDRC_LPR); + lpr0 = saved_lpr0 & ~AT91_DDRSDRC_LPCB; + lpr0 |= AT91_DDRSDRC_LPCB_SELF_REFRESH; + + /* self-refresh mode now */ + at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0); + at91_ramc_write(1, AT91_DDRSDRC_LPR, lpr1); + + return saved_lpr0; +} + +#define sdram_selfrefresh_disable(saved_lpr0) \ + do { \ + at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0); \ + at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1); \ + } while (0) +#define wait_for_interrupt_enable() cpu_do_idle() + +#else +#include <mach/at91sam9_sdramc.h> + +#ifdef CONFIG_ARCH_AT91SAM9263 +/* + * FIXME either or both the SDRAM controllers (EB0, EB1) might be in use; + * handle those cases both here and in the Suspend-To-RAM support. + */ +#warning Assuming EB1 SDRAM controller is *NOT* used +#endif + +static inline u32 sdram_selfrefresh_enable(void) +{ + u32 saved_lpr, lpr; + + saved_lpr = at91_ramc_read(0, AT91_SDRAMC_LPR); + + lpr = saved_lpr & ~AT91_SDRAMC_LPCB; + at91_ramc_write(0, AT91_SDRAMC_LPR, lpr | AT91_SDRAMC_LPCB_SELF_REFRESH); + return saved_lpr; +} + +#define sdram_selfrefresh_disable(saved_lpr) at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr) +#define wait_for_interrupt_enable() cpu_do_idle() + +#endif diff --git a/arch/arm/mach-at91/pm_slowclock.S b/arch/arm/mach-at91/pm_slowclock.S new file mode 100644 index 00000000..f7922a43 --- /dev/null +++ b/arch/arm/mach-at91/pm_slowclock.S @@ -0,0 +1,326 @@ +/* + * arch/arm/mach-at91/pm_slow_clock.S + * + * Copyright (C) 2006 Savin Zlobec + * + * AT91SAM9 support: + * Copyright (C) 2007 Anti Sullin <anti.sullin@artecdesign.ee + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include <linux/linkage.h> +#include <mach/hardware.h> +#include <mach/at91_pmc.h> + +#if defined(CONFIG_ARCH_AT91RM9200) +#include <mach/at91rm9200_mc.h> +#elif defined(CONFIG_ARCH_AT91CAP9) +#include <mach/at91cap9_ddrsdr.h> +#elif defined(CONFIG_ARCH_AT91SAM9G45) +#include <mach/at91sam9_ddrsdr.h> +#else +#include <mach/at91sam9_sdramc.h> +#endif + + +#ifdef CONFIG_ARCH_AT91SAM9263 +/* + * FIXME either or both the SDRAM controllers (EB0, EB1) might be in use; + * handle those cases both here and in the Suspend-To-RAM support. + */ +#warning Assuming EB1 SDRAM controller is *NOT* used +#endif + +/* + * When SLOWDOWN_MASTER_CLOCK is defined we will also slow down the Master + * clock during suspend by adjusting its prescalar and divisor. + * NOTE: This hasn't been shown to be stable on SAM9s; and on the RM9200 there + * are errata regarding adjusting the prescalar and divisor. + */ +#undef SLOWDOWN_MASTER_CLOCK + +#define MCKRDY_TIMEOUT 1000 +#define MOSCRDY_TIMEOUT 1000 +#define PLLALOCK_TIMEOUT 1000 +#define PLLBLOCK_TIMEOUT 1000 + + +/* + * Wait until master clock is ready (after switching master clock source) + */ + .macro wait_mckrdy + mov r4, #MCKRDY_TIMEOUT +1: sub r4, r4, #1 + cmp r4, #0 + beq 2f + ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)] + tst r3, #AT91_PMC_MCKRDY + beq 1b +2: + .endm + +/* + * Wait until master oscillator has stabilized. + */ + .macro wait_moscrdy + mov r4, #MOSCRDY_TIMEOUT +1: sub r4, r4, #1 + cmp r4, #0 + beq 2f + ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)] + tst r3, #AT91_PMC_MOSCS + beq 1b +2: + .endm + +/* + * Wait until PLLA has locked. + */ + .macro wait_pllalock + mov r4, #PLLALOCK_TIMEOUT +1: sub r4, r4, #1 + cmp r4, #0 + beq 2f + ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)] + tst r3, #AT91_PMC_LOCKA + beq 1b +2: + .endm + +/* + * Wait until PLLB has locked. + */ + .macro wait_pllblock + mov r4, #PLLBLOCK_TIMEOUT +1: sub r4, r4, #1 + cmp r4, #0 + beq 2f + ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)] + tst r3, #AT91_PMC_LOCKB + beq 1b +2: + .endm + + .text + +ENTRY(at91_slow_clock) + /* Save registers on stack */ + stmfd sp!, {r0 - r12, lr} + + /* + * Register usage: + * R1 = Base address of AT91_PMC + * R2 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS) + * R3 = temporary register + * R4 = temporary register + * R5 = Base address of second RAM Controller or 0 if not present + */ + ldr r1, .at91_va_base_pmc + ldr r2, .at91_va_base_sdramc + ldr r5, .at91_va_base_ramc1 + + /* Drain write buffer */ + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 + +#ifdef CONFIG_ARCH_AT91RM9200 + /* Put SDRAM in self-refresh mode */ + mov r3, #1 + str r3, [r2, #AT91_SDRAMC_SRR] +#elif defined(CONFIG_ARCH_AT91CAP9) \ + || defined(CONFIG_ARCH_AT91SAM9G45) + + /* prepare for DDRAM self-refresh mode */ + ldr r3, [r2, #AT91_DDRSDRC_LPR] + str r3, .saved_sam9_lpr + bic r3, #AT91_DDRSDRC_LPCB + orr r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH + + /* figure out if we use the second ram controller */ + cmp r5, #0 + ldrne r4, [r5, #AT91_DDRSDRC_LPR] + strne r4, .saved_sam9_lpr1 + bicne r4, #AT91_DDRSDRC_LPCB + orrne r4, #AT91_DDRSDRC_LPCB_SELF_REFRESH + + /* Enable DDRAM self-refresh mode */ + str r3, [r2, #AT91_DDRSDRC_LPR] + strne r4, [r5, #AT91_DDRSDRC_LPR] +#else + /* Enable SDRAM self-refresh mode */ + ldr r3, [r2, #AT91_SDRAMC_LPR] + str r3, .saved_sam9_lpr + + bic r3, #AT91_SDRAMC_LPCB + orr r3, #AT91_SDRAMC_LPCB_SELF_REFRESH + str r3, [r2, #AT91_SDRAMC_LPR] +#endif + + /* Save Master clock setting */ + ldr r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)] + str r3, .saved_mckr + + /* + * Set the Master clock source to slow clock + */ + bic r3, r3, #AT91_PMC_CSS + str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)] + + wait_mckrdy + +#ifdef SLOWDOWN_MASTER_CLOCK + /* + * Set the Master Clock PRES and MDIV fields. + * + * See AT91RM9200 errata #27 and #28 for details. + */ + mov r3, #0 + str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)] + + wait_mckrdy +#endif + + /* Save PLLA setting and disable it */ + ldr r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)] + str r3, .saved_pllar + + mov r3, #AT91_PMC_PLLCOUNT + orr r3, r3, #(1 << 29) /* bit 29 always set */ + str r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)] + + /* Save PLLB setting and disable it */ + ldr r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)] + str r3, .saved_pllbr + + mov r3, #AT91_PMC_PLLCOUNT + str r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)] + + /* Turn off the main oscillator */ + ldr r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)] + bic r3, r3, #AT91_PMC_MOSCEN + str r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)] + + /* Wait for interrupt */ + mcr p15, 0, r0, c7, c0, 4 + + /* Turn on the main oscillator */ + ldr r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)] + orr r3, r3, #AT91_PMC_MOSCEN + str r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)] + + wait_moscrdy + + /* Restore PLLB setting */ + ldr r3, .saved_pllbr + str r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)] + + tst r3, #(AT91_PMC_MUL & 0xff0000) + bne 1f + tst r3, #(AT91_PMC_MUL & ~0xff0000) + beq 2f +1: + wait_pllblock +2: + + /* Restore PLLA setting */ + ldr r3, .saved_pllar + str r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)] + + tst r3, #(AT91_PMC_MUL & 0xff0000) + bne 3f + tst r3, #(AT91_PMC_MUL & ~0xff0000) + beq 4f +3: + wait_pllalock +4: + +#ifdef SLOWDOWN_MASTER_CLOCK + /* + * First set PRES if it was not 0, + * than set CSS and MDIV fields. + * + * See AT91RM9200 errata #27 and #28 for details. + */ + ldr r3, .saved_mckr + tst r3, #AT91_PMC_PRES + beq 2f + and r3, r3, #AT91_PMC_PRES + str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)] + + wait_mckrdy +#endif + + /* + * Restore master clock setting + */ +2: ldr r3, .saved_mckr + str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)] + + wait_mckrdy + +#ifdef CONFIG_ARCH_AT91RM9200 + /* Do nothing - self-refresh is automatically disabled. */ +#elif defined(CONFIG_ARCH_AT91CAP9) \ + || defined(CONFIG_ARCH_AT91SAM9G45) + /* Restore LPR on AT91 with DDRAM */ + ldr r3, .saved_sam9_lpr + str r3, [r2, #AT91_DDRSDRC_LPR] + + /* if we use the second ram controller */ + cmp r5, #0 + ldrne r4, .saved_sam9_lpr1 + strne r4, [r5, #AT91_DDRSDRC_LPR] + +#else + /* Restore LPR on AT91 with SDRAM */ + ldr r3, .saved_sam9_lpr + str r3, [r2, #AT91_SDRAMC_LPR] +#endif + + /* Restore registers, and return */ + ldmfd sp!, {r0 - r12, pc} + + +.saved_mckr: + .word 0 + +.saved_pllar: + .word 0 + +.saved_pllbr: + .word 0 + +.saved_sam9_lpr: + .word 0 + +.saved_sam9_lpr1: + .word 0 + +.at91_va_base_pmc: + .word AT91_VA_BASE_SYS + AT91_PMC + +#ifdef CONFIG_ARCH_AT91RM9200 +.at91_va_base_sdramc: + .word AT91_VA_BASE_SYS +#elif defined(CONFIG_ARCH_AT91CAP9) \ + || defined(CONFIG_ARCH_AT91SAM9G45) +.at91_va_base_sdramc: + .word AT91_VA_BASE_SYS + AT91_DDRSDRC0 +#else +.at91_va_base_sdramc: + .word AT91_VA_BASE_SYS + AT91_SDRAMC0 +#endif + +.at91_va_base_ramc1: +#if defined(CONFIG_ARCH_AT91SAM9G45) + .word AT91_VA_BASE_SYS + AT91_DDRSDRC1 +#else + .word 0 +#endif + +ENTRY(at91_slow_clock_sz) + .word .-at91_slow_clock diff --git a/arch/arm/mach-at91/sam9_smc.c b/arch/arm/mach-at91/sam9_smc.c new file mode 100644 index 00000000..5eab6aa6 --- /dev/null +++ b/arch/arm/mach-at91/sam9_smc.c @@ -0,0 +1,47 @@ +/* + * linux/arch/arm/mach-at91/sam9_smc.c + * + * Copyright (C) 2008 Andrew Victor + * + * 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/module.h> +#include <linux/io.h> + +#include <mach/at91sam9_smc.h> + +#include "sam9_smc.h" + +void __init sam9_smc_configure(int cs, struct sam9_smc_config* config) +{ + /* Setup register */ + at91_sys_write(AT91_SMC_SETUP(cs), + AT91_SMC_NWESETUP_(config->nwe_setup) + | AT91_SMC_NCS_WRSETUP_(config->ncs_write_setup) + | AT91_SMC_NRDSETUP_(config->nrd_setup) + | AT91_SMC_NCS_RDSETUP_(config->ncs_read_setup) + ); + + /* Pulse register */ + at91_sys_write(AT91_SMC_PULSE(cs), + AT91_SMC_NWEPULSE_(config->nwe_pulse) + | AT91_SMC_NCS_WRPULSE_(config->ncs_write_pulse) + | AT91_SMC_NRDPULSE_(config->nrd_pulse) + | AT91_SMC_NCS_RDPULSE_(config->ncs_read_pulse) + ); + + /* Cycle register */ + at91_sys_write(AT91_SMC_CYCLE(cs), + AT91_SMC_NWECYCLE_(config->write_cycle) + | AT91_SMC_NRDCYCLE_(config->read_cycle) + ); + + /* Mode register */ + at91_sys_write(AT91_SMC_MODE(cs), + config->mode + | AT91_SMC_TDF_(config->tdf_cycles) + ); +} diff --git a/arch/arm/mach-at91/sam9_smc.h b/arch/arm/mach-at91/sam9_smc.h new file mode 100644 index 00000000..bf72cfb3 --- /dev/null +++ b/arch/arm/mach-at91/sam9_smc.h @@ -0,0 +1,33 @@ +/* + * linux/arch/arm/mach-at91/sam9_smc. + * + * Copyright (C) 2008 Andrew Victor + * + * 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. + */ + +struct sam9_smc_config { + /* Setup register */ + u8 ncs_read_setup; + u8 nrd_setup; + u8 ncs_write_setup; + u8 nwe_setup; + + /* Pulse register */ + u8 ncs_read_pulse; + u8 nrd_pulse; + u8 ncs_write_pulse; + u8 nwe_pulse; + + /* Cycle register */ + u16 read_cycle; + u16 write_cycle; + + /* Mode register */ + u32 mode; + u8 tdf_cycles:4; +}; + +extern void __init sam9_smc_configure(int cs, struct sam9_smc_config* config); |