Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6d7d7b3e authored by Stephen Warren's avatar Stephen Warren Committed by Olof Johansson
Browse files

ARM: tegra: Pass uncompress.h UART selection to DEBUG_LL

uncompress.h now saves the selected UART's physical address in Tegra's
IRAM, along with a cookie to indicate validity.

The first time it's run, macro addruart in debug-macro.S looks for this
cookie, and if it's present, uses the UART address stored there. If not,
the static value TEGRA_DEBUG_UART_BASE is used, as was previous behaviour.
The static behaviour will thus be used when not booting using a zImage.

This work was inspired by work by Doug Anderson <dianders@chromium.org>;
see http://lkml.org/lkml/2011/9/26/284

. However, this patch relies on
the data passing describe above, rather than duplicating the UART
selection logic in debug-macro.S; the latest selection logic is more
complex due to the need to check reset/clock bits too.

Signed-off-by: default avatarStephen Warren <swarren@nvidia.com>
Tested-by: default avatarDoug Anderson <dianders@chromium.org>
Acked-by: default avatarDoug Anderson <dianders@chromium.org>
Signed-off-by: default avatarOlof Johansson <olof@lixom.net>
parent fe263989
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -33,6 +33,23 @@
#include "clock.h"
#include "fuse.h"

/*
 * Storage for debug-macro.S's state.
 *
 * This must be in .data not .bss so that it gets initialized each time the
 * kernel is loaded. The data is declared here rather than debug-macro.S so
 * that multiple inclusions of debug-macro.S point at the same data.
 */
#define TEGRA_DEBUG_UART_OFFSET (TEGRA_DEBUG_UART_BASE & 0xFFFF)
u32 tegra_uart_config[3] = {
	/* Debug UART initialization required */
	1,
	/* Debug UART physical address */
	(u32)(IO_APB_PHYS + TEGRA_DEBUG_UART_OFFSET),
	/* Debug UART virtual address */
	(u32)(IO_APB_VIRT + TEGRA_DEBUG_UART_OFFSET),
};

#ifdef CONFIG_OF
static const struct of_device_id tegra_dt_irq_match[] __initconst = {
	{ .compatible = "arm,cortex-a9-gic", .data = gic_of_init },
+77 −11
Original line number Diff line number Diff line
/*
 * arch/arm/mach-tegra/include/mach/debug-macro.S
 *
 * Copyright (C) 2010 Google, Inc.
 * 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
@@ -18,18 +24,78 @@
 *
 */

#include <linux/serial_reg.h>

#include <mach/io.h>
#include <mach/iomap.h>
#include <mach/irammap.h>

		.macro  addruart, rp, rv, tmp
        ldr     \rp, =IO_APB_PHYS       @ physical
        ldr     \rv, =IO_APB_VIRT        @ virtual
	orr	\rp, \rp, #(TEGRA_DEBUG_UART_BASE & 0xFF)
	orr	\rp, \rp, #(TEGRA_DEBUG_UART_BASE & 0xFF00)
	orr	\rv, \rv, #(TEGRA_DEBUG_UART_BASE & 0xFF)
	orr	\rv, \rv, #(TEGRA_DEBUG_UART_BASE & 0xFF00)
		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 intitialization?
		bne	100f			@ no; go load the addresses
		mov	\rv, #0			@ yes; record init is done
		str	\rv, [\tmp]
		mov	\rp, #TEGRA_IRAM_BASE	@ See if cookie is in IRAM
		ldr	\rv, [\rp, #TEGRA_IRAM_DEBUG_UART_OFFSET]
		movw	\rp, #TEGRA_IRAM_DEBUG_UART_COOKIE & 0xffff
		movt	\rp, #TEGRA_IRAM_DEBUG_UART_COOKIE >> 16
		cmp	\rv, \rp		@ Cookie present?
		bne	100f			@ No, use default UART
		mov	\rp, #TEGRA_IRAM_BASE	@ Load UART address from IRAM
		ldr	\rv, [\rp, #TEGRA_IRAM_DEBUG_UART_OFFSET + 4]
		str	\rv, [\tmp, #4]		@ Store in tegra_uart_phys
		sub	\rv, \rv, #IO_APB_PHYS	@ Calculate virt address
		add	\rv, \rv, #IO_APB_VIRT
		str	\rv, [\tmp, #8]		@ Store in tegra_uart_virt
		b	100f

		.align
99:		.word	.
		.word	tegra_uart_config
		.ltorg

100:		ldr	\rp, [\tmp, #4]		@ Load tegra_uart_phys
		ldr	\rv, [\tmp, #8]		@ Load tegra_uart_virt
		.endm

#define UART_SHIFT 2
#include <asm/hardware/debug-8250.S>

/*
 * Code below is swiped from <asm/hardware/debug-8250.S>, but add an extra
 * check to make sure that we aren't in the CONFIG_TEGRA_DEBUG_UART_NONE case.
 * We use the fact that all 5 valid UART addresses all have something in the
 * 2nd-to-lowest byte.
 */

		.macro	senduart, rd, rx
		tst	\rx, #0x0000ff00
		strneb	\rd, [\rx, #UART_TX << UART_SHIFT]
1001:
		.endm

		.macro	busyuart, rd, rx
		tst	\rx, #0x0000ff00
		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
		tst	\rx, #0x0000ff00
		beq	1002f
1001:		ldrb	\rd, [\rx, #UART_MSR << UART_SHIFT]
		tst	\rd, #UART_MSR_CTS
		beq	1001b
1002:
#endif
		.endm
+35 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
 */

#ifndef __MACH_TEGRA_IRAMMAP_H
#define __MACH_TEGRA_IRAMMAP_H

#include <asm/sizes.h>

/* The first 1K of IRAM is permanently reserved for the CPU reset handler */
#define TEGRA_IRAM_RESET_HANDLER_OFFSET	0
#define TEGRA_IRAM_RESET_HANDLER_SIZE	SZ_1K

/*
 * These locations are written to by uncompress.h, and read by debug-macro.S.
 * The first word holds the cookie value if the data is valid. The second
 * word holds the UART physical address.
 */
#define TEGRA_IRAM_DEBUG_UART_OFFSET	SZ_1K
#define TEGRA_IRAM_DEBUG_UART_SIZE	8
#define TEGRA_IRAM_DEBUG_UART_COOKIE	0x55415254

#endif
+14 −1
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@
 *
 * Copyright (C) 2010 Google, Inc.
 * Copyright (C) 2011 Google, Inc.
 * Copyright (C) 2011 NVIDIA CORPORATION. All Rights Reserved.
 * Copyright (C) 2011-2012 NVIDIA CORPORATION. All Rights Reserved.
 *
 * Author:
 *	Colin Cross <ccross@google.com>
@@ -30,6 +30,7 @@
#include <linux/serial_reg.h>

#include <mach/iomap.h>
#include <mach/irammap.h>

#define DEBUG_UART_SHIFT 2

@@ -49,6 +50,17 @@ static inline void flush(void)
{
}

static inline void save_uart_address(void)
{
	u32 *buf = (u32 *)(TEGRA_IRAM_BASE + TEGRA_IRAM_DEBUG_UART_OFFSET);

	if (uart) {
		buf[0] = TEGRA_IRAM_DEBUG_UART_COOKIE;
		buf[1] = (u32)uart;
	} else
		buf[0] = 0;
}

/*
 * Setup before decompression.  This is where we do UART selection for
 * earlyprintk and init the uart_base register.
@@ -125,6 +137,7 @@ static inline void arch_decomp_setup(void)
	}
	if (i == ARRAY_SIZE(uarts))
		uart = (volatile u8 *)TEGRA_DEBUG_UART_BASE;
	save_uart_address();
	if (uart == NULL)
		return;