0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/init.h>
0011 #include <linux/bitops.h>
0012 #include <linux/memblock.h>
0013 #include <linux/ioport.h>
0014 #include <linux/kernel.h>
0015 #include <linux/io.h>
0016 #include <linux/of.h>
0017 #include <linux/of_clk.h>
0018 #include <linux/of_fdt.h>
0019 #include <linux/of_platform.h>
0020 #include <linux/libfdt.h>
0021 #include <linux/smp.h>
0022 #include <asm/addrspace.h>
0023 #include <asm/bmips.h>
0024 #include <asm/bootinfo.h>
0025 #include <asm/cpu-type.h>
0026 #include <asm/mipsregs.h>
0027 #include <asm/prom.h>
0028 #include <asm/smp-ops.h>
0029 #include <asm/time.h>
0030 #include <asm/traps.h>
0031 #include <asm/fw/cfe/cfe_api.h>
0032
0033 #define RELO_NORMAL_VEC BIT(18)
0034
0035 #define REG_BCM6328_OTP ((void __iomem *)CKSEG1ADDR(0x1000062c))
0036 #define BCM6328_TP1_DISABLED BIT(9)
0037
0038 static const unsigned long kbase = VMLINUX_LOAD_ADDRESS & 0xfff00000;
0039
0040 struct bmips_quirk {
0041 const char *compatible;
0042 void (*quirk_fn)(void);
0043 };
0044
0045 static void kbase_setup(void)
0046 {
0047 __raw_writel(kbase | RELO_NORMAL_VEC,
0048 BMIPS_GET_CBR() + BMIPS_RELO_VECTOR_CONTROL_1);
0049 ebase = kbase;
0050 }
0051
0052 static void bcm3384_viper_quirks(void)
0053 {
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070 board_ebase_setup = &kbase_setup;
0071 bmips_smp_enabled = 0;
0072 }
0073
0074 static void bcm63xx_fixup_cpu1(void)
0075 {
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085 memcpy((void *)0xa0000200, &bmips_smp_movevec, 0x20);
0086 __sync();
0087 set_c0_cause(C_SW0);
0088 cpumask_set_cpu(1, &bmips_booted_mask);
0089 }
0090
0091 static void bcm6328_quirks(void)
0092 {
0093
0094 if (__raw_readl(REG_BCM6328_OTP) & BCM6328_TP1_DISABLED)
0095 bmips_smp_enabled = 0;
0096 else
0097 bcm63xx_fixup_cpu1();
0098 }
0099
0100 static void bcm6358_quirks(void)
0101 {
0102
0103
0104
0105
0106 bmips_smp_enabled = 0;
0107 }
0108
0109 static void bcm6368_quirks(void)
0110 {
0111 bcm63xx_fixup_cpu1();
0112 }
0113
0114 static const struct bmips_quirk bmips_quirk_list[] = {
0115 { "brcm,bcm3368", &bcm6358_quirks },
0116 { "brcm,bcm3384-viper", &bcm3384_viper_quirks },
0117 { "brcm,bcm33843-viper", &bcm3384_viper_quirks },
0118 { "brcm,bcm6328", &bcm6328_quirks },
0119 { "brcm,bcm6358", &bcm6358_quirks },
0120 { "brcm,bcm6362", &bcm6368_quirks },
0121 { "brcm,bcm6368", &bcm6368_quirks },
0122 { "brcm,bcm63168", &bcm6368_quirks },
0123 { "brcm,bcm63268", &bcm6368_quirks },
0124 { },
0125 };
0126
0127 static void __init bmips_init_cfe(void)
0128 {
0129 cfe_seal = fw_arg3;
0130
0131 if (cfe_seal != CFE_EPTSEAL)
0132 return;
0133
0134 cfe_init(fw_arg0, fw_arg2);
0135 }
0136
0137 void __init prom_init(void)
0138 {
0139 bmips_init_cfe();
0140 bmips_cpu_setup();
0141 register_bmips_smp_ops();
0142 }
0143
0144 const char *get_system_type(void)
0145 {
0146 return "Generic BMIPS kernel";
0147 }
0148
0149 void __init plat_time_init(void)
0150 {
0151 struct device_node *np;
0152 u32 freq;
0153
0154 np = of_find_node_by_name(NULL, "cpus");
0155 if (!np)
0156 panic("missing 'cpus' DT node");
0157 if (of_property_read_u32(np, "mips-hpt-frequency", &freq) < 0)
0158 panic("missing 'mips-hpt-frequency' property");
0159 of_node_put(np);
0160
0161 mips_hpt_frequency = freq;
0162 }
0163
0164 void __init plat_mem_setup(void)
0165 {
0166 void *dtb;
0167 const struct bmips_quirk *q;
0168
0169 set_io_port_base(0);
0170 ioport_resource.start = 0;
0171 ioport_resource.end = ~0;
0172
0173
0174 if (fw_arg0 == 0 && fw_arg1 == 0xffffffff)
0175 dtb = phys_to_virt(fw_arg2);
0176 else
0177 dtb = get_fdt();
0178
0179 if (!dtb)
0180 cfe_die("no dtb found");
0181
0182 __dt_setup_arch(dtb);
0183
0184 for (q = bmips_quirk_list; q->quirk_fn; q++) {
0185 if (of_flat_dt_is_compatible(of_get_flat_dt_root(),
0186 q->compatible)) {
0187 q->quirk_fn();
0188 }
0189 }
0190 }
0191
0192 void __init device_tree_init(void)
0193 {
0194 struct device_node *np;
0195
0196 unflatten_and_copy_device_tree();
0197
0198
0199 np = of_find_node_by_name(NULL, "cpus");
0200 if (np && of_get_available_child_count(np) <= 1)
0201 bmips_smp_enabled = 0;
0202 of_node_put(np);
0203 }
0204
0205 static int __init plat_dev_init(void)
0206 {
0207 of_clk_init(NULL);
0208 return 0;
0209 }
0210
0211 arch_initcall(plat_dev_init);