From d8f2aa3298610b44127dbc4796d8038aa5847e0b Mon Sep 17 00:00:00 2001 From: Olav Morken Date: Fri, 23 Jan 2009 12:56:27 +0100 Subject: [PATCH 1/4] AVR32: Make cacheflush cpu-dependent The AT32UC3A series of processors doesn't contain any cache, and issuing cache control instructions on those will cause an exception. This commit makes cacheflush.h arch-dependent in preparation for the AT32UC3A-support. Signed-off-by: Gunnar Rangoy Signed-off-by: Paul Driveklepp Signed-off-by: Olav Morken Signed-off-by: Haavard Skinnemoen --- board/atmel/atstk1000/flash.c | 2 +- board/earthlcd/favr-32-ezkit/flash.c | 2 +- cpu/at32ap/cache.c | 2 +- include/asm-avr32/dma-mapping.h | 2 +- lib_avr32/board.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/board/atmel/atstk1000/flash.c b/board/atmel/atstk1000/flash.c index 4d380f3fa..0ba06ddc5 100644 --- a/board/atmel/atstk1000/flash.c +++ b/board/atmel/atstk1000/flash.c @@ -22,7 +22,7 @@ #include #ifdef CONFIG_ATSTK1000_EXT_FLASH -#include +#include #include #include diff --git a/board/earthlcd/favr-32-ezkit/flash.c b/board/earthlcd/favr-32-ezkit/flash.c index 5f73ff04d..0a2614667 100644 --- a/board/earthlcd/favr-32-ezkit/flash.c +++ b/board/earthlcd/favr-32-ezkit/flash.c @@ -20,7 +20,7 @@ #include #ifdef CONFIG_FAVR32_EZKIT_EXT_FLASH -#include +#include #include #include diff --git a/cpu/at32ap/cache.c b/cpu/at32ap/cache.c index 16a0565df..28b945669 100644 --- a/cpu/at32ap/cache.c +++ b/cpu/at32ap/cache.c @@ -22,7 +22,7 @@ #include -#include +#include void dcache_clean_range(volatile void *start, size_t size) { diff --git a/include/asm-avr32/dma-mapping.h b/include/asm-avr32/dma-mapping.h index 3b46fa3e6..0be7804da 100644 --- a/include/asm-avr32/dma-mapping.h +++ b/include/asm-avr32/dma-mapping.h @@ -23,7 +23,7 @@ #define __ASM_AVR32_DMA_MAPPING_H #include -#include +#include enum dma_data_direction { DMA_BIDIRECTIONAL = 0, diff --git a/lib_avr32/board.c b/lib_avr32/board.c index 959375a48..57115df09 100644 --- a/lib_avr32/board.c +++ b/lib_avr32/board.c @@ -86,7 +86,7 @@ void *sbrk(ptrdiff_t increment) } #ifdef CONFIG_SYS_DMA_ALLOC_LEN -#include +#include #include static unsigned long dma_alloc_start; From a38de083d2979db3680f0d0978c509a172c8fa00 Mon Sep 17 00:00:00 2001 From: Olav Morken Date: Fri, 23 Jan 2009 12:56:28 +0100 Subject: [PATCH 2/4] AVR32: Move addrspace.h to arch-directory, and move some functions from io.h to addrspace.h The AVR32A architecture (which AT32UC3A-series is based on) has a different memory layout than the AVR32B-architecture. This patch moves addrspace.h to an arch-dependent directory in preparation for AT32UC3A-support. It also moves some address-space manipulation functions from io.h to addrspace.h. Signed-off-by: Gunnar Rangoy Signed-off-by: Paul Driveklepp Signed-off-by: Olav Morken Signed-off-by: Haavard Skinnemoen --- .../{ => arch-at32ap700x}/addrspace.h | 38 ++++++++++++++++++ include/asm-avr32/io.h | 39 +------------------ lib_avr32/bootm.c | 2 +- 3 files changed, 41 insertions(+), 38 deletions(-) rename include/asm-avr32/{ => arch-at32ap700x}/addrspace.h (63%) diff --git a/include/asm-avr32/addrspace.h b/include/asm-avr32/arch-at32ap700x/addrspace.h similarity index 63% rename from include/asm-avr32/addrspace.h rename to include/asm-avr32/arch-at32ap700x/addrspace.h index b2ba1ee2f..409eee353 100644 --- a/include/asm-avr32/addrspace.h +++ b/include/asm-avr32/arch-at32ap700x/addrspace.h @@ -22,6 +22,8 @@ #ifndef __ASM_AVR32_ADDRSPACE_H #define __ASM_AVR32_ADDRSPACE_H +#include + /* Memory segments when segmentation is enabled */ #define P0SEG 0x00000000 #define P1SEG 0x80000000 @@ -43,4 +45,40 @@ #define P3SEGADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | P3SEG)) #define P4SEGADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | P4SEG)) +/* virt_to_phys will only work when address is in P1 or P2 */ +static inline unsigned long virt_to_phys(volatile void *address) +{ + return PHYSADDR(address); +} + +static inline void * phys_to_virt(unsigned long address) +{ + return (void *)P1SEGADDR(address); +} + +#define cached(addr) ((void *)P1SEGADDR(addr)) +#define uncached(addr) ((void *)P2SEGADDR(addr)) + +/* + * Given a physical address and a length, return a virtual address + * that can be used to access the memory range with the caching + * properties specified by "flags". + * + * This implementation works for memory below 512MiB (flash, etc.) as + * well as above 3.5GiB (internal peripherals.) + */ +#define MAP_NOCACHE (0) +#define MAP_WRCOMBINE (1 << 7) +#define MAP_WRBACK (MAP_WRCOMBINE | (1 << 9)) +#define MAP_WRTHROUGH (MAP_WRBACK | (1 << 0)) + +static inline void * +map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags) +{ + if (flags == MAP_WRBACK) + return (void *)P1SEGADDR(paddr); + else + return (void *)P2SEGADDR(paddr); +} + #endif /* __ASM_AVR32_ADDRSPACE_H */ diff --git a/include/asm-avr32/io.h b/include/asm-avr32/io.h index 50967ac7e..1cb17ead3 100644 --- a/include/asm-avr32/io.h +++ b/include/asm-avr32/io.h @@ -73,21 +73,8 @@ extern void __readwrite_bug(const char *fn); #define inw(p) ({ unsigned int __v = __le16_to_cpu(__raw_readw(p)); __v; }) #define inl(p) ({ unsigned int __v = __le32_to_cpu(__raw_readl(p)); __v; }) -#include - -/* virt_to_phys will only work when address is in P1 or P2 */ -static inline phys_addr_t virt_to_phys(volatile void *address) -{ - return PHYSADDR(address); -} - -static inline void *phys_to_virt(phys_addr_t address) -{ - return (void *)P1SEGADDR(address); -} - -#define cached(addr) ((void *)P1SEGADDR(addr)) -#define uncached(addr) ((void *)P2SEGADDR(addr)) +#include +/* Provides virt_to_phys, phys_to_virt, cached, uncached, map_physmem */ #endif /* __KERNEL__ */ @@ -95,28 +82,6 @@ static inline void sync(void) { } -/* - * Given a physical address and a length, return a virtual address - * that can be used to access the memory range with the caching - * properties specified by "flags". - * - * This implementation works for memory below 512MiB (flash, etc.) as - * well as above 3.5GiB (internal peripherals.) - */ -#define MAP_NOCACHE (0) -#define MAP_WRCOMBINE (1 << 7) -#define MAP_WRBACK (MAP_WRCOMBINE | (1 << 9)) -#define MAP_WRTHROUGH (MAP_WRBACK | (1 << 0)) - -static inline void * -map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags) -{ - if (flags == MAP_WRBACK) - return (void *)P1SEGADDR(paddr); - else - return (void *)P2SEGADDR(paddr); -} - /* * Take down a mapping set up by map_physmem(). */ diff --git a/lib_avr32/bootm.c b/lib_avr32/bootm.c index 03ab8d1fa..0ca4718c8 100644 --- a/lib_avr32/bootm.c +++ b/lib_avr32/bootm.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include From f5f652fa91aa69db8117d211af1b4fe09f2edd3b Mon Sep 17 00:00:00 2001 From: Gunnar Rangoy Date: Fri, 23 Jan 2009 12:56:29 +0100 Subject: [PATCH 3/4] AVR32: Make GPIO implmentation cpu dependent There are some differences in the implementation of GPIO in the at32uc chip compared to the ap700x series. Signed-off-by: Gunnar Rangoy Signed-off-by: Paul Driveklepp Signed-off-by: Olav Morken Signed-off-by: Haavard Skinnemoen --- include/asm-avr32/arch-at32ap700x/gpio-impl.h | 86 +++++++++++++++++++ include/asm-avr32/arch-common/portmux-gpio.h | 83 +----------------- 2 files changed, 88 insertions(+), 81 deletions(-) create mode 100644 include/asm-avr32/arch-at32ap700x/gpio-impl.h diff --git a/include/asm-avr32/arch-at32ap700x/gpio-impl.h b/include/asm-avr32/arch-at32ap700x/gpio-impl.h new file mode 100644 index 000000000..8801bd006 --- /dev/null +++ b/include/asm-avr32/arch-at32ap700x/gpio-impl.h @@ -0,0 +1,86 @@ +#ifndef __ASM_AVR32_ARCH_GPIO_IMPL_H__ +#define __ASM_AVR32_ARCH_GPIO_IMPL_H__ + +/* Register offsets */ +struct gpio_regs { + u32 GPER; + u32 GPERS; + u32 GPERC; + u32 GPERT; + u32 PMR0; + u32 PMR0S; + u32 PMR0C; + u32 PMR0T; + u32 PMR1; + u32 PMR1S; + u32 PMR1C; + u32 PMR1T; + u32 __reserved0[4]; + u32 ODER; + u32 ODERS; + u32 ODERC; + u32 ODERT; + u32 OVR; + u32 OVRS; + u32 OVRC; + u32 OVRT; + u32 PVR; + u32 __reserved_PVRS; + u32 __reserved_PVRC; + u32 __reserved_PVRT; + u32 PUER; + u32 PUERS; + u32 PUERC; + u32 PUERT; + u32 PDER; + u32 PDERS; + u32 PDERC; + u32 PDERT; + u32 IER; + u32 IERS; + u32 IERC; + u32 IERT; + u32 IMR0; + u32 IMR0S; + u32 IMR0C; + u32 IMR0T; + u32 IMR1; + u32 IMR1S; + u32 IMR1C; + u32 IMR1T; + u32 GFER; + u32 GFERS; + u32 GFERC; + u32 GFERT; + u32 IFR; + u32 __reserved_IFRS; + u32 IFRC; + u32 __reserved_IFRT; + u32 ODMER; + u32 ODMERS; + u32 ODMERC; + u32 ODMERT; + u32 __reserved1[4]; + u32 ODCR0; + u32 ODCR0S; + u32 ODCR0C; + u32 ODCR0T; + u32 ODCR1; + u32 ODCR1S; + u32 ODCR1C; + u32 ODCR1T; + u32 __reserved2[4]; + u32 OSRR0; + u32 OSRR0S; + u32 OSRR0C; + u32 OSRR0T; + u32 __reserved3[8]; + u32 STER; + u32 STERS; + u32 STERC; + u32 STERT; + u32 __reserved4[35]; + u32 VERSION; +}; + +#endif /* __ASM_AVR32_ARCH_GPIO_IMPL_H__ */ diff --git a/include/asm-avr32/arch-common/portmux-gpio.h b/include/asm-avr32/arch-common/portmux-gpio.h index 24943ecdb..1306cbe5d 100644 --- a/include/asm-avr32/arch-common/portmux-gpio.h +++ b/include/asm-avr32/arch-common/portmux-gpio.h @@ -24,87 +24,8 @@ #include -/* Register offsets */ -struct gpio_regs { - u32 GPER; - u32 GPERS; - u32 GPERC; - u32 GPERT; - u32 PMR0; - u32 PMR0S; - u32 PMR0C; - u32 PMR0T; - u32 PMR1; - u32 PMR1S; - u32 PMR1C; - u32 PMR1T; - u32 __reserved0[4]; - u32 ODER; - u32 ODERS; - u32 ODERC; - u32 ODERT; - u32 OVR; - u32 OVRS; - u32 OVRC; - u32 OVRT; - u32 PVR; - u32 __reserved_PVRS; - u32 __reserved_PVRC; - u32 __reserved_PVRT; - u32 PUER; - u32 PUERS; - u32 PUERC; - u32 PUERT; - u32 PDER; - u32 PDERS; - u32 PDERC; - u32 PDERT; - u32 IER; - u32 IERS; - u32 IERC; - u32 IERT; - u32 IMR0; - u32 IMR0S; - u32 IMR0C; - u32 IMR0T; - u32 IMR1; - u32 IMR1S; - u32 IMR1C; - u32 IMR1T; - u32 GFER; - u32 GFERS; - u32 GFERC; - u32 GFERT; - u32 IFR; - u32 __reserved_IFRS; - u32 IFRC; - u32 __reserved_IFRT; - u32 ODMER; - u32 ODMERS; - u32 ODMERC; - u32 ODMERT; - u32 __reserved1[4]; - u32 ODCR0; - u32 ODCR0S; - u32 ODCR0C; - u32 ODCR0T; - u32 ODCR1; - u32 ODCR1S; - u32 ODCR1C; - u32 ODCR1T; - u32 __reserved2[4]; - u32 OSRR0; - u32 OSRR0S; - u32 OSRR0C; - u32 OSRR0T; - u32 __reserved3[8]; - u32 STER; - u32 STERS; - u32 STERC; - u32 STERT; - u32 __reserved4[35]; - u32 VERSION; -}; +/* Register layout for this specific device */ +#include /* Register access macros */ #define gpio_readl(port, reg) \ From b423f94063bf04e92047ff85c7e53441eb3b712b Mon Sep 17 00:00:00 2001 From: Olav Morken Date: Fri, 23 Jan 2009 12:56:32 +0100 Subject: [PATCH 4/4] AVR32: Must add NOPs after disabling interrupts for AT32UC3A0512ES The AT32UC3A0512ES chip has a bug when disabling interrupts. As a workaround, two NOPs can be inserted. Signed-off-by: Gunnar Rangoy Signed-off-by: Paul Driveklepp Signed-off-by: Olav Morken Signed-off-by: Haavard Skinnemoen --- lib_avr32/interrupts.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib_avr32/interrupts.c b/lib_avr32/interrupts.c index 28df20db0..bbbc490db 100644 --- a/lib_avr32/interrupts.c +++ b/lib_avr32/interrupts.c @@ -35,5 +35,12 @@ int disable_interrupts(void) sr = sysreg_read(SR); asm volatile("ssrf %0" : : "n"(SYSREG_GM_OFFSET)); +#ifdef CONFIG_AT32UC3A0xxx + /* Two NOPs are required after masking interrupts on the + * AT32UC3A0512ES. See errata 41.4.5.5. */ + asm("nop"); + asm("nop"); +#endif + return !SYSREG_BFEXT(GM, sr); }