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 */
5*4882a593Smuzhiyun #include <linux/init.h>
6*4882a593Smuzhiyun #include <linux/kernel.h>
7*4882a593Smuzhiyun #include <linux/export.h>
8*4882a593Smuzhiyun #include <linux/reboot.h>
9*4882a593Smuzhiyun #include <linux/string.h>
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun #include <asm/bootinfo.h>
12*4882a593Smuzhiyun #include <asm/cpu.h>
13*4882a593Smuzhiyun #include <asm/mipsregs.h>
14*4882a593Smuzhiyun #include <asm/io.h>
15*4882a593Smuzhiyun #include <asm/sibyte/sb1250.h>
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun #include <asm/sibyte/bcm1480_regs.h>
18*4882a593Smuzhiyun #include <asm/sibyte/bcm1480_scd.h>
19*4882a593Smuzhiyun #include <asm/sibyte/sb1250_scd.h>
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun unsigned int sb1_pass;
22*4882a593Smuzhiyun unsigned int soc_pass;
23*4882a593Smuzhiyun unsigned int soc_type;
24*4882a593Smuzhiyun EXPORT_SYMBOL(soc_type);
25*4882a593Smuzhiyun unsigned int periph_rev;
26*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(periph_rev);
27*4882a593Smuzhiyun unsigned int zbbus_mhz;
28*4882a593Smuzhiyun EXPORT_SYMBOL(zbbus_mhz);
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun static unsigned int part_type;
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun static char *soc_str;
33*4882a593Smuzhiyun static char *pass_str;
34*4882a593Smuzhiyun
setup_bcm1x80_bcm1x55(void)35*4882a593Smuzhiyun static int __init setup_bcm1x80_bcm1x55(void)
36*4882a593Smuzhiyun {
37*4882a593Smuzhiyun int ret = 0;
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun switch (soc_pass) {
40*4882a593Smuzhiyun case K_SYS_REVISION_BCM1480_S0:
41*4882a593Smuzhiyun periph_rev = 1;
42*4882a593Smuzhiyun pass_str = "S0 (pass1)";
43*4882a593Smuzhiyun break;
44*4882a593Smuzhiyun case K_SYS_REVISION_BCM1480_A1:
45*4882a593Smuzhiyun periph_rev = 1;
46*4882a593Smuzhiyun pass_str = "A1 (pass1)";
47*4882a593Smuzhiyun break;
48*4882a593Smuzhiyun case K_SYS_REVISION_BCM1480_A2:
49*4882a593Smuzhiyun periph_rev = 1;
50*4882a593Smuzhiyun pass_str = "A2 (pass1)";
51*4882a593Smuzhiyun break;
52*4882a593Smuzhiyun case K_SYS_REVISION_BCM1480_A3:
53*4882a593Smuzhiyun periph_rev = 1;
54*4882a593Smuzhiyun pass_str = "A3 (pass1)";
55*4882a593Smuzhiyun break;
56*4882a593Smuzhiyun case K_SYS_REVISION_BCM1480_B0:
57*4882a593Smuzhiyun periph_rev = 1;
58*4882a593Smuzhiyun pass_str = "B0 (pass2)";
59*4882a593Smuzhiyun break;
60*4882a593Smuzhiyun default:
61*4882a593Smuzhiyun printk("Unknown %s rev %x\n", soc_str, soc_pass);
62*4882a593Smuzhiyun periph_rev = 1;
63*4882a593Smuzhiyun pass_str = "Unknown Revision";
64*4882a593Smuzhiyun break;
65*4882a593Smuzhiyun }
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun return ret;
68*4882a593Smuzhiyun }
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun /* Setup code likely to be common to all SiByte platforms */
71*4882a593Smuzhiyun
sys_rev_decode(void)72*4882a593Smuzhiyun static int __init sys_rev_decode(void)
73*4882a593Smuzhiyun {
74*4882a593Smuzhiyun int ret = 0;
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun switch (soc_type) {
77*4882a593Smuzhiyun case K_SYS_SOC_TYPE_BCM1x80:
78*4882a593Smuzhiyun if (part_type == K_SYS_PART_BCM1480)
79*4882a593Smuzhiyun soc_str = "BCM1480";
80*4882a593Smuzhiyun else if (part_type == K_SYS_PART_BCM1280)
81*4882a593Smuzhiyun soc_str = "BCM1280";
82*4882a593Smuzhiyun else
83*4882a593Smuzhiyun soc_str = "BCM1x80";
84*4882a593Smuzhiyun ret = setup_bcm1x80_bcm1x55();
85*4882a593Smuzhiyun break;
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun case K_SYS_SOC_TYPE_BCM1x55:
88*4882a593Smuzhiyun if (part_type == K_SYS_PART_BCM1455)
89*4882a593Smuzhiyun soc_str = "BCM1455";
90*4882a593Smuzhiyun else if (part_type == K_SYS_PART_BCM1255)
91*4882a593Smuzhiyun soc_str = "BCM1255";
92*4882a593Smuzhiyun else
93*4882a593Smuzhiyun soc_str = "BCM1x55";
94*4882a593Smuzhiyun ret = setup_bcm1x80_bcm1x55();
95*4882a593Smuzhiyun break;
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun default:
98*4882a593Smuzhiyun printk("Unknown part type %x\n", part_type);
99*4882a593Smuzhiyun ret = 1;
100*4882a593Smuzhiyun break;
101*4882a593Smuzhiyun }
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun return ret;
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun
bcm1480_setup(void)106*4882a593Smuzhiyun void __init bcm1480_setup(void)
107*4882a593Smuzhiyun {
108*4882a593Smuzhiyun uint64_t sys_rev;
109*4882a593Smuzhiyun int plldiv;
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun sb1_pass = read_c0_prid() & PRID_REV_MASK;
112*4882a593Smuzhiyun sys_rev = __raw_readq(IOADDR(A_SCD_SYSTEM_REVISION));
113*4882a593Smuzhiyun soc_type = SYS_SOC_TYPE(sys_rev);
114*4882a593Smuzhiyun part_type = G_SYS_PART(sys_rev);
115*4882a593Smuzhiyun soc_pass = G_SYS_REVISION(sys_rev);
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun if (sys_rev_decode()) {
118*4882a593Smuzhiyun printk("Restart after failure to identify SiByte chip\n");
119*4882a593Smuzhiyun machine_restart(NULL);
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun plldiv = G_BCM1480_SYS_PLL_DIV(__raw_readq(IOADDR(A_SCD_SYSTEM_CFG)));
123*4882a593Smuzhiyun zbbus_mhz = ((plldiv >> 1) * 50) + ((plldiv & 1) * 25);
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun printk("Broadcom SiByte %s %s @ %d MHz (SB-1A rev %d)\n",
126*4882a593Smuzhiyun soc_str, pass_str, zbbus_mhz * 2, sb1_pass);
127*4882a593Smuzhiyun printk("Board type: %s\n", get_system_type());
128*4882a593Smuzhiyun }
129