| 
									
										
										
										
											2006-01-09 17:05:41 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2008-08-05 16:14:15 +01:00
										 |  |  |  * arch/arm/mach-at91/include/mach/uncompress.h | 
					
						
							| 
									
										
										
										
											2006-01-09 17:05:41 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2012-02-15 18:44:40 +08:00
										 |  |  |  * Copyright (C) 2003 SAN People | 
					
						
							|  |  |  |  * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> | 
					
						
							| 
									
										
										
										
											2006-01-09 17:05:41 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * 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
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-06 12:10:45 +01:00
										 |  |  | #include <linux/io.h>
 | 
					
						
							| 
									
										
										
										
											2008-01-29 15:43:13 +01:00
										 |  |  | #include <linux/atmel_serial.h>
 | 
					
						
							| 
									
										
										
										
											2012-02-29 13:07:39 -06:00
										 |  |  | #include <mach/hardware.h>
 | 
					
						
							| 
									
										
										
										
											2008-01-29 15:43:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-15 18:44:40 +08:00
										 |  |  | #include <mach/at91_dbgu.h>
 | 
					
						
							|  |  |  | #include <mach/cpu.h>
 | 
					
						
							| 
									
										
										
										
											2006-01-09 17:05:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-15 18:35:40 +08:00
										 |  |  | void __iomem *at91_uart; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-15 18:44:40 +08:00
										 |  |  | #if !defined(CONFIG_ARCH_AT91X40)
 | 
					
						
							|  |  |  | static const u32 uarts_rm9200[] = { | 
					
						
							|  |  |  | 	AT91_BASE_DBGU0, | 
					
						
							|  |  |  | 	AT91RM9200_BASE_US0, | 
					
						
							|  |  |  | 	AT91RM9200_BASE_US1, | 
					
						
							|  |  |  | 	AT91RM9200_BASE_US2, | 
					
						
							|  |  |  | 	AT91RM9200_BASE_US3, | 
					
						
							|  |  |  | 	0, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const u32 uarts_sam9260[] = { | 
					
						
							|  |  |  | 	AT91_BASE_DBGU0, | 
					
						
							|  |  |  | 	AT91SAM9260_BASE_US0, | 
					
						
							|  |  |  | 	AT91SAM9260_BASE_US1, | 
					
						
							|  |  |  | 	AT91SAM9260_BASE_US2, | 
					
						
							|  |  |  | 	AT91SAM9260_BASE_US3, | 
					
						
							|  |  |  | 	AT91SAM9260_BASE_US4, | 
					
						
							|  |  |  | 	AT91SAM9260_BASE_US5, | 
					
						
							|  |  |  | 	0, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const u32 uarts_sam9261[] = { | 
					
						
							|  |  |  | 	AT91_BASE_DBGU0, | 
					
						
							|  |  |  | 	AT91SAM9261_BASE_US0, | 
					
						
							|  |  |  | 	AT91SAM9261_BASE_US1, | 
					
						
							|  |  |  | 	AT91SAM9261_BASE_US2, | 
					
						
							|  |  |  | 	0, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const u32 uarts_sam9263[] = { | 
					
						
							|  |  |  | 	AT91_BASE_DBGU1, | 
					
						
							|  |  |  | 	AT91SAM9263_BASE_US0, | 
					
						
							|  |  |  | 	AT91SAM9263_BASE_US1, | 
					
						
							|  |  |  | 	AT91SAM9263_BASE_US2, | 
					
						
							|  |  |  | 	0, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const u32 uarts_sam9g45[] = { | 
					
						
							|  |  |  | 	AT91_BASE_DBGU1, | 
					
						
							|  |  |  | 	AT91SAM9G45_BASE_US0, | 
					
						
							|  |  |  | 	AT91SAM9G45_BASE_US1, | 
					
						
							|  |  |  | 	AT91SAM9G45_BASE_US2, | 
					
						
							|  |  |  | 	AT91SAM9G45_BASE_US3, | 
					
						
							|  |  |  | 	0, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const u32 uarts_sam9rl[] = { | 
					
						
							|  |  |  | 	AT91_BASE_DBGU0, | 
					
						
							|  |  |  | 	AT91SAM9RL_BASE_US0, | 
					
						
							|  |  |  | 	AT91SAM9RL_BASE_US1, | 
					
						
							|  |  |  | 	AT91SAM9RL_BASE_US2, | 
					
						
							|  |  |  | 	AT91SAM9RL_BASE_US3, | 
					
						
							|  |  |  | 	0, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const u32 uarts_sam9x5[] = { | 
					
						
							|  |  |  | 	AT91_BASE_DBGU0, | 
					
						
							|  |  |  | 	AT91SAM9X5_BASE_USART0, | 
					
						
							|  |  |  | 	AT91SAM9X5_BASE_USART1, | 
					
						
							|  |  |  | 	AT91SAM9X5_BASE_USART2, | 
					
						
							|  |  |  | 	0, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-04 15:16:41 +08:00
										 |  |  | static const u32 uarts_sama5[] = { | 
					
						
							|  |  |  | 	AT91_BASE_DBGU1, | 
					
						
							|  |  |  | 	SAMA5D3_BASE_USART0, | 
					
						
							|  |  |  | 	SAMA5D3_BASE_USART1, | 
					
						
							|  |  |  | 	SAMA5D3_BASE_USART2, | 
					
						
							|  |  |  | 	SAMA5D3_BASE_USART3, | 
					
						
							|  |  |  | 	0, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-14 20:10:19 +00:00
										 |  |  | static inline const u32* decomp_soc_detect(void __iomem *dbgu_base) | 
					
						
							| 
									
										
										
										
											2012-02-15 18:44:40 +08:00
										 |  |  | { | 
					
						
							|  |  |  | 	u32 cidr, socid; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cidr = __raw_readl(dbgu_base + AT91_DBGU_CIDR); | 
					
						
							|  |  |  | 	socid = cidr & ~AT91_CIDR_VERSION; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (socid) { | 
					
						
							|  |  |  | 	case ARCH_ID_AT91RM9200: | 
					
						
							|  |  |  | 		return uarts_rm9200; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case ARCH_ID_AT91SAM9G20: | 
					
						
							|  |  |  | 	case ARCH_ID_AT91SAM9260: | 
					
						
							|  |  |  | 		return uarts_sam9260; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case ARCH_ID_AT91SAM9261: | 
					
						
							|  |  |  | 		return uarts_sam9261; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case ARCH_ID_AT91SAM9263: | 
					
						
							|  |  |  | 		return uarts_sam9263; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case ARCH_ID_AT91SAM9G45: | 
					
						
							|  |  |  | 		return uarts_sam9g45; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case ARCH_ID_AT91SAM9RL64: | 
					
						
							|  |  |  | 		return uarts_sam9rl; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-04 15:16:42 +08:00
										 |  |  | 	case ARCH_ID_AT91SAM9N12: | 
					
						
							| 
									
										
										
										
											2012-02-15 18:44:40 +08:00
										 |  |  | 	case ARCH_ID_AT91SAM9X5: | 
					
						
							|  |  |  | 		return uarts_sam9x5; | 
					
						
							| 
									
										
										
										
											2013-07-04 15:16:41 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	case ARCH_ID_SAMA5D3: | 
					
						
							|  |  |  | 		return uarts_sama5; | 
					
						
							| 
									
										
										
										
											2012-02-15 18:44:40 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* at91sam9g10 */ | 
					
						
							|  |  |  | 	if ((cidr & ~AT91_CIDR_EXT) == ARCH_ID_AT91SAM9G10) { | 
					
						
							|  |  |  | 		return uarts_sam9261; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	/* at91sam9xe */ | 
					
						
							|  |  |  | 	else if ((cidr & AT91_CIDR_ARCH) == ARCH_FAMILY_AT91SAM9XE) { | 
					
						
							|  |  |  | 		return uarts_sam9260; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-15 18:35:40 +08:00
										 |  |  | static inline void arch_decomp_setup(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-02-15 18:44:40 +08:00
										 |  |  | 	int i = 0; | 
					
						
							|  |  |  | 	const u32* usarts; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-14 20:10:19 +00:00
										 |  |  | 	usarts = decomp_soc_detect((void __iomem *)AT91_BASE_DBGU0); | 
					
						
							| 
									
										
										
										
											2012-02-15 18:44:40 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (!usarts) | 
					
						
							| 
									
										
										
										
											2012-09-14 20:10:19 +00:00
										 |  |  | 		usarts = decomp_soc_detect((void __iomem *)AT91_BASE_DBGU1); | 
					
						
							| 
									
										
										
										
											2012-02-15 18:44:40 +08:00
										 |  |  | 	if (!usarts) { | 
					
						
							|  |  |  | 		at91_uart = NULL; | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	do { | 
					
						
							|  |  |  | 		/* physical address */ | 
					
						
							|  |  |  | 		at91_uart = (void __iomem *)usarts[i]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (__raw_readl(at91_uart + ATMEL_US_BRGR)) | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		i++; | 
					
						
							|  |  |  | 	} while (usarts[i]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	at91_uart = NULL; | 
					
						
							| 
									
										
										
										
											2012-02-15 18:35:40 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2012-02-15 18:44:40 +08:00
										 |  |  | #else
 | 
					
						
							|  |  |  | static inline void arch_decomp_setup(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	at91_uart = NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-09 17:05:41 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * The following code assumes the serial port has already been | 
					
						
							| 
									
										
										
										
											2006-11-30 17:16:43 +01:00
										 |  |  |  * initialized by the bootloader.  If you didn't setup a port in | 
					
						
							| 
									
										
										
										
											2006-01-09 17:05:41 +00:00
										 |  |  |  * your bootloader then nothing will appear (which might be desired). | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This does not append a newline | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2006-03-28 10:24:33 +01:00
										 |  |  | static void putc(int c) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-02-15 18:44:40 +08:00
										 |  |  | 	if (!at91_uart) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-15 18:35:40 +08:00
										 |  |  | 	while (!(__raw_readl(at91_uart + ATMEL_US_CSR) & ATMEL_US_TXRDY)) | 
					
						
							| 
									
										
										
										
											2006-03-28 10:24:33 +01:00
										 |  |  | 		barrier(); | 
					
						
							| 
									
										
										
										
											2012-02-15 18:35:40 +08:00
										 |  |  | 	__raw_writel(c, at91_uart + ATMEL_US_THR); | 
					
						
							| 
									
										
										
										
											2006-03-28 10:24:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline void flush(void) | 
					
						
							| 
									
										
										
										
											2006-01-09 17:05:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-02-15 18:44:40 +08:00
										 |  |  | 	if (!at91_uart) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-09 17:05:41 +00:00
										 |  |  | 	/* wait for transmission to complete */ | 
					
						
							| 
									
										
										
										
											2012-02-15 18:35:40 +08:00
										 |  |  | 	while (!(__raw_readl(at91_uart + ATMEL_US_CSR) & ATMEL_US_TXEMPTY)) | 
					
						
							| 
									
										
										
										
											2006-03-28 10:24:33 +01:00
										 |  |  | 		barrier(); | 
					
						
							| 
									
										
										
										
											2006-01-09 17:05:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 |