]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/powerpc/cpu/mpc5xx/cpu.c
Add GPL-2.0+ SPDX-License-Identifier to source files
[karo-tx-uboot.git] / arch / powerpc / cpu / mpc5xx / cpu.c
1 /*
2  * (C) Copyright 2003
3  * Martin Winistoerfer, martinwinistoerfer@gmx.ch.
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 /*
9  * File:                cpu.c
10  *
11  * Discription:         Some cpu specific function for watchdog,
12  *                      cpu version test, clock setting ...
13  *
14  */
15
16
17 #include <common.h>
18 #include <watchdog.h>
19 #include <command.h>
20 #include <mpc5xx.h>
21
22 DECLARE_GLOBAL_DATA_PTR;
23
24 #if (defined(CONFIG_MPC555))
25 #  define       ID_STR  "MPC555/556"
26
27 /*
28  * Check version of cpu with Processor Version Register (PVR)
29  */
30 static int check_cpu_version (long clock, uint pvr, uint immr)
31 {
32     char buf[32];
33         /* The highest 16 bits should be 0x0002 for a MPC555/556 */
34         if ((pvr >> 16) == 0x0002) {
35                 printf (" " ID_STR " Version %x", (pvr >> 16));
36                 printf (" at %s MHz:", strmhz (buf, clock));
37         } else {
38                 printf ("Not supported cpu version");
39                 return -1;
40         }
41         return 0;
42 }
43 #endif /* CONFIG_MPC555 */
44
45
46 /*
47  * Check version of mpc5xx
48  */
49 int checkcpu (void)
50 {
51         ulong clock = gd->cpu_clk;
52         uint immr = get_immr (0);       /* Return full IMMR contents */
53         uint pvr = get_pvr ();          /* Retrieve PVR register */
54
55         puts ("CPU:   ");
56
57         return check_cpu_version (clock, pvr, immr);
58 }
59
60 /*
61  * Called by macro WATCHDOG_RESET
62  */
63 #if defined(CONFIG_WATCHDOG)
64 void watchdog_reset (void)
65 {
66         int re_enable = disable_interrupts ();
67
68         reset_5xx_watchdog ((immap_t *) CONFIG_SYS_IMMR);
69         if (re_enable)
70                 enable_interrupts ();
71 }
72
73 /*
74  * Will clear software reset
75  */
76 void reset_5xx_watchdog (volatile immap_t * immr)
77 {
78         /* Use the MPC5xx Internal Watchdog */
79         immr->im_siu_conf.sc_swsr = 0x556c;     /* Prevent SW time-out */
80         immr->im_siu_conf.sc_swsr = 0xaa39;
81 }
82
83 #endif /* CONFIG_WATCHDOG */
84
85
86 /*
87  * Get timebase clock frequency
88  */
89 unsigned long get_tbclk (void)
90 {
91         volatile immap_t *immr = (volatile immap_t *) CONFIG_SYS_IMMR;
92         ulong oscclk, factor;
93
94         if (immr->im_clkrst.car_sccr & SCCR_TBS) {
95                 return (gd->cpu_clk / 16);
96         }
97
98         factor = (((CONFIG_SYS_PLPRCR) & PLPRCR_MF_MSK) >> PLPRCR_MF_SHIFT) + 1;
99
100         oscclk = gd->cpu_clk / factor;
101
102         if ((immr->im_clkrst.car_sccr & SCCR_RTSEL) == 0 || factor > 2) {
103                 return (oscclk / 4);
104         }
105         return (oscclk / 16);
106 }
107
108 void dcache_enable (void)
109 {
110         return;
111 }
112
113 void dcache_disable (void)
114 {
115         return;
116 }
117
118 int dcache_status (void)
119 {
120         return 0;       /* always off */
121 }
122
123 /*
124  * Reset board
125  */
126 int do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
127 {
128 #if defined(CONFIG_PATI)
129         volatile ulong *addr = (ulong *) CONFIG_SYS_RESET_ADDRESS;
130         *addr = 1;
131 #else
132         ulong addr;
133
134         /* Interrupts off, enable reset */
135         __asm__ volatile        ("  mtspr       81, %r0         \n\t"
136                                  "  mfmsr       %r3             \n\t"
137                                  "  rlwinm      %r31,%r3,0,25,23\n\t"
138                                  "  mtmsr       %r31            \n\t");
139         /*
140          * Trying to execute the next instruction at a non-existing address
141          * should cause a machine check, resulting in reset
142          */
143 #ifdef CONFIG_SYS_RESET_ADDRESS
144         addr = CONFIG_SYS_RESET_ADDRESS;
145 #else
146         /*
147          * note: when CONFIG_SYS_MONITOR_BASE points to a RAM address, CONFIG_SYS_MONITOR_BASE         * - sizeof (ulong) is usually a valid address. Better pick an address
148          * known to be invalid on your system and assign it to CONFIG_SYS_RESET_ADDRESS.
149          * "(ulong)-1" used to be a good choice for many systems...
150          */
151         addr = CONFIG_SYS_MONITOR_BASE - sizeof (ulong);
152 #endif
153         ((void (*) (void)) addr) ();
154 #endif  /* #if defined(CONFIG_PATI) */
155         return 1;
156 }