diff options
author | Paul Burton <paul.burton@imgtec.com> | 2016-10-05 18:18:21 +0100 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2016-10-06 18:04:20 +0200 |
commit | 3f5f0a4475e13345326061f00c68f428232ba2bc (patch) | |
tree | 0ad2657c668b23aafab4692d83c7156e55ca138f /arch/mips/mti-sead3 | |
parent | eed0eabd12ef061821cbfa20d903476e07645320 (diff) | |
download | talos-obmc-linux-3f5f0a4475e13345326061f00c68f428232ba2bc.tar.gz talos-obmc-linux-3f5f0a4475e13345326061f00c68f428232ba2bc.zip |
MIPS: generic: Convert SEAD-3 to a generic board
Convert the MIPS SEAD-3 board support to be a generic board, supported
by generic kernels.
Because the SEAD-3 boot protocol was defined long ago and we don't want
to force a switch to the UHI protocol, SEAD-3 is added as a legacy board
which is detected by reading the REVISION register. This may technically
not be a valid memory read & future work will include attempting to
handle that gracefully. In practice since SEAD-3 is the only legacy
board supported by the generic kernel so far the read will only happen
on SEAD-3 boards, and even once Malta is converted the same REVISION
register exists there too. Other boards such as Boston, Ci20 & Ci40 will
use the UHI boot protocol & thus not run any of the legacy board detect
functions.
Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/14354/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/mti-sead3')
-rw-r--r-- | arch/mips/mti-sead3/Makefile | 15 | ||||
-rw-r--r-- | arch/mips/mti-sead3/Platform | 7 | ||||
-rw-r--r-- | arch/mips/mti-sead3/sead3-dtshim.c | 292 | ||||
-rw-r--r-- | arch/mips/mti-sead3/sead3-init.c | 100 | ||||
-rw-r--r-- | arch/mips/mti-sead3/sead3-int.c | 23 | ||||
-rw-r--r-- | arch/mips/mti-sead3/sead3-setup.c | 39 | ||||
-rw-r--r-- | arch/mips/mti-sead3/sead3-time.c | 91 |
7 files changed, 0 insertions, 567 deletions
diff --git a/arch/mips/mti-sead3/Makefile b/arch/mips/mti-sead3/Makefile deleted file mode 100644 index 1674b9cf7527..000000000000 --- a/arch/mips/mti-sead3/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# -# Carsten Langgaard, carstenl@mips.com -# Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. -# -# Copyright (C) 2008 Wind River Systems, Inc. -# written by Ralf Baechle <ralf@linux-mips.org> -# -# Copyright (C) 2012 MIPS Technoligies, Inc. All rights reserved. -# Steven J. Hill <sjhill@mips.com> -# -obj-y := sead3-dtshim.o -obj-y += sead3-init.o -obj-y += sead3-int.o -obj-y += sead3-setup.o -obj-y += sead3-time.o diff --git a/arch/mips/mti-sead3/Platform b/arch/mips/mti-sead3/Platform deleted file mode 100644 index 387092427145..000000000000 --- a/arch/mips/mti-sead3/Platform +++ /dev/null @@ -1,7 +0,0 @@ -# -# MIPS SEAD-3 board -# -platform-$(CONFIG_MIPS_SEAD3) += mti-sead3/ -cflags-$(CONFIG_MIPS_SEAD3) += -I$(srctree)/arch/mips/include/asm/mach-sead3 -load-$(CONFIG_MIPS_SEAD3) += 0xffffffff80100000 -all-$(CONFIG_MIPS_SEAD3) := $(COMPRESSION_FNAME).srec diff --git a/arch/mips/mti-sead3/sead3-dtshim.c b/arch/mips/mti-sead3/sead3-dtshim.c deleted file mode 100644 index d6b0708d7a6f..000000000000 --- a/arch/mips/mti-sead3/sead3-dtshim.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright (C) 2016 Imagination Technologies - * Author: Paul Burton <paul.burton@imgtec.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#define pr_fmt(fmt) "sead3-dtshim: " fmt - -#include <linux/errno.h> -#include <linux/libfdt.h> -#include <linux/printk.h> - -#include <asm/fw/fw.h> -#include <asm/io.h> - -#define SEAD_CONFIG CKSEG1ADDR(0x1b100110) -#define SEAD_CONFIG_GIC_PRESENT BIT(1) - -static unsigned char fdt_buf[16 << 10] __initdata; - -static int append_memory(void *fdt) -{ - unsigned long phys_memsize, memsize; - __be32 mem_array[2]; - int err, mem_off; - char *var; - - /* find memory size from the bootloader environment */ - var = fw_getenv("memsize"); - if (var) { - err = kstrtoul(var, 0, &phys_memsize); - if (err) { - pr_err("Failed to read memsize env variable '%s'\n", - var); - return -EINVAL; - } - } else { - pr_warn("The bootloader didn't provide memsize: defaulting to 32MB\n"); - phys_memsize = 32 << 20; - } - - /* default to using all available RAM */ - memsize = phys_memsize; - - /* allow the user to override the usable memory */ - var = strstr(arcs_cmdline, "memsize="); - if (var) - memsize = memparse(var + strlen("memsize="), NULL); - - /* if the user says there's more RAM than we thought, believe them */ - phys_memsize = max_t(unsigned long, phys_memsize, memsize); - - /* find or add a memory node */ - mem_off = fdt_path_offset(fdt, "/memory"); - if (mem_off == -FDT_ERR_NOTFOUND) - mem_off = fdt_add_subnode(fdt, 0, "memory"); - if (mem_off < 0) { - pr_err("Unable to find or add memory DT node: %d\n", mem_off); - return mem_off; - } - - err = fdt_setprop_string(fdt, mem_off, "device_type", "memory"); - if (err) { - pr_err("Unable to set memory node device_type: %d\n", err); - return err; - } - - mem_array[0] = 0; - mem_array[1] = cpu_to_be32(phys_memsize); - err = fdt_setprop(fdt, mem_off, "reg", mem_array, sizeof(mem_array)); - if (err) { - pr_err("Unable to set memory regs property: %d\n", err); - return err; - } - - mem_array[0] = 0; - mem_array[1] = cpu_to_be32(memsize); - err = fdt_setprop(fdt, mem_off, "linux,usable-memory", - mem_array, sizeof(mem_array)); - if (err) { - pr_err("Unable to set linux,usable-memory property: %d\n", err); - return err; - } - - return 0; -} - -static int remove_gic(void *fdt) -{ - const unsigned int cpu_ehci_int = 2; - const unsigned int cpu_uart_int = 4; - const unsigned int cpu_eth_int = 6; - int gic_off, cpu_off, uart_off, eth_off, ehci_off, err; - uint32_t cfg, cpu_phandle; - - /* leave the GIC node intact if a GIC is present */ - cfg = __raw_readl((uint32_t *)SEAD_CONFIG); - if (cfg & SEAD_CONFIG_GIC_PRESENT) - return 0; - - gic_off = fdt_node_offset_by_compatible(fdt, -1, "mti,gic"); - if (gic_off < 0) { - pr_err("unable to find DT GIC node: %d\n", gic_off); - return gic_off; - } - - err = fdt_nop_node(fdt, gic_off); - if (err) { - pr_err("unable to nop GIC node\n"); - return err; - } - - cpu_off = fdt_node_offset_by_compatible(fdt, -1, - "mti,cpu-interrupt-controller"); - if (cpu_off < 0) { - pr_err("unable to find CPU intc node: %d\n", cpu_off); - return cpu_off; - } - - cpu_phandle = fdt_get_phandle(fdt, cpu_off); - if (!cpu_phandle) { - pr_err("unable to get CPU intc phandle\n"); - return -EINVAL; - } - - err = fdt_setprop_u32(fdt, 0, "interrupt-parent", cpu_phandle); - if (err) { - pr_err("unable to set root interrupt-parent: %d\n", err); - return err; - } - - uart_off = fdt_node_offset_by_compatible(fdt, -1, "ns16550a"); - while (uart_off >= 0) { - err = fdt_setprop_u32(fdt, uart_off, "interrupts", - cpu_uart_int); - if (err) { - pr_err("unable to set UART interrupts property: %d\n", - err); - return err; - } - - uart_off = fdt_node_offset_by_compatible(fdt, uart_off, - "ns16550a"); - } - if (uart_off != -FDT_ERR_NOTFOUND) { - pr_err("error searching for UART DT node: %d\n", uart_off); - return uart_off; - } - - eth_off = fdt_node_offset_by_compatible(fdt, -1, "smsc,lan9115"); - if (eth_off < 0) { - pr_err("unable to find ethernet DT node: %d\n", eth_off); - return eth_off; - } - - err = fdt_setprop_u32(fdt, eth_off, "interrupts", cpu_eth_int); - if (err) { - pr_err("unable to set ethernet interrupts property: %d\n", err); - return err; - } - - ehci_off = fdt_node_offset_by_compatible(fdt, -1, "mti,sead3-ehci"); - if (ehci_off < 0) { - pr_err("unable to find EHCI DT node: %d\n", ehci_off); - return ehci_off; - } - - err = fdt_setprop_u32(fdt, ehci_off, "interrupts", cpu_ehci_int); - if (err) { - pr_err("unable to set EHCI interrupts property: %d\n", err); - return err; - } - - return 0; -} - -static int serial_config(void *fdt) -{ - const char *yamontty, *mode_var; - char mode_var_name[9], path[18], parity; - unsigned int uart, baud, stop_bits; - bool hw_flow; - int chosen_off, err; - - yamontty = fw_getenv("yamontty"); - if (!yamontty || !strcmp(yamontty, "tty0")) { - uart = 0; - } else if (!strcmp(yamontty, "tty1")) { - uart = 1; - } else { - pr_warn("yamontty environment variable '%s' invalid\n", - yamontty); - uart = 0; - } - - baud = stop_bits = 0; - parity = 0; - hw_flow = false; - - snprintf(mode_var_name, sizeof(mode_var_name), "modetty%u", uart); - mode_var = fw_getenv(mode_var_name); - if (mode_var) { - while (mode_var[0] >= '0' && mode_var[0] <= '9') { - baud *= 10; - baud += mode_var[0] - '0'; - mode_var++; - } - if (mode_var[0] == ',') - mode_var++; - if (mode_var[0]) - parity = mode_var[0]; - if (mode_var[0] == ',') - mode_var++; - if (mode_var[0]) - stop_bits = mode_var[0] - '0'; - if (mode_var[0] == ',') - mode_var++; - if (!strcmp(mode_var, "hw")) - hw_flow = true; - } - - if (!baud) - baud = 38400; - - if (parity != 'e' && parity != 'n' && parity != 'o') - parity = 'n'; - - if (stop_bits != 7 && stop_bits != 8) - stop_bits = 8; - - WARN_ON(snprintf(path, sizeof(path), "uart%u:%u%c%u%s", - uart, baud, parity, stop_bits, - hw_flow ? "r" : "") >= sizeof(path)); - - /* find or add chosen node */ - chosen_off = fdt_path_offset(fdt, "/chosen"); - if (chosen_off == -FDT_ERR_NOTFOUND) - chosen_off = fdt_path_offset(fdt, "/chosen@0"); - if (chosen_off == -FDT_ERR_NOTFOUND) - chosen_off = fdt_add_subnode(fdt, 0, "chosen"); - if (chosen_off < 0) { - pr_err("Unable to find or add DT chosen node: %d\n", - chosen_off); - return chosen_off; - } - - err = fdt_setprop_string(fdt, chosen_off, "stdout-path", path); - if (err) { - pr_err("Unable to set stdout-path property: %d\n", err); - return err; - } - - return 0; -} - -void __init *sead3_dt_shim(void *fdt) -{ - int err; - - if (fdt_check_header(fdt)) - panic("Corrupt DT"); - - /* if this isn't SEAD3, leave the DT alone */ - if (fdt_node_check_compatible(fdt, 0, "mti,sead-3")) - return fdt; - - err = fdt_open_into(fdt, fdt_buf, sizeof(fdt_buf)); - if (err) - panic("Unable to open FDT: %d", err); - - err = append_memory(fdt_buf); - if (err) - panic("Unable to patch FDT: %d", err); - - err = remove_gic(fdt_buf); - if (err) - panic("Unable to patch FDT: %d", err); - - err = serial_config(fdt_buf); - if (err) - panic("Unable to patch FDT: %d", err); - - err = fdt_pack(fdt_buf); - if (err) - panic("Unable to pack FDT: %d\n", err); - - return fdt_buf; -} diff --git a/arch/mips/mti-sead3/sead3-init.c b/arch/mips/mti-sead3/sead3-init.c deleted file mode 100644 index 50f3fcb0fd80..000000000000 --- a/arch/mips/mti-sead3/sead3-init.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. - */ -#include <linux/init.h> -#include <linux/io.h> - -#include <asm/bootinfo.h> -#include <asm/cacheflush.h> -#include <asm/traps.h> -#include <asm/mips-boards/generic.h> -#include <asm/fw/fw.h> - -extern char except_vec_nmi; -extern char except_vec_ejtag_debug; - -static void __init mips_nmi_setup(void) -{ - void *base; - - base = cpu_has_veic ? - (void *)(CAC_BASE + 0xa80) : - (void *)(CAC_BASE + 0x380); -#ifdef CONFIG_CPU_MICROMIPS - /* - * Decrement the exception vector address by one for microMIPS. - */ - memcpy(base, (&except_vec_nmi - 1), 0x80); - - /* - * This is a hack. We do not know if the boot loader was built with - * microMIPS instructions or not. If it was not, the NMI exception - * code at 0x80000a80 will be taken in MIPS32 mode. The hand coded - * assembly below forces us into microMIPS mode if we are a pure - * microMIPS kernel. The assembly instructions are: - * - * 3C1A8000 lui k0,0x8000 - * 375A0381 ori k0,k0,0x381 - * 03400008 jr k0 - * 00000000 nop - * - * The mode switch occurs by jumping to the unaligned exception - * vector address at 0x80000381 which would have been 0x80000380 - * in MIPS32 mode. The jump to the unaligned address transitions - * us into microMIPS mode. - */ - if (!cpu_has_veic) { - void *base2 = (void *)(CAC_BASE + 0xa80); - *((unsigned int *)base2) = 0x3c1a8000; - *((unsigned int *)base2 + 1) = 0x375a0381; - *((unsigned int *)base2 + 2) = 0x03400008; - *((unsigned int *)base2 + 3) = 0x00000000; - flush_icache_range((unsigned long)base2, - (unsigned long)base2 + 0x10); - } -#else - memcpy(base, &except_vec_nmi, 0x80); -#endif - flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); -} - -static void __init mips_ejtag_setup(void) -{ - void *base; - - base = cpu_has_veic ? - (void *)(CAC_BASE + 0xa00) : - (void *)(CAC_BASE + 0x300); -#ifdef CONFIG_CPU_MICROMIPS - /* Deja vu... */ - memcpy(base, (&except_vec_ejtag_debug - 1), 0x80); - if (!cpu_has_veic) { - void *base2 = (void *)(CAC_BASE + 0xa00); - *((unsigned int *)base2) = 0x3c1a8000; - *((unsigned int *)base2 + 1) = 0x375a0301; - *((unsigned int *)base2 + 2) = 0x03400008; - *((unsigned int *)base2 + 3) = 0x00000000; - flush_icache_range((unsigned long)base2, - (unsigned long)base2 + 0x10); - } -#else - memcpy(base, &except_vec_ejtag_debug, 0x80); -#endif - flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); -} - -void __init prom_init(void) -{ - board_nmi_handler_setup = mips_nmi_setup; - board_ejtag_handler_setup = mips_ejtag_setup; - - fw_init_cmdline(); -} - -void __init prom_free_prom_memory(void) -{ -} diff --git a/arch/mips/mti-sead3/sead3-int.c b/arch/mips/mti-sead3/sead3-int.c deleted file mode 100644 index 2e6b73244ecd..000000000000 --- a/arch/mips/mti-sead3/sead3-int.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. - */ -#include <linux/init.h> -#include <linux/irqchip.h> -#include <linux/irqchip/mips-gic.h> - -#include <asm/cpu-info.h> -#include <asm/irq.h> - -void __init arch_init_irq(void) -{ - irqchip_init(); - - pr_info("GIC: %spresent\n", (gic_present) ? "" : "not "); - pr_info("EIC: %s\n", - (current_cpu_data.options & MIPS_CPU_VEIC) ? "on" : "off"); -} - diff --git a/arch/mips/mti-sead3/sead3-setup.c b/arch/mips/mti-sead3/sead3-setup.c deleted file mode 100644 index c915e54f10ac..000000000000 --- a/arch/mips/mti-sead3/sead3-setup.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. - * Copyright (C) 2013 Imagination Technologies Ltd. - */ -#include <linux/init.h> -#include <linux/libfdt.h> -#include <linux/of_fdt.h> - -#include <asm/prom.h> - -#include <asm/mach-sead3/sead3-dtshim.h> -#include <asm/mips-boards/generic.h> - -const char *get_system_type(void) -{ - return "MIPS SEAD3"; -} - -void __init *plat_get_fdt(void) -{ - return (void *)__dtb_start; -} - -void __init plat_mem_setup(void) -{ - void *fdt = plat_get_fdt(); - - fdt = sead3_dt_shim(fdt); - __dt_setup_arch(fdt); -} - -void __init device_tree_init(void) -{ - unflatten_and_copy_device_tree(); -} diff --git a/arch/mips/mti-sead3/sead3-time.c b/arch/mips/mti-sead3/sead3-time.c deleted file mode 100644 index 71feb5194478..000000000000 --- a/arch/mips/mti-sead3/sead3-time.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. - */ -#include <linux/init.h> -#include <linux/irqchip/mips-gic.h> - -#include <asm/cpu.h> -#include <asm/setup.h> -#include <asm/time.h> -#include <asm/irq.h> -#include <asm/mips-boards/generic.h> - -static void __iomem *status_reg = (void __iomem *)0xbf000410; - -/* - * Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect. - */ -static unsigned int __init estimate_cpu_frequency(void) -{ - unsigned int prid = read_c0_prid() & (PRID_COMP_MASK | PRID_IMP_MASK); - unsigned int tick = 0; - unsigned int freq; - unsigned int orig; - unsigned long flags; - - local_irq_save(flags); - - orig = readl(status_reg) & 0x2; /* get original sample */ - /* wait for transition */ - while ((readl(status_reg) & 0x2) == orig) - ; - orig = orig ^ 0x2; /* flip the bit */ - - write_c0_count(0); - - /* wait 1 second (the sampling clock transitions every 10ms) */ - while (tick < 100) { - /* wait for transition */ - while ((readl(status_reg) & 0x2) == orig) - ; - orig = orig ^ 0x2; /* flip the bit */ - tick++; - } - - freq = read_c0_count(); - - local_irq_restore(flags); - - mips_hpt_frequency = freq; - - /* Adjust for processor */ - if ((prid != (PRID_COMP_MIPS | PRID_IMP_20KC)) && - (prid != (PRID_COMP_MIPS | PRID_IMP_25KF))) - freq *= 2; - - freq += 5000; /* rounding */ - freq -= freq%10000; - - return freq ; -} - -int get_c0_perfcount_int(void) -{ - if (gic_present) - return gic_get_c0_perfcount_int(); - if (cp0_perfcount_irq >= 0) - return MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; - return -1; -} -EXPORT_SYMBOL_GPL(get_c0_perfcount_int); - -unsigned int get_c0_compare_int(void) -{ - if (gic_present) - return gic_get_c0_compare_int(); - return MIPS_CPU_IRQ_BASE + cp0_compare_irq; -} - -void __init plat_time_init(void) -{ - unsigned int est_freq; - - est_freq = estimate_cpu_frequency(); - - pr_debug("CPU frequency %d.%02d MHz\n", (est_freq / 1000000), - (est_freq % 1000000) * 100 / 1000000); -} |