2 * arch/arm/mach-tegra/include/mach/uncompress.h
4 * Copyright (C) 2010 Google, Inc.
5 * Copyright (C) 2011 Google, Inc.
6 * Copyright (C) 2011-2012 NVIDIA CORPORATION. All Rights Reserved.
9 * Colin Cross <ccross@google.com>
10 * Erik Gilling <konkers@google.com>
11 * Doug Anderson <dianders@chromium.org>
12 * Stephen Warren <swarren@nvidia.com>
14 * This software is licensed under the terms of the GNU General Public
15 * License version 2, as published by the Free Software Foundation, and
16 * may be copied, distributed, and modified under those terms.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
25 #ifndef __MACH_TEGRA_UNCOMPRESS_H
26 #define __MACH_TEGRA_UNCOMPRESS_H
28 #include <linux/types.h>
29 #include <linux/serial_reg.h>
31 #include <mach/irammap.h>
33 #include "../../iomap.h"
35 #define BIT(x) (1 << (x))
36 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
38 #define DEBUG_UART_SHIFT 2
42 static void putc(int c
)
47 while (!(uart
[UART_LSR
<< DEBUG_UART_SHIFT
] & UART_LSR_THRE
))
49 uart
[UART_TX
<< DEBUG_UART_SHIFT
] = c
;
52 static inline void flush(void)
56 static inline void save_uart_address(void)
58 u32
*buf
= (u32
*)(TEGRA_IRAM_BASE
+ TEGRA_IRAM_DEBUG_UART_OFFSET
);
61 buf
[0] = TEGRA_IRAM_DEBUG_UART_COOKIE
;
75 TEGRA_CLK_RESET_BASE
+ 0x04,
76 TEGRA_CLK_RESET_BASE
+ 0x10,
81 TEGRA_CLK_RESET_BASE
+ 0x04,
82 TEGRA_CLK_RESET_BASE
+ 0x10,
87 TEGRA_CLK_RESET_BASE
+ 0x08,
88 TEGRA_CLK_RESET_BASE
+ 0x14,
93 TEGRA_CLK_RESET_BASE
+ 0x0c,
94 TEGRA_CLK_RESET_BASE
+ 0x18,
99 TEGRA_CLK_RESET_BASE
+ 0x0c,
100 TEGRA_CLK_RESET_BASE
+ 0x18,
105 static inline bool uart_clocked(int i
)
107 if (*(u8
*)uarts
[i
].reset_reg
& BIT(uarts
[i
].bit
))
110 if (!(*(u8
*)uarts
[i
].clock_reg
& BIT(uarts
[i
].bit
)))
116 #ifdef CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA
117 int auto_odmdata(void)
119 volatile u32
*pmc
= (volatile u32
*)TEGRA_PMC_BASE
;
120 u32 odmdata
= pmc
[0xa0 / 4];
123 * Bits 19:18 are the console type: 0=default, 1=none, 2==DCC, 3==UART
124 * Some boards apparently swap the last two values, but we don't have
125 * any way of catering for that here, so we just accept either. If this
126 * doesn't make sense for your board, just don't enable this feature.
128 * Bits 17:15 indicate the UART to use, 0/1/2/3/4 are UART A/B/C/D/E.
131 switch ((odmdata
>> 18) & 3) {
139 return (odmdata
>> 15) & 7;
143 #ifdef CONFIG_TEGRA_DEBUG_UART_AUTO_SCRATCH
144 int auto_scratch(void)
149 * Look for the first UART that:
150 * a) Is not in reset.
152 * c) Has a 'D' in the scratchpad register.
154 * Note that on Tegra30, the first two conditions are required, since
155 * if not true, accesses to the UART scratch register will hang.
156 * Tegra20 doesn't have this issue.
158 * The intent is that the bootloader will tell the kernel which UART
159 * to use by setting up those conditions. If nothing found, we'll fall
160 * back to what's specified in TEGRA_DEBUG_UART_BASE.
162 for (i
= 0; i
< ARRAY_SIZE(uarts
); i
++) {
163 if (!uart_clocked(i
))
166 uart
= (volatile u8
*)uarts
[i
].base
;
167 if (uart
[UART_SCR
<< DEBUG_UART_SHIFT
] != 'D')
178 * Setup before decompression. This is where we do UART selection for
179 * earlyprintk and init the uart_base register.
181 static inline void arch_decomp_setup(void)
183 int uart_id
, auto_uart_id
;
184 volatile u32
*apb_misc
= (volatile u32
*)TEGRA_APB_MISC_BASE
;
187 #if defined(CONFIG_TEGRA_DEBUG_UARTA)
189 #elif defined(CONFIG_TEGRA_DEBUG_UARTB)
191 #elif defined(CONFIG_TEGRA_DEBUG_UARTC)
193 #elif defined(CONFIG_TEGRA_DEBUG_UARTD)
195 #elif defined(CONFIG_TEGRA_DEBUG_UARTE)
201 #if defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
202 auto_uart_id
= auto_odmdata();
203 #elif defined(CONFIG_TEGRA_DEBUG_UART_AUTO_SCRATCH)
204 auto_uart_id
= auto_scratch();
208 if (auto_uart_id
!= -1)
209 uart_id
= auto_uart_id
;
211 if (uart_id
< 0 || uart_id
>= ARRAY_SIZE(uarts
) ||
212 !uart_clocked(uart_id
))
215 uart
= (volatile u8
*)uarts
[uart_id
].base
;
221 chip
= (apb_misc
[0x804 / 4] >> 8) & 0xff;
227 uart
[UART_LCR
<< DEBUG_UART_SHIFT
] |= UART_LCR_DLAB
;
228 uart
[UART_DLL
<< DEBUG_UART_SHIFT
] = div
& 0xff;
229 uart
[UART_DLM
<< DEBUG_UART_SHIFT
] = div
>> 8;
230 uart
[UART_LCR
<< DEBUG_UART_SHIFT
] = 3;
233 static inline void arch_decomp_wdog(void)