linux/arch/arm/plat-samsung/include/plat/uncompress.h
<<
>>
Prefs
   1/* arch/arm/plat-samsung/include/plat/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
 143#ifdef CONFIG_S3C_BOOT_UART_FORCE_FIFO
 144static inline void arch_enable_uart_fifo(void)
 145{
 146        u32 fifocon = uart_rd(S3C2410_UFCON);
 147
 148        if (!(fifocon & S3C2410_UFCON_FIFOMODE)) {
 149                fifocon |= S3C2410_UFCON_RESETBOTH;
 150                uart_wr(S3C2410_UFCON, fifocon);
 151
 152                /* wait for fifo reset to complete */
 153                while (1) {
 154                        fifocon = uart_rd(S3C2410_UFCON);
 155                        if (!(fifocon & S3C2410_UFCON_RESETBOTH))
 156                                break;
 157                }
 158        }
 159}
 160#else
 161#define arch_enable_uart_fifo() do { } while(0)
 162#endif
 163
 164
 165static void
 166arch_decomp_setup(void)
 167{
 168        /* we may need to setup the uart(s) here if we are not running
 169         * on an BAST... the BAST will have left the uarts configured
 170         * after calling linux.
 171         */
 172
 173        arch_detect_cpu();
 174        arch_decomp_wdog_start();
 175
 176        /* Enable the UART FIFOs if they where not enabled and our
 177         * configuration says we should turn them on.
 178         */
 179
 180        arch_enable_uart_fifo();
 181}
 182
 183
 184#endif /* __ASM_PLAT_UNCOMPRESS_H */
 185