linux/arch/arm/mach-ns9xxx/include/mach/uncompress.h
<<
>>
Prefs
   1/*
   2 * arch/arm/mach-ns9xxx/include/mach/uncompress.h
   3 *
   4 * Copyright (C) 2006 by Digi International Inc.
   5 * All rights reserved.
   6 *
   7 * This program is free software; you can redistribute it and/or modify it
   8 * under the terms of the GNU General Public License version 2 as published by
   9 * the Free Software Foundation.
  10 */
  11#ifndef __ASM_ARCH_UNCOMPRESS_H
  12#define __ASM_ARCH_UNCOMPRESS_H
  13
  14#include <linux/io.h>
  15
  16#define __REG(x)        ((void __iomem __force *)(x))
  17
  18static void putc_dummy(char c, void __iomem *base)
  19{
  20        /* nothing */
  21}
  22
  23static int timeout;
  24
  25static void putc_ns9360(char c, void __iomem *base)
  26{
  27        do {
  28                if (timeout)
  29                        --timeout;
  30
  31                if (__raw_readl(base + 8) & (1 << 3)) {
  32                        __raw_writeb(c, base + 16);
  33                        timeout = 0x10000;
  34                        break;
  35                }
  36        } while (timeout);
  37}
  38
  39static void putc_a9m9750dev(char c, void __iomem *base)
  40{
  41        do {
  42                if (timeout)
  43                        --timeout;
  44
  45                if (__raw_readb(base + 5) & (1 << 5)) {
  46                        __raw_writeb(c, base);
  47                        timeout = 0x10000;
  48                        break;
  49                }
  50        } while (timeout);
  51
  52}
  53
  54static void putc_ns921x(char c, void __iomem *base)
  55{
  56        do {
  57                if (timeout)
  58                        --timeout;
  59
  60                if (!(__raw_readl(base) & (1 << 11))) {
  61                        __raw_writeb(c, base + 0x0028);
  62                        timeout = 0x10000;
  63                        break;
  64                }
  65        } while (timeout);
  66}
  67
  68#define MSCS __REG(0xA0900184)
  69
  70#define NS9360_UARTA    __REG(0x90200040)
  71#define NS9360_UARTB    __REG(0x90200000)
  72#define NS9360_UARTC    __REG(0x90300000)
  73#define NS9360_UARTD    __REG(0x90300040)
  74
  75#define NS9360_UART_ENABLED(base)                                       \
  76                (__raw_readl(NS9360_UARTA) & (1 << 31))
  77
  78#define A9M9750DEV_UARTA        __REG(0x40000000)
  79
  80#define NS921XSYS_CLOCK __REG(0xa090017c)
  81#define NS921X_UARTA    __REG(0x90010000)
  82#define NS921X_UARTB    __REG(0x90018000)
  83#define NS921X_UARTC    __REG(0x90020000)
  84#define NS921X_UARTD    __REG(0x90028000)
  85
  86#define NS921X_UART_ENABLED(base)                                       \
  87                (__raw_readl((base) + 0x1000) & (1 << 29))
  88
  89static void autodetect(void (**putc)(char, void __iomem *), void __iomem **base)
  90{
  91        timeout = 0x10000;
  92        if (((__raw_readl(MSCS) >> 16) & 0xfe) == 0x00) {
  93                /* ns9360 or ns9750 */
  94                if (NS9360_UART_ENABLED(NS9360_UARTA)) {
  95                        *putc = putc_ns9360;
  96                        *base = NS9360_UARTA;
  97                        return;
  98                } else if (NS9360_UART_ENABLED(NS9360_UARTB)) {
  99                        *putc = putc_ns9360;
 100                        *base = NS9360_UARTB;
 101                        return;
 102                } else if (NS9360_UART_ENABLED(NS9360_UARTC)) {
 103                        *putc = putc_ns9360;
 104                        *base = NS9360_UARTC;
 105                        return;
 106                } else if (NS9360_UART_ENABLED(NS9360_UARTD)) {
 107                        *putc = putc_ns9360;
 108                        *base = NS9360_UARTD;
 109                        return;
 110                } else if (__raw_readl(__REG(0xa09001f4)) == 0xfffff001) {
 111                        *putc = putc_a9m9750dev;
 112                        *base = A9M9750DEV_UARTA;
 113                        return;
 114                }
 115        } else if (((__raw_readl(MSCS) >> 16) & 0xfe) == 0x02) {
 116                /* ns921x */
 117                u32 clock = __raw_readl(NS921XSYS_CLOCK);
 118
 119                if ((clock & (1 << 1)) &&
 120                                NS921X_UART_ENABLED(NS921X_UARTA)) {
 121                        *putc = putc_ns921x;
 122                        *base = NS921X_UARTA;
 123                        return;
 124                } else if ((clock & (1 << 2)) &&
 125                                NS921X_UART_ENABLED(NS921X_UARTB)) {
 126                        *putc = putc_ns921x;
 127                        *base = NS921X_UARTB;
 128                        return;
 129                } else if ((clock & (1 << 3)) &&
 130                                NS921X_UART_ENABLED(NS921X_UARTC)) {
 131                        *putc = putc_ns921x;
 132                        *base = NS921X_UARTC;
 133                        return;
 134                } else if ((clock & (1 << 4)) &&
 135                                NS921X_UART_ENABLED(NS921X_UARTD)) {
 136                        *putc = putc_ns921x;
 137                        *base = NS921X_UARTD;
 138                        return;
 139                }
 140        }
 141
 142        *putc = putc_dummy;
 143}
 144
 145void (*myputc)(char, void __iomem *);
 146void __iomem *base;
 147
 148static void putc(char c)
 149{
 150        myputc(c, base);
 151}
 152
 153static void arch_decomp_setup(void)
 154{
 155        autodetect(&myputc, &base);
 156}
 157#define arch_decomp_wdog()
 158
 159static void flush(void)
 160{
 161        /* nothing */
 162}
 163
 164#endif /* ifndef __ASM_ARCH_UNCOMPRESS_H */
 165