4 * Copyright (C) 2007 OpenWrt.org
5 * Copyright (C) 2007 Gabor Juhos <juhosg@freemail.hu>
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
13 #include <linux/types.h>
14 #include <linux/autoconf.h>
15 #include <linux/kernel.h>
16 #include <linux/init.h>
17 #include <linux/string.h>
19 #include <asm/bootinfo.h>
20 #include <asm/addrspace.h>
21 #include <asm/byteorder.h>
23 #include <asm/mach-adm5120/adm5120_defs.h>
24 #include <asm/mach-adm5120/adm5120_switch.h>
25 #include <asm/mach-adm5120/adm5120_info.h>
26 #include <asm/mach-adm5120/myloader.h>
27 #include <asm/mach-adm5120/routerboot.h>
28 #include <asm/mach-adm5120/zynos.h>
30 extern char *prom_getenv(char *envname
);
34 struct adm5120_board adm5120_board
;
35 unsigned int adm5120_boot_loader
;
37 unsigned int adm5120_product_code
;
38 unsigned int adm5120_revision
;
39 unsigned int adm5120_package
;
40 unsigned int adm5120_nand_boot
;
41 unsigned long adm5120_speed
;
42 unsigned long adm5120_memsize
;
47 static char *boot_loader_names
[BOOT_LOADER_LAST
+1] = {
48 [BOOT_LOADER_UNKNOWN
] = "Unknown",
49 [BOOT_LOADER_CFE
] = "CFE",
50 [BOOT_LOADER_UBOOT
] = "U-Boot",
51 [BOOT_LOADER_MYLOADER
] = "MyLoader",
52 [BOOT_LOADER_ROUTERBOOT
]= "RouterBOOT",
53 [BOOT_LOADER_BOOTBASE
] = "Bootbase"
56 static struct adm5120_board __initdata adm5120_boards
[] = {
57 /* FIXME: some boards have invalid fields */
59 .name
= "Cellvision CAS-630/630W",
60 .mach_type
= MACH_ADM5120_CAS630
,
63 .flash0_size
= 4*1024*1024,
66 .name
= "Cellvision CAS-670/670W",
67 .mach_type
= MACH_ADM5120_CAS670
,
70 .flash0_size
= 4*1024*1024,
73 .name
= "Cellvision CAS-700/700W",
74 .mach_type
= MACH_ADM5120_CAS700
,
77 .flash0_size
= 4*1024*1024,
80 .name
= "Cellvision CAS-771/771W",
81 .mach_type
= MACH_ADM5120_CAS771
,
84 .flash0_size
= 4*1024*1024,
87 .name
= "Cellvision CAS-790",
88 .mach_type
= MACH_ADM5120_CAS790
,
91 .flash0_size
= 4*1024*1024,
94 .name
= "Cellvision CAS-861/861W",
95 .mach_type
= MACH_ADM5120_CAS861
,
98 .flash0_size
= 4*1024*1024,
101 .name
= "Cellvision NFS-101U/101WU",
102 .mach_type
= MACH_ADM5120_NFS101U
,
105 .flash0_size
= 4*1024*1024,
108 .name
= "Cellvision NFS-202U/202WU",
109 .mach_type
= MACH_ADM5120_NFS202U
,
112 .flash0_size
= 4*1024*1024,
115 .name
= "Compex NetPassage 27G",
116 .mach_type
= MACH_ADM5120_NP27G
,
119 .flash0_size
= 4*1024*1024,
122 .name
= "Compex NetPassage 28G",
123 .mach_type
= MACH_ADM5120_NP28G
,
126 .flash0_size
= 4*1024*1024,
129 .name
= "Compex NP28G (HotSpot)",
130 .mach_type
= MACH_ADM5120_NP28GHS
,
133 .flash0_size
= 4*1024*1024,
136 .name
= "Compex WP54AG",
137 .mach_type
= MACH_ADM5120_WP54AG
,
140 .flash0_size
= 4*1024*1024,
143 .name
= "Compex WP54G",
144 .mach_type
= MACH_ADM5120_WP54G
,
147 .flash0_size
= 4*1024*1024,
150 .name
= "Compex WP54G-WRT",
151 .mach_type
= MACH_ADM5120_WP54G_WRT
,
154 .flash0_size
= 4*1024*1024,
157 .name
= "Compex WP54G v1C",
158 .mach_type
= MACH_ADM5120_WP54Gv1C
,
161 .flash0_size
= 2*1024*1024,
164 .name
= "Compex WPP54AG",
165 .mach_type
= MACH_ADM5120_WPP54AG
,
168 .flash0_size
= 4*1024*1024,
171 .name
= "Compex WPP54G",
172 .mach_type
= MACH_ADM5120_WPP54G
,
175 .flash0_size
= 4*1024*1024,
178 .name
= "Edimax BR-6104K",
179 .mach_type
= MACH_ADM5120_BR6104K
,
182 .flash0_size
= 2*1024*1024,
185 .name
= "Infineon EASY 5120",
186 .mach_type
= MACH_ADM5120_EASY5120
,
189 .flash0_size
= 2*1024*1024,
192 .name
= "Infineon EASY 5120-RT",
193 .mach_type
= MACH_ADM5120_EASY5120RT
,
196 .flash0_size
= 2*1024*1024,
199 .name
= "Infineon EASY 5120P-ATA",
200 .mach_type
= MACH_ADM5120_EASY5120PATA
,
203 .flash0_size
= 2*1024*1024,
206 .name
= "Infineon EASY 83000",
207 .mach_type
= MACH_ADM5120_EASY83000
,
210 .flash0_size
= 4*1024*1024,
213 .name
= "RouterBOARD 111",
214 .mach_type
= MACH_ADM5120_RB_111
,
217 .flash0_size
= 128*1024,
220 .name
= "RouterBOARD 112",
221 .mach_type
= MACH_ADM5120_RB_112
,
224 .flash0_size
= 128*1024,
227 .name
= "RouterBOARD 133",
228 .mach_type
= MACH_ADM5120_RB_133
,
231 .flash0_size
= 128*1024,
234 .name
= "RouterBOARD 133C",
235 .mach_type
= MACH_ADM5120_RB_133C
,
238 .flash0_size
= 128*1024,
241 .name
= "RouterBOARD 150",
242 .mach_type
= MACH_ADM5120_RB_150
,
245 .flash0_size
= 128*1024,
248 .name
= "RouterBOARD 153",
249 .mach_type
= MACH_ADM5120_RB_153
,
252 .flash0_size
= 128*1024,
255 .name
= "ZyXEL ES-2024A",
256 .mach_type
= MACH_ADM5120_ES2024A
,
259 .flash0_size
= 4*1024*1024,
262 .name
= "ZyXEL ES-2024PWR",
263 .mach_type
= MACH_ADM5120_ES2024PWR
,
266 .flash0_size
= 4*1024*1024,
269 .name
= "ZyXEL ES-2108",
270 .mach_type
= MACH_ADM5120_ES2108
,
273 .flash0_size
= 4*1024*1024,
276 .name
= "ZyXEL ES-2108-F",
277 .mach_type
= MACH_ADM5120_ES2108F
,
280 .flash0_size
= 4*1024*1024,
283 .name
= "ZyXEL ES-2108-G",
284 .mach_type
= MACH_ADM5120_ES2108G
,
287 .flash0_size
= 4*1024*1024,
290 .name
= "ZyXEL ES-2108-LC",
291 .mach_type
= MACH_ADM5120_ES2108LC
,
294 .flash0_size
= 4*1024*1024,
297 .name
= "ZyXEL ES-2108-PWR",
298 .mach_type
= MACH_ADM5120_ES2108PWR
,
301 .flash0_size
= 4*1024*1024,
304 .name
= "ZyXEL HomeSafe 100/100W",
305 .mach_type
= MACH_ADM5120_HS100
,
308 .flash0_size
= 4*1024*1024,
311 .name
= "ZyXEL Prestige 334",
312 .mach_type
= MACH_ADM5120_P334
,
315 .flash0_size
= 2*1024*1024,
318 .name
= "ZyXEL Prestige 334U",
319 .mach_type
= MACH_ADM5120_P334U
,
322 .flash0_size
= 4*1024*1024,
325 .name
= "ZyXEL Prestige 334W",
326 .mach_type
= MACH_ADM5120_P334W
,
329 .flash0_size
= 2*1024*1024,
332 .name
= "ZyXEL Prestige 334WH",
333 .mach_type
= MACH_ADM5120_P334WH
,
336 .flash0_size
= 4*1024*1024,
339 .name
= "ZyXEL Prestige 334WHD",
340 .mach_type
= MACH_ADM5120_P334WHD
,
343 .flash0_size
= 4*1024*1024,
346 .name
= "ZyXEL Prestige 334WT",
347 .mach_type
= MACH_ADM5120_P334WT
,
350 .flash0_size
= 4*1024*1024,
353 .name
= "ZyXEL Prestige 335/335WT",
354 .mach_type
= MACH_ADM5120_P335
,
357 .flash0_size
= 4*1024*1024,
360 .name
= "ZyXEL Prestige 335Plus",
361 .mach_type
= MACH_ADM5120_P335PLUS
,
364 .flash0_size
= 4*1024*1024,
367 .name
= "ZyXEL Prestige 335U",
368 .mach_type
= MACH_ADM5120_P335U
,
371 .flash0_size
= 4*1024*1024,
374 .name
= "Unknown ADM5120 board",
375 .mach_type
= MACH_ADM5120_UNKNOWN
,
378 .flash0_size
= 4*1024*1024,
382 #define DUMMY_BOARD() {.mach_type = MACH_ADM5120_UNKNOWN}
389 unsigned long mach_type
;
393 #define MYLO_BOARD(v,d,sv,sd,mt) { .vid = (v), .did = (d), .svid = (sv), \
394 .sdid = (sd), .mach_type = (mt) }
396 #define COMPEX_BOARD(d,mt) MYLO_BOARD(VENID_COMPEX,(d),VENID_COMPEX,(d),(mt))
398 static struct mylo_board mylo_boards
[] __initdata
= {
399 COMPEX_BOARD(DEVID_COMPEX_NP27G
, MACH_ADM5120_NP27G
),
400 COMPEX_BOARD(DEVID_COMPEX_NP28G
, MACH_ADM5120_NP28G
),
401 COMPEX_BOARD(DEVID_COMPEX_NP28GHS
, MACH_ADM5120_NP28GHS
),
402 COMPEX_BOARD(DEVID_COMPEX_WP54G
, MACH_ADM5120_WP54G
),
403 COMPEX_BOARD(DEVID_COMPEX_WP54Gv1C
, MACH_ADM5120_WP54Gv1C
),
404 COMPEX_BOARD(DEVID_COMPEX_WP54AG
, MACH_ADM5120_WP54AG
),
405 COMPEX_BOARD(DEVID_COMPEX_WPP54G
, MACH_ADM5120_WPP54G
),
406 COMPEX_BOARD(DEVID_COMPEX_WPP54AG
, MACH_ADM5120_WPP54AG
),
410 #define ROUTERBOARD_NAME_LEN 16
413 unsigned long mach_type
;
414 char name
[ROUTERBOARD_NAME_LEN
];
417 #define ROUTERBOARD(n, mt) { .name = (n), .mach_type = (mt) }
418 static struct routerboard routerboards
[] __initdata
= {
419 ROUTERBOARD("111", MACH_ADM5120_RB_111
),
420 ROUTERBOARD("112", MACH_ADM5120_RB_112
),
421 ROUTERBOARD("133", MACH_ADM5120_RB_133
),
422 ROUTERBOARD("133C", MACH_ADM5120_RB_133C
),
423 ROUTERBOARD("miniROUTER", MACH_ADM5120_RB_150
),
424 ROUTERBOARD("153", MACH_ADM5120_RB_150
),
429 unsigned long mach_type
;
430 unsigned int vendor_id
;
434 #define ZYNOS_BOARD(vi, bi, mt) { .vendor_id = (vi), .board_id = (bi), \
437 #define ZYXEL_BOARD(bi, mt) ZYNOS_BOARD(ZYNOS_VENDOR_ID_ZYXEL, bi, mt)
438 #define DLINK_BOARD(bi, mt) ZYNOS_BOARD(ZYNOS_VENDOR_ID_DLINK, bi, mt)
439 #define LUCENT_BOARD(bi, mt) ZYNOS_BOARD(ZYNOS_VENDOR_ID_LUCENT, bi, mt)
441 static struct zynos_board zynos_boards
[] __initdata
= {
442 ZYXEL_BOARD(ZYNOS_BOARD_HS100
, MACH_ADM5120_HS100
),
443 ZYXEL_BOARD(ZYNOS_BOARD_P334
, MACH_ADM5120_P334
),
444 ZYXEL_BOARD(ZYNOS_BOARD_P334U
, MACH_ADM5120_P334U
),
445 ZYXEL_BOARD(ZYNOS_BOARD_P334W
, MACH_ADM5120_P334W
),
446 ZYXEL_BOARD(ZYNOS_BOARD_P334WH
, MACH_ADM5120_P334WH
),
447 ZYXEL_BOARD(ZYNOS_BOARD_P334WHD
, MACH_ADM5120_P334WHD
),
448 ZYXEL_BOARD(ZYNOS_BOARD_P334WT
, MACH_ADM5120_P334WT
),
449 ZYXEL_BOARD(ZYNOS_BOARD_P335
, MACH_ADM5120_P335
),
450 ZYXEL_BOARD(ZYNOS_BOARD_P335PLUS
, MACH_ADM5120_P335PLUS
),
451 ZYXEL_BOARD(ZYNOS_BOARD_P335U
, MACH_ADM5120_P335U
),
455 struct common_board
{
457 unsigned long mach_type
;
460 #define DEFBOARD(n, mt) { .name = (n), .mach_type = (mt) }
461 static struct common_board common_boards
[] __initdata
= {
462 DEFBOARD("CAS-630", MACH_ADM5120_CAS630
),
463 DEFBOARD("CAS-670", MACH_ADM5120_CAS670
),
464 DEFBOARD("CAS-700", MACH_ADM5120_CAS700
),
465 DEFBOARD("CAS-771", MACH_ADM5120_CAS771
),
466 DEFBOARD("CAS-790", MACH_ADM5120_CAS790
),
467 DEFBOARD("CAS-861", MACH_ADM5120_CAS861
),
468 DEFBOARD("NFS-101U", MACH_ADM5120_NFS101U
),
469 DEFBOARD("NFS-202U", MACH_ADM5120_NFS202U
),
470 DEFBOARD("EASY 5120", MACH_ADM5120_EASY5120
),
471 DEFBOARD("EASY 5120-RT", MACH_ADM5120_EASY5120RT
),
472 DEFBOARD("EASY 5120P-ATA", MACH_ADM5120_EASY5120PATA
),
473 DEFBOARD("EASY 83000", MACH_ADM5120_EASY83000
),
474 DEFBOARD("BR-6104K", MACH_ADM5120_BR6104K
),
475 DEFBOARD("WP54G-WRT", MACH_ADM5120_WP54G_WRT
),
476 DEFBOARD("P-334WT", MACH_ADM5120_P334WT
),
477 DEFBOARD("P-335", MACH_ADM5120_P335
),
483 static inline u16
read_le16(void *buf
)
488 return ((u16
)p
[0] + ((u16
)p
[1] << 8));
491 static inline u32
read_le32(void *buf
)
496 return ((u32
)p
[0] + ((u32
)p
[1] << 8) + ((u32
)p
[2] << 16) +
500 static inline u16
read_be16(void *buf
)
505 return (((u16
)p
[0] << 8) + (u16
)p
[1]);
508 static inline u32
read_be32(void *buf
)
513 return (((u32
)p
[0] << 24) + ((u32
)p
[1] << 16) + ((u32
)p
[2] << 8) +
520 #define CFE_EPTSEAL 0x43464531 /* CFE1 is the magic number to recognize CFE
521 from other bootloaders */
523 static int __init
cfe_present(void)
526 * This method only works, when we are booted directly from the CFE.
528 u32 cfe_handle
= (u32
) fw_arg0
;
529 u32 cfe_a1_val
= (u32
) fw_arg1
;
530 u32 cfe_entry
= (u32
) fw_arg2
;
531 u32 cfe_seal
= (u32
) fw_arg3
;
533 /* Check for CFE by finding the CFE magic number */
534 if (cfe_seal
!= CFE_EPTSEAL
) {
535 /* We are not booted from CFE */
539 /* cfe_a1_val must be 0, because only one CPU present in the ADM5120 */
540 if (cfe_a1_val
!= 0) {
544 /* The cfe_handle, and the cfe_entry must be kernel mode addresses */
545 if ((cfe_handle
< KSEG0
) || (cfe_entry
< KSEG0
)) {
552 static unsigned long __init
cfe_detect_board(void)
554 return MACH_ADM5120_WP54G_WRT
;
558 * MyLoader based boards
560 #define SYS_PARAMS_ADDR KSEG1ADDR(ADM5120_SRAM0_BASE+0x0F000)
561 #define BOARD_PARAMS_ADDR KSEG1ADDR(ADM5120_SRAM0_BASE+0x0F800)
562 #define PART_TABLE_ADDR KSEG1ADDR(ADM5120_SRAM0_BASE+0x10000)
564 static unsigned long __init
myloader_detect_board(void)
566 struct mylo_system_params
*sysp
;
567 struct mylo_board_params
*boardp
;
568 struct mylo_partition_table
*parts
;
569 struct mylo_board
*board
;
572 ret
= MACH_ADM5120_UNKNOWN
;
574 sysp
= (struct mylo_system_params
*)(SYS_PARAMS_ADDR
);
575 boardp
= (struct mylo_board_params
*)(BOARD_PARAMS_ADDR
);
576 parts
= (struct mylo_partition_table
*)(PART_TABLE_ADDR
);
578 /* Check for some magic numbers */
579 if ((le32_to_cpu(sysp
->magic
) != MYLO_MAGIC_SYS_PARAMS
) ||
580 (le32_to_cpu(boardp
->magic
) != MYLO_MAGIC_BOARD_PARAMS
) ||
581 (le32_to_cpu(parts
->magic
) != MYLO_MAGIC_PARTITIONS
))
584 for (board
= mylo_boards
; board
->mach_type
!= MACH_ADM5120_UNKNOWN
;
586 if ((le16_to_cpu(sysp
->vid
) == board
->vid
) &&
587 (le16_to_cpu(sysp
->did
) == board
->did
) &&
588 (le16_to_cpu(sysp
->svid
) == board
->svid
) &&
589 (le16_to_cpu(sysp
->sdid
) == board
->sdid
)) {
590 ret
= board
->mach_type
;
595 /* assume MyLoader as the boot-loader */
596 adm5120_boot_loader
= BOOT_LOADER_MYLOADER
;
603 * RouterBOOT based boards
605 static int __init
routerboot_load_hs(u8
*buf
, u16 buflen
,
606 struct rb_hard_settings
*hs
)
615 if (read_le32(buf
) != RB_MAGIC_HARD
)
618 /* skip magic value */
626 if (id
== RB_ID_TERMINATOR
|| buflen
< 2)
629 len
= read_le16(buf
);
637 case RB_ID_BIOS_VERSION
:
638 hs
->bios_ver
= (char *)buf
;
640 case RB_ID_BOARD_NAME
:
641 hs
->name
= (char *)buf
;
643 case RB_ID_MEMORY_SIZE
:
644 hs
->mem_size
= read_le32(buf
);
646 case RB_ID_MAC_ADDRESS_COUNT
:
647 hs
->mac_count
= read_le32(buf
);
649 case RB_ID_MAC_ADDRESS_PACK
:
650 hs
->mac_count
= len
/RB_MAC_SIZE
;
651 if (hs
->mac_count
> RB_MAX_MAC_COUNT
)
652 hs
->mac_count
= RB_MAX_MAC_COUNT
;
654 for (i
=0; i
< hs
->mac_count
; i
++) {
655 for (j
=0; j
< RB_MAC_SIZE
; j
++)
656 hs
->macs
[i
][j
] = mac
[j
];
670 #define RB_BS_OFFS 0x14
671 #define RB_OFFS_MAX (128*1024)
673 static unsigned long __init
routerboot_detect_board(void)
675 struct routerboard
*board
;
676 struct rb_hard_settings hs
;
677 struct rb_bios_settings
*bs
;
682 ret
= MACH_ADM5120_UNKNOWN
;
684 base
= (u8
*)KSEG1ADDR(ADM5120_SRAM0_BASE
);
685 bs
= (struct rb_bios_settings
*)(base
+ RB_BS_OFFS
);
687 off
= read_le32(&bs
->hs_offs
);
688 len
= read_le32(&bs
->hs_size
);
689 if (off
> RB_OFFS_MAX
)
692 memset(&hs
, 0, sizeof(hs
));
693 if (routerboot_load_hs(base
+off
, len
, &hs
) != 0)
696 /* assume RouterBOOT as the boot-loader */
697 adm5120_boot_loader
= BOOT_LOADER_ROUTERBOOT
;
702 for (board
= routerboards
; board
->mach_type
!= MACH_ADM5120_UNKNOWN
;
704 if (strncmp(board
->name
, hs
.name
, strlen(board
->name
)) == 0) {
705 ret
= board
->mach_type
;
716 static inline u32
zynos_dbgarea_present(u8
*data
)
720 t
= read_be32(data
+5);
721 if (t
!= ZYNOS_MAGIC_DBGAREA1
)
724 t
= read_be32(data
+9);
725 if (t
!= ZYNOS_MAGIC_DBGAREA2
)
731 #define CHECK_VENDOR(n) (strnicmp(vendor,(n),strlen(n)) == 0)
733 static inline unsigned int zynos_get_vendor_id(struct zynos_board_info
*info
)
735 unsigned char vendor
[ZYNOS_NAME_LEN
];
738 for (i
=0; i
<ZYNOS_NAME_LEN
; i
++)
739 vendor
[i
]=info
->vendor
[i
];
741 if CHECK_VENDOR(ZYNOS_VENDOR_ZYXEL
)
742 return ZYNOS_VENDOR_ID_ZYXEL
;
744 /* TODO: there are no known ADM5120 based boards from other vendors */
745 if CHECK_VENDOR(ZYNOS_VENDOR_DLINK
)
746 return ZYNOS_VENDOR_ID_DLINK
;
748 if CHECK_VENDOR(ZYNOS_VENDOR_LUCENT
)
749 return ZYNOS_VENDOR_ID_LUCENT
;
751 if CHECK_VENDOR(ZYNOS_VENDOR_NETGEAR
)
752 return ZYNOS_VENDOR_ID_NETGEAR
;
755 return ZYNOS_VENDOR_ID_OTHER
;
758 static inline u16
zynos_get_board_id(struct zynos_board_info
*info
)
760 return read_be16(&info
->board_id
);
763 static inline u32
zynos_get_bootext_addr(struct zynos_board_info
*info
)
765 return read_be32(&info
->bootext_addr
);
769 #define ZYNOS_INFO_ADDR KSEG1ADDR(ADM5120_SRAM0_BASE+0x3F90)
770 #define ZYNOS_HDBG_ADDR KSEG1ADDR(ADM5120_SRAM0_BASE+0x4000)
771 #define BOOTEXT_ADDR_MIN KSEG1ADDR(ADM5120_SRAM0_BASE)
772 #define BOOTEXT_ADDR_MAX (BOOTEXT_ADDR_MIN + (2*1024*1024))
774 static unsigned long __init
zynos_detect_board(void)
776 struct zynos_board_info
*info
;
777 struct zynos_board
*board
;
778 unsigned int vendor_id
;
783 ret
= MACH_ADM5120_UNKNOWN
;
784 /* check presence of the dbgarea */
785 if (zynos_dbgarea_present((u8
*)ZYNOS_HDBG_ADDR
) == 0)
788 info
= (struct zynos_board_info
*)(ZYNOS_INFO_ADDR
);
790 /* check for a valid BootExt address */
791 t
= zynos_get_bootext_addr(info
);
792 if ((t
< BOOTEXT_ADDR_MIN
) || (t
> BOOTEXT_ADDR_MAX
))
795 vendor_id
= zynos_get_vendor_id(info
);
796 board_id
= zynos_get_board_id(info
);
798 for (board
= zynos_boards
; board
->mach_type
!= MACH_ADM5120_UNKNOWN
;
800 if ((board
->vendor_id
== vendor_id
) &&
801 (board
->board_id
== board_id
)) {
802 ret
= board
->mach_type
;
807 /* assume Bootbase as the boot-loader */
808 adm5120_boot_loader
= BOOT_LOADER_BOOTBASE
;
815 * U-Boot based boards
817 static int __init
uboot_present(void)
819 /* FIXME: not yet implemented */
823 static unsigned long __init
uboot_detect_board(void)
825 /* FIXME: not yet implemented */
826 return MACH_ADM5120_UNKNOWN
;
832 static unsigned long __init
prom_detect_board(void)
838 ret
= MACH_ADM5120_UNKNOWN
;
839 name
= prom_getenv("board_name");
846 for (i
=0; i
<ARRAY_SIZE(common_boards
); i
++) {
847 if (strcmp(common_boards
[i
].name
, name
) == 0) {
848 ret
= common_boards
[i
].mach_type
;
857 static void __init
adm5120_detect_board(void)
859 struct adm5120_board
*board
;
862 adm5120_boot_loader
= BOOT_LOADER_UNKNOWN
;
864 /* Try to detect board type without bootloader */
865 t
= routerboot_detect_board();
867 if (t
== MACH_ADM5120_UNKNOWN
)
868 t
= zynos_detect_board();
870 if (t
== MACH_ADM5120_UNKNOWN
)
871 t
= myloader_detect_board();
873 /* Try to detect bootloader type */
875 adm5120_boot_loader
= BOOT_LOADER_CFE
;
876 if (t
== MACH_ADM5120_UNKNOWN
)
877 t
= cfe_detect_board();
878 } else if (uboot_present()) {
879 adm5120_boot_loader
= BOOT_LOADER_UBOOT
;
880 if (t
== MACH_ADM5120_UNKNOWN
)
881 t
= uboot_detect_board();
883 if (t
== MACH_ADM5120_UNKNOWN
)
884 t
= prom_detect_board();
887 for (board
= adm5120_boards
; board
->mach_type
!= MACH_ADM5120_UNKNOWN
;
889 if (board
->mach_type
== t
)
893 memcpy(&adm5120_board
, board
, sizeof(adm5120_board
));
896 #define SWITCH_READ(r) *(u32 *)(KSEG1ADDR(ADM5120_SWITCH_BASE)+(r))
897 #define SWITCH_WRITE(r,v) *(u32 *)(KSEG1ADDR(ADM5120_SWITCH_BASE)+(r))=(v)
900 * CPU settings detection
902 #define CODE_GET_PC(c) ((c) & CODE_PC_MASK)
903 #define CODE_GET_REV(c) (((c) >> CODE_REV_SHIFT) & CODE_REV_MASK)
904 #define CODE_GET_PK(c) (((c) >> CODE_PK_SHIFT) & CODE_PK_MASK)
905 #define CODE_GET_CLKS(c) (((c) >> CODE_CLKS_SHIFT) & CODE_CLKS_MASK)
906 #define CODE_GET_NAB(c) (((c) & CODE_NAB) != 0)
908 static void __init
adm5120_detect_cpuinfo(void)
913 code
= SWITCH_READ(SWITCH_REG_CODE
);
915 adm5120_product_code
= CODE_GET_PC(code
);
916 adm5120_revision
= CODE_GET_REV(code
);
917 adm5120_package
= (CODE_GET_PK(code
) == CODE_PK_BGA
) ?
918 ADM5120_PACKAGE_BGA
: ADM5120_PACKAGE_PQFP
;
919 adm5120_nand_boot
= CODE_GET_NAB(code
);
921 clks
= CODE_GET_CLKS(code
);
922 adm5120_speed
= ADM5120_SPEED_175
;
924 adm5120_speed
+= 25000000;
926 adm5120_speed
+= 50000000;
930 # define mem_dbg(f, ...) prom_printf("mem_detect: " f, ## __VA_ARGS__)
931 extern void prom_printf(char *, ...);
933 # define mem_dbg(f, ...)
936 static void __init
adm5120_detect_memsize(void)
943 memctrl
= SWITCH_READ(SWITCH_REG_MEMCTRL
);
944 switch (memctrl
& MEMCTRL_SDRS_MASK
) {
945 case MEMCTRL_SDRS_4M
:
948 case MEMCTRL_SDRS_8M
:
951 case MEMCTRL_SDRS_16M
:
959 /* FIXME: need to disable buffers for both SDRAM banks? */
961 mem_dbg("checking for %ldMB chip\n",maxsize
>> 20);
963 /* detect size of the 1st SDRAM bank */
964 p
= (volatile u8
*)KSEG1ADDR(0);
966 for (size
= 2<<20; size
<= (maxsize
>> 1); size
<<= 1) {
970 mem_dbg("1st pattern at 0x%lx is 0x%02x\n", size
, *r
);
973 mem_dbg("2nd pattern at 0x%lx is 0x%02x\n", size
, *r
);
975 /* mirrored address */
976 mem_dbg("mirrored data found at 0x%lx\n", size
);
982 mem_dbg("1st pattern at 0x%lx is 0x%02x\n", size
, p
[size
]);
987 mem_dbg("2nd pattern at 0x%lx is 0x%02x\n", size
, p
[size
]);
991 /* mirrored address */
992 mem_dbg("mirrored data found at 0x%lx\n", size
);
998 mem_dbg("%ldMB chip found\n", size
>> 20);
1000 if (size
== (32 << 20))
1001 /* if bank size is 32MB, 2nd bank is not supported */
1004 if ((memctrl
& MEMCTRL_SDR1_ENABLE
) == 0)
1005 /* if 2nd bank is not enabled, we are done */
1009 * some bootloaders enable 2nd bank, even if the 2nd SDRAM chip
1012 mem_dbg("checking second bank\n");
1013 p
+= (maxsize
+size
)-1;
1024 if (maxsize
!= size
) {
1025 /* adjusting MECTRL register */
1026 memctrl
&= ~(MEMCTRL_SDRS_MASK
);
1029 memctrl
|= MEMCTRL_SDRS_4M
;
1032 memctrl
|= MEMCTRL_SDRS_8M
;
1035 memctrl
|= MEMCTRL_SDRS_16M
;
1038 memctrl
|= MEMCTRL_SDRS_64M
;
1041 SWITCH_WRITE(SWITCH_REG_MEMCTRL
, memctrl
);
1046 adm5120_memsize
= size
;
1047 mem_dbg("%ldMB memory found\n",size
>>20);
1050 void __init
adm5120_info_show(void)
1052 /* FIXME: move this somewhere else */
1053 printk(KERN_INFO
"ADM%04X%s revision %d, running at %ldMHz\n",
1054 adm5120_product_code
,
1055 (adm5120_package
== ADM5120_PACKAGE_BGA
) ? "" : "P",
1056 adm5120_revision
, (adm5120_speed
/ 1000000)
1058 printk(KERN_INFO
"Boot loader is: %s\n", boot_loader_names
[adm5120_boot_loader
]);
1059 printk(KERN_INFO
"Booted from : %s flash\n", adm5120_nand_boot
? "NAND":"NOR");
1060 printk(KERN_INFO
"Board is : %s\n", adm5120_board_name());
1061 printk(KERN_INFO
"Memory size : %ldMB\n", adm5120_memsize
>> 20);
1064 void __init
adm5120_info_init(void)
1067 adm5120_detect_cpuinfo();
1068 adm5120_detect_memsize();
1069 adm5120_detect_board();
1071 adm5120_info_show();