0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 #include "bcm47xx_private.h"
0030
0031 #include <linux/bcm47xx_sprom.h>
0032 #include <linux/export.h>
0033 #include <linux/types.h>
0034 #include <linux/ethtool.h>
0035 #include <linux/phy.h>
0036 #include <linux/phy_fixed.h>
0037 #include <linux/ssb/ssb.h>
0038 #include <linux/ssb/ssb_embedded.h>
0039 #include <linux/bcma/bcma_soc.h>
0040 #include <asm/bootinfo.h>
0041 #include <asm/idle.h>
0042 #include <asm/prom.h>
0043 #include <asm/reboot.h>
0044 #include <asm/time.h>
0045 #include <bcm47xx.h>
0046 #include <bcm47xx_board.h>
0047
0048 union bcm47xx_bus bcm47xx_bus;
0049 EXPORT_SYMBOL(bcm47xx_bus);
0050
0051 enum bcm47xx_bus_type bcm47xx_bus_type;
0052 EXPORT_SYMBOL(bcm47xx_bus_type);
0053
0054 static void bcm47xx_machine_restart(char *command)
0055 {
0056 pr_alert("Please stand by while rebooting the system...\n");
0057 local_irq_disable();
0058
0059 switch (bcm47xx_bus_type) {
0060 #ifdef CONFIG_BCM47XX_SSB
0061 case BCM47XX_BUS_TYPE_SSB:
0062 if (bcm47xx_bus.ssb.chip_id == 0x4785)
0063 write_c0_diag4(1 << 22);
0064 ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 1);
0065 if (bcm47xx_bus.ssb.chip_id == 0x4785) {
0066 __asm__ __volatile__(
0067 ".set\tmips3\n\t"
0068 "sync\n\t"
0069 "wait\n\t"
0070 ".set\tmips0");
0071 }
0072 break;
0073 #endif
0074 #ifdef CONFIG_BCM47XX_BCMA
0075 case BCM47XX_BUS_TYPE_BCMA:
0076 bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 1);
0077 break;
0078 #endif
0079 }
0080 while (1)
0081 cpu_relax();
0082 }
0083
0084 static void bcm47xx_machine_halt(void)
0085 {
0086
0087 local_irq_disable();
0088 switch (bcm47xx_bus_type) {
0089 #ifdef CONFIG_BCM47XX_SSB
0090 case BCM47XX_BUS_TYPE_SSB:
0091 ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0);
0092 break;
0093 #endif
0094 #ifdef CONFIG_BCM47XX_BCMA
0095 case BCM47XX_BUS_TYPE_BCMA:
0096 bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 0);
0097 break;
0098 #endif
0099 }
0100 while (1)
0101 cpu_relax();
0102 }
0103
0104 #ifdef CONFIG_BCM47XX_SSB
0105 static void __init bcm47xx_register_ssb(void)
0106 {
0107 int err;
0108 char buf[100];
0109 struct ssb_mipscore *mcore;
0110
0111 err = ssb_bus_host_soc_register(&bcm47xx_bus.ssb, SSB_ENUM_BASE);
0112 if (err)
0113 panic("Failed to initialize SSB bus (err %d)", err);
0114
0115 mcore = &bcm47xx_bus.ssb.mipscore;
0116 if (bcm47xx_nvram_getenv("kernel_args", buf, sizeof(buf)) >= 0) {
0117 if (strstr(buf, "console=ttyS1")) {
0118 struct ssb_serial_port port;
0119
0120 pr_debug("Swapping serial ports!\n");
0121
0122 memcpy(&port, &mcore->serial_ports[0], sizeof(port));
0123 memcpy(&mcore->serial_ports[0], &mcore->serial_ports[1],
0124 sizeof(port));
0125 memcpy(&mcore->serial_ports[1], &port, sizeof(port));
0126 }
0127 }
0128 }
0129 #endif
0130
0131 #ifdef CONFIG_BCM47XX_BCMA
0132 static void __init bcm47xx_register_bcma(void)
0133 {
0134 int err;
0135
0136 err = bcma_host_soc_register(&bcm47xx_bus.bcma);
0137 if (err)
0138 panic("Failed to register BCMA bus (err %d)", err);
0139 }
0140 #endif
0141
0142
0143
0144
0145
0146
0147 void __init plat_mem_setup(void)
0148 {
0149 struct cpuinfo_mips *c = ¤t_cpu_data;
0150
0151 if (c->cputype == CPU_74K) {
0152 pr_info("Using bcma bus\n");
0153 #ifdef CONFIG_BCM47XX_BCMA
0154 bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA;
0155 bcm47xx_register_bcma();
0156 bcm47xx_set_system_type(bcm47xx_bus.bcma.bus.chipinfo.id);
0157 #ifdef CONFIG_HIGHMEM
0158 bcm47xx_prom_highmem_init();
0159 #endif
0160 #endif
0161 } else {
0162 pr_info("Using ssb bus\n");
0163 #ifdef CONFIG_BCM47XX_SSB
0164 bcm47xx_bus_type = BCM47XX_BUS_TYPE_SSB;
0165 bcm47xx_sprom_register_fallbacks();
0166 bcm47xx_register_ssb();
0167 bcm47xx_set_system_type(bcm47xx_bus.ssb.chip_id);
0168 #endif
0169 }
0170
0171 _machine_restart = bcm47xx_machine_restart;
0172 _machine_halt = bcm47xx_machine_halt;
0173 pm_power_off = bcm47xx_machine_halt;
0174 }
0175
0176 #ifdef CONFIG_BCM47XX_BCMA
0177 static struct device * __init bcm47xx_setup_device(void)
0178 {
0179 struct device *dev;
0180 int err;
0181
0182 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
0183 if (!dev)
0184 return NULL;
0185
0186 err = dev_set_name(dev, "bcm47xx_soc");
0187 if (err) {
0188 pr_err("Failed to set SoC device name: %d\n", err);
0189 kfree(dev);
0190 return NULL;
0191 }
0192
0193 err = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
0194 if (err)
0195 pr_err("Failed to set SoC DMA mask: %d\n", err);
0196
0197 return dev;
0198 }
0199 #endif
0200
0201
0202
0203
0204
0205 void __init bcm47xx_bus_setup(void)
0206 {
0207 #ifdef CONFIG_BCM47XX_BCMA
0208 if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA) {
0209 int err;
0210
0211 bcm47xx_bus.bcma.dev = bcm47xx_setup_device();
0212 if (!bcm47xx_bus.bcma.dev)
0213 panic("Failed to setup SoC device\n");
0214
0215 err = bcma_host_soc_init(&bcm47xx_bus.bcma);
0216 if (err)
0217 panic("Failed to initialize BCMA bus (err %d)", err);
0218 }
0219 #endif
0220
0221
0222 bcm47xx_board_detect();
0223 mips_set_machine_name(bcm47xx_board_get_name());
0224 }
0225
0226 static int __init bcm47xx_cpu_fixes(void)
0227 {
0228 switch (bcm47xx_bus_type) {
0229 #ifdef CONFIG_BCM47XX_SSB
0230 case BCM47XX_BUS_TYPE_SSB:
0231
0232 break;
0233 #endif
0234 #ifdef CONFIG_BCM47XX_BCMA
0235 case BCM47XX_BUS_TYPE_BCMA:
0236
0237
0238
0239
0240
0241
0242 if (bcm47xx_bus.bcma.bus.chipinfo.id == BCMA_CHIP_ID_BCM4706)
0243 cpu_wait = NULL;
0244 break;
0245 #endif
0246 }
0247 return 0;
0248 }
0249 arch_initcall(bcm47xx_cpu_fixes);
0250
0251 static struct fixed_phy_status bcm47xx_fixed_phy_status __initdata = {
0252 .link = 1,
0253 .speed = SPEED_100,
0254 .duplex = DUPLEX_FULL,
0255 };
0256
0257 static int __init bcm47xx_register_bus_complete(void)
0258 {
0259 switch (bcm47xx_bus_type) {
0260 #ifdef CONFIG_BCM47XX_SSB
0261 case BCM47XX_BUS_TYPE_SSB:
0262
0263 break;
0264 #endif
0265 #ifdef CONFIG_BCM47XX_BCMA
0266 case BCM47XX_BUS_TYPE_BCMA:
0267 if (device_register(bcm47xx_bus.bcma.dev))
0268 pr_err("Failed to register SoC device\n");
0269 bcma_bus_register(&bcm47xx_bus.bcma.bus);
0270 break;
0271 #endif
0272 }
0273 bcm47xx_buttons_register();
0274 bcm47xx_leds_register();
0275 bcm47xx_workarounds();
0276
0277 fixed_phy_add(PHY_POLL, 0, &bcm47xx_fixed_phy_status);
0278 return 0;
0279 }
0280 device_initcall(bcm47xx_register_bus_complete);