14f572898SJean-Christophe PLAGNIOL-VILLARD /* 24f572898SJean-Christophe PLAGNIOL-VILLARD * Copyright (C) 2004-2007 ARM Limited. 34f572898SJean-Christophe PLAGNIOL-VILLARD * Copyright (C) 2008 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> 44f572898SJean-Christophe PLAGNIOL-VILLARD * 54f572898SJean-Christophe PLAGNIOL-VILLARD * This program is free software; you can redistribute it and/or 64f572898SJean-Christophe PLAGNIOL-VILLARD * modify it under the terms of the GNU General Public License version 2 74f572898SJean-Christophe PLAGNIOL-VILLARD * as published by the Free Software Foundation. 84f572898SJean-Christophe PLAGNIOL-VILLARD * 94f572898SJean-Christophe PLAGNIOL-VILLARD * This program is distributed in the hope that it will be useful, 104f572898SJean-Christophe PLAGNIOL-VILLARD * but WITHOUT ANY WARRANTY; without even the implied warranty of 114f572898SJean-Christophe PLAGNIOL-VILLARD * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 124f572898SJean-Christophe PLAGNIOL-VILLARD * GNU General Public License for more details. 134f572898SJean-Christophe PLAGNIOL-VILLARD * 144f572898SJean-Christophe PLAGNIOL-VILLARD * You should have received a copy of the GNU General Public License 154f572898SJean-Christophe PLAGNIOL-VILLARD * along with this program; if not, write to the Free Software 164f572898SJean-Christophe PLAGNIOL-VILLARD * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 174f572898SJean-Christophe PLAGNIOL-VILLARD * 184f572898SJean-Christophe PLAGNIOL-VILLARD * As a special exception, if other files instantiate templates or use macros 194f572898SJean-Christophe PLAGNIOL-VILLARD * or inline functions from this file, or you compile this file and link it 204f572898SJean-Christophe PLAGNIOL-VILLARD * with other works to produce a work based on this file, this file does not 214f572898SJean-Christophe PLAGNIOL-VILLARD * by itself cause the resulting work to be covered by the GNU General Public 224f572898SJean-Christophe PLAGNIOL-VILLARD * License. However the source code for this file must still be made available 234f572898SJean-Christophe PLAGNIOL-VILLARD * in accordance with section (3) of the GNU General Public License. 244f572898SJean-Christophe PLAGNIOL-VILLARD 254f572898SJean-Christophe PLAGNIOL-VILLARD * This exception does not invalidate any other reasons why a work based on 264f572898SJean-Christophe PLAGNIOL-VILLARD * this file might be covered by the GNU General Public License. 274f572898SJean-Christophe PLAGNIOL-VILLARD */ 284f572898SJean-Christophe PLAGNIOL-VILLARD 294f572898SJean-Christophe PLAGNIOL-VILLARD #include <common.h> 304f572898SJean-Christophe PLAGNIOL-VILLARD #include <devices.h> 314f572898SJean-Christophe PLAGNIOL-VILLARD 3266e8f9daSJean-Christophe PLAGNIOL-VILLARD #if defined(CONFIG_CPU_V6) 334f572898SJean-Christophe PLAGNIOL-VILLARD /* 3466e8f9daSJean-Christophe PLAGNIOL-VILLARD * ARMV6 354f572898SJean-Christophe PLAGNIOL-VILLARD */ 3666e8f9daSJean-Christophe PLAGNIOL-VILLARD #define DCC_RBIT (1 << 30) 3766e8f9daSJean-Christophe PLAGNIOL-VILLARD #define DCC_WBIT (1 << 29) 384f572898SJean-Christophe PLAGNIOL-VILLARD 3966e8f9daSJean-Christophe PLAGNIOL-VILLARD #define write_dcc(x) \ 404f572898SJean-Christophe PLAGNIOL-VILLARD __asm__ volatile ("mcr p14, 0, %0, c0, c5, 0\n" : : "r" (x)) 414f572898SJean-Christophe PLAGNIOL-VILLARD 4266e8f9daSJean-Christophe PLAGNIOL-VILLARD #define read_dcc(x) \ 434f572898SJean-Christophe PLAGNIOL-VILLARD __asm__ volatile ("mrc p14, 0, %0, c0, c5, 0\n" : "=r" (x)) 444f572898SJean-Christophe PLAGNIOL-VILLARD 4566e8f9daSJean-Christophe PLAGNIOL-VILLARD #define status_dcc(x) \ 464f572898SJean-Christophe PLAGNIOL-VILLARD __asm__ volatile ("mrc p14, 0, %0, c0, c1, 0\n" : "=r" (x)) 474f572898SJean-Christophe PLAGNIOL-VILLARD 48*65a76d4fSJean-Christophe PLAGNIOL-VILLARD #elif defined(CONFIG_CPU_XSCALE) 49*65a76d4fSJean-Christophe PLAGNIOL-VILLARD /* 50*65a76d4fSJean-Christophe PLAGNIOL-VILLARD * XSCALE 51*65a76d4fSJean-Christophe PLAGNIOL-VILLARD */ 52*65a76d4fSJean-Christophe PLAGNIOL-VILLARD #define DCC_RBIT (1 << 31) 53*65a76d4fSJean-Christophe PLAGNIOL-VILLARD #define DCC_WBIT (1 << 28) 54*65a76d4fSJean-Christophe PLAGNIOL-VILLARD 55*65a76d4fSJean-Christophe PLAGNIOL-VILLARD #define write_dcc(x) \ 56*65a76d4fSJean-Christophe PLAGNIOL-VILLARD __asm__ volatile ("mcr p14, 0, %0, c8, c0, 0\n" : : "r" (x)) 57*65a76d4fSJean-Christophe PLAGNIOL-VILLARD 58*65a76d4fSJean-Christophe PLAGNIOL-VILLARD #define read_dcc(x) \ 59*65a76d4fSJean-Christophe PLAGNIOL-VILLARD __asm__ volatile ("mrc p14, 0, %0, c9, c0, 0\n" : "=r" (x)) 60*65a76d4fSJean-Christophe PLAGNIOL-VILLARD 61*65a76d4fSJean-Christophe PLAGNIOL-VILLARD #define status_dcc(x) \ 62*65a76d4fSJean-Christophe PLAGNIOL-VILLARD __asm__ volatile ("mrc p14, 0, %0, c14, c0, 0\n" : "=r" (x)) 63*65a76d4fSJean-Christophe PLAGNIOL-VILLARD 6466e8f9daSJean-Christophe PLAGNIOL-VILLARD #else 6566e8f9daSJean-Christophe PLAGNIOL-VILLARD #define DCC_RBIT (1 << 0) 6666e8f9daSJean-Christophe PLAGNIOL-VILLARD #define DCC_WBIT (1 << 1) 6766e8f9daSJean-Christophe PLAGNIOL-VILLARD 6866e8f9daSJean-Christophe PLAGNIOL-VILLARD #define write_dcc(x) \ 6966e8f9daSJean-Christophe PLAGNIOL-VILLARD __asm__ volatile ("mcr p14, 0, %0, c1, c0, 0\n" : : "r" (x)) 7066e8f9daSJean-Christophe PLAGNIOL-VILLARD 7166e8f9daSJean-Christophe PLAGNIOL-VILLARD #define read_dcc(x) \ 7266e8f9daSJean-Christophe PLAGNIOL-VILLARD __asm__ volatile ("mrc p14, 0, %0, c1, c0, 0\n" : "=r" (x)) 7366e8f9daSJean-Christophe PLAGNIOL-VILLARD 7466e8f9daSJean-Christophe PLAGNIOL-VILLARD #define status_dcc(x) \ 7566e8f9daSJean-Christophe PLAGNIOL-VILLARD __asm__ volatile ("mrc p14, 0, %0, c0, c0, 0\n" : "=r" (x)) 7666e8f9daSJean-Christophe PLAGNIOL-VILLARD 7766e8f9daSJean-Christophe PLAGNIOL-VILLARD #endif 7866e8f9daSJean-Christophe PLAGNIOL-VILLARD 7966e8f9daSJean-Christophe PLAGNIOL-VILLARD #define can_read_dcc(x) do { \ 8066e8f9daSJean-Christophe PLAGNIOL-VILLARD status_dcc(x); \ 8166e8f9daSJean-Christophe PLAGNIOL-VILLARD x &= DCC_RBIT; \ 824f572898SJean-Christophe PLAGNIOL-VILLARD } while (0); 834f572898SJean-Christophe PLAGNIOL-VILLARD 8466e8f9daSJean-Christophe PLAGNIOL-VILLARD #define can_write_dcc(x) do { \ 8566e8f9daSJean-Christophe PLAGNIOL-VILLARD status_dcc(x); \ 8666e8f9daSJean-Christophe PLAGNIOL-VILLARD x &= DCC_WBIT; \ 874f572898SJean-Christophe PLAGNIOL-VILLARD x = (x == 0); \ 884f572898SJean-Christophe PLAGNIOL-VILLARD } while (0); 894f572898SJean-Christophe PLAGNIOL-VILLARD 904f572898SJean-Christophe PLAGNIOL-VILLARD #define TIMEOUT_COUNT 0x4000000 914f572898SJean-Christophe PLAGNIOL-VILLARD 924f572898SJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_ARM_DCC_MULTI 934f572898SJean-Christophe PLAGNIOL-VILLARD #define arm_dcc_init serial_init 944f572898SJean-Christophe PLAGNIOL-VILLARD void serial_setbrg(void) {} 954f572898SJean-Christophe PLAGNIOL-VILLARD #define arm_dcc_getc serial_getc 964f572898SJean-Christophe PLAGNIOL-VILLARD #define arm_dcc_putc serial_putc 974f572898SJean-Christophe PLAGNIOL-VILLARD #define arm_dcc_puts serial_puts 984f572898SJean-Christophe PLAGNIOL-VILLARD #define arm_dcc_tstc serial_tstc 994f572898SJean-Christophe PLAGNIOL-VILLARD #endif 1004f572898SJean-Christophe PLAGNIOL-VILLARD 1014f572898SJean-Christophe PLAGNIOL-VILLARD int arm_dcc_init(void) 1024f572898SJean-Christophe PLAGNIOL-VILLARD { 1034f572898SJean-Christophe PLAGNIOL-VILLARD return 0; 1044f572898SJean-Christophe PLAGNIOL-VILLARD } 1054f572898SJean-Christophe PLAGNIOL-VILLARD 1064f572898SJean-Christophe PLAGNIOL-VILLARD int arm_dcc_getc(void) 1074f572898SJean-Christophe PLAGNIOL-VILLARD { 1084f572898SJean-Christophe PLAGNIOL-VILLARD int ch; 1094f572898SJean-Christophe PLAGNIOL-VILLARD register unsigned int reg; 1104f572898SJean-Christophe PLAGNIOL-VILLARD 1114f572898SJean-Christophe PLAGNIOL-VILLARD do { 11266e8f9daSJean-Christophe PLAGNIOL-VILLARD can_read_dcc(reg); 1134f572898SJean-Christophe PLAGNIOL-VILLARD } while (!reg); 11466e8f9daSJean-Christophe PLAGNIOL-VILLARD read_dcc(ch); 1154f572898SJean-Christophe PLAGNIOL-VILLARD 1164f572898SJean-Christophe PLAGNIOL-VILLARD return ch; 1174f572898SJean-Christophe PLAGNIOL-VILLARD } 1184f572898SJean-Christophe PLAGNIOL-VILLARD 1194f572898SJean-Christophe PLAGNIOL-VILLARD void arm_dcc_putc(char ch) 1204f572898SJean-Christophe PLAGNIOL-VILLARD { 1214f572898SJean-Christophe PLAGNIOL-VILLARD register unsigned int reg; 1224f572898SJean-Christophe PLAGNIOL-VILLARD unsigned int timeout_count = TIMEOUT_COUNT; 1234f572898SJean-Christophe PLAGNIOL-VILLARD 1244f572898SJean-Christophe PLAGNIOL-VILLARD while (--timeout_count) { 12566e8f9daSJean-Christophe PLAGNIOL-VILLARD can_write_dcc(reg); 1264f572898SJean-Christophe PLAGNIOL-VILLARD if (reg) 1274f572898SJean-Christophe PLAGNIOL-VILLARD break; 1284f572898SJean-Christophe PLAGNIOL-VILLARD } 1294f572898SJean-Christophe PLAGNIOL-VILLARD if (timeout_count == 0) 1304f572898SJean-Christophe PLAGNIOL-VILLARD return; 1314f572898SJean-Christophe PLAGNIOL-VILLARD else 13266e8f9daSJean-Christophe PLAGNIOL-VILLARD write_dcc(ch); 1334f572898SJean-Christophe PLAGNIOL-VILLARD } 1344f572898SJean-Christophe PLAGNIOL-VILLARD 1354f572898SJean-Christophe PLAGNIOL-VILLARD void arm_dcc_puts(const char *s) 1364f572898SJean-Christophe PLAGNIOL-VILLARD { 1374f572898SJean-Christophe PLAGNIOL-VILLARD while (*s) 1384f572898SJean-Christophe PLAGNIOL-VILLARD arm_dcc_putc(*s++); 1394f572898SJean-Christophe PLAGNIOL-VILLARD } 1404f572898SJean-Christophe PLAGNIOL-VILLARD 1414f572898SJean-Christophe PLAGNIOL-VILLARD int arm_dcc_tstc(void) 1424f572898SJean-Christophe PLAGNIOL-VILLARD { 1434f572898SJean-Christophe PLAGNIOL-VILLARD register unsigned int reg; 1444f572898SJean-Christophe PLAGNIOL-VILLARD 14566e8f9daSJean-Christophe PLAGNIOL-VILLARD can_read_dcc(reg); 1464f572898SJean-Christophe PLAGNIOL-VILLARD 1474f572898SJean-Christophe PLAGNIOL-VILLARD return reg; 1484f572898SJean-Christophe PLAGNIOL-VILLARD } 1494f572898SJean-Christophe PLAGNIOL-VILLARD 1504f572898SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_ARM_DCC_MULTI 1514f572898SJean-Christophe PLAGNIOL-VILLARD static device_t arm_dcc_dev; 1524f572898SJean-Christophe PLAGNIOL-VILLARD 1534f572898SJean-Christophe PLAGNIOL-VILLARD int drv_arm_dcc_init(void) 1544f572898SJean-Christophe PLAGNIOL-VILLARD { 1554f572898SJean-Christophe PLAGNIOL-VILLARD int rc; 1564f572898SJean-Christophe PLAGNIOL-VILLARD 1574f572898SJean-Christophe PLAGNIOL-VILLARD /* Device initialization */ 1584f572898SJean-Christophe PLAGNIOL-VILLARD memset(&arm_dcc_dev, 0, sizeof(arm_dcc_dev)); 1594f572898SJean-Christophe PLAGNIOL-VILLARD 1604f572898SJean-Christophe PLAGNIOL-VILLARD strcpy(arm_dcc_dev.name, "dcc"); 1614f572898SJean-Christophe PLAGNIOL-VILLARD arm_dcc_dev.ext = 0; /* No extensions */ 1624f572898SJean-Christophe PLAGNIOL-VILLARD arm_dcc_dev.flags = DEV_FLAGS_INPUT | DEV_FLAGS_OUTPUT; 1634f572898SJean-Christophe PLAGNIOL-VILLARD arm_dcc_dev.tstc = arm_dcc_tstc; /* 'tstc' function */ 1644f572898SJean-Christophe PLAGNIOL-VILLARD arm_dcc_dev.getc = arm_dcc_getc; /* 'getc' function */ 1654f572898SJean-Christophe PLAGNIOL-VILLARD arm_dcc_dev.putc = arm_dcc_putc; /* 'putc' function */ 1664f572898SJean-Christophe PLAGNIOL-VILLARD arm_dcc_dev.puts = arm_dcc_puts; /* 'puts' function */ 1674f572898SJean-Christophe PLAGNIOL-VILLARD 16866e8f9daSJean-Christophe PLAGNIOL-VILLARD return device_register(&arm_dcc_dev); 1694f572898SJean-Christophe PLAGNIOL-VILLARD } 1704f572898SJean-Christophe PLAGNIOL-VILLARD #endif 171