xref: /rk3399_rockchip-uboot/drivers/serial/arm_dcc.c (revision e05412f5ec27a07df92efa5cad47acd1c7fbea08)
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