xref: /OK3568_Linux_fs/kernel/arch/mips/sibyte/swarm/setup.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (C) 2000, 2001, 2002, 2003, 2004 Broadcom Corporation
4*4882a593Smuzhiyun  * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
5*4882a593Smuzhiyun  */
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun /*
8*4882a593Smuzhiyun  * Setup code for the SWARM board
9*4882a593Smuzhiyun  */
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #include <linux/spinlock.h>
12*4882a593Smuzhiyun #include <linux/mm.h>
13*4882a593Smuzhiyun #include <linux/memblock.h>
14*4882a593Smuzhiyun #include <linux/blkdev.h>
15*4882a593Smuzhiyun #include <linux/init.h>
16*4882a593Smuzhiyun #include <linux/kernel.h>
17*4882a593Smuzhiyun #include <linux/screen_info.h>
18*4882a593Smuzhiyun #include <linux/initrd.h>
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun #include <asm/irq.h>
21*4882a593Smuzhiyun #include <asm/io.h>
22*4882a593Smuzhiyun #include <asm/bootinfo.h>
23*4882a593Smuzhiyun #include <asm/mipsregs.h>
24*4882a593Smuzhiyun #include <asm/reboot.h>
25*4882a593Smuzhiyun #include <asm/time.h>
26*4882a593Smuzhiyun #include <asm/traps.h>
27*4882a593Smuzhiyun #include <asm/sibyte/sb1250.h>
28*4882a593Smuzhiyun #if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
29*4882a593Smuzhiyun #include <asm/sibyte/bcm1480_regs.h>
30*4882a593Smuzhiyun #elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
31*4882a593Smuzhiyun #include <asm/sibyte/sb1250_regs.h>
32*4882a593Smuzhiyun #else
33*4882a593Smuzhiyun #error invalid SiByte board configuration
34*4882a593Smuzhiyun #endif
35*4882a593Smuzhiyun #include <asm/sibyte/sb1250_genbus.h>
36*4882a593Smuzhiyun #include <asm/sibyte/board.h>
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun #if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
39*4882a593Smuzhiyun extern void bcm1480_setup(void);
40*4882a593Smuzhiyun #elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
41*4882a593Smuzhiyun extern void sb1250_setup(void);
42*4882a593Smuzhiyun #else
43*4882a593Smuzhiyun #error invalid SiByte board configuration
44*4882a593Smuzhiyun #endif
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun extern int xicor_probe(void);
47*4882a593Smuzhiyun extern int xicor_set_time(time64_t);
48*4882a593Smuzhiyun extern time64_t xicor_get_time(void);
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun extern int m41t81_probe(void);
51*4882a593Smuzhiyun extern int m41t81_set_time(time64_t);
52*4882a593Smuzhiyun extern time64_t m41t81_get_time(void);
53*4882a593Smuzhiyun 
get_system_type(void)54*4882a593Smuzhiyun const char *get_system_type(void)
55*4882a593Smuzhiyun {
56*4882a593Smuzhiyun 	return "SiByte " SIBYTE_BOARD_NAME;
57*4882a593Smuzhiyun }
58*4882a593Smuzhiyun 
swarm_be_handler(struct pt_regs * regs,int is_fixup)59*4882a593Smuzhiyun int swarm_be_handler(struct pt_regs *regs, int is_fixup)
60*4882a593Smuzhiyun {
61*4882a593Smuzhiyun 	if (!is_fixup && (regs->cp0_cause & 4)) {
62*4882a593Smuzhiyun 		/* Data bus error - print PA */
63*4882a593Smuzhiyun 		printk("DBE physical address: %010Lx\n",
64*4882a593Smuzhiyun 		       __read_64bit_c0_register($26, 1));
65*4882a593Smuzhiyun 	}
66*4882a593Smuzhiyun 	return is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL;
67*4882a593Smuzhiyun }
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun enum swarm_rtc_type {
70*4882a593Smuzhiyun 	RTC_NONE,
71*4882a593Smuzhiyun 	RTC_XICOR,
72*4882a593Smuzhiyun 	RTC_M41T81,
73*4882a593Smuzhiyun };
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun enum swarm_rtc_type swarm_rtc_type;
76*4882a593Smuzhiyun 
read_persistent_clock64(struct timespec64 * ts)77*4882a593Smuzhiyun void read_persistent_clock64(struct timespec64 *ts)
78*4882a593Smuzhiyun {
79*4882a593Smuzhiyun 	time64_t sec;
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun 	switch (swarm_rtc_type) {
82*4882a593Smuzhiyun 	case RTC_XICOR:
83*4882a593Smuzhiyun 		sec = xicor_get_time();
84*4882a593Smuzhiyun 		break;
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun 	case RTC_M41T81:
87*4882a593Smuzhiyun 		sec = m41t81_get_time();
88*4882a593Smuzhiyun 		break;
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun 	case RTC_NONE:
91*4882a593Smuzhiyun 	default:
92*4882a593Smuzhiyun 		sec = mktime64(2000, 1, 1, 0, 0, 0);
93*4882a593Smuzhiyun 		break;
94*4882a593Smuzhiyun 	}
95*4882a593Smuzhiyun 	ts->tv_sec = sec;
96*4882a593Smuzhiyun 	ts->tv_nsec = 0;
97*4882a593Smuzhiyun }
98*4882a593Smuzhiyun 
update_persistent_clock64(struct timespec64 now)99*4882a593Smuzhiyun int update_persistent_clock64(struct timespec64 now)
100*4882a593Smuzhiyun {
101*4882a593Smuzhiyun 	time64_t sec = now.tv_sec;
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun 	switch (swarm_rtc_type) {
104*4882a593Smuzhiyun 	case RTC_XICOR:
105*4882a593Smuzhiyun 		return xicor_set_time(sec);
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun 	case RTC_M41T81:
108*4882a593Smuzhiyun 		return m41t81_set_time(sec);
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun 	case RTC_NONE:
111*4882a593Smuzhiyun 	default:
112*4882a593Smuzhiyun 		return -1;
113*4882a593Smuzhiyun 	}
114*4882a593Smuzhiyun }
115*4882a593Smuzhiyun 
plat_mem_setup(void)116*4882a593Smuzhiyun void __init plat_mem_setup(void)
117*4882a593Smuzhiyun {
118*4882a593Smuzhiyun #if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
119*4882a593Smuzhiyun 	bcm1480_setup();
120*4882a593Smuzhiyun #elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
121*4882a593Smuzhiyun 	sb1250_setup();
122*4882a593Smuzhiyun #else
123*4882a593Smuzhiyun #error invalid SiByte board configuration
124*4882a593Smuzhiyun #endif
125*4882a593Smuzhiyun 
126*4882a593Smuzhiyun 	board_be_handler = swarm_be_handler;
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun 	if (xicor_probe())
129*4882a593Smuzhiyun 		swarm_rtc_type = RTC_XICOR;
130*4882a593Smuzhiyun 	if (m41t81_probe())
131*4882a593Smuzhiyun 		swarm_rtc_type = RTC_M41T81;
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun #ifdef CONFIG_VT
134*4882a593Smuzhiyun 	screen_info = (struct screen_info) {
135*4882a593Smuzhiyun 		.orig_video_page	= 52,
136*4882a593Smuzhiyun 		.orig_video_mode	= 3,
137*4882a593Smuzhiyun 		.orig_video_cols	= 80,
138*4882a593Smuzhiyun 		.flags			= 12,
139*4882a593Smuzhiyun 		.orig_video_ega_bx	= 3,
140*4882a593Smuzhiyun 		.orig_video_lines	= 25,
141*4882a593Smuzhiyun 		.orig_video_isVGA	= 0x22,
142*4882a593Smuzhiyun 		.orig_video_points	= 16,
143*4882a593Smuzhiyun        };
144*4882a593Smuzhiyun        /* XXXKW for CFE, get lines/cols from environment */
145*4882a593Smuzhiyun #endif
146*4882a593Smuzhiyun }
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun #ifdef LEDS_PHYS
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun #ifdef CONFIG_SIBYTE_CARMEL
151*4882a593Smuzhiyun /* XXXKW need to detect Monterey/LittleSur/etc */
152*4882a593Smuzhiyun #undef LEDS_PHYS
153*4882a593Smuzhiyun #define LEDS_PHYS MLEDS_PHYS
154*4882a593Smuzhiyun #endif
155*4882a593Smuzhiyun 
setleds(char * str)156*4882a593Smuzhiyun void setleds(char *str)
157*4882a593Smuzhiyun {
158*4882a593Smuzhiyun 	void *reg;
159*4882a593Smuzhiyun 	int i;
160*4882a593Smuzhiyun 
161*4882a593Smuzhiyun 	for (i = 0; i < 4; i++) {
162*4882a593Smuzhiyun 		reg = IOADDR(LEDS_PHYS) + 0x20 + ((3 - i) << 3);
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun 		if (!str[i])
165*4882a593Smuzhiyun 			writeb(' ', reg);
166*4882a593Smuzhiyun 		else
167*4882a593Smuzhiyun 			writeb(str[i], reg);
168*4882a593Smuzhiyun 	}
169*4882a593Smuzhiyun }
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun #endif /* LEDS_PHYS */
172