Message ID | 1350328024-30485-3-git-send-email-swarren@wwwdotorg.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Monday 15 October 2012, Stephen Warren wrote: > Rob, Arnd, Olof, I'd particularly like feedback on whether the following: > > #include "../../mach-tegra/iomap.h" > > in arch/arm/include/debug/tegra.S is acceptable. I'd really like to > continue to #include a header to share the defines to Tegra physical > memory layout and virtual based addresses with Tegra's io.c's struct > map_desc entries, so they can't get out of sync. So, the include can > either use the relative path as quoted above (which I don't think will > cause any significant maintenance issue), or Tegra's iomap.h would have > to be moved somewhere public so e.g. <tegra-iomap.h> could be included. I don't have a good answer for this unfortunately. I wouldn't want relative include paths to take over because they can paper over a lot of other problems when people get lazy. > Second, is the Kconfig.debug change reasonable? I guess I could remove > the second choice menu I added, and just put all the options in the main > "Kernel low-level debugging port" choice. However, that would make the > "if" statements in "config DEBUG_LL_INCLUDE" rather more unwieldy. It looks ok to me in principle, but you could also solve this by making DEBUG_TEGRA_UART a silent option like this: @@ -345,6 +345,46 @@ choice Say Y here if you want kernel low-level debugging support on SOCFPGA based platforms. + config DEBUG_TEGRA_UARTA + depends on ARCH_TEGRA + select DEBUG_TEGRA_UART + bool "Use Tegra UARTA for low-level debug" + help + Say Y here if you want kernel low-level debugging support + on Tegra based platforms. + + config DEBUG_TEGRA_UARTB + depends on ARCH_TEGRA + select DEBUG_TEGRA_UART + bool "Use Tegra UARTB for low-level debug" + help + Say Y here if you want kernel low-level debugging support + on Tegra based platforms. + + config DEBUG_TEGRA_UARTC + depends on ARCH_TEGRA + select DEBUG_TEGRA_UART + bool "Use Tegra UARTC for low-level debug" + help + Say Y here if you want kernel low-level debugging support + on Tegra based platforms. + + config DEBUG_TEGRA_UARTD + depends on ARCH_TEGRA + select DEBUG_TEGRA_UART + bool "Use Tegra UARTD for low-level debug" + help + Say Y here if you want kernel low-level debugging support + on Tegra based platforms. + + config DEBUG_TEGRA_UARTE + depends on ARCH_TEGRA + select DEBUG_TEGRA_UART + bool "Use Tegra UARTE for low-level debug" + help + Say Y here if you want kernel low-level debugging support + on Tegra based platforms. + config DEBUG_VEXPRESS_UART0_DETECT bool "Autodetect UART0 on Versatile Express Cortex-A core tiles" depends on ARCH_VEXPRESS && CPU_CP15_MMU @@ -409,6 +416,36 @@ choice endchoice +config DEBUG_TEGRA_UART + bool I don't have a strong preference either way. ARnd
On 10/15/2012 02:07 PM, Stephen Warren wrote: > From: Stephen Warren <swarren@nvidia.com> > > Move Tegra's debug-macro.S over to the common debug macro directory. > > Move Tegra's debug UART selection menu into ARM's Kconfig.debug, so that > all related options are selected in the same place. > > Tegra's uncompress.h is left in mach-tegra/include/mach; it will be > removed whenever Tegra is converted to multi-platform. > > Signed-off-by: Stephen Warren <swarren@nvidia.com> > --- > Rob, Arnd, Olof, I'd particularly like feedback on whether the following: > > #include "../../mach-tegra/iomap.h" > > in arch/arm/include/debug/tegra.S is acceptable. I'd really like to > continue to #include a header to share the defines to Tegra physical > memory layout and virtual based addresses with Tegra's io.c's struct > map_desc entries, so they can't get out of sync. So, the include can > either use the relative path as quoted above (which I don't think will > cause any significant maintenance issue), or Tegra's iomap.h would have > to be moved somewhere public so e.g. <tegra-iomap.h> could be included. We already have a way to get the phys and virt addresses at runtime with addruart macro. Couldn't we wrap this with a proper function and setup the mapping at runtime. This would move it out of the platforms. I'd also like to make the virtual address the same on all platforms (but different offsets within a 1MB section) and make the phys address a kconfig option. This would also eliminate the need for the platform include and potentially addruart for that matter. Rob
On 10/17/2012 08:38 AM, Rob Herring wrote: > On 10/15/2012 02:07 PM, Stephen Warren wrote: >> From: Stephen Warren <swarren@nvidia.com> >> >> Move Tegra's debug-macro.S over to the common debug macro directory. >> >> Move Tegra's debug UART selection menu into ARM's Kconfig.debug, so that >> all related options are selected in the same place. >> >> Tegra's uncompress.h is left in mach-tegra/include/mach; it will be >> removed whenever Tegra is converted to multi-platform. >> >> Signed-off-by: Stephen Warren <swarren@nvidia.com> >> --- >> Rob, Arnd, Olof, I'd particularly like feedback on whether the following: >> >> #include "../../mach-tegra/iomap.h" >> >> in arch/arm/include/debug/tegra.S is acceptable. I'd really like to >> continue to #include a header to share the defines to Tegra physical >> memory layout and virtual based addresses with Tegra's io.c's struct >> map_desc entries, so they can't get out of sync. So, the include can >> either use the relative path as quoted above (which I don't think will >> cause any significant maintenance issue), or Tegra's iomap.h would have >> to be moved somewhere public so e.g. <tegra-iomap.h> could be included. > > We already have a way to get the phys and virt addresses at runtime with > addruart macro. So this discussion is mainly about the implementation of addruart. > Couldn't we wrap this with a proper function and setup > the mapping at runtime. This would move it out of the platforms. So, the mapping already is set up at run-time at least during early boot; __create_page_tables() in arch/arm/kernel/head.S calls addruart and sets up an entry for it. I suppose the implication here is that the virtual address that addruart returns doesn't have to match anything that the machine later sets up using iotable_init(). If that's true, then Tegra's debug-macro.S only needs to know the UART physical address, and can make up almost any arbitrary virtual address (perhaps even driven by the logic you mention in your next paragraph below) and hence need not rely on Tegra's iomap.h. That said, we'd still have to manually remember not to create conflicting virtual address setups in the two places, which would still be easier with a shared header. However, I then have two questions: 1) How long do the page tables set up by __create_page_tables() last; do they stick around forever, or at least as long as the macros from debug-macro.S are used, or are they replaced sometime, on the assumption that the machine's .map_io() will call iotable_init() and end up setting up the same mapping? 2) If the virtual address returned by addruart on Tegra is different than any virtual addresses set up by Tegra's .map_io(), and Tegra's .map_io() sets up a very broad mapping that covers all peripherals including the UART, and hence the UART physical registers get mapped into two virtual addresses, will this cause any problems? IIRC, duplicate mappings can cause some issues on ARM, but perhaps that only applies to memory-like mappings, and not completely uncached IO mappings? > I'd also like to make the virtual address the same on all platforms (but > different offsets within a 1MB section) and make the phys address a > kconfig option. This would also eliminate the need for the platform > include and potentially addruart for that matter.
On 10/17/2012 10:22 AM, Stephen Warren wrote: > On 10/17/2012 08:38 AM, Rob Herring wrote: >> On 10/15/2012 02:07 PM, Stephen Warren wrote: >>> From: Stephen Warren <swarren@nvidia.com> >>> >>> Move Tegra's debug-macro.S over to the common debug macro directory. >>> >>> Move Tegra's debug UART selection menu into ARM's Kconfig.debug, so that >>> all related options are selected in the same place. >>> >>> Tegra's uncompress.h is left in mach-tegra/include/mach; it will be >>> removed whenever Tegra is converted to multi-platform. >>> >>> Signed-off-by: Stephen Warren <swarren@nvidia.com> >>> --- >>> Rob, Arnd, Olof, I'd particularly like feedback on whether the following: >>> >>> #include "../../mach-tegra/iomap.h" >>> >>> in arch/arm/include/debug/tegra.S is acceptable. I'd really like to >>> continue to #include a header to share the defines to Tegra physical >>> memory layout and virtual based addresses with Tegra's io.c's struct >>> map_desc entries, so they can't get out of sync. So, the include can >>> either use the relative path as quoted above (which I don't think will >>> cause any significant maintenance issue), or Tegra's iomap.h would have >>> to be moved somewhere public so e.g. <tegra-iomap.h> could be included. >> >> We already have a way to get the phys and virt addresses at runtime with >> addruart macro. > > So this discussion is mainly about the implementation of addruart. > >> Couldn't we wrap this with a proper function and setup >> the mapping at runtime. This would move it out of the platforms. > > So, the mapping already is set up at run-time at least during early > boot; __create_page_tables() in arch/arm/kernel/head.S calls addruart > and sets up an entry for it. > > I suppose the implication here is that the virtual address that addruart > returns doesn't have to match anything that the machine later sets up > using iotable_init(). > > If that's true, then Tegra's debug-macro.S only needs to know the UART > physical address, and can make up almost any arbitrary virtual address > (perhaps even driven by the logic you mention in your next paragraph > below) and hence need not rely on Tegra's iomap.h. That said, we'd still > have to manually remember not to create conflicting virtual address > setups in the two places, which would still be easier with a shared header. > > However, I then have two questions: > > 1) How long do the page tables set up by __create_page_tables() last; do > they stick around forever, or at least as long as the macros from > debug-macro.S are used, or are they replaced sometime, on the assumption > that the machine's .map_io() will call iotable_init() and end up setting > up the same mapping? So answering my own question here after testing this: If I use a different (to iomap.h) virtual address in debug-macro.S, then the very very early output from earlyprintk does work: > [ 0.000000] Booting Linux on physical CPU 0 > [ 0.000000] Initializing cgroup subsys cpu > [ 0.000000] Linux version 3.7.0-rc1-next-20121016-... > [ 0.000000] CPU: ARMv7 Processor [411fc090] revision 0 (ARMv7), cr=10c5387d > [ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache > [ 0.000000] Machine: nVidia Tegra20 (Flattened Device Tree), model: NVIDIA Tegra2 Harmony evaluation board > [ 0.000000] bootconsole [earlycon0] enabled > [ 0.000000] Memory policy: ECC disabled, Data cache writealloc However, the kernel either hangs or output simply stops working at that point. If I modify Tegra's iotable_init() call to add an entry to map the UART to the virtual address debug-macro.S assumes, then everything works again. That implies we really do need to keep the two pieces of code completely in sync, so a shared header is the right way to go. It also implies that having duplicate mappings of the same physical address doesn't cause any immediate obvious catastrophic problems. Ways we might avoid files in arch/arm/include/debug having to use relative include paths to pick up that header are: a) Move mach-${mach}/include/mach/iomap.h to iomap-${mach}.h in some standard include path. b) Rework debug-macro.S so that it isn't an include file, but rather a regular top-level file. In other words, rather than compiling arch/arm/kernel/debug.S, and having that #include DEBUG_LL_INCLUDE, instead compile DEBUG_LL_SOURCE (i.e. arch/arm/mach-${mach}/debug.S by default), and have that #include any common parts (e.g. implementation of printhex8). This has benefits of: b1) arch/arm/mach-${mach}/debug.S is in the mach directory that owns it, rather than having them all dumped into a common location. b2) Can use #include "iomap.h", a non-relative include, to pick up the shared header b3) Perhaps we can simplify the current debug.S e.g. have a common debug-semihosting.S that contains the semihosting stuff, and only include that from mach-*/debug.S if that machine uses semihosting, or similar? (b) seems like a lot of work. I don't see any advantage of (a) over just using the relative include.
On 10/17/2012 11:22 AM, Stephen Warren wrote: > On 10/17/2012 08:38 AM, Rob Herring wrote: >> On 10/15/2012 02:07 PM, Stephen Warren wrote: >>> From: Stephen Warren <swarren@nvidia.com> >>> >>> Move Tegra's debug-macro.S over to the common debug macro directory. >>> >>> Move Tegra's debug UART selection menu into ARM's Kconfig.debug, so that >>> all related options are selected in the same place. >>> >>> Tegra's uncompress.h is left in mach-tegra/include/mach; it will be >>> removed whenever Tegra is converted to multi-platform. >>> >>> Signed-off-by: Stephen Warren <swarren@nvidia.com> >>> --- >>> Rob, Arnd, Olof, I'd particularly like feedback on whether the following: >>> >>> #include "../../mach-tegra/iomap.h" >>> >>> in arch/arm/include/debug/tegra.S is acceptable. I'd really like to >>> continue to #include a header to share the defines to Tegra physical >>> memory layout and virtual based addresses with Tegra's io.c's struct >>> map_desc entries, so they can't get out of sync. So, the include can >>> either use the relative path as quoted above (which I don't think will >>> cause any significant maintenance issue), or Tegra's iomap.h would have >>> to be moved somewhere public so e.g. <tegra-iomap.h> could be included. >> >> We already have a way to get the phys and virt addresses at runtime with >> addruart macro. > > So this discussion is mainly about the implementation of addruart. > >> Couldn't we wrap this with a proper function and setup >> the mapping at runtime. This would move it out of the platforms. > > So, the mapping already is set up at run-time at least during early > boot; __create_page_tables() in arch/arm/kernel/head.S calls addruart > and sets up an entry for it. > > I suppose the implication here is that the virtual address that addruart > returns doesn't have to match anything that the machine later sets up > using iotable_init(). > > If that's true, then Tegra's debug-macro.S only needs to know the UART > physical address, and can make up almost any arbitrary virtual address > (perhaps even driven by the logic you mention in your next paragraph > below) and hence need not rely on Tegra's iomap.h. That said, we'd still > have to manually remember not to create conflicting virtual address > setups in the two places, which would still be easier with a shared header. The virtual address has to remain the same. A non-platform specific header for a fixed virtual address define would be cleaner than relative includes. > > However, I then have two questions: > > 1) How long do the page tables set up by __create_page_tables() last; do > they stick around forever, or at least as long as the macros from > debug-macro.S are used, or are they replaced sometime, on the assumption > that the machine's .map_io() will call iotable_init() and end up setting > up the same mapping? It works to... [ 0.000000] Booting Linux on physical CPU 0 [ 0.000000] Linux version 3.5.4+ (rob@rob-laptop) (gcc version 4.7.2 (Ubuntu/Linaro 4.7.2-1ubuntu1) ) #280 SMP Wed Oct 17 18:00:29 CDT 2012 () [ 0.000000] CPU: ARMv7 Processor [413fc090] revision 0 (ARMv7), cr=10c5387d [ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache [ 0.000000] Machine: Highbank, model: Calxeda Highbank [ 0.000000] bootconsole [earlycon0] enabled [ 0.000000] cma: CMA: reserved 16 MiB at 2e800000 [ 0.000000] Memory policy: ECC disabled, Data cache writealloc ...here with no iotable mapping. > > 2) If the virtual address returned by addruart on Tegra is different > than any virtual addresses set up by Tegra's .map_io(), and Tegra's > .map_io() sets up a very broad mapping that covers all peripherals > including the UART, and hence the UART physical registers get mapped > into two virtual addresses, will this cause any problems? IIRC, > duplicate mappings can cause some issues on ARM, but perhaps that only > applies to memory-like mappings, and not completely uncached IO mappings? The virt address has to match. It can initially be a 1MB section and then replaced with a 4K entry, but the same DEBUG_LL macros are used throughout the boot process as the mapping is updated. Duplicate mappings of different memory types is the problem. Multiple mapping of the same type are fine and common (the zero page for example). Rob
On Wed, Oct 17, 2012 at 03:12:17PM -0600, Stephen Warren wrote: > That implies we really do need to keep the two pieces of code completely > in sync, so a shared header is the right way to go. It also implies that > having duplicate mappings of the same physical address doesn't cause any > immediate obvious catastrophic problems. > > Ways we might avoid files in arch/arm/include/debug having to use > relative include paths to pick up that header are: Why not take the opposite approach. Treat the platform as setting up the addresses for the UART. Then arrange for the debug macros to match that. Or we define a common virtual address for debug UARTs (which platforms would not be able to use). > b) Rework debug-macro.S so that it isn't an include file, but rather a > regular top-level file. No, that won't work. It's used in two places - the kernel and the decompressor. Hence why it is an include file (it's not an include file just for the fun of it.)
On 10/18/2012 03:53 AM, Russell King - ARM Linux wrote: > On Wed, Oct 17, 2012 at 03:12:17PM -0600, Stephen Warren wrote: >> That implies we really do need to keep the two pieces of code completely >> in sync, so a shared header is the right way to go. It also implies that >> having duplicate mappings of the same physical address doesn't cause any >> immediate obvious catastrophic problems. >> >> Ways we might avoid files in arch/arm/include/debug having to use >> relative include paths to pick up that header are: > > Why not take the opposite approach. Treat the platform as setting up the > addresses for the UART. Then arrange for the debug macros to match that. Well, wouldn't the debug macros match it by including a common header file that defined the virtual address:-) > Or we define a common virtual address for debug UARTs (which platforms > would not be able to use). That seems like good idea. >> b) Rework debug-macro.S so that it isn't an include file, but rather a >> regular top-level file. > > No, that won't work. It's used in two places - the kernel and the > decompressor. Hence why it is an include file (it's not an include > file just for the fun of it.) Can't the file just be compiled twice by the two different Makefiles?
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index b0f3857..96b9425 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -345,6 +345,13 @@ choice Say Y here if you want kernel low-level debugging support on SOCFPGA based platforms. + config DEBUG_TEGRA_UART + depends on ARCH_TEGRA + bool "Use Tegra UART for low-level debug" + help + Say Y here if you want kernel low-level debugging support + on Tegra based platforms. + config DEBUG_VEXPRESS_UART0_DETECT bool "Autodetect UART0 on Versatile Express Cortex-A core tiles" depends on ARCH_VEXPRESS && CPU_CP15_MMU @@ -409,6 +416,36 @@ choice endchoice +choice + prompt "Low-level debug console UART" + depends on DEBUG_LL && DEBUG_TEGRA_UART + + config TEGRA_DEBUG_UART_AUTO_ODMDATA + bool "Via ODMDATA" + help + Automatically determines which UART to use for low-level debug based + on the ODMDATA value. This value is part of the BCT, and is written + to the boot memory device using nvflash, or other flashing tool. + When bits 19:18 are 3, then bits 17:15 indicate which UART to use; + 0/1/2/3/4 are UART A/B/C/D/E. + + config TEGRA_DEBUG_UARTA + bool "UART A" + + config TEGRA_DEBUG_UARTB + bool "UART B" + + config TEGRA_DEBUG_UARTC + bool "UART C" + + config TEGRA_DEBUG_UARTD + bool "UART D" + + config TEGRA_DEBUG_UARTE + bool "UART E" + +endchoice + config DEBUG_LL_INCLUDE string default "debug/icedcc.S" if DEBUG_ICEDCC @@ -418,6 +455,7 @@ config DEBUG_LL_INCLUDE default "debug/socfpga.S" if DEBUG_SOCFPGA_UART default "debug/vexpress.S" if DEBUG_VEXPRESS_UART0_DETECT || \ DEBUG_VEXPRESS_UART0_CA9 || DEBUG_VEXPRESS_UART0_RS1 + default "debug/tegra.S" if DEBUG_TEGRA_UART default "mach/debug-macro.S" config EARLY_PRINTK diff --git a/arch/arm/include/debug/tegra.S b/arch/arm/include/debug/tegra.S new file mode 100644 index 0000000..b957abb --- /dev/null +++ b/arch/arm/include/debug/tegra.S @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2010,2011 Google, Inc. + * Copyright (C) 2011-2012 NVIDIA CORPORATION. All Rights Reserved. + * + * Author: + * Colin Cross <ccross@google.com> + * Erik Gilling <konkers@google.com> + * Doug Anderson <dianders@chromium.org> + * Stephen Warren <swarren@nvidia.com> + * + * Portions based on mach-omap2's debug-macro.S + * Copyright (C) 1994-1999 Russell King + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#include <linux/serial_reg.h> + +#include "../../mach-tegra/iomap.h" + +#define UART_SHIFT 2 + +#define TEGRA_CLK_RST_DEVICES_L (TEGRA_CLK_RESET_BASE + 0x04) +#define TEGRA_CLK_RST_DEVICES_H (TEGRA_CLK_RESET_BASE + 0x08) +#define TEGRA_CLK_RST_DEVICES_U (TEGRA_CLK_RESET_BASE + 0x0c) +#define TEGRA_CLK_OUT_ENB_L (TEGRA_CLK_RESET_BASE + 0x10) +#define TEGRA_CLK_OUT_ENB_H (TEGRA_CLK_RESET_BASE + 0x14) +#define TEGRA_CLK_OUT_ENB_U (TEGRA_CLK_RESET_BASE + 0x18) +#define TEGRA_PMC_SCRATCH20 (TEGRA_PMC_BASE + 0xa0) +#define TEGRA_APB_MISC_GP_HIDREV (TEGRA_APB_MISC_BASE + 0x804) + +#define checkuart(rp, rv, lhu, bit, uart) \ + /* Load address of CLK_RST register */ \ + movw rp, #TEGRA_CLK_RST_DEVICES_##lhu & 0xffff ; \ + movt rp, #TEGRA_CLK_RST_DEVICES_##lhu >> 16 ; \ + /* Load value from CLK_RST register */ \ + ldr rp, [rp, #0] ; \ + /* Test UART's reset bit */ \ + tst rp, #(1 << bit) ; \ + /* If set, can't use UART; jump to save no UART */ \ + bne 90f ; \ + /* Load address of CLK_OUT_ENB register */ \ + movw rp, #TEGRA_CLK_OUT_ENB_##lhu & 0xffff ; \ + movt rp, #TEGRA_CLK_OUT_ENB_##lhu >> 16 ; \ + /* Load value from CLK_OUT_ENB register */ \ + ldr rp, [rp, #0] ; \ + /* Test UART's clock enable bit */ \ + tst rp, #(1 << bit) ; \ + /* If clear, can't use UART; jump to save no UART */ \ + beq 90f ; \ + /* Passed all tests, load address of UART registers */ \ + movw rp, #TEGRA_UART##uart##_BASE & 0xffff ; \ + movt rp, #TEGRA_UART##uart##_BASE >> 16 ; \ + /* Jump to save UART address */ \ + b 91f + + .macro addruart, rp, rv, tmp + adr \rp, 99f @ actual addr of 99f + ldr \rv, [\rp] @ linked addr is stored there + sub \rv, \rv, \rp @ offset between the two + ldr \rp, [\rp, #4] @ linked tegra_uart_config + sub \tmp, \rp, \rv @ actual tegra_uart_config + ldr \rp, [\tmp] @ Load tegra_uart_config + cmp \rp, #1 @ needs initialization? + bne 100f @ no; go load the addresses + mov \rv, #0 @ yes; record init is done + str \rv, [\tmp] + +#ifdef CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA + /* Check ODMDATA */ +10: movw \rp, #TEGRA_PMC_SCRATCH20 & 0xffff + movt \rp, #TEGRA_PMC_SCRATCH20 >> 16 + ldr \rp, [\rp, #0] @ Load PMC_SCRATCH20 + ubfx \rv, \rp, #18, #2 @ 19:18 are console type + cmp \rv, #2 @ 2 and 3 mean DCC, UART + beq 11f @ some boards swap the meaning + cmp \rv, #3 @ so accept either + bne 90f +11: ubfx \rv, \rp, #15, #3 @ 17:15 are UART ID + cmp \rv, #0 @ UART 0? + beq 20f + cmp \rv, #1 @ UART 1? + beq 21f + cmp \rv, #2 @ UART 2? + beq 22f + cmp \rv, #3 @ UART 3? + beq 23f + cmp \rv, #4 @ UART 4? + beq 24f + b 90f @ invalid +#endif + +#if defined(CONFIG_TEGRA_DEBUG_UARTA) || \ + defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA) + /* Check UART A validity */ +20: checkuart(\rp, \rv, L, 6, A) +#endif + +#if defined(CONFIG_TEGRA_DEBUG_UARTB) || \ + defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA) + /* Check UART B validity */ +21: checkuart(\rp, \rv, L, 7, B) +#endif + +#if defined(CONFIG_TEGRA_DEBUG_UARTC) || \ + defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA) + /* Check UART C validity */ +22: checkuart(\rp, \rv, H, 23, C) +#endif + +#if defined(CONFIG_TEGRA_DEBUG_UARTD) || \ + defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA) + /* Check UART D validity */ +23: checkuart(\rp, \rv, U, 1, D) +#endif + +#if defined(CONFIG_TEGRA_DEBUG_UARTE) || \ + defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA) + /* Check UART E validity */ +24: + checkuart(\rp, \rv, U, 2, E) +#endif + + /* No valid UART found */ +90: mov \rp, #0 + /* fall through */ + + /* Record whichever UART we chose */ +91: str \rp, [\tmp, #4] @ Store in tegra_uart_phys + cmp \rp, #0 @ Valid UART address? + bne 92f @ Yes, go process it + str \rp, [\tmp, #8] @ Store 0 in tegra_uart_phys + b 100f @ Done +92: sub \rv, \rp, #IO_APB_PHYS @ Calculate virt address + add \rv, \rv, #IO_APB_VIRT + str \rv, [\tmp, #8] @ Store in tegra_uart_virt + movw \rv, #TEGRA_APB_MISC_GP_HIDREV & 0xffff + movt \rv, #TEGRA_APB_MISC_GP_HIDREV >> 16 + ldr \rv, [\rv, #0] @ Load HIDREV + ubfx \rv, \rv, #8, #8 @ 15:8 are SoC version + cmp \rv, #0x20 @ Tegra20? + moveq \rv, #0x75 @ Tegra20 divisor + movne \rv, #0xdd @ Tegra30 divisor + str \rv, [\tmp, #12] @ Save divisor to scratch + /* uart[UART_LCR] = UART_LCR_WLEN8 | UART_LCR_DLAB; */ + mov \rv, #UART_LCR_WLEN8 | UART_LCR_DLAB + str \rv, [\rp, #UART_LCR << UART_SHIFT] + /* uart[UART_DLL] = div & 0xff; */ + ldr \rv, [\tmp, #12] + and \rv, \rv, #0xff + str \rv, [\rp, #UART_DLL << UART_SHIFT] + /* uart[UART_DLM] = div >> 8; */ + ldr \rv, [\tmp, #12] + lsr \rv, \rv, #8 + str \rv, [\rp, #UART_DLM << UART_SHIFT] + /* uart[UART_LCR] = UART_LCR_WLEN8; */ + mov \rv, #UART_LCR_WLEN8 + str \rv, [\rp, #UART_LCR << UART_SHIFT] + b 100f + + .align +99: .word . + .word tegra_uart_config + .ltorg + + /* Load previously selected UART address */ +100: ldr \rp, [\tmp, #4] @ Load tegra_uart_phys + ldr \rv, [\tmp, #8] @ Load tegra_uart_virt + .endm + +/* + * Code below is swiped from <asm/hardware/debug-8250.S>, but add an extra + * check to make sure that the UART address is actually valid. + */ + + .macro senduart, rd, rx + cmp \rx, #0 + strneb \rd, [\rx, #UART_TX << UART_SHIFT] +1001: + .endm + + .macro busyuart, rd, rx + cmp \rx, #0 + beq 1002f +1001: ldrb \rd, [\rx, #UART_LSR << UART_SHIFT] + and \rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE + teq \rd, #UART_LSR_TEMT | UART_LSR_THRE + bne 1001b +1002: + .endm + + .macro waituart, rd, rx +#ifdef FLOW_CONTROL + cmp \rx, #0 + beq 1002f +1001: ldrb \rd, [\rx, #UART_MSR << UART_SHIFT] + tst \rd, #UART_MSR_CTS + beq 1001b +1002: +#endif + .endm diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index 97fcd16..e426d1b 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -57,35 +57,6 @@ config TEGRA_AHB which controls AHB bus master arbitration and some perfomance parameters(priority, prefech size). -choice - prompt "Low-level debug console UART" - -config TEGRA_DEBUG_UART_AUTO_ODMDATA - bool "Via ODMDATA" - help - Automatically determines which UART to use for low-level debug based - on the ODMDATA value. This value is part of the BCT, and is written - to the boot memory device using nvflash, or other flashing tool. - When bits 19:18 are 3, then bits 17:15 indicate which UART to use; - 0/1/2/3/4 are UART A/B/C/D/E. - -config TEGRA_DEBUG_UARTA - bool "UART-A" - -config TEGRA_DEBUG_UARTB - bool "UART-B" - -config TEGRA_DEBUG_UARTC - bool "UART-C" - -config TEGRA_DEBUG_UARTD - bool "UART-D" - -config TEGRA_DEBUG_UARTE - bool "UART-E" - -endchoice - config TEGRA_EMC_SCALING_ENABLE bool "Enable scaling the memory frequency" diff --git a/arch/arm/mach-tegra/include/mach/debug-macro.S b/arch/arm/mach-tegra/include/mach/debug-macro.S deleted file mode 100644 index d4c23d6..0000000 --- a/arch/arm/mach-tegra/include/mach/debug-macro.S +++ /dev/null @@ -1,211 +0,0 @@ -/* - * arch/arm/mach-tegra/include/mach/debug-macro.S - * - * Copyright (C) 2010,2011 Google, Inc. - * Copyright (C) 2011-2012 NVIDIA CORPORATION. All Rights Reserved. - * - * Author: - * Colin Cross <ccross@google.com> - * Erik Gilling <konkers@google.com> - * Doug Anderson <dianders@chromium.org> - * Stephen Warren <swarren@nvidia.com> - * - * Portions based on mach-omap2's debug-macro.S - * Copyright (C) 1994-1999 Russell King - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * 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. - * - */ - -#include <linux/serial_reg.h> - -#include "../../iomap.h" - -#define UART_SHIFT 2 - -#define TEGRA_CLK_RST_DEVICES_L (TEGRA_CLK_RESET_BASE + 0x04) -#define TEGRA_CLK_RST_DEVICES_H (TEGRA_CLK_RESET_BASE + 0x08) -#define TEGRA_CLK_RST_DEVICES_U (TEGRA_CLK_RESET_BASE + 0x0c) -#define TEGRA_CLK_OUT_ENB_L (TEGRA_CLK_RESET_BASE + 0x10) -#define TEGRA_CLK_OUT_ENB_H (TEGRA_CLK_RESET_BASE + 0x14) -#define TEGRA_CLK_OUT_ENB_U (TEGRA_CLK_RESET_BASE + 0x18) -#define TEGRA_PMC_SCRATCH20 (TEGRA_PMC_BASE + 0xa0) -#define TEGRA_APB_MISC_GP_HIDREV (TEGRA_APB_MISC_BASE + 0x804) - -#define checkuart(rp, rv, lhu, bit, uart) \ - /* Load address of CLK_RST register */ \ - movw rp, #TEGRA_CLK_RST_DEVICES_##lhu & 0xffff ; \ - movt rp, #TEGRA_CLK_RST_DEVICES_##lhu >> 16 ; \ - /* Load value from CLK_RST register */ \ - ldr rp, [rp, #0] ; \ - /* Test UART's reset bit */ \ - tst rp, #(1 << bit) ; \ - /* If set, can't use UART; jump to save no UART */ \ - bne 90f ; \ - /* Load address of CLK_OUT_ENB register */ \ - movw rp, #TEGRA_CLK_OUT_ENB_##lhu & 0xffff ; \ - movt rp, #TEGRA_CLK_OUT_ENB_##lhu >> 16 ; \ - /* Load value from CLK_OUT_ENB register */ \ - ldr rp, [rp, #0] ; \ - /* Test UART's clock enable bit */ \ - tst rp, #(1 << bit) ; \ - /* If clear, can't use UART; jump to save no UART */ \ - beq 90f ; \ - /* Passed all tests, load address of UART registers */ \ - movw rp, #TEGRA_UART##uart##_BASE & 0xffff ; \ - movt rp, #TEGRA_UART##uart##_BASE >> 16 ; \ - /* Jump to save UART address */ \ - b 91f - - .macro addruart, rp, rv, tmp - adr \rp, 99f @ actual addr of 99f - ldr \rv, [\rp] @ linked addr is stored there - sub \rv, \rv, \rp @ offset between the two - ldr \rp, [\rp, #4] @ linked tegra_uart_config - sub \tmp, \rp, \rv @ actual tegra_uart_config - ldr \rp, [\tmp] @ Load tegra_uart_config - cmp \rp, #1 @ needs initialization? - bne 100f @ no; go load the addresses - mov \rv, #0 @ yes; record init is done - str \rv, [\tmp] - -#ifdef CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA - /* Check ODMDATA */ -10: movw \rp, #TEGRA_PMC_SCRATCH20 & 0xffff - movt \rp, #TEGRA_PMC_SCRATCH20 >> 16 - ldr \rp, [\rp, #0] @ Load PMC_SCRATCH20 - ubfx \rv, \rp, #18, #2 @ 19:18 are console type - cmp \rv, #2 @ 2 and 3 mean DCC, UART - beq 11f @ some boards swap the meaning - cmp \rv, #3 @ so accept either - bne 90f -11: ubfx \rv, \rp, #15, #3 @ 17:15 are UART ID - cmp \rv, #0 @ UART 0? - beq 20f - cmp \rv, #1 @ UART 1? - beq 21f - cmp \rv, #2 @ UART 2? - beq 22f - cmp \rv, #3 @ UART 3? - beq 23f - cmp \rv, #4 @ UART 4? - beq 24f - b 90f @ invalid -#endif - -#if defined(CONFIG_TEGRA_DEBUG_UARTA) || \ - defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA) - /* Check UART A validity */ -20: checkuart(\rp, \rv, L, 6, A) -#endif - -#if defined(CONFIG_TEGRA_DEBUG_UARTB) || \ - defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA) - /* Check UART B validity */ -21: checkuart(\rp, \rv, L, 7, B) -#endif - -#if defined(CONFIG_TEGRA_DEBUG_UARTC) || \ - defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA) - /* Check UART C validity */ -22: checkuart(\rp, \rv, H, 23, C) -#endif - -#if defined(CONFIG_TEGRA_DEBUG_UARTD) || \ - defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA) - /* Check UART D validity */ -23: checkuart(\rp, \rv, U, 1, D) -#endif - -#if defined(CONFIG_TEGRA_DEBUG_UARTE) || \ - defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA) - /* Check UART E validity */ -24: - checkuart(\rp, \rv, U, 2, E) -#endif - - /* No valid UART found */ -90: mov \rp, #0 - /* fall through */ - - /* Record whichever UART we chose */ -91: str \rp, [\tmp, #4] @ Store in tegra_uart_phys - cmp \rp, #0 @ Valid UART address? - bne 92f @ Yes, go process it - str \rp, [\tmp, #8] @ Store 0 in tegra_uart_phys - b 100f @ Done -92: sub \rv, \rp, #IO_APB_PHYS @ Calculate virt address - add \rv, \rv, #IO_APB_VIRT - str \rv, [\tmp, #8] @ Store in tegra_uart_virt - movw \rv, #TEGRA_APB_MISC_GP_HIDREV & 0xffff - movt \rv, #TEGRA_APB_MISC_GP_HIDREV >> 16 - ldr \rv, [\rv, #0] @ Load HIDREV - ubfx \rv, \rv, #8, #8 @ 15:8 are SoC version - cmp \rv, #0x20 @ Tegra20? - moveq \rv, #0x75 @ Tegra20 divisor - movne \rv, #0xdd @ Tegra30 divisor - str \rv, [\tmp, #12] @ Save divisor to scratch - /* uart[UART_LCR] = UART_LCR_WLEN8 | UART_LCR_DLAB; */ - mov \rv, #UART_LCR_WLEN8 | UART_LCR_DLAB - str \rv, [\rp, #UART_LCR << UART_SHIFT] - /* uart[UART_DLL] = div & 0xff; */ - ldr \rv, [\tmp, #12] - and \rv, \rv, #0xff - str \rv, [\rp, #UART_DLL << UART_SHIFT] - /* uart[UART_DLM] = div >> 8; */ - ldr \rv, [\tmp, #12] - lsr \rv, \rv, #8 - str \rv, [\rp, #UART_DLM << UART_SHIFT] - /* uart[UART_LCR] = UART_LCR_WLEN8; */ - mov \rv, #UART_LCR_WLEN8 - str \rv, [\rp, #UART_LCR << UART_SHIFT] - b 100f - - .align -99: .word . - .word tegra_uart_config - .ltorg - - /* Load previously selected UART address */ -100: ldr \rp, [\tmp, #4] @ Load tegra_uart_phys - ldr \rv, [\tmp, #8] @ Load tegra_uart_virt - .endm - -/* - * Code below is swiped from <asm/hardware/debug-8250.S>, but add an extra - * check to make sure that the UART address is actually valid. - */ - - .macro senduart, rd, rx - cmp \rx, #0 - strneb \rd, [\rx, #UART_TX << UART_SHIFT] -1001: - .endm - - .macro busyuart, rd, rx - cmp \rx, #0 - beq 1002f -1001: ldrb \rd, [\rx, #UART_LSR << UART_SHIFT] - and \rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE - teq \rd, #UART_LSR_TEMT | UART_LSR_THRE - bne 1001b -1002: - .endm - - .macro waituart, rd, rx -#ifdef FLOW_CONTROL - cmp \rx, #0 - beq 1002f -1001: ldrb \rd, [\rx, #UART_MSR << UART_SHIFT] - tst \rd, #UART_MSR_CTS - beq 1001b -1002: -#endif - .endm