--- a/arch/mips/config-shared.in +++ b/arch/mips/config-shared.in @@ -208,6 +208,14 @@ if [ "$CONFIG_SIBYTE_SB1xxx_SOC" = "y" ] fi define_bool CONFIG_MIPS_RTC y fi +dep_bool 'Support for Broadcom MIPS-based boards' CONFIG_MIPS_BRCM $CONFIG_EXPERIMENTAL +dep_bool 'Support for Broadcom BCM947XX' CONFIG_BCM947XX $CONFIG_MIPS_BRCM +if [ "$CONFIG_BCM947XX" = "y" ] ; then + bool ' Support for Broadcom BCM4710' CONFIG_BCM4710 + bool ' Support for Broadcom BCM4310' CONFIG_BCM4310 + bool ' Support for Broadcom BCM4704' CONFIG_BCM4704 + bool ' Support for Broadcom BCM5365' CONFIG_BCM5365 +fi bool 'Support for SNI RM200 PCI' CONFIG_SNI_RM200_PCI bool 'Support for TANBAC TB0226 (Mbase)' CONFIG_TANBAC_TB0226 bool 'Support for TANBAC TB0229 (VR4131DIMM)' CONFIG_TANBAC_TB0229 @@ -229,6 +237,11 @@ define_bool CONFIG_RWSEM_GENERIC_SPINLOC define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n # +# Provide an option for a default kernel command line +# +string 'Default kernel command string' CONFIG_CMDLINE "" + +# # Select some configuration options automatically based on user selections. # if [ "$CONFIG_ACER_PICA_61" = "y" ]; then @@ -554,6 +567,12 @@ if [ "$CONFIG_SIBYTE_SB1xxx_SOC" = "y" ] define_bool CONFIG_SWAP_IO_SPACE_L y define_bool CONFIG_BOOT_ELF32 y fi +if [ "$CONFIG_BCM947XX" = "y" ] ; then + define_bool CONFIG_PCI y + define_bool CONFIG_NONCOHERENT_IO y + define_bool CONFIG_NEW_TIME_C y + define_bool CONFIG_NEW_IRQ y +fi if [ "$CONFIG_SNI_RM200_PCI" = "y" ]; then define_bool CONFIG_ARC32 y define_bool CONFIG_ARC_MEMORY y @@ -1042,7 +1061,11 @@ comment 'Kernel hacking' bool 'Are you using a crosscompiler' CONFIG_CROSSCOMPILE bool 'Enable run-time debugging' CONFIG_RUNTIME_DEBUG -bool 'Remote GDB kernel debugging' CONFIG_KGDB +if [ "$CONFIG_BCM947XX" = "y" ] ; then + bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG +else + bool 'Remote GDB kernel debugging' CONFIG_KGDB +fi dep_bool ' Console output to GDB' CONFIG_GDB_CONSOLE $CONFIG_KGDB if [ "$CONFIG_KGDB" = "y" ]; then define_bool CONFIG_DEBUG_INFO y --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -162,7 +162,7 @@ static inline int __cpu_has_fpu(void) static inline void cpu_probe_legacy(struct cpuinfo_mips *c) { - switch (c->processor_id & 0xff00) { + switch (c->processor_id & PRID_IMP_MASK) { case PRID_IMP_R2000: c->cputype = CPU_R2000; c->isa_level = MIPS_CPU_ISA_I; @@ -172,7 +172,7 @@ static inline void cpu_probe_legacy(stru c->tlbsize = 64; break; case PRID_IMP_R3000: - if ((c->processor_id & 0xff) == PRID_REV_R3000A) + if ((c->processor_id & PRID_REV_MASK) == PRID_REV_R3000A) if (cpu_has_confreg()) c->cputype = CPU_R3081E; else @@ -187,12 +187,12 @@ static inline void cpu_probe_legacy(stru break; case PRID_IMP_R4000: if (read_c0_config() & CONF_SC) { - if ((c->processor_id & 0xff) >= PRID_REV_R4400) + if ((c->processor_id & PRID_REV_MASK) >= PRID_REV_R4400) c->cputype = CPU_R4400PC; else c->cputype = CPU_R4000PC; } else { - if ((c->processor_id & 0xff) >= PRID_REV_R4400) + if ((c->processor_id & PRID_REV_MASK) >= PRID_REV_R4400) c->cputype = CPU_R4400SC; else c->cputype = CPU_R4000SC; @@ -438,7 +438,7 @@ static inline void decode_config1(struct static inline void cpu_probe_mips(struct cpuinfo_mips *c) { decode_config1(c); - switch (c->processor_id & 0xff00) { + switch (c->processor_id & PRID_IMP_MASK) { case PRID_IMP_4KC: c->cputype = CPU_4KC; c->isa_level = MIPS_CPU_ISA_M32; @@ -479,10 +479,10 @@ static inline void cpu_probe_alchemy(str { decode_config1(c); c->options |= MIPS_CPU_PREFETCH; - switch (c->processor_id & 0xff00) { + switch (c->processor_id & PRID_IMP_MASK) { case PRID_IMP_AU1_REV1: case PRID_IMP_AU1_REV2: - switch ((c->processor_id >> 24) & 0xff) { + switch ((c->processor_id >> 24) & PRID_REV_MASK) { case 0: c->cputype = CPU_AU1000; break; @@ -510,10 +510,34 @@ static inline void cpu_probe_alchemy(str } } +static inline void cpu_probe_broadcom(struct cpuinfo_mips *c) +{ + decode_config1(c); + c->options |= MIPS_CPU_PREFETCH; + switch (c->processor_id & PRID_IMP_MASK) { + case PRID_IMP_BCM4710: + c->cputype = CPU_BCM4710; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_4KTLB | MIPS_CPU_COUNTER; + c->scache.flags = MIPS_CACHE_NOT_PRESENT; + break; + case PRID_IMP_4KC: + case PRID_IMP_BCM3302: + c->cputype = CPU_BCM3302; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_4KTLB | MIPS_CPU_COUNTER; + c->scache.flags = MIPS_CACHE_NOT_PRESENT; + break; + default: + c->cputype = CPU_UNKNOWN; + break; + } +} + static inline void cpu_probe_sibyte(struct cpuinfo_mips *c) { decode_config1(c); - switch (c->processor_id & 0xff00) { + switch (c->processor_id & PRID_IMP_MASK) { case PRID_IMP_SB1: c->cputype = CPU_SB1; c->isa_level = MIPS_CPU_ISA_M64; @@ -535,7 +559,7 @@ static inline void cpu_probe_sibyte(stru static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c) { decode_config1(c); - switch (c->processor_id & 0xff00) { + switch (c->processor_id & PRID_IMP_MASK) { case PRID_IMP_SR71000: c->cputype = CPU_SR71000; c->isa_level = MIPS_CPU_ISA_M64; @@ -560,7 +584,7 @@ __init void cpu_probe(void) c->cputype = CPU_UNKNOWN; c->processor_id = read_c0_prid(); - switch (c->processor_id & 0xff0000) { + switch (c->processor_id & PRID_COMP_MASK) { case PRID_COMP_LEGACY: cpu_probe_legacy(c); @@ -571,6 +595,9 @@ __init void cpu_probe(void) case PRID_COMP_ALCHEMY: cpu_probe_alchemy(c); break; + case PRID_COMP_BROADCOM: + cpu_probe_broadcom(c); + break; case PRID_COMP_SIBYTE: cpu_probe_sibyte(c); break; --- a/arch/mips/kernel/head.S +++ b/arch/mips/kernel/head.S @@ -28,12 +28,20 @@ #include #include +#ifdef CONFIG_BCM4710 +#undef eret +#define eret nop; nop; eret +#endif + .text + j kernel_entry + nop + /* * Reserved space for exception handlers. * Necessary for machines which link their kernels at KSEG0. */ - .fill 0x400 + .fill 0x3f4 /* The following two symbols are used for kernel profiling. */ EXPORT(stext) --- a/arch/mips/kernel/proc.c +++ b/arch/mips/kernel/proc.c @@ -78,9 +78,10 @@ static const char *cpu_name[] = { [CPU_AU1550] "Au1550", [CPU_24K] "MIPS 24K", [CPU_AU1200] "Au1200", + [CPU_BCM4710] "BCM4710", + [CPU_BCM3302] "BCM3302", }; - static int show_cpuinfo(struct seq_file *m, void *v) { unsigned int version = current_cpu_data.processor_id; --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -493,6 +493,7 @@ void __init setup_arch(char **cmdline_p) void swarm_setup(void); void hp_setup(void); void au1x00_setup(void); + void brcm_setup(void); void frame_info_init(void); frame_info_init(); @@ -691,6 +692,11 @@ void __init setup_arch(char **cmdline_p) pmc_yosemite_setup(); break; #endif +#if defined(CONFIG_BCM4710) || defined(CONFIG_BCM4310) + case MACH_GROUP_BRCM: + brcm_setup(); + break; +#endif default: panic("Unsupported architecture"); } --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -920,6 +920,7 @@ void __init per_cpu_trap_init(void) void __init trap_init(void) { extern char except_vec1_generic; + extern char except_vec2_generic; extern char except_vec3_generic, except_vec3_r4000; extern char except_vec_ejtag_debug; extern char except_vec4; @@ -927,6 +928,7 @@ void __init trap_init(void) /* Copy the generic exception handler code to it's final destination. */ memcpy((void *)(KSEG0 + 0x80), &except_vec1_generic, 0x80); + memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80); /* * Setup default vectors @@ -985,6 +987,12 @@ void __init trap_init(void) set_except_vector(13, handle_tr); set_except_vector(22, handle_mdmx); + if (current_cpu_data.cputype == CPU_SB1) { + /* Enable timer interrupt and scd mapped interrupt */ + clear_c0_status(0xf000); + set_c0_status(0xc00); + } + if (cpu_has_fpu && !cpu_has_nofpuex) set_except_vector(15, handle_fpe); --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -726,6 +726,19 @@ LOADADDR += 0x80020000 endif # +# Broadcom BCM947XX variants +# +ifdef CONFIG_BCM947XX +LIBS += arch/mips/bcm947xx/generic/brcm.o arch/mips/bcm947xx/bcm947xx.o +SUBDIRS += arch/mips/bcm947xx/generic arch/mips/bcm947xx +LOADADDR := 0x80001000 + +zImage: vmlinux + $(MAKE) -C arch/$(ARCH)/bcm947xx/compressed +export LOADADDR +endif + +# # Choosing incompatible machines durings configuration will result in # error messages during linking. Select a default linkscript if # none has been choosen above. @@ -779,6 +792,7 @@ archclean: $(MAKE) -C arch/$(ARCH)/tools clean $(MAKE) -C arch/mips/baget clean $(MAKE) -C arch/mips/lasat clean + $(MAKE) -C arch/mips/bcm947xx/compressed clean archmrproper: @$(MAKEBOOT) mrproper --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -1118,3 +1118,47 @@ void __init ld_mmu_r4xx0(void) build_clear_page(); build_copy_page(); } + +#ifdef CONFIG_BCM4704 +static void __init mips32_icache_fill(unsigned long addr, uint nbytes) +{ + unsigned long ic_lsize = current_cpu_data.icache.linesz; + int i; + for (i = 0; i < nbytes; i += ic_lsize) + fill_icache_line((addr + i)); +} + +/* + * This must be run from the cache on 4704A0 + * so there are no mips core BIU ops in progress + * when the PFC is enabled. + */ +#define PFC_CR0 0xff400000 /* control reg 0 */ +#define PFC_CR1 0xff400004 /* control reg 1 */ +static void __init enable_pfc(u32 mode) +{ + /* write range */ + *(volatile u32 *)PFC_CR1 = 0xffff0000; + + /* enable */ + *(volatile u32 *)PFC_CR0 = mode; +} +#endif + + +void check_enable_mips_pfc(int val) +{ + +#ifdef CONFIG_BCM4704 + struct cpuinfo_mips *c = ¤t_cpu_data; + + /* enable prefetch cache */ + if (((c->processor_id & (PRID_COMP_MASK | PRID_IMP_MASK)) == PRID_IMP_BCM3302) + && (read_c0_diag() & (1 << 29))) { + mips32_icache_fill((unsigned long) &enable_pfc, 64); + enable_pfc(val); + } +#endif +} + + --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -13,7 +13,9 @@ obj-$(CONFIG_MIPS_GT64120) += ops-gt6412 obj-$(CONFIG_MIPS_MSC) += ops-msc.o obj-$(CONFIG_MIPS_NILE4) += ops-nile4.o obj-$(CONFIG_SNI_RM200_PCI) += ops-sni.o +ifndef CONFIG_BCM947XX obj-y += pci.o +endif obj-$(CONFIG_PCI_AUTO) += pci_auto.o include $(TOPDIR)/Rules.make --- a/drivers/char/serial.c +++ b/drivers/char/serial.c @@ -444,6 +444,10 @@ static _INLINE_ unsigned int serial_in(s return inb(info->port+1); #endif case SERIAL_IO_MEM: +#ifdef CONFIG_BCM4310 + readb((unsigned long) info->iomem_base + + (UART_SCR<iomem_reg_shift)); +#endif return readb((unsigned long) info->iomem_base + (offset<iomem_reg_shift)); default: @@ -464,6 +468,9 @@ static _INLINE_ void serial_out(struct a case SERIAL_IO_MEM: writeb(value, (unsigned long) info->iomem_base + (offset<iomem_reg_shift)); +#ifdef CONFIG_BCM4704 + *((volatile unsigned int *) KSEG1ADDR(0x18000000)); +#endif break; default: outb(value, info->port+offset); @@ -1728,7 +1735,7 @@ static void change_speed(struct async_st /* Special case since 134 is really 134.5 */ quot = (2*baud_base / 269); else if (baud) - quot = baud_base / baud; + quot = (baud_base + (baud / 2)) / baud; } /* If the quotient is zero refuse the change */ if (!quot && old_termios) { @@ -1745,12 +1752,12 @@ static void change_speed(struct async_st /* Special case since 134 is really 134.5 */ quot = (2*baud_base / 269); else if (baud) - quot = baud_base / baud; + quot = (baud_base + (baud / 2)) / baud; } } /* As a last resort, if the quotient is zero, default to 9600 bps */ if (!quot) - quot = baud_base / 9600; + quot = (baud_base + 4800) / 9600; /* * Work around a bug in the Oxford Semiconductor 952 rev B * chip which causes it to seriously miscalculate baud rates @@ -5994,6 +6001,13 @@ static int __init serial_console_setup(s * Divisor, bytesize and parity */ state = rs_table + co->index; + /* + * Safe guard: state structure must have been initialized + */ + if (state->iomem_base == NULL) { + printk("!unable to setup serial console!\n"); + return -1; + } if (doflow) state->flags |= ASYNC_CONS_FLOW; info = &async_sercons; @@ -6007,7 +6021,7 @@ static int __init serial_console_setup(s info->io_type = state->io_type; info->iomem_base = state->iomem_base; info->iomem_reg_shift = state->iomem_reg_shift; - quot = state->baud_base / baud; + quot = (state->baud_base + (baud / 2)) / baud; cval = cflag & (CSIZE | CSTOPB); #if defined(__powerpc__) || defined(__alpha__) cval >>= 8; --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -3,6 +3,8 @@ # Makefile for the Linux network (ethercard) device drivers. # +EXTRA_CFLAGS := -I$(TOPDIR)/arch/mips/bcm947xx/include + obj-y := obj-m := obj-n := --- a/drivers/parport/Config.in +++ b/drivers/parport/Config.in @@ -11,6 +11,7 @@ comment 'Parallel port support' tristate 'Parallel port support' CONFIG_PARPORT if [ "$CONFIG_PARPORT" != "n" ]; then dep_tristate ' PC-style hardware' CONFIG_PARPORT_PC $CONFIG_PARPORT + dep_tristate ' Asus WL500g parallel port' CONFIG_PARPORT_SPLINK $CONFIG_PARPORT if [ "$CONFIG_PARPORT_PC" != "n" -a "$CONFIG_SERIAL" != "n" ]; then if [ "$CONFIG_SERIAL" = "m" ]; then define_tristate CONFIG_PARPORT_PC_CML1 m --- a/drivers/parport/Makefile +++ b/drivers/parport/Makefile @@ -22,6 +22,7 @@ endif obj-$(CONFIG_PARPORT) += parport.o obj-$(CONFIG_PARPORT_PC) += parport_pc.o +obj-$(CONFIG_PARPORT_SPLINK) += parport_splink.o obj-$(CONFIG_PARPORT_PC_PCMCIA) += parport_cs.o obj-$(CONFIG_PARPORT_AMIGA) += parport_amiga.o obj-$(CONFIG_PARPORT_MFC3) += parport_mfc3.o --- a/include/asm-mips/bootinfo.h +++ b/include/asm-mips/bootinfo.h @@ -37,6 +37,7 @@ #define MACH_GROUP_HP_LJ 20 /* Hewlett Packard LaserJet */ #define MACH_GROUP_LASAT 21 #define MACH_GROUP_TITAN 22 /* PMC-Sierra Titan */ +#define MACH_GROUP_BRCM 23 /* Broadcom */ /* * Valid machtype values for group unknown (low order halfword of mips_machtype) @@ -197,6 +198,15 @@ #define MACH_TANBAC_TB0229 7 /* TANBAC TB0229 (VR4131DIMM) */ /* + * Valid machtypes for group Broadcom + */ +#define MACH_BCM93725 0 +#define MACH_BCM93725_VJ 1 +#define MACH_BCM93730 2 +#define MACH_BCM947XX 3 +#define MACH_BCM933XX 4 + +/* * Valid machtype for group TITAN */ #define MACH_TITAN_YOSEMITE 1 /* PMC-Sierra Yosemite */ --- a/include/asm-mips/cpu.h +++ b/include/asm-mips/cpu.h @@ -22,6 +22,11 @@ spec. */ +#define PRID_COPT_MASK 0xff000000 +#define PRID_COMP_MASK 0x00ff0000 +#define PRID_IMP_MASK 0x0000ff00 +#define PRID_REV_MASK 0x000000ff + #define PRID_COMP_LEGACY 0x000000 #define PRID_COMP_MIPS 0x010000 #define PRID_COMP_BROADCOM 0x020000 @@ -58,6 +63,7 @@ #define PRID_IMP_RM7000 0x2700 #define PRID_IMP_NEVADA 0x2800 /* RM5260 ??? */ #define PRID_IMP_RM9000 0x3400 +#define PRID_IMP_BCM4710 0x4000 #define PRID_IMP_R5432 0x5400 #define PRID_IMP_R5500 0x5500 #define PRID_IMP_4KC 0x8000 @@ -66,10 +72,16 @@ #define PRID_IMP_4KEC 0x8400 #define PRID_IMP_4KSC 0x8600 #define PRID_IMP_25KF 0x8800 +#define PRID_IMP_BCM3302 0x9000 +#define PRID_IMP_BCM3303 0x9100 #define PRID_IMP_24K 0x9300 #define PRID_IMP_UNKNOWN 0xff00 +#define BCM330X(id) \ + (((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == (PRID_COMP_BROADCOM | PRID_IMP_BCM3302)) \ + || ((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == (PRID_COMP_BROADCOM | PRID_IMP_BCM3303))) + /* * These are the PRID's for when 23:16 == PRID_COMP_SIBYTE */ @@ -174,7 +186,9 @@ #define CPU_AU1550 57 #define CPU_24K 58 #define CPU_AU1200 59 -#define CPU_LAST 59 +#define CPU_BCM4710 60 +#define CPU_BCM3302 61 +#define CPU_LAST 61 /* * ISA Level encodings --- a/include/asm-mips/r4kcache.h +++ b/include/asm-mips/r4kcache.h @@ -567,4 +567,17 @@ static inline void blast_scache128_page_ cache128_unroll32(addr|ws,Index_Writeback_Inv_SD); } +extern inline void fill_icache_line(unsigned long addr) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + ".set mips3\n\t" + "cache %1, (%0)\n\t" + ".set mips0\n\t" + ".set reorder" + : + : "r" (addr), + "i" (Fill)); +} + #endif /* __ASM_R4KCACHE_H */ --- a/include/asm-mips/serial.h +++ b/include/asm-mips/serial.h @@ -223,6 +223,13 @@ #define TXX927_SERIAL_PORT_DEFNS #endif +#ifdef CONFIG_BCM947XX +/* reserve 4 ports to be configured at runtime */ +#define BCM947XX_SERIAL_PORT_DEFNS { 0, }, { 0, }, { 0, }, { 0, }, +#else +#define BCM947XX_SERIAL_PORT_DEFNS +#endif + #ifdef CONFIG_HAVE_STD_PC_SERIAL_PORT #define STD_SERIAL_PORT_DEFNS \ /* UART CLK PORT IRQ FLAGS */ \ @@ -470,6 +477,7 @@ #define SERIAL_PORT_DFNS \ ATLAS_SERIAL_PORT_DEFNS \ AU1000_SERIAL_PORT_DEFNS \ + BCM947XX_SERIAL_PORT_DEFNS \ COBALT_SERIAL_PORT_DEFNS \ DDB5477_SERIAL_PORT_DEFNS \ EV96100_SERIAL_PORT_DEFNS \ --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -255,7 +255,13 @@ static struct dev_name_struct { { "ftlb", 0x2c08 }, { "ftlc", 0x2c10 }, { "ftld", 0x2c18 }, +#if defined(CONFIG_MTD_BLOCK) || defined(CONFIG_MTD_BLOCK_RO) { "mtdblock", 0x1f00 }, + { "mtdblock0",0x1f00 }, + { "mtdblock1",0x1f01 }, + { "mtdblock2",0x1f02 }, + { "mtdblock3",0x1f03 }, +#endif { "nb", 0x2b00 }, { NULL, 0 } };