uncompress.h 3.6 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/* linux/include/asm-arm/arch-s3c2410/uncompress.h
 *
 * (c) 2003 Simtec Electronics
 *    Ben Dooks <ben@simtec.co.uk>
 *
 * S3C2410 - uncompress code
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * Changelog:
 *  22-May-2003 BJD  Created
 *  08-Sep-2003 BJD  Moved to linux v2.6
 *  12-Mar-2004 BJD  Updated header protection
 *  12-Oct-2004 BJD  Take account of debug uart configuration
 *  15-Nov-2004 BJD  Fixed uart configuration
 *  22-Feb-2005 BJD  Added watchdog to uncompress
19
 *  04-Apr-2005 LCVR Added support to S3C2400 (no cpuid at GSTATUS1)
L
Linus Torvalds 已提交
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
*/

#ifndef __ASM_ARCH_UNCOMPRESS_H
#define __ASM_ARCH_UNCOMPRESS_H

#include <linux/config.h>

/* defines for UART registers */
#include "asm/arch/regs-serial.h"
#include "asm/arch/regs-gpio.h"
#include "asm/arch/regs-watchdog.h"

#include <asm/arch/map.h>

/* working in physical space... */
#undef S3C2410_GPIOREG
#undef S3C2410_WDOGREG

#define S3C2410_GPIOREG(x) ((S3C2410_PA_GPIO + (x)))
#define S3C2410_WDOGREG(x) ((S3C2410_PA_WATCHDOG + (x)))

/* how many bytes we allow into the FIFO at a time in FIFO mode */
#define FIFO_MAX	 (14)

#define uart_base S3C2410_PA_UART + (0x4000*CONFIG_S3C2410_LOWLEVEL_UART_PORT)

static __inline__ void
uart_wr(unsigned int reg, unsigned int val)
{
	volatile unsigned int *ptr;

	ptr = (volatile unsigned int *)(reg + uart_base);
	*ptr = val;
}

static __inline__ unsigned int
uart_rd(unsigned int reg)
{
	volatile unsigned int *ptr;

	ptr = (volatile unsigned int *)(reg + uart_base);
	return *ptr;
}


/* we can deal with the case the UARTs are being run
 * in FIFO mode, so that we don't hold up our execution
 * waiting for tx to happen...
*/

static void
putc(char ch)
{
73
	int cpuid = S3C2410_GSTATUS1_2410;
L
Linus Torvalds 已提交
74

75 76
#ifndef CONFIG_CPU_S3C2400
	cpuid = *((volatile unsigned int *)S3C2410_GSTATUS1);
L
Linus Torvalds 已提交
77
	cpuid &= S3C2410_GSTATUS1_IDMASK;
78
#endif
L
Linus Torvalds 已提交
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162

	if (ch == '\n')
		putc('\r');    /* expand newline to \r\n */

	if (uart_rd(S3C2410_UFCON) & S3C2410_UFCON_FIFOMODE) {
		int level;

		while (1) {
			level = uart_rd(S3C2410_UFSTAT);

			if (cpuid == S3C2410_GSTATUS1_2440) {
				level &= S3C2440_UFSTAT_TXMASK;
				level >>= S3C2440_UFSTAT_TXSHIFT;
			} else {
				level &= S3C2410_UFSTAT_TXMASK;
				level >>= S3C2410_UFSTAT_TXSHIFT;
			}

			if (level < FIFO_MAX)
				break;
		}

	} else {
		/* not using fifos */

		while ((uart_rd(S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE) != S3C2410_UTRSTAT_TXE);
	}

	/* write byte to transmission register */
	uart_wr(S3C2410_UTXH, ch);
}

static void
putstr(const char *ptr)
{
	for (; *ptr != '\0'; ptr++) {
		putc(*ptr);
	}
}

/* CONFIG_S3C2410_BOOT_WATCHDOG
 *
 * Simple boot-time watchdog setup, to reboot the system if there is
 * any problem with the boot process
*/

#ifdef CONFIG_S3C2410_BOOT_WATCHDOG

#define WDOG_COUNT (0xff00)

#define __raw_writel(d,ad) do { *((volatile unsigned int *)(ad)) = (d); } while(0)

static inline void arch_decomp_wdog(void)
{
	__raw_writel(WDOG_COUNT, S3C2410_WTCNT);
}

static void arch_decomp_wdog_start(void)
{
	__raw_writel(WDOG_COUNT, S3C2410_WTDAT);
	__raw_writel(WDOG_COUNT, S3C2410_WTCNT);
	__raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x40), S3C2410_WTCON);
}

#else
#define arch_decomp_wdog_start()
#define arch_decomp_wdog()
#endif

static void error(char *err);

static void
arch_decomp_setup(void)
{
	/* we may need to setup the uart(s) here if we are not running
	 * on an BAST... the BAST will have left the uarts configured
	 * after calling linux.
	 */

	arch_decomp_wdog_start();
}


#endif /* __ASM_ARCH_UNCOMPRESS_H */