linux/arch/arm/plat-s3c/include/plat/uncompress.h
<<
>>
Prefs
   1/* linux/include/asm-arm/plat-s3c/uncompress.h
   2 *
   3 * Copyright 2003, 2007 Simtec Electronics
   4 *      http://armlinux.simtec.co.uk/
   5 *      Ben Dooks <ben@simtec.co.uk>
   6 *
   7 * S3C - uncompress code
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License version 2 as
  11 * published by the Free Software Foundation.
  12*/
  13
  14#ifndef __ASM_PLAT_UNCOMPRESS_H
  15#define __ASM_PLAT_UNCOMPRESS_H
  16
  17typedef unsigned int upf_t;     /* cannot include linux/serial_core.h */
  18
  19/* uart setup */
  20
  21static unsigned int fifo_mask;
  22static unsigned int fifo_max;
  23
  24/* forward declerations */
  25
  26static void arch_detect_cpu(void);
  27
  28/* defines for UART registers */
  29
  30#include <plat/regs-serial.h>
  31#include <plat/regs-watchdog.h>
  32
  33/* working in physical space... */
  34#undef S3C2410_WDOGREG
  35#define S3C2410_WDOGREG(x) ((S3C24XX_PA_WATCHDOG + (x)))
  36
  37/* how many bytes we allow into the FIFO at a time in FIFO mode */
  38#define FIFO_MAX         (14)
  39
  40#define uart_base S3C_PA_UART + (S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT)
  41
  42static __inline__ void
  43uart_wr(unsigned int reg, unsigned int val)
  44{
  45        volatile unsigned int *ptr;
  46
  47        ptr = (volatile unsigned int *)(reg + uart_base);
  48        *ptr = val;
  49}
  50
  51static __inline__ unsigned int
  52uart_rd(unsigned int reg)
  53{
  54        volatile unsigned int *ptr;
  55
  56        ptr = (volatile unsigned int *)(reg + uart_base);
  57        return *ptr;
  58}
  59
  60/* we can deal with the case the UARTs are being run
  61 * in FIFO mode, so that we don't hold up our execution
  62 * waiting for tx to happen...
  63*/
  64
  65static void putc(int ch)
  66{
  67        if (uart_rd(S3C2410_UFCON) & S3C2410_UFCON_FIFOMODE) {
  68                int level;
  69
  70                while (1) {
  71                        level = uart_rd(S3C2410_UFSTAT);
  72                        level &= fifo_mask;
  73
  74                        if (level < fifo_max)
  75                                break;
  76                }
  77
  78        } else {
  79                /* not using fifos */
  80
  81                while ((uart_rd(S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE) != S3C2410_UTRSTAT_TXE)
  82                        barrier();
  83        }
  84
  85        /* write byte to transmission register */
  86        uart_wr(S3C2410_UTXH, ch);
  87}
  88
  89static inline void flush(void)
  90{
  91}
  92
  93#define __raw_writel(d, ad)                     \
  94        do {                                                    \
  95                *((volatile unsigned int __force *)(ad)) = (d); \
  96        } while (0)
  97
  98/* CONFIG_S3C_BOOT_WATCHDOG
  99 *
 100 * Simple boot-time watchdog setup, to reboot the system if there is
 101 * any problem with the boot process
 102*/
 103
 104#ifdef CONFIG_S3C_BOOT_WATCHDOG
 105
 106#define WDOG_COUNT (0xff00)
 107
 108static inline void arch_decomp_wdog(void)
 109{
 110        __raw_writel(WDOG_COUNT, S3C2410_WTCNT);
 111}
 112
 113static void arch_decomp_wdog_start(void)
 114{
 115        __raw_writel(WDOG_COUNT, S3C2410_WTDAT);
 116        __raw_writel(WDOG_COUNT, S3C2410_WTCNT);
 117        __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x80), S3C2410_WTCON);
 118}
 119
 120#else
 121#define arch_decomp_wdog_start()
 122#define arch_decomp_wdog()
 123#endif
 124
 125#ifdef CONFIG_S3C_BOOT_ERROR_RESET
 126
 127static void arch_decomp_error(const char *x)
 128{
 129        putstr("\n\n");
 130        putstr(x);
 131        putstr("\n\n -- System resetting\n");
 132
 133        __raw_writel(0x4000, S3C2410_WTDAT);
 134        __raw_writel(0x4000, S3C2410_WTCNT);
 135        __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x40), S3C2410_WTCON);
 136
 137        while(1);
 138}
 139
 140#define arch_error arch_decomp_error
 141#endif
 142
 143static void error(char *err);
 144
 145#ifdef CONFIG_S3C_BOOT_UART_FORCE_FIFO
 146static inline void arch_enable_uart_fifo(void)
 147{
 148        u32 fifocon = uart_rd(S3C2410_UFCON);
 149
 150        if (!(fifocon & S3C2410_UFCON_FIFOMODE)) {
 151                fifocon |= S3C2410_UFCON_RESETBOTH;
 152                uart_wr(S3C2410_UFCON, fifocon);
 153
 154                /* wait for fifo reset to complete */
 155                while (1) {
 156                        fifocon = uart_rd(S3C2410_UFCON);
 157                        if (!(fifocon & S3C2410_UFCON_RESETBOTH))
 158                                break;
 159                }
 160        }
 161}
 162#else
 163#define arch_enable_uart_fifo() do { } while(0)
 164#endif
 165
 166
 167static void
 168arch_decomp_setup(void)
 169{
 170        /* we may need to setup the uart(s) here if we are not running
 171         * on an BAST... the BAST will have left the uarts configured
 172         * after calling linux.
 173         */
 174
 175        arch_detect_cpu();
 176        arch_decomp_wdog_start();
 177
 178        /* Enable the UART FIFOs if they where not enabled and our
 179         * configuration says we should turn them on.
 180         */
 181
 182        arch_enable_uart_fifo();
 183}
 184
 185
 186#endif /* __ASM_PLAT_UNCOMPRESS_H */
 187