]>
Commit | Line | Data |
---|---|---|
4f572898 JCPV |
1 | /* |
2 | * Copyright (C) 2004-2007 ARM Limited. | |
3 | * Copyright (C) 2008 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> | |
4 | * | |
5b8031cc | 5 | * SPDX-License-Identifier: GPL-2.0 |
4f572898 JCPV |
6 | * |
7 | * As a special exception, if other files instantiate templates or use macros | |
8 | * or inline functions from this file, or you compile this file and link it | |
9 | * with other works to produce a work based on this file, this file does not | |
10 | * by itself cause the resulting work to be covered by the GNU General Public | |
11 | * License. However the source code for this file must still be made available | |
12 | * in accordance with section (3) of the GNU General Public License. | |
13 | ||
14 | * This exception does not invalidate any other reasons why a work based on | |
15 | * this file might be covered by the GNU General Public License. | |
16 | */ | |
17 | ||
18 | #include <common.h> | |
a168d3af | 19 | #include <serial.h> |
4f572898 | 20 | |
fd602c56 | 21 | #if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V7) |
4f572898 | 22 | /* |
fd602c56 | 23 | * ARMV6 & ARMV7 |
4f572898 | 24 | */ |
66e8f9da JCPV |
25 | #define DCC_RBIT (1 << 30) |
26 | #define DCC_WBIT (1 << 29) | |
4f572898 | 27 | |
66e8f9da JCPV |
28 | #define write_dcc(x) \ |
29 | __asm__ volatile ("mcr p14, 0, %0, c0, c5, 0\n" : : "r" (x)) | |
4f572898 | 30 | |
66e8f9da JCPV |
31 | #define read_dcc(x) \ |
32 | __asm__ volatile ("mrc p14, 0, %0, c0, c5, 0\n" : "=r" (x)) | |
4f572898 | 33 | |
66e8f9da JCPV |
34 | #define status_dcc(x) \ |
35 | __asm__ volatile ("mrc p14, 0, %0, c0, c1, 0\n" : "=r" (x)) | |
4f572898 | 36 | |
65a76d4f JCPV |
37 | #elif defined(CONFIG_CPU_XSCALE) |
38 | /* | |
39 | * XSCALE | |
40 | */ | |
41 | #define DCC_RBIT (1 << 31) | |
42 | #define DCC_WBIT (1 << 28) | |
43 | ||
44 | #define write_dcc(x) \ | |
45 | __asm__ volatile ("mcr p14, 0, %0, c8, c0, 0\n" : : "r" (x)) | |
46 | ||
47 | #define read_dcc(x) \ | |
48 | __asm__ volatile ("mrc p14, 0, %0, c9, c0, 0\n" : "=r" (x)) | |
49 | ||
50 | #define status_dcc(x) \ | |
51 | __asm__ volatile ("mrc p14, 0, %0, c14, c0, 0\n" : "=r" (x)) | |
52 | ||
e05412f5 SDPP |
53 | #elif defined(CONFIG_CPU_ARMV8) |
54 | /* | |
55 | * ARMV8 | |
56 | */ | |
57 | #define DCC_RBIT (1 << 30) | |
58 | #define DCC_WBIT (1 << 29) | |
59 | ||
60 | #define write_dcc(x) \ | |
61 | __asm__ volatile ("msr dbgdtrtx_el0, %0\n" : : "r" (x)) | |
62 | ||
63 | #define read_dcc(x) \ | |
64 | __asm__ volatile ("mrs %0, dbgdtrrx_el0\n" : "=r" (x)) | |
65 | ||
66 | #define status_dcc(x) \ | |
67 | __asm__ volatile ("mrs %0, mdccsr_el0\n" : "=r" (x)) | |
68 | ||
66e8f9da JCPV |
69 | #else |
70 | #define DCC_RBIT (1 << 0) | |
71 | #define DCC_WBIT (1 << 1) | |
4f572898 | 72 | |
66e8f9da JCPV |
73 | #define write_dcc(x) \ |
74 | __asm__ volatile ("mcr p14, 0, %0, c1, c0, 0\n" : : "r" (x)) | |
4f572898 | 75 | |
66e8f9da JCPV |
76 | #define read_dcc(x) \ |
77 | __asm__ volatile ("mrc p14, 0, %0, c1, c0, 0\n" : "=r" (x)) | |
4f572898 | 78 | |
66e8f9da JCPV |
79 | #define status_dcc(x) \ |
80 | __asm__ volatile ("mrc p14, 0, %0, c0, c0, 0\n" : "=r" (x)) | |
81 | ||
82 | #endif | |
4f572898 | 83 | |
66e8f9da JCPV |
84 | #define can_read_dcc(x) do { \ |
85 | status_dcc(x); \ | |
86 | x &= DCC_RBIT; \ | |
4f572898 JCPV |
87 | } while (0); |
88 | ||
66e8f9da JCPV |
89 | #define can_write_dcc(x) do { \ |
90 | status_dcc(x); \ | |
91 | x &= DCC_WBIT; \ | |
92 | x = (x == 0); \ | |
4f572898 JCPV |
93 | } while (0); |
94 | ||
95 | #define TIMEOUT_COUNT 0x4000000 | |
96 | ||
a168d3af | 97 | static int arm_dcc_init(void) |
4f572898 | 98 | { |
4f572898 JCPV |
99 | return 0; |
100 | } | |
101 | ||
a168d3af | 102 | static int arm_dcc_getc(void) |
4f572898 JCPV |
103 | { |
104 | int ch; | |
105 | register unsigned int reg; | |
106 | ||
66e8f9da JCPV |
107 | do { |
108 | can_read_dcc(reg); | |
109 | } while (!reg); | |
110 | read_dcc(ch); | |
4f572898 JCPV |
111 | |
112 | return ch; | |
113 | } | |
114 | ||
a168d3af | 115 | static void arm_dcc_putc(char ch) |
4f572898 JCPV |
116 | { |
117 | register unsigned int reg; | |
118 | unsigned int timeout_count = TIMEOUT_COUNT; | |
119 | ||
66e8f9da JCPV |
120 | while (--timeout_count) { |
121 | can_write_dcc(reg); | |
122 | if (reg) | |
123 | break; | |
4f572898 | 124 | } |
66e8f9da JCPV |
125 | if (timeout_count == 0) |
126 | return; | |
127 | else | |
128 | write_dcc(ch); | |
4f572898 JCPV |
129 | } |
130 | ||
a168d3af | 131 | static int arm_dcc_tstc(void) |
4f572898 JCPV |
132 | { |
133 | register unsigned int reg; | |
134 | ||
66e8f9da | 135 | can_read_dcc(reg); |
4f572898 JCPV |
136 | |
137 | return reg; | |
138 | } | |
139 | ||
a168d3af JT |
140 | static void arm_dcc_setbrg(void) |
141 | { | |
142 | } | |
143 | ||
144 | static struct serial_device arm_dcc_drv = { | |
145 | .name = "arm_dcc", | |
146 | .start = arm_dcc_init, | |
147 | .stop = NULL, | |
148 | .setbrg = arm_dcc_setbrg, | |
149 | .putc = arm_dcc_putc, | |
012a2c15 | 150 | .puts = default_serial_puts, |
a168d3af JT |
151 | .getc = arm_dcc_getc, |
152 | .tstc = arm_dcc_tstc, | |
153 | }; | |
154 | ||
155 | void arm_dcc_initialize(void) | |
156 | { | |
157 | serial_register(&arm_dcc_drv); | |
158 | } | |
159 | ||
e70fb539 MS |
160 | __weak struct serial_device *default_serial_console(void) |
161 | { | |
a168d3af | 162 | return &arm_dcc_drv; |
e70fb539 | 163 | } |