uboot/drivers/serial/arm_dcc.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2004-2007 ARM Limited.
   3 * Copyright (C) 2008 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
   4 *
   5 * This program is free software; you can redistribute it and/or
   6 * modify it under the terms of the GNU General Public License version 2
   7 * as published by the Free Software Foundation.
   8 *
   9 * This program is distributed in the hope that it will be useful,
  10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12 * GNU General Public License for more details.
  13 *
  14 * You should have received a copy of the GNU General Public License
  15 * along with this program; if not, write to the Free Software
  16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17 *
  18 * As a special exception, if other files instantiate templates or use macros
  19 * or inline functions from this file, or you compile this file and link it
  20 * with other works to produce a work based on this file, this file does not
  21 * by itself cause the resulting work to be covered by the GNU General Public
  22 * License. However the source code for this file must still be made available
  23 * in accordance with section (3) of the GNU General Public License.
  24
  25 * This exception does not invalidate any other reasons why a work based on
  26 * this file might be covered by the GNU General Public License.
  27 */
  28
  29#include <common.h>
  30#include <stdio_dev.h>
  31
  32#if defined(CONFIG_CPU_V6)
  33/*
  34 * ARMV6
  35 */
  36#define DCC_RBIT        (1 << 30)
  37#define DCC_WBIT        (1 << 29)
  38
  39#define write_dcc(x)    \
  40                __asm__ volatile ("mcr p14, 0, %0, c0, c5, 0\n" : : "r" (x))
  41
  42#define read_dcc(x)     \
  43                __asm__ volatile ("mrc p14, 0, %0, c0, c5, 0\n" : "=r" (x))
  44
  45#define status_dcc(x)   \
  46                __asm__ volatile ("mrc p14, 0, %0, c0, c1, 0\n" : "=r" (x))
  47
  48#elif defined(CONFIG_CPU_XSCALE)
  49/*
  50 * XSCALE
  51 */
  52#define DCC_RBIT        (1 << 31)
  53#define DCC_WBIT        (1 << 28)
  54
  55#define write_dcc(x)    \
  56                __asm__ volatile ("mcr p14, 0, %0, c8, c0, 0\n" : : "r" (x))
  57
  58#define read_dcc(x)     \
  59                __asm__ volatile ("mrc p14, 0, %0, c9, c0, 0\n" : "=r" (x))
  60
  61#define status_dcc(x)   \
  62                __asm__ volatile ("mrc p14, 0, %0, c14, c0, 0\n" : "=r" (x))
  63
  64#else
  65#define DCC_RBIT        (1 << 0)
  66#define DCC_WBIT        (1 << 1)
  67
  68#define write_dcc(x)    \
  69                __asm__ volatile ("mcr p14, 0, %0, c1, c0, 0\n" : : "r" (x))
  70
  71#define read_dcc(x)     \
  72                __asm__ volatile ("mrc p14, 0, %0, c1, c0, 0\n" : "=r" (x))
  73
  74#define status_dcc(x)   \
  75                __asm__ volatile ("mrc p14, 0, %0, c0, c0, 0\n" : "=r" (x))
  76
  77#endif
  78
  79#define can_read_dcc(x) do {    \
  80                status_dcc(x);  \
  81                x &= DCC_RBIT;  \
  82                } while (0);
  83
  84#define can_write_dcc(x) do {   \
  85                status_dcc(x);  \
  86                x &= DCC_WBIT;  \
  87                x = (x == 0);   \
  88                } while (0);
  89
  90#define TIMEOUT_COUNT 0x4000000
  91
  92#ifndef CONFIG_ARM_DCC_MULTI
  93#define arm_dcc_init serial_init
  94void serial_setbrg(void) {}
  95#define arm_dcc_getc serial_getc
  96#define arm_dcc_putc serial_putc
  97#define arm_dcc_puts serial_puts
  98#define arm_dcc_tstc serial_tstc
  99#endif
 100
 101int arm_dcc_init(void)
 102{
 103        return 0;
 104}
 105
 106int arm_dcc_getc(void)
 107{
 108        int ch;
 109        register unsigned int reg;
 110
 111        do {
 112                can_read_dcc(reg);
 113        } while (!reg);
 114        read_dcc(ch);
 115
 116        return ch;
 117}
 118
 119void arm_dcc_putc(char ch)
 120{
 121        register unsigned int reg;
 122        unsigned int timeout_count = TIMEOUT_COUNT;
 123
 124        while (--timeout_count) {
 125                can_write_dcc(reg);
 126                if (reg)
 127                        break;
 128        }
 129        if (timeout_count == 0)
 130                return;
 131        else
 132                write_dcc(ch);
 133}
 134
 135void arm_dcc_puts(const char *s)
 136{
 137        while (*s)
 138                arm_dcc_putc(*s++);
 139}
 140
 141int arm_dcc_tstc(void)
 142{
 143        register unsigned int reg;
 144
 145        can_read_dcc(reg);
 146
 147        return reg;
 148}
 149
 150#ifdef CONFIG_ARM_DCC_MULTI
 151static struct stdio_dev arm_dcc_dev;
 152
 153int drv_arm_dcc_init(void)
 154{
 155        int rc;
 156
 157        /* Device initialization */
 158        memset(&arm_dcc_dev, 0, sizeof(arm_dcc_dev));
 159
 160        strcpy(arm_dcc_dev.name, "dcc");
 161        arm_dcc_dev.ext = 0;    /* No extensions */
 162        arm_dcc_dev.flags = DEV_FLAGS_INPUT | DEV_FLAGS_OUTPUT;
 163        arm_dcc_dev.tstc = arm_dcc_tstc;        /* 'tstc' function */
 164        arm_dcc_dev.getc = arm_dcc_getc;        /* 'getc' function */
 165        arm_dcc_dev.putc = arm_dcc_putc;        /* 'putc' function */
 166        arm_dcc_dev.puts = arm_dcc_puts;        /* 'puts' function */
 167
 168        return stdio_register(&arm_dcc_dev);
 169}
 170#endif
 171