]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/openrisc/cpu/cpu.c
mxc_ipuv3: fix memory alignment of framebuffer
[karo-tx-uboot.git] / arch / openrisc / cpu / cpu.c
1 /*
2  * (C) Copyright 2011, Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
3  * (C) Copyright 2011, Julius Baxter <julius@opencores.org>
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 #include <common.h>
25 #include <asm/system.h>
26 #include <asm/openrisc_exc.h>
27
28 static volatile int illegal_instruction;
29
30 static void illegal_instruction_handler(void)
31 {
32         ulong *epcr = (ulong *)mfspr(SPR_EPCR_BASE);
33
34         /* skip over the illegal instruction */
35         mtspr(SPR_EPCR_BASE, (ulong)(++epcr));
36         illegal_instruction = 1;
37 }
38
39 static void checkinstructions(void)
40 {
41         ulong ra = 1, rb = 1, rc;
42
43         exception_install_handler(EXC_ILLEGAL_INSTR,
44                                 illegal_instruction_handler);
45
46         illegal_instruction = 0;
47         asm volatile("l.mul %0,%1,%2" : "=r" (rc) : "r" (ra), "r" (rb));
48         printf("           Hardware multiplier: %s\n",
49                 illegal_instruction ? "no" : "yes");
50
51         illegal_instruction = 0;
52         asm volatile("l.div %0,%1,%2" : "=r" (rc) : "r" (ra), "r" (rb));
53         printf("           Hardware divider: %s\n",
54                 illegal_instruction ? "no" : "yes");
55
56         exception_free_handler(EXC_ILLEGAL_INSTR);
57 }
58
59 int checkcpu(void)
60 {
61         ulong upr = mfspr(SPR_UPR);
62         ulong vr = mfspr(SPR_VR);
63         ulong iccfgr = mfspr(SPR_ICCFGR);
64         ulong dccfgr = mfspr(SPR_DCCFGR);
65         ulong immucfgr = mfspr(SPR_IMMUCFGR);
66         ulong dmmucfgr = mfspr(SPR_DMMUCFGR);
67         ulong cpucfgr = mfspr(SPR_CPUCFGR);
68         uint ver = (vr & SPR_VR_VER) >> 24;
69         uint rev = vr & SPR_VR_REV;
70         uint block_size;
71         uint ways;
72         uint sets;
73
74         printf("CPU:   OpenRISC-%x00 (rev %d) @ %d MHz\n",
75                 ver, rev, (CONFIG_SYS_CLK_FREQ / 1000000));
76
77         if (upr & SPR_UPR_DCP) {
78                 block_size = (dccfgr & SPR_DCCFGR_CBS) ? 32 : 16;
79                 ways = 1 << (dccfgr & SPR_DCCFGR_NCW);
80                 printf("       D-Cache: %d bytes, %d bytes/line, %d way(s)\n",
81                        checkdcache(), block_size, ways);
82         } else {
83                 printf("       D-Cache: no\n");
84         }
85
86         if (upr & SPR_UPR_ICP) {
87                 block_size = (iccfgr & SPR_ICCFGR_CBS) ? 32 : 16;
88                 ways = 1 << (iccfgr & SPR_ICCFGR_NCW);
89                 printf("       I-Cache: %d bytes, %d bytes/line, %d way(s)\n",
90                        checkicache(), block_size, ways);
91         } else {
92                 printf("       I-Cache: no\n");
93         }
94
95         if (upr & SPR_UPR_DMP) {
96                 sets = 1 << ((dmmucfgr & SPR_DMMUCFGR_NTS) >> 2);
97                 ways = (dmmucfgr & SPR_DMMUCFGR_NTW) + 1;
98                 printf("       DMMU: %d sets, %d way(s)\n",
99                        sets, ways);
100         } else {
101                 printf("       DMMU: no\n");
102         }
103
104         if (upr & SPR_UPR_IMP) {
105                 sets = 1 << ((immucfgr & SPR_IMMUCFGR_NTS) >> 2);
106                 ways = (immucfgr & SPR_IMMUCFGR_NTW) + 1;
107                 printf("       IMMU: %d sets, %d way(s)\n",
108                        sets, ways);
109         } else {
110                 printf("       IMMU: no\n");
111         }
112
113         printf("       MAC unit: %s\n",
114                 (upr & SPR_UPR_MP) ? "yes" : "no");
115         printf("       Debug unit: %s\n",
116                 (upr & SPR_UPR_DUP) ? "yes" : "no");
117         printf("       Performance counters: %s\n",
118                 (upr & SPR_UPR_PCUP) ? "yes" : "no");
119         printf("       Power management: %s\n",
120                 (upr & SPR_UPR_PMP) ? "yes" : "no");
121         printf("       Interrupt controller: %s\n",
122                 (upr & SPR_UPR_PICP) ? "yes" : "no");
123         printf("       Timer: %s\n",
124                 (upr & SPR_UPR_TTP) ? "yes" : "no");
125         printf("       Custom unit(s): %s\n",
126                 (upr & SPR_UPR_CUP) ? "yes" : "no");
127
128         printf("       Supported instructions:\n");
129         printf("           ORBIS32: %s\n",
130                 (cpucfgr & SPR_CPUCFGR_OB32S) ? "yes" : "no");
131         printf("           ORBIS64: %s\n",
132                 (cpucfgr & SPR_CPUCFGR_OB64S) ? "yes" : "no");
133         printf("           ORFPX32: %s\n",
134                 (cpucfgr & SPR_CPUCFGR_OF32S) ? "yes" : "no");
135         printf("           ORFPX64: %s\n",
136                 (cpucfgr & SPR_CPUCFGR_OF64S) ? "yes" : "no");
137
138         checkinstructions();
139
140         return 0;
141 }
142
143 int cleanup_before_linux(void)
144 {
145         disable_interrupts();
146         return 0;
147 }
148
149 extern void __reset(void);
150
151 int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
152 {
153         disable_interrupts();
154         /* Code the jump to __reset here as the compiler is prone to
155            emitting a bad jump instruction if the function is in flash */
156         __asm__("l.movhi r1,hi(__reset);  \
157                  l.ori r1,r1,lo(__reset); \
158                  l.jr r1");
159         /* not reached, __reset does not return */
160         return 0;
161 }