0001
0002
0003
0004
0005 #include <linux/export.h>
0006 #include <linux/init.h>
0007 #include <linux/kernel.h>
0008 #include <linux/reboot.h>
0009 #include <linux/string.h>
0010
0011 #include <asm/bootinfo.h>
0012 #include <asm/cpu.h>
0013 #include <asm/mipsregs.h>
0014 #include <asm/io.h>
0015 #include <asm/sibyte/sb1250.h>
0016 #include <asm/sibyte/sb1250_regs.h>
0017 #include <asm/sibyte/sb1250_scd.h>
0018
0019 unsigned int sb1_pass;
0020 unsigned int soc_pass;
0021 unsigned int soc_type;
0022 EXPORT_SYMBOL(soc_type);
0023 unsigned int periph_rev;
0024 EXPORT_SYMBOL_GPL(periph_rev);
0025 unsigned int zbbus_mhz;
0026 EXPORT_SYMBOL(zbbus_mhz);
0027
0028 static char *soc_str;
0029 static char *pass_str;
0030 static unsigned int war_pass;
0031
0032 static int __init setup_bcm1250(void)
0033 {
0034 int ret = 0;
0035
0036 switch (soc_pass) {
0037 case K_SYS_REVISION_BCM1250_PASS1:
0038 periph_rev = 1;
0039 pass_str = "Pass 1";
0040 break;
0041 case K_SYS_REVISION_BCM1250_A10:
0042 periph_rev = 2;
0043 pass_str = "A8/A10";
0044
0045 war_pass = K_SYS_REVISION_BCM1250_PASS2;
0046 break;
0047 case K_SYS_REVISION_BCM1250_PASS2_2:
0048 periph_rev = 2;
0049 pass_str = "B1";
0050 break;
0051 case K_SYS_REVISION_BCM1250_B2:
0052 periph_rev = 2;
0053 pass_str = "B2";
0054 war_pass = K_SYS_REVISION_BCM1250_PASS2_2;
0055 break;
0056 case K_SYS_REVISION_BCM1250_PASS3:
0057 periph_rev = 3;
0058 pass_str = "C0";
0059 break;
0060 case K_SYS_REVISION_BCM1250_C1:
0061 periph_rev = 3;
0062 pass_str = "C1";
0063 break;
0064 default:
0065 if (soc_pass < K_SYS_REVISION_BCM1250_PASS2_2) {
0066 periph_rev = 2;
0067 pass_str = "A0-A6";
0068 war_pass = K_SYS_REVISION_BCM1250_PASS2;
0069 } else {
0070 printk("Unknown BCM1250 rev %x\n", soc_pass);
0071 ret = 1;
0072 }
0073 break;
0074 }
0075
0076 return ret;
0077 }
0078
0079 int sb1250_m3_workaround_needed(void)
0080 {
0081 switch (soc_type) {
0082 case K_SYS_SOC_TYPE_BCM1250:
0083 case K_SYS_SOC_TYPE_BCM1250_ALT:
0084 case K_SYS_SOC_TYPE_BCM1250_ALT2:
0085 case K_SYS_SOC_TYPE_BCM1125:
0086 case K_SYS_SOC_TYPE_BCM1125H:
0087 return soc_pass < K_SYS_REVISION_BCM1250_C0;
0088
0089 default:
0090 return 0;
0091 }
0092 }
0093
0094 static int __init setup_bcm112x(void)
0095 {
0096 int ret = 0;
0097
0098 switch (soc_pass) {
0099 case 0:
0100
0101 periph_rev = 3;
0102 pass_str = "A1";
0103 war_pass = K_SYS_REVISION_BCM112x_A1;
0104 break;
0105 case K_SYS_REVISION_BCM112x_A1:
0106 periph_rev = 3;
0107 pass_str = "A1";
0108 break;
0109 case K_SYS_REVISION_BCM112x_A2:
0110 periph_rev = 3;
0111 pass_str = "A2";
0112 break;
0113 case K_SYS_REVISION_BCM112x_A3:
0114 periph_rev = 3;
0115 pass_str = "A3";
0116 break;
0117 case K_SYS_REVISION_BCM112x_A4:
0118 periph_rev = 3;
0119 pass_str = "A4";
0120 break;
0121 case K_SYS_REVISION_BCM112x_B0:
0122 periph_rev = 3;
0123 pass_str = "B0";
0124 break;
0125 default:
0126 printk("Unknown %s rev %x\n", soc_str, soc_pass);
0127 ret = 1;
0128 }
0129
0130 return ret;
0131 }
0132
0133
0134
0135 static int __init sys_rev_decode(void)
0136 {
0137 int ret = 0;
0138
0139 war_pass = soc_pass;
0140 switch (soc_type) {
0141 case K_SYS_SOC_TYPE_BCM1250:
0142 case K_SYS_SOC_TYPE_BCM1250_ALT:
0143 case K_SYS_SOC_TYPE_BCM1250_ALT2:
0144 soc_str = "BCM1250";
0145 ret = setup_bcm1250();
0146 break;
0147 case K_SYS_SOC_TYPE_BCM1120:
0148 soc_str = "BCM1120";
0149 ret = setup_bcm112x();
0150 break;
0151 case K_SYS_SOC_TYPE_BCM1125:
0152 soc_str = "BCM1125";
0153 ret = setup_bcm112x();
0154 break;
0155 case K_SYS_SOC_TYPE_BCM1125H:
0156 soc_str = "BCM1125H";
0157 ret = setup_bcm112x();
0158 break;
0159 default:
0160 printk("Unknown SOC type %x\n", soc_type);
0161 ret = 1;
0162 break;
0163 }
0164
0165 return ret;
0166 }
0167
0168 void __init sb1250_setup(void)
0169 {
0170 uint64_t sys_rev;
0171 int plldiv;
0172 int bad_config = 0;
0173
0174 sb1_pass = read_c0_prid() & PRID_REV_MASK;
0175 sys_rev = __raw_readq(IOADDR(A_SCD_SYSTEM_REVISION));
0176 soc_type = SYS_SOC_TYPE(sys_rev);
0177 soc_pass = G_SYS_REVISION(sys_rev);
0178
0179 if (sys_rev_decode()) {
0180 printk("Restart after failure to identify SiByte chip\n");
0181 machine_restart(NULL);
0182 }
0183
0184 plldiv = G_SYS_PLL_DIV(__raw_readq(IOADDR(A_SCD_SYSTEM_CFG)));
0185 zbbus_mhz = ((plldiv >> 1) * 50) + ((plldiv & 1) * 25);
0186
0187 printk("Broadcom SiByte %s %s @ %d MHz (SB1 rev %d)\n",
0188 soc_str, pass_str, zbbus_mhz * 2, sb1_pass);
0189 printk("Board type: %s\n", get_system_type());
0190
0191 switch (war_pass) {
0192 case K_SYS_REVISION_BCM1250_PASS1:
0193 printk("@@@@ This is a BCM1250 A0-A2 (Pass 1) board, "
0194 "and the kernel doesn't have the proper "
0195 "workarounds compiled in. @@@@\n");
0196 bad_config = 1;
0197 break;
0198 case K_SYS_REVISION_BCM1250_PASS2:
0199
0200 #if !defined(CONFIG_SB1_PASS_2_WORKAROUNDS) || \
0201 !defined(CONFIG_SB1_PASS_2_1_WORKAROUNDS)
0202 printk("@@@@ This is a BCM1250 A3-A10 board, and the "
0203 "kernel doesn't have the proper workarounds "
0204 "compiled in. @@@@\n");
0205 bad_config = 1;
0206 #endif
0207 #ifdef CONFIG_CPU_HAS_PREFETCH
0208 printk("@@@@ Prefetches may be enabled in this kernel, "
0209 "but are buggy on this board. @@@@\n");
0210 bad_config = 1;
0211 #endif
0212 break;
0213 case K_SYS_REVISION_BCM1250_PASS2_2:
0214 #ifndef CONFIG_SB1_PASS_2_WORKAROUNDS
0215 printk("@@@@ This is a BCM1250 B1/B2. board, and the "
0216 "kernel doesn't have the proper workarounds "
0217 "compiled in. @@@@\n");
0218 bad_config = 1;
0219 #endif
0220 #if defined(CONFIG_SB1_PASS_2_1_WORKAROUNDS) || \
0221 !defined(CONFIG_CPU_HAS_PREFETCH)
0222 printk("@@@@ This is a BCM1250 B1/B2, but the kernel is "
0223 "conservatively configured for an 'A' stepping. "
0224 "@@@@\n");
0225 #endif
0226 break;
0227 default:
0228 break;
0229 }
0230 if (bad_config) {
0231 printk("Invalid configuration for this chip.\n");
0232 machine_restart(NULL);
0233 }
0234 }