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> 30a168d3afSJagannadha Sutradharudu Teki #include <serial.h> 314f572898SJean-Christophe PLAGNIOL-VILLARD 32fd602c56SAlexander Merkle #if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V7) 334f572898SJean-Christophe PLAGNIOL-VILLARD /* 34fd602c56SAlexander Merkle * ARMV6 & ARMV7 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 4865a76d4fSJean-Christophe PLAGNIOL-VILLARD #elif defined(CONFIG_CPU_XSCALE) 4965a76d4fSJean-Christophe PLAGNIOL-VILLARD /* 5065a76d4fSJean-Christophe PLAGNIOL-VILLARD * XSCALE 5165a76d4fSJean-Christophe PLAGNIOL-VILLARD */ 5265a76d4fSJean-Christophe PLAGNIOL-VILLARD #define DCC_RBIT (1 << 31) 5365a76d4fSJean-Christophe PLAGNIOL-VILLARD #define DCC_WBIT (1 << 28) 5465a76d4fSJean-Christophe PLAGNIOL-VILLARD 5565a76d4fSJean-Christophe PLAGNIOL-VILLARD #define write_dcc(x) \ 5665a76d4fSJean-Christophe PLAGNIOL-VILLARD __asm__ volatile ("mcr p14, 0, %0, c8, c0, 0\n" : : "r" (x)) 5765a76d4fSJean-Christophe PLAGNIOL-VILLARD 5865a76d4fSJean-Christophe PLAGNIOL-VILLARD #define read_dcc(x) \ 5965a76d4fSJean-Christophe PLAGNIOL-VILLARD __asm__ volatile ("mrc p14, 0, %0, c9, c0, 0\n" : "=r" (x)) 6065a76d4fSJean-Christophe PLAGNIOL-VILLARD 6165a76d4fSJean-Christophe PLAGNIOL-VILLARD #define status_dcc(x) \ 6265a76d4fSJean-Christophe PLAGNIOL-VILLARD __asm__ volatile ("mrc p14, 0, %0, c14, c0, 0\n" : "=r" (x)) 6365a76d4fSJean-Christophe PLAGNIOL-VILLARD 64*e05412f5SSiva Durga Prasad Paladugu #elif defined(CONFIG_CPU_ARMV8) 65*e05412f5SSiva Durga Prasad Paladugu /* 66*e05412f5SSiva Durga Prasad Paladugu * ARMV8 67*e05412f5SSiva Durga Prasad Paladugu */ 68*e05412f5SSiva Durga Prasad Paladugu #define DCC_RBIT (1 << 30) 69*e05412f5SSiva Durga Prasad Paladugu #define DCC_WBIT (1 << 29) 70*e05412f5SSiva Durga Prasad Paladugu 71*e05412f5SSiva Durga Prasad Paladugu #define write_dcc(x) \ 72*e05412f5SSiva Durga Prasad Paladugu __asm__ volatile ("msr dbgdtrtx_el0, %0\n" : : "r" (x)) 73*e05412f5SSiva Durga Prasad Paladugu 74*e05412f5SSiva Durga Prasad Paladugu #define read_dcc(x) \ 75*e05412f5SSiva Durga Prasad Paladugu __asm__ volatile ("mrs %0, dbgdtrrx_el0\n" : "=r" (x)) 76*e05412f5SSiva Durga Prasad Paladugu 77*e05412f5SSiva Durga Prasad Paladugu #define status_dcc(x) \ 78*e05412f5SSiva Durga Prasad Paladugu __asm__ volatile ("mrs %0, mdccsr_el0\n" : "=r" (x)) 79*e05412f5SSiva Durga Prasad Paladugu 8066e8f9daSJean-Christophe PLAGNIOL-VILLARD #else 8166e8f9daSJean-Christophe PLAGNIOL-VILLARD #define DCC_RBIT (1 << 0) 8266e8f9daSJean-Christophe PLAGNIOL-VILLARD #define DCC_WBIT (1 << 1) 8366e8f9daSJean-Christophe PLAGNIOL-VILLARD 8466e8f9daSJean-Christophe PLAGNIOL-VILLARD #define write_dcc(x) \ 8566e8f9daSJean-Christophe PLAGNIOL-VILLARD __asm__ volatile ("mcr p14, 0, %0, c1, c0, 0\n" : : "r" (x)) 8666e8f9daSJean-Christophe PLAGNIOL-VILLARD 8766e8f9daSJean-Christophe PLAGNIOL-VILLARD #define read_dcc(x) \ 8866e8f9daSJean-Christophe PLAGNIOL-VILLARD __asm__ volatile ("mrc p14, 0, %0, c1, c0, 0\n" : "=r" (x)) 8966e8f9daSJean-Christophe PLAGNIOL-VILLARD 9066e8f9daSJean-Christophe PLAGNIOL-VILLARD #define status_dcc(x) \ 9166e8f9daSJean-Christophe PLAGNIOL-VILLARD __asm__ volatile ("mrc p14, 0, %0, c0, c0, 0\n" : "=r" (x)) 9266e8f9daSJean-Christophe PLAGNIOL-VILLARD 9366e8f9daSJean-Christophe PLAGNIOL-VILLARD #endif 9466e8f9daSJean-Christophe PLAGNIOL-VILLARD 9566e8f9daSJean-Christophe PLAGNIOL-VILLARD #define can_read_dcc(x) do { \ 9666e8f9daSJean-Christophe PLAGNIOL-VILLARD status_dcc(x); \ 9766e8f9daSJean-Christophe PLAGNIOL-VILLARD x &= DCC_RBIT; \ 984f572898SJean-Christophe PLAGNIOL-VILLARD } while (0); 994f572898SJean-Christophe PLAGNIOL-VILLARD 10066e8f9daSJean-Christophe PLAGNIOL-VILLARD #define can_write_dcc(x) do { \ 10166e8f9daSJean-Christophe PLAGNIOL-VILLARD status_dcc(x); \ 10266e8f9daSJean-Christophe PLAGNIOL-VILLARD x &= DCC_WBIT; \ 1034f572898SJean-Christophe PLAGNIOL-VILLARD x = (x == 0); \ 1044f572898SJean-Christophe PLAGNIOL-VILLARD } while (0); 1054f572898SJean-Christophe PLAGNIOL-VILLARD 1064f572898SJean-Christophe PLAGNIOL-VILLARD #define TIMEOUT_COUNT 0x4000000 1074f572898SJean-Christophe PLAGNIOL-VILLARD 108a168d3afSJagannadha Sutradharudu Teki static int arm_dcc_init(void) 1094f572898SJean-Christophe PLAGNIOL-VILLARD { 1104f572898SJean-Christophe PLAGNIOL-VILLARD return 0; 1114f572898SJean-Christophe PLAGNIOL-VILLARD } 1124f572898SJean-Christophe PLAGNIOL-VILLARD 113a168d3afSJagannadha Sutradharudu Teki static int arm_dcc_getc(void) 1144f572898SJean-Christophe PLAGNIOL-VILLARD { 1154f572898SJean-Christophe PLAGNIOL-VILLARD int ch; 1164f572898SJean-Christophe PLAGNIOL-VILLARD register unsigned int reg; 1174f572898SJean-Christophe PLAGNIOL-VILLARD 1184f572898SJean-Christophe PLAGNIOL-VILLARD do { 11966e8f9daSJean-Christophe PLAGNIOL-VILLARD can_read_dcc(reg); 1204f572898SJean-Christophe PLAGNIOL-VILLARD } while (!reg); 12166e8f9daSJean-Christophe PLAGNIOL-VILLARD read_dcc(ch); 1224f572898SJean-Christophe PLAGNIOL-VILLARD 1234f572898SJean-Christophe PLAGNIOL-VILLARD return ch; 1244f572898SJean-Christophe PLAGNIOL-VILLARD } 1254f572898SJean-Christophe PLAGNIOL-VILLARD 126a168d3afSJagannadha Sutradharudu Teki static void arm_dcc_putc(char ch) 1274f572898SJean-Christophe PLAGNIOL-VILLARD { 1284f572898SJean-Christophe PLAGNIOL-VILLARD register unsigned int reg; 1294f572898SJean-Christophe PLAGNIOL-VILLARD unsigned int timeout_count = TIMEOUT_COUNT; 1304f572898SJean-Christophe PLAGNIOL-VILLARD 1314f572898SJean-Christophe PLAGNIOL-VILLARD while (--timeout_count) { 13266e8f9daSJean-Christophe PLAGNIOL-VILLARD can_write_dcc(reg); 1334f572898SJean-Christophe PLAGNIOL-VILLARD if (reg) 1344f572898SJean-Christophe PLAGNIOL-VILLARD break; 1354f572898SJean-Christophe PLAGNIOL-VILLARD } 1364f572898SJean-Christophe PLAGNIOL-VILLARD if (timeout_count == 0) 1374f572898SJean-Christophe PLAGNIOL-VILLARD return; 1384f572898SJean-Christophe PLAGNIOL-VILLARD else 13966e8f9daSJean-Christophe PLAGNIOL-VILLARD write_dcc(ch); 1404f572898SJean-Christophe PLAGNIOL-VILLARD } 1414f572898SJean-Christophe PLAGNIOL-VILLARD 142a168d3afSJagannadha Sutradharudu Teki static int arm_dcc_tstc(void) 1434f572898SJean-Christophe PLAGNIOL-VILLARD { 1444f572898SJean-Christophe PLAGNIOL-VILLARD register unsigned int reg; 1454f572898SJean-Christophe PLAGNIOL-VILLARD 14666e8f9daSJean-Christophe PLAGNIOL-VILLARD can_read_dcc(reg); 1474f572898SJean-Christophe PLAGNIOL-VILLARD 1484f572898SJean-Christophe PLAGNIOL-VILLARD return reg; 1494f572898SJean-Christophe PLAGNIOL-VILLARD } 1504f572898SJean-Christophe PLAGNIOL-VILLARD 151a168d3afSJagannadha Sutradharudu Teki static void arm_dcc_setbrg(void) 152a168d3afSJagannadha Sutradharudu Teki { 153a168d3afSJagannadha Sutradharudu Teki } 154a168d3afSJagannadha Sutradharudu Teki 155a168d3afSJagannadha Sutradharudu Teki static struct serial_device arm_dcc_drv = { 156a168d3afSJagannadha Sutradharudu Teki .name = "arm_dcc", 157a168d3afSJagannadha Sutradharudu Teki .start = arm_dcc_init, 158a168d3afSJagannadha Sutradharudu Teki .stop = NULL, 159a168d3afSJagannadha Sutradharudu Teki .setbrg = arm_dcc_setbrg, 160a168d3afSJagannadha Sutradharudu Teki .putc = arm_dcc_putc, 161012a2c15SAxel Lin .puts = default_serial_puts, 162a168d3afSJagannadha Sutradharudu Teki .getc = arm_dcc_getc, 163a168d3afSJagannadha Sutradharudu Teki .tstc = arm_dcc_tstc, 164a168d3afSJagannadha Sutradharudu Teki }; 165a168d3afSJagannadha Sutradharudu Teki 166a168d3afSJagannadha Sutradharudu Teki void arm_dcc_initialize(void) 167a168d3afSJagannadha Sutradharudu Teki { 168a168d3afSJagannadha Sutradharudu Teki serial_register(&arm_dcc_drv); 169a168d3afSJagannadha Sutradharudu Teki } 170a168d3afSJagannadha Sutradharudu Teki 171e70fb539SMichal Simek __weak struct serial_device *default_serial_console(void) 172e70fb539SMichal Simek { 173a168d3afSJagannadha Sutradharudu Teki return &arm_dcc_drv; 174e70fb539SMichal Simek } 175