blob: c23ef50547279ee624682cd514233267f44c6942 [file] [log] [blame]
Stefan Roeseb79316f2005-08-15 12:31:23 +02001/*
2 * Copyright (C) 2005 Sandburst Corporation
3 *
Wolfgang Denk3765b3e2013-10-07 13:07:26 +02004 * SPDX-License-Identifier: GPL-2.0+
Stefan Roeseb79316f2005-08-15 12:31:23 +02005 */
6#include <config.h>
7#include <common.h>
8#include <command.h>
9#include <asm/processor.h>
10#include <asm/io.h>
11#include <spd_sdram.h>
12#include <i2c.h>
Stefan Roeseb79316f2005-08-15 12:31:23 +020013#include "sb_common.h"
14
Wolfgang Denkd87080b2006-03-31 18:32:53 +020015DECLARE_GLOBAL_DATA_PTR;
16
Stefan Roeseb79316f2005-08-15 12:31:23 +020017long int fixed_sdram (void);
18
19/*************************************************************************
20 * metrobox_get_master
21 *
Wolfgang Denk3d078ce2005-08-15 16:03:56 +020022 * PRI_N - active low signal. If the GPIO pin is low we are the master
Stefan Roeseb79316f2005-08-15 12:31:23 +020023 *
24 ************************************************************************/
25int sbcommon_get_master(void)
26{
27 ppc440_gpio_regs_t *gpio_regs;
28
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020029 gpio_regs = (ppc440_gpio_regs_t *)CONFIG_SYS_GPIO_BASE;
Stefan Roeseb79316f2005-08-15 12:31:23 +020030
31 if (gpio_regs->in & SBCOMMON_GPIO_PRI_N) {
32 return 0;
33 }
34 else {
35 return 1;
36 }
37}
38
39/*************************************************************************
40 * metrobox_secondary_present
41 *
42 * Figure out if secondary/slave board is present
43 *
44 ************************************************************************/
45int sbcommon_secondary_present(void)
46{
47 ppc440_gpio_regs_t *gpio_regs;
48
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020049 gpio_regs = (ppc440_gpio_regs_t *)CONFIG_SYS_GPIO_BASE;
Stefan Roeseb79316f2005-08-15 12:31:23 +020050
51 if (gpio_regs->in & SBCOMMON_GPIO_SEC_PRES)
52 return 0;
53 else
54 return 1;
55}
56
57/*************************************************************************
58 * sbcommon_get_serial_number
59 *
60 * Retrieve the board serial number via the mac address in eeprom
61 *
62 ************************************************************************/
63unsigned short sbcommon_get_serial_number(void)
64{
65 unsigned char buff[0x100];
66 unsigned short sernum;
67
68 /* Get the board serial number from eeprom */
Wolfgang Denk3d078ce2005-08-15 16:03:56 +020069 /* Initialize I2C */
Dirk Eibach880540d2013-04-25 02:40:01 +000070 i2c_set_bus_num(0);
Stefan Roeseb79316f2005-08-15 12:31:23 +020071
72 /* Read 256 bytes in EEPROM */
73 i2c_read (0x50, 0, 1, buff, 0x100);
74
75 memcpy(&sernum, &buff[0xF4], 2);
76 sernum /= 32;
77
78 return (sernum);
79}
80
81/*************************************************************************
82 * sbcommon_fans
83 *
Wolfgang Denk3d078ce2005-08-15 16:03:56 +020084 * Spin up fans 2 & 3 to get some air moving. OS will take care
Stefan Roeseb79316f2005-08-15 12:31:23 +020085 * of the rest. This is mostly a precaution...
86 *
87 * Assumes i2c bus 1 is ready.
88 *
89 ************************************************************************/
90void sbcommon_fans(void)
91{
92 /*
93 * Attempt to turn on 2 of the fans...
94 * Need to go through the bridge
95 */
Dirk Eibach880540d2013-04-25 02:40:01 +000096 i2c_set_bus_num(1);
Stefan Roeseb79316f2005-08-15 12:31:23 +020097 puts ("FANS: ");
98
99 /* select fan4 through the bridge */
Dirk Eibach880540d2013-04-25 02:40:01 +0000100 i2c_reg_write(0x73, /* addr */
101 0x00, /* reg */
102 0x08); /* val = bus 4 */
Stefan Roeseb79316f2005-08-15 12:31:23 +0200103
104 /* Turn on FAN 4 */
Dirk Eibach880540d2013-04-25 02:40:01 +0000105 i2c_reg_write(0x2e,
106 1,
107 0x80);
Stefan Roeseb79316f2005-08-15 12:31:23 +0200108
Dirk Eibach880540d2013-04-25 02:40:01 +0000109 i2c_reg_write(0x2e,
110 0,
111 0x19);
Stefan Roeseb79316f2005-08-15 12:31:23 +0200112
113 /* Deselect bus 4 on the bridge */
Dirk Eibach880540d2013-04-25 02:40:01 +0000114 i2c_reg_write(0x73,
115 0x00,
116 0x00);
Stefan Roeseb79316f2005-08-15 12:31:23 +0200117
118 /* select fan3 through the bridge */
Dirk Eibach880540d2013-04-25 02:40:01 +0000119 i2c_reg_write(0x73, /* addr */
120 0x00, /* reg */
121 0x04); /* val = bus 3 */
Stefan Roeseb79316f2005-08-15 12:31:23 +0200122
123 /* Turn on FAN 3 */
Dirk Eibach880540d2013-04-25 02:40:01 +0000124 i2c_reg_write(0x2e,
125 1,
126 0x80);
Stefan Roeseb79316f2005-08-15 12:31:23 +0200127
Dirk Eibach880540d2013-04-25 02:40:01 +0000128 i2c_reg_write(0x2e,
129 0,
130 0x19);
Stefan Roeseb79316f2005-08-15 12:31:23 +0200131
132 /* Deselect bus 3 on the bridge */
Dirk Eibach880540d2013-04-25 02:40:01 +0000133 i2c_reg_write(0x73,
134 0x00,
135 0x00);
Stefan Roeseb79316f2005-08-15 12:31:23 +0200136
137 /* select fan2 through the bridge */
Dirk Eibach880540d2013-04-25 02:40:01 +0000138 i2c_reg_write(0x73, /* addr */
139 0x00, /* reg */
140 0x02); /* val = bus 4 */
Stefan Roeseb79316f2005-08-15 12:31:23 +0200141
142 /* Turn on FAN 2 */
Dirk Eibach880540d2013-04-25 02:40:01 +0000143 i2c_reg_write(0x2e,
144 1,
145 0x80);
Stefan Roeseb79316f2005-08-15 12:31:23 +0200146
Dirk Eibach880540d2013-04-25 02:40:01 +0000147 i2c_reg_write(0x2e,
148 0,
149 0x19);
Stefan Roeseb79316f2005-08-15 12:31:23 +0200150
151 /* Deselect bus 2 on the bridge */
Dirk Eibach880540d2013-04-25 02:40:01 +0000152 i2c_reg_write(0x73,
153 0x00,
154 0x00);
Stefan Roeseb79316f2005-08-15 12:31:23 +0200155
156 /* select fan1 through the bridge */
Dirk Eibach880540d2013-04-25 02:40:01 +0000157 i2c_reg_write(0x73, /* addr */
158 0x00, /* reg */
159 0x01); /* val = bus 0 */
Stefan Roeseb79316f2005-08-15 12:31:23 +0200160
161 /* Turn on FAN 1 */
Dirk Eibach880540d2013-04-25 02:40:01 +0000162 i2c_reg_write(0x2e,
163 1,
164 0x80);
Stefan Roeseb79316f2005-08-15 12:31:23 +0200165
Dirk Eibach880540d2013-04-25 02:40:01 +0000166 i2c_reg_write(0x2e,
167 0,
168 0x19);
Stefan Roeseb79316f2005-08-15 12:31:23 +0200169
170 /* Deselect bus 1 on the bridge */
Dirk Eibach880540d2013-04-25 02:40:01 +0000171 i2c_reg_write(0x73,
172 0x00,
173 0x00);
Stefan Roeseb79316f2005-08-15 12:31:23 +0200174
175 puts ("on\n");
Dirk Eibach880540d2013-04-25 02:40:01 +0000176 i2c_set_bus_num(0);
Stefan Roeseb79316f2005-08-15 12:31:23 +0200177
178 return;
179
180}
181
182/*************************************************************************
183 * initdram
184 *
185 * Initialize sdram
186 *
187 ************************************************************************/
Becky Bruce9973e3c2008-06-09 16:03:40 -0500188phys_size_t initdram (int board_type)
Stefan Roeseb79316f2005-08-15 12:31:23 +0200189{
190 long dram_size = 0;
191
192#if defined(CONFIG_SPD_EEPROM)
Wolfgang Denkd87080b2006-03-31 18:32:53 +0200193 dram_size = spd_sdram ();
Stefan Roeseb79316f2005-08-15 12:31:23 +0200194#else
195 dram_size = fixed_sdram ();
196#endif
197 return dram_size;
198}
199
200
201/*************************************************************************
202 * testdram
203 *
204 *
205 ************************************************************************/
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200206#if defined(CONFIG_SYS_DRAM_TEST)
Stefan Roeseb79316f2005-08-15 12:31:23 +0200207int testdram (void)
208{
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200209 uint *pstart = (uint *) CONFIG_SYS_MEMTEST_START;
210 uint *pend = (uint *) CONFIG_SYS_MEMTEST_END;
Stefan Roeseb79316f2005-08-15 12:31:23 +0200211 uint *p;
212
213 printf("Testing SDRAM: ");
214 for (p = pstart; p < pend; p++)
215 *p = 0xaaaaaaaa;
216
217 for (p = pstart; p < pend; p++) {
218 if (*p != 0xaaaaaaaa) {
219 printf ("SDRAM test fails at: %08x\n", (uint) p);
220 return 1;
221 }
222 }
223
224 for (p = pstart; p < pend; p++)
225 *p = 0x55555555;
226
227 for (p = pstart; p < pend; p++) {
228 if (*p != 0x55555555) {
229 printf ("SDRAM test fails at: %08x\n", (uint) p);
230 return 1;
231 }
232 }
233
234 printf("OK\n");
235 return 0;
236}
237#endif
238
239#if !defined(CONFIG_SPD_EEPROM)
240/*************************************************************************
241 * fixed sdram init -- doesn't use serial presence detect.
242 *
Wolfgang Denk3d078ce2005-08-15 16:03:56 +0200243 * Assumes: 128 MB, non-ECC, non-registered
244 * PLB @ 133 MHz
Stefan Roeseb79316f2005-08-15 12:31:23 +0200245 *
246 ************************************************************************/
247long int fixed_sdram (void)
248{
249 uint reg;
250
251 /*--------------------------------------------------------------------
252 * Setup some default
253 *------------------------------------------------------------------*/
Stefan Roese95b602b2009-09-24 13:59:57 +0200254 mtsdram (SDRAM0_UABBA, 0x00000000); /* ubba=0 (default) */
255 mtsdram (SDRAM0_SLIO, 0x00000000); /* rdre=0 wrre=0 rarw=0 */
256 mtsdram (SDRAM0_DEVOPT, 0x00000000); /* dll=0 ds=0 (normal) */
257 mtsdram (SDRAM0_WDDCTR, 0x00000000); /* wrcp=0 dcd=0 */
258 mtsdram (SDRAM0_CLKTR, 0x40000000); /* clkp=1 (90 deg wr) dcdt=0 */
Stefan Roeseb79316f2005-08-15 12:31:23 +0200259
260 /*--------------------------------------------------------------------
261 * Setup for board-specific specific mem
262 *------------------------------------------------------------------*/
263 /*
264 * Following for CAS Latency = 2.5 @ 133 MHz PLB
265 */
Stefan Roese95b602b2009-09-24 13:59:57 +0200266 mtsdram (SDRAM0_B0CR, 0x000a4001); /* SDBA=0x000 128MB, Mode 3, enabled */
267 mtsdram (SDRAM0_TR0, 0x410a4012); /* WR=2 WD=1 CL=2.5 PA=3 CP=4 LD=2 */
Wolfgang Denk3d078ce2005-08-15 16:03:56 +0200268 /* RA=10 RD=3 */
Stefan Roese95b602b2009-09-24 13:59:57 +0200269 mtsdram (SDRAM0_TR1, 0x8080082f); /* SS=T2 SL=STAGE 3 CD=1 CT=0x02f */
270 mtsdram (SDRAM0_RTR, 0x08200000); /* Rate 15.625 ns @ 133 MHz PLB */
271 mtsdram (SDRAM0_CFG1, 0x00000000); /* Self-refresh exit, disable PM */
Wolfgang Denk3d078ce2005-08-15 16:03:56 +0200272 udelay (400); /* Delay 200 usecs (min) */
Stefan Roeseb79316f2005-08-15 12:31:23 +0200273
274 /*--------------------------------------------------------------------
275 * Enable the controller, then wait for DCEN to complete
276 *------------------------------------------------------------------*/
Stefan Roese95b602b2009-09-24 13:59:57 +0200277 mtsdram (SDRAM0_CFG0, 0x86000000); /* DCEN=1, PMUD=1, 64-bit */
Stefan Roeseb79316f2005-08-15 12:31:23 +0200278 for (;;) {
Stefan Roese95b602b2009-09-24 13:59:57 +0200279 mfsdram (SDRAM0_MCSTS, reg);
Stefan Roeseb79316f2005-08-15 12:31:23 +0200280 if (reg & 0x80000000)
281 break;
282 }
283
Wolfgang Denk3d078ce2005-08-15 16:03:56 +0200284 return (128 * 1024 * 1024); /* 128 MB */
Stefan Roeseb79316f2005-08-15 12:31:23 +0200285}
286#endif /* !defined(CONFIG_SPD_EEPROM) */
287
Stefan Roeseb79316f2005-08-15 12:31:23 +0200288/*************************************************************************
Stefan Roeseb79316f2005-08-15 12:31:23 +0200289 * board_get_enetaddr
290 *
291 * Get the ethernet MAC address for the management ethernet from the
292 * strap EEPROM. Note that is the BASE address for the range of
293 * external ethernet MACs on the board. The base + 31 is the actual
294 * mgmt mac address.
295 *
296 ************************************************************************/
Stefan Roeseb79316f2005-08-15 12:31:23 +0200297
Mike Frysingerd8d21e62009-02-16 18:03:14 -0500298void board_get_enetaddr(int macaddr_idx, uchar *enet)
Stefan Roeseb79316f2005-08-15 12:31:23 +0200299{
300 int i;
301 unsigned short tmp;
302 unsigned char buff[0x100], *cp;
303
304 if (0 == macaddr_idx) {
305
306 /* Initialize I2C */
Dirk Eibach880540d2013-04-25 02:40:01 +0000307 i2c_set_bus_num(0);
Stefan Roeseb79316f2005-08-15 12:31:23 +0200308
309 /* Read 256 bytes in EEPROM */
310 i2c_read (0x50, 0, 1, buff, 0x100);
311
312 cp = &buff[0xF0];
313
314 for (i = 0; i < 6; i++,cp++)
315 enet[i] = *cp;
316
317 memcpy(&tmp, &enet[4], 2);
318 tmp += 31;
319 memcpy(&enet[4], &tmp, 2);
320
Stefan Roeseb79316f2005-08-15 12:31:23 +0200321 } else {
322 enet[0] = 0x02;
323 enet[1] = 0x00;
324 enet[2] = 0x00;
325 enet[3] = 0x00;
326 enet[4] = 0x00;
327 if (1 == sbcommon_get_master() ) {
328 /* Master/Primary card */
329 enet[5] = 0x01;
330 } else {
331 /* Slave/Secondary card */
332 enet [5] = 0x02;
333 }
334 }
335
336 return;
337}
338
339#ifdef CONFIG_POST
340/*
341 * Returns 1 if keys pressed to start the power-on long-running tests
342 * Called from board_init_f().
343 */
344int post_hotkeys_pressed(void)
345{
346
347 return (ctrlc());
348}
349#endif