board_f: Drop return value from initdram()
[oweals/u-boot.git] / board / keymile / km82xx / km82xx.c
1 /*
2  * (C) Copyright 2007 - 2008
3  * Heiko Schocher, DENX Software Engineering, hs@denx.de.
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 #include <common.h>
9 #include <mpc8260.h>
10 #include <ioports.h>
11 #include <malloc.h>
12 #include <asm/io.h>
13
14 #include <libfdt.h>
15 #include <i2c.h>
16 #include "../common/common.h"
17
18 DECLARE_GLOBAL_DATA_PTR;
19
20 static uchar ivm_content[CONFIG_SYS_IVM_EEPROM_MAX_LEN];
21
22 /*
23  * I/O Port configuration table
24  *
25  * if conf is 1, then that port pin will be configured at boot time
26  * according to the five values podr/pdir/ppar/psor/pdat for that entry
27  */
28 const iop_conf_t iop_conf_tab[4][32] = {
29
30         /* Port A */
31         {       /*            conf      ppar psor pdir podr pdat */
32                 { 0,             0,   0,   0,   0,   0 }, /* PA31            */
33                 { 0,             0,   0,   0,   0,   0 }, /* PA30            */
34                 { 0,             0,   0,   0,   0,   0 }, /* PA29            */
35                 { 0,             0,   0,   0,   0,   0 }, /* PA28            */
36                 { 0,             0,   0,   0,   0,   0 }, /* PA27            */
37                 { 0,             0,   0,   0,   0,   0 }, /* PA26            */
38                 { 0,             0,   0,   0,   0,   0 }, /* PA25            */
39                 { 0,             0,   0,   0,   0,   0 }, /* PA24            */
40                 { 0,             0,   0,   0,   0,   0 }, /* PA23            */
41                 { 0,             0,   0,   0,   0,   0 }, /* PA22            */
42                 { 0,             0,   0,   0,   0,   0 }, /* PA21            */
43                 { 0,             0,   0,   0,   0,   0 }, /* PA20            */
44                 { 0,             0,   0,   0,   0,   0 }, /* PA19            */
45                 { 0,             0,   0,   0,   0,   0 }, /* PA18            */
46                 { 0,             0,   0,   0,   0,   0 }, /* PA17            */
47                 { 0,             0,   0,   0,   0,   0 }, /* PA16            */
48                 { 0,             0,   0,   0,   0,   0 }, /* PA15            */
49                 { 0,             0,   0,   0,   0,   0 }, /* PA14            */
50                 { 0,             0,   0,   0,   0,   0 }, /* PA13            */
51                 { 0,             0,   0,   0,   0,   0 }, /* PA12            */
52                 { 0,             0,   0,   0,   0,   0 }, /* PA11            */
53                 { 0,             0,   0,   0,   0,   0 }, /* PA10            */
54                 { 1,             1,   0,   1,   0,   0 }, /* PA9 SMC2 TxD    */
55                 { 1,             1,   0,   0,   0,   0 }, /* PA8 SMC2 RxD    */
56                 { 0,             0,   0,   0,   0,   0 }, /* PA7             */
57                 { 0,             0,   0,   0,   0,   0 }, /* PA6             */
58                 { 0,             0,   0,   0,   0,   0 }, /* PA5             */
59                 { 0,             0,   0,   0,   0,   0 }, /* PA4             */
60                 { 0,             0,   0,   0,   0,   0 }, /* PA3             */
61                 { 0,             0,   0,   0,   0,   0 }, /* PA2             */
62                 { 0,             0,   0,   0,   0,   0 }, /* PA1             */
63                 { 0,             0,   0,   0,   0,   0 }  /* PA0             */
64         },
65
66         /* Port B */
67         {       /*            conf      ppar psor pdir podr pdat */
68                 { 0,             0,   0,   0,   0,   0 }, /* PB31            */
69                 { 0,             0,   0,   0,   0,   0 }, /* PB30            */
70                 { 0,             0,   0,   0,   0,   0 }, /* PB29            */
71                 { 0,             0,   0,   0,   0,   0 }, /* PB28            */
72                 { 0,             0,   0,   0,   0,   0 }, /* PB27            */
73                 { 0,             0,   0,   0,   0,   0 }, /* PB26            */
74                 { 0,             0,   0,   0,   0,   0 }, /* PB25            */
75                 { 0,             0,   0,   0,   0,   0 }, /* PB24            */
76                 { 0,             0,   0,   0,   0,   0 }, /* PB23            */
77                 { 0,             0,   0,   0,   0,   0 }, /* PB22            */
78                 { 0,             0,   0,   0,   0,   0 }, /* PB21            */
79                 { 0,             0,   0,   0,   0,   0 }, /* PB20            */
80                 { 0,             0,   0,   0,   0,   0 }, /* PB19            */
81                 { 0,             0,   0,   0,   0,   0 }, /* PB18            */
82                 { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
83                 { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
84                 { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
85                 { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
86                 { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
87                 { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
88                 { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
89                 { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
90                 { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
91                 { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
92                 { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
93                 { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
94                 { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
95                 { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
96                 { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
97                 { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
98                 { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
99                 { 0,             0,   0,   0,   0,   0 }  /* non-existent    */
100         },
101
102         /* Port C */
103         {       /*            conf      ppar psor pdir podr pdat */
104                 { 0,             0,   0,   0,   0,   0 }, /* PC31            */
105                 { 0,             0,   0,   0,   0,   0 }, /* PC30            */
106                 { 0,             0,   0,   0,   0,   0 }, /* PC29            */
107                 { 0,             0,   0,   0,   0,   0 }, /* PC28            */
108                 { 0,             0,   0,   0,   0,   0 }, /* PC27            */
109                 { 0,             0,   0,   0,   0,   0 }, /* PC26            */
110                 { 1,             1,   0,   0,   0,   0 }, /* PC25 RxClk      */
111                 { 1,             1,   0,   0,   0,   0 }, /* PC24 TxClk      */
112                 { 0,             0,   0,   0,   0,   0 }, /* PC23            */
113                 { 0,             0,   0,   0,   0,   0 }, /* PC22            */
114                 { 0,             0,   0,   0,   0,   0 }, /* PC21            */
115                 { 0,             0,   0,   0,   0,   0 }, /* PC20            */
116                 { 0,             0,   0,   0,   0,   0 }, /* PC19            */
117                 { 0,             0,   0,   0,   0,   0 }, /* PC18            */
118                 { 0,             0,   0,   0,   0,   0 }, /* PC17            */
119                 { 0,             0,   0,   0,   0,   0 }, /* PC16            */
120                 { 0,             0,   0,   0,   0,   0 }, /* PC15            */
121                 { 0,             0,   0,   0,   0,   0 }, /* PC14            */
122                 { 0,             0,   0,   0,   0,   0 }, /* PC13            */
123                 { 0,             0,   0,   0,   0,   0 }, /* PC12            */
124                 { 0,             0,   0,   0,   0,   0 }, /* PC11            */
125                 { 0,             0,   0,   0,   0,   0 }, /* PC10            */
126                 { 1,             1,   0,   0,   0,   0 }, /* PC9  SCC4: CTS  */
127                 { 1,             1,   0,   0,   0,   0 }, /* PC8  SCC4: CD   */
128                 { 0,             0,   0,   0,   0,   0 }, /* PC7             */
129                 { 0,             0,   0,   0,   0,   0 }, /* PC6             */
130                 { 0,             0,   0,   0,   0,   0 }, /* PC5             */
131                 { 0,             0,   0,   0,   0,   0 }, /* PC4             */
132                 { 0,             0,   0,   0,   0,   0 }, /* PC3             */
133                 { 0,             0,   0,   0,   0,   0 }, /* PC2             */
134                 { 0,             0,   0,   0,   0,   0 }, /* PC1             */
135                 { 0,             0,   0,   0,   0,   0 }, /* PC0             */
136         },
137
138         /* Port D */
139         {       /*            conf      ppar psor pdir podr pdat */
140                 { 0,             0,   0,   0,   0,   0 }, /* PD31            */
141                 { 0,             0,   0,   0,   0,   0 }, /* PD30            */
142                 { 0,             0,   0,   0,   0,   0 }, /* PD29            */
143                 { 0,             0,   0,   0,   0,   0 }, /* PD28            */
144                 { 0,             0,   0,   0,   0,   0 }, /* PD27            */
145                 { 0,             0,   0,   0,   0,   0 }, /* PD26            */
146                 { 0,             0,   0,   0,   0,   0 }, /* PD25            */
147                 { 0,             0,   0,   0,   0,   0 }, /* PD24            */
148                 { 0,             0,   0,   0,   0,   0 }, /* PD23            */
149                 { 1,             1,   0,   0,   0,   0 }, /* PD22 SCC4: RXD  */
150                 { 1,             1,   0,   1,   0,   0 }, /* PD21 SCC4: TXD  */
151                 { 1,             1,   0,   1,   0,   0 }, /* PD20 SCC4: RTS  */
152                 { 0,             0,   0,   0,   0,   0 }, /* PD19            */
153                 { 0,             0,   0,   0,   0,   0 }, /* PD18            */
154                 { 0,             0,   0,   0,   0,   0 }, /* PD17            */
155                 { 0,             0,   0,   0,   0,   0 }, /* PD16            */
156 #if defined(CONFIG_HARD_I2C)
157                 { 1,             1,   1,   0,   1,   0 }, /* PD15 I2C SDA    */
158                 { 1,             1,   1,   0,   1,   0 }, /* PD14 I2C SCL    */
159 #else
160                 { 1,             0,   0,   0,   1,   1 }, /* PD15            */
161                 { 1,             0,   0,   1,   1,   1 }, /* PD14            */
162 #endif
163                 { 0,             0,   0,   0,   0,   0 }, /* PD13            */
164                 { 0,             0,   0,   0,   0,   0 }, /* PD12            */
165                 { 0,             0,   0,   0,   0,   0 }, /* PD11            */
166                 { 0,             0,   0,   0,   0,   0 }, /* PD10            */
167                 { 0,             0,   0,   0,   0,   0 }, /* PD9             */
168                 { 0,             0,   0,   0,   0,   0 }, /* PD8             */
169                 { 0,             0,   0,   0,   0,   0 }, /* PD7             */
170                 { 0,             0,   0,   0,   0,   0 }, /* PD6             */
171                 { 0,             0,   0,   0,   0,   0 }, /* PD5             */
172                 { 0,             0,   0,   0,   0,   0 }, /* PD4             */
173                 { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
174                 { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
175                 { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
176                 { 0,             0,   0,   0,   0,   0 }  /* non-existent    */
177         }
178 };
179
180 /*
181  * Try SDRAM initialization with P/LSDMR=sdmr and ORx=orx
182  *
183  * This routine performs standard 8260 initialization sequence
184  * and calculates the available memory size. It may be called
185  * several times to try different SDRAM configurations on both
186  * 60x and local buses.
187  */
188 static long int try_init(memctl8260_t *memctl, ulong sdmr,
189                                   ulong orx, uchar *base)
190 {
191         uchar c = 0xff;
192         ulong maxsize, size;
193         int i;
194
195         /*
196          * We must be able to test a location outsize the maximum legal size
197          * to find out THAT we are outside; but this address still has to be
198          * mapped by the controller. That means, that the initial mapping has
199          * to be (at least) twice as large as the maximum expected size.
200          */
201         maxsize = (1 + (~orx | 0x7fff))/* / 2*/;
202
203         out_be32(&memctl->memc_or1, orx);
204
205         /*
206          * Quote from 8260 UM (10.4.2 SDRAM Power-On Initialization, 10-35):
207          *
208          * "At system reset, initialization software must set up the
209          *  programmable parameters in the memory controller banks registers
210          *  (ORx, BRx, P/LSDMR). After all memory parameters are configured,
211          *  system software should execute the following initialization sequence
212          *  for each SDRAM device.
213          *
214          *  1. Issue a PRECHARGE-ALL-BANKS command
215          *  2. Issue eight CBR REFRESH commands
216          *  3. Issue a MODE-SET command to initialize the mode register
217          *
218          *  The initial commands are executed by setting P/LSDMR[OP] and
219          *  accessing the SDRAM with a single-byte transaction."
220          *
221          * The appropriate BRx/ORx registers have already been set when we
222          * get here. The SDRAM can be accessed at the address
223          * CONFIG_SYS_SDRAM_BASE.
224          */
225
226         out_be32(&memctl->memc_psdmr, sdmr | PSDMR_OP_PREA);
227         out_8(base, c);
228
229         out_be32(&memctl->memc_psdmr, sdmr | PSDMR_OP_CBRR);
230         for (i = 0; i < 8; i++)
231                 out_8(base, c);
232
233         out_be32(&memctl->memc_psdmr, sdmr | PSDMR_OP_MRW);
234         /* setting MR on address lines */
235         out_8((uchar *)(base + CONFIG_SYS_MRS_OFFS), c);
236
237         out_be32(&memctl->memc_psdmr, sdmr | PSDMR_OP_NORM | PSDMR_RFEN);
238         out_8(base, c);
239
240         size = get_ram_size((long *)base, maxsize);
241         out_be32(&memctl->memc_or1, orx | ~(size - 1));
242
243         return size;
244 }
245
246 #ifdef CONFIG_SYS_SDRAM_LIST
247
248 /*
249  * If CONFIG_SYS_SDRAM_LIST is defined, we cycle through all SDRAM
250  * configurations therein (should be from high to lower) to find the
251  * one actually matching the current configuration.
252  * CONFIG_SYS_PSDMR and CONFIG_SYS_OR1 will contain the base values which are
253  * common among all possible configurations; values in CONFIG_SYS_SDRAM_LIST
254  * (defined as the initialization value for the array of struct sdram_conf_s)
255  * will then be ORed with such base values.
256  */
257
258 struct sdram_conf_s {
259         ulong size;
260         int or1;
261         int psdmr;
262 };
263
264 static struct sdram_conf_s sdram_conf[] = CONFIG_SYS_SDRAM_LIST;
265
266 static long probe_sdram(memctl8260_t *memctl)
267 {
268         int n = 0;
269         long psize = 0;
270
271         for (n = 0; n < ARRAY_SIZE(sdram_conf); psize = 0, n++) {
272                 psize = try_init(memctl,
273                         CONFIG_SYS_PSDMR | sdram_conf[n].psdmr,
274                         CONFIG_SYS_OR1 | sdram_conf[n].or1,
275                         (uchar *) CONFIG_SYS_SDRAM_BASE);
276                 debug("Probing %ld bytes returned %ld\n",
277                         sdram_conf[n].size, psize);
278                 if (psize == sdram_conf[n].size)
279                         break;
280         }
281         return psize;
282 }
283
284 #else /* CONFIG_SYS_SDRAM_LIST */
285
286 static long probe_sdram(memctl8260_t *memctl)
287 {
288         return try_init(memctl, CONFIG_SYS_PSDMR, CONFIG_SYS_OR1,
289                                         (uchar *) CONFIG_SYS_SDRAM_BASE);
290 }
291 #endif /* CONFIG_SYS_SDRAM_LIST */
292
293
294 int initdram(void)
295 {
296         immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
297         memctl8260_t *memctl = &immap->im_memctl;
298
299         long psize;
300
301         out_8(&memctl->memc_psrt, CONFIG_SYS_PSRT);
302         out_be16(&memctl->memc_mptpr, CONFIG_SYS_MPTPR);
303
304         /* 60x SDRAM setup:
305          */
306         psize = probe_sdram(memctl);
307
308         icache_enable();
309
310         gd->ram_size = psize;
311
312         return 0;
313 }
314
315 int checkboard(void)
316 {
317 #if defined(CONFIG_MGCOGE)
318         puts("Board: Keymile mgcoge");
319 #else
320         puts("Board: Keymile mgcoge3ne");
321 #endif
322         if (ethernet_present())
323                 puts(" with PIGGY.");
324         puts("\n");
325         return 0;
326 }
327
328 int last_stage_init(void)
329 {
330         struct bfticu_iomap *base =
331                 (struct bfticu_iomap *)CONFIG_SYS_FPGA_BASE;
332         u8 dip_switch;
333
334         dip_switch = in_8(&base->mswitch);
335         dip_switch &= BFTICU_DIPSWITCH_MASK;
336         /* dip switch 'full reset' or 'db erase' or 'Local mgmt IP' or any */
337         if (dip_switch != 0) {
338                 /* start bootloader */
339                 puts("DIP:   Enabled\n");
340                 setenv("actual_bank", "0");
341         }
342         set_km_env();
343         return 0;
344 }
345
346 #ifdef CONFIG_MGCOGE3NE
347 static void set_pin(int state, unsigned long mask, int port);
348
349 /*
350  * For mgcoge3ne boards, the mgcoge3un control is controlled from
351  * a GPIO line on the PPC CPU. If bobcatreset is set the line
352  * will toggle once what forces the mgocge3un part to restart
353  * immediately.
354  */
355 static void handle_mgcoge3un_reset(void)
356 {
357         char *bobcatreset = getenv("bobcatreset");
358         if (bobcatreset) {
359                 if (strcmp(bobcatreset, "true") == 0) {
360                         puts("Forcing bobcat reset\n");
361                         set_pin(0, 0x00000004, 3); /* clear PD29 (reset arm) */
362                         udelay(1000);
363                         set_pin(1, 0x00000004, 3);
364                 } else
365                         set_pin(1, 0x00000004, 3); /* don't reset arm */
366         }
367 }
368 #endif
369
370 int ethernet_present(void)
371 {
372         struct km_bec_fpga *base =
373                 (struct km_bec_fpga *)CONFIG_SYS_KMBEC_FPGA_BASE;
374
375         return in_8(&base->bprth) & PIGGY_PRESENT;
376 }
377
378 /*
379  * Early board initalization.
380  */
381 int board_early_init_r(void)
382 {
383         struct km_bec_fpga *base =
384                 (struct km_bec_fpga *)CONFIG_SYS_KMBEC_FPGA_BASE;
385
386         /* setup the UPIOx */
387         /* General Unit Reset disabled, Flash Bank enabled, UnitLed on */
388         out_8(&base->oprth, (WRG_RESET | H_OPORTS_14 | WRG_LED));
389         /* SCC4 enable, halfduplex, FCC1 powerdown */
390         out_8(&base->oprtl, (H_OPORTS_SCC4_ENA | H_OPORTS_SCC4_FD_ENA |
391                 H_OPORTS_FCC1_PW_DWN));
392
393 #ifdef CONFIG_MGCOGE3NE
394         handle_mgcoge3un_reset();
395 #endif
396         return 0;
397 }
398
399 int misc_init_r(void)
400 {
401         ivm_read_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN);
402         return 0;
403 }
404
405 int hush_init_var(void)
406 {
407         ivm_analyze_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN);
408         return 0;
409 }
410
411 #define SDA_MASK        0x00010000
412 #define SCL_MASK        0x00020000
413
414 static void set_pin(int state, unsigned long mask, int port)
415 {
416         ioport_t *iop = ioport_addr((immap_t *)CONFIG_SYS_IMMR, port);
417
418         if (state)
419                 setbits_be32(&iop->pdat, mask);
420         else
421                 clrbits_be32(&iop->pdat, mask);
422
423         setbits_be32(&iop->pdir, mask);
424 }
425
426 static int get_pin(unsigned long mask, int port)
427 {
428         ioport_t *iop = ioport_addr((immap_t *)CONFIG_SYS_IMMR, port);
429
430         clrbits_be32(&iop->pdir, mask);
431         return 0 != (in_be32(&iop->pdat) & mask);
432 }
433
434 void set_sda(int state)
435 {
436         set_pin(state, SDA_MASK, 3);
437 }
438
439 void set_scl(int state)
440 {
441         set_pin(state, SCL_MASK, 3);
442 }
443
444 int get_sda(void)
445 {
446         return get_pin(SDA_MASK, 3);
447 }
448
449 int get_scl(void)
450 {
451         return get_pin(SCL_MASK, 3);
452 }
453
454 int ft_board_setup(void *blob, bd_t *bd)
455 {
456         ft_cpu_setup(blob, bd);
457
458         return 0;
459 }
460
461 #if defined(CONFIG_MGCOGE3NE)
462 int get_testpin(void)
463 {
464         /* Testpin is Port C pin 29 - enable = low */
465         int testpin = !get_pin(0x00000004, 2);
466         return testpin;
467 }
468 #endif