^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * License. See the file "COPYING" in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2004-2007 Cavium Networks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2008, 2009 Wind River Systems
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * written by Ralf Baechle <ralf@linux-mips.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/compiler.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/console.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/memblock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/serial.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/string.h> /* for memset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/serial_core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/serial_8250.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/of_fdt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/libfdt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/kexec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <asm/processor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <asm/reboot.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <asm/smp-ops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <asm/irq_cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <asm/mipsregs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <asm/bootinfo.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <asm/sections.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <asm/fw/fw.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <asm/setup.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <asm/prom.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <asm/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <asm/octeon/octeon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <asm/octeon/pci-octeon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <asm/octeon/cvmx-rst-defs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * TRUE for devices having registers with little-endian byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * order, FALSE for registers with native-endian byte order.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * PCI mandates little-endian, USB and SATA are configuraable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * but we chose little-endian for these.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) const bool octeon_should_swizzle_table[256] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) [0x00] = true, /* bootbus/CF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) [0x1b] = true, /* PCI mmio window */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) [0x1c] = true, /* PCI mmio window */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) [0x1d] = true, /* PCI mmio window */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) [0x1e] = true, /* PCI mmio window */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) [0x68] = true, /* OCTEON III USB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) [0x69] = true, /* OCTEON III USB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) [0x6c] = true, /* OCTEON III SATA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) [0x6f] = true, /* OCTEON II USB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) EXPORT_SYMBOL(octeon_should_swizzle_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #ifdef CONFIG_PCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) extern void pci_console_init(const char *arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static unsigned long long max_memory = ULLONG_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static unsigned long long reserve_low_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) DEFINE_SEMAPHORE(octeon_bootbus_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) EXPORT_SYMBOL(octeon_bootbus_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static struct octeon_boot_descriptor *octeon_boot_desc_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct cvmx_bootinfo *octeon_bootinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) EXPORT_SYMBOL(octeon_bootinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #ifdef CONFIG_KEXEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * Wait for relocation code is prepared and send
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * secondary CPUs to spin until kernel is relocated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static void octeon_kexec_smp_down(void *ignored)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) int cpu = smp_processor_id();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) local_irq_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) set_cpu_online(cpu, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) while (!atomic_read(&kexec_ready_to_reboot))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) asm volatile (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) " sync \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) " synci ($0) \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) kexec_reboot();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define OCTEON_DDR0_BASE (0x0ULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define OCTEON_DDR0_SIZE (0x010000000ULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define OCTEON_DDR1_BASE (0x410000000ULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define OCTEON_DDR1_SIZE (0x010000000ULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define OCTEON_DDR2_BASE (0x020000000ULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define OCTEON_DDR2_SIZE (0x3e0000000ULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define OCTEON_MAX_PHY_MEM_SIZE (16*1024*1024*1024ULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static struct kimage *kimage_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static void kexec_bootmem_init(uint64_t mem_size, uint32_t low_reserved_bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) int64_t addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct cvmx_bootmem_desc *bootmem_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) bootmem_desc = cvmx_bootmem_get_desc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (mem_size > OCTEON_MAX_PHY_MEM_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) mem_size = OCTEON_MAX_PHY_MEM_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) pr_err("Error: requested memory too large,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) "truncating to maximum size\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) bootmem_desc->major_version = CVMX_BOOTMEM_DESC_MAJ_VER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) bootmem_desc->minor_version = CVMX_BOOTMEM_DESC_MIN_VER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) addr = (OCTEON_DDR0_BASE + reserve_low_mem + low_reserved_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) bootmem_desc->head_addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (mem_size <= OCTEON_DDR0_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) __cvmx_bootmem_phy_free(addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) mem_size - reserve_low_mem -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) low_reserved_bytes, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) __cvmx_bootmem_phy_free(addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) OCTEON_DDR0_SIZE - reserve_low_mem -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) low_reserved_bytes, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) mem_size -= OCTEON_DDR0_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (mem_size > OCTEON_DDR1_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) __cvmx_bootmem_phy_free(OCTEON_DDR1_BASE, OCTEON_DDR1_SIZE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) __cvmx_bootmem_phy_free(OCTEON_DDR2_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) mem_size - OCTEON_DDR1_SIZE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) __cvmx_bootmem_phy_free(OCTEON_DDR1_BASE, mem_size, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) static int octeon_kexec_prepare(struct kimage *image)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) char *bootloader = "kexec";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) octeon_boot_desc_ptr->argc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) for (i = 0; i < image->nr_segments; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (!strncmp(bootloader, (char *)image->segment[i].buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) strlen(bootloader))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * convert command line string to array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * of parameters (as bootloader does).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) int argc = 0, offt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) char *str = (char *)image->segment[i].buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) char *ptr = strchr(str, ' ');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) while (ptr && (OCTEON_ARGV_MAX_ARGS > argc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) *ptr = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (ptr[1] != ' ') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) offt = (int)(ptr - str + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) octeon_boot_desc_ptr->argv[argc] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) image->segment[i].mem + offt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) argc++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) ptr = strchr(ptr + 1, ' ');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) octeon_boot_desc_ptr->argc = argc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * Information about segments will be needed during pre-boot memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * initialization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) kimage_ptr = image;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static void octeon_generic_shutdown(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct cvmx_bootmem_desc *bootmem_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) void *named_block_array_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) bootmem_desc = cvmx_bootmem_get_desc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) named_block_array_ptr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) cvmx_phys_to_ptr(bootmem_desc->named_block_array_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /* disable watchdogs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) for_each_online_cpu(cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) cvmx_write_csr(CVMX_CIU_WDOGX(cpu_logical_map(cpu)), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) cvmx_write_csr(CVMX_CIU_WDOGX(cvmx_get_core_num()), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (kimage_ptr != kexec_crash_image) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) memset(named_block_array_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) CVMX_BOOTMEM_NUM_NAMED_BLOCKS *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) sizeof(struct cvmx_bootmem_named_block_desc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * Mark all memory (except low 0x100000 bytes) as free.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * It is the same thing that bootloader does.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) kexec_bootmem_init(octeon_bootinfo->dram_size*1024ULL*1024ULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 0x100000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * Allocate all segments to avoid their corruption during boot.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) for (i = 0; i < kimage_ptr->nr_segments; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) cvmx_bootmem_alloc_address(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) kimage_ptr->segment[i].memsz + 2*PAGE_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) kimage_ptr->segment[i].mem - PAGE_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * Do not mark all memory as free. Free only named sections
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * leaving the rest of memory unchanged.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) struct cvmx_bootmem_named_block_desc *ptr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) (struct cvmx_bootmem_named_block_desc *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) named_block_array_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) for (i = 0; i < bootmem_desc->named_block_num_blocks; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (ptr[i].size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) cvmx_bootmem_free_named(ptr[i].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) kexec_args[2] = 1UL; /* running on octeon_main_processor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) kexec_args[3] = (unsigned long)octeon_boot_desc_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) secondary_kexec_args[2] = 0UL; /* running on secondary cpu */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) secondary_kexec_args[3] = (unsigned long)octeon_boot_desc_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) static void octeon_shutdown(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) octeon_generic_shutdown();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) smp_call_function(octeon_kexec_smp_down, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) smp_wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) while (num_online_cpus() > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) static void octeon_crash_shutdown(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) octeon_generic_shutdown();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) default_machine_crash_shutdown(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) void octeon_crash_smp_send_stop(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) /* disable watchdogs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) for_each_online_cpu(cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) cvmx_write_csr(CVMX_CIU_WDOGX(cpu_logical_map(cpu)), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) #endif /* CONFIG_KEXEC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) #ifdef CONFIG_CAVIUM_RESERVE32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) uint64_t octeon_reserve32_memory;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) EXPORT_SYMBOL(octeon_reserve32_memory);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) #ifdef CONFIG_KEXEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) /* crashkernel cmdline parameter is parsed _after_ memory setup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * we also parse it here (workaround for EHB5200) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) static uint64_t crashk_size, crashk_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) static int octeon_uart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) extern asmlinkage void handle_int(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * Return non zero if we are currently running in the Octeon simulator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) * Returns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) int octeon_is_simulation(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return octeon_bootinfo->board_type == CVMX_BOARD_TYPE_SIM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) EXPORT_SYMBOL(octeon_is_simulation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * Return true if Octeon is in PCI Host mode. This means
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * Linux can control the PCI bus.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * Returns Non zero if Octeon in host mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) int octeon_is_pci_host(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) #ifdef CONFIG_PCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) return octeon_bootinfo->config_flags & CVMX_BOOTINFO_CFG_FLAG_PCI_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) * Get the clock rate of Octeon
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) * Returns Clock rate in HZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) uint64_t octeon_get_clock_rate(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) struct cvmx_sysinfo *sysinfo = cvmx_sysinfo_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) return sysinfo->cpu_clock_hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) EXPORT_SYMBOL(octeon_get_clock_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) static u64 octeon_io_clock_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) u64 octeon_get_io_clock_rate(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) return octeon_io_clock_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) EXPORT_SYMBOL(octeon_get_io_clock_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) * Write to the LCD display connected to the bootbus. This display
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) * exists on most Cavium evaluation boards. If it doesn't exist, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) * this function doesn't do anything.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) * @s: String to write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) static void octeon_write_lcd(const char *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (octeon_bootinfo->led_display_base_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) void __iomem *lcd_address =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) ioremap(octeon_bootinfo->led_display_base_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) for (i = 0; i < 8; i++, s++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (*s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) iowrite8(*s, lcd_address + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) iowrite8(' ', lcd_address + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) iounmap(lcd_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) * Return the console uart passed by the bootloader
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) * Returns uart (0 or 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) static int octeon_get_boot_uart(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) return (octeon_boot_desc_ptr->flags & OCTEON_BL_FLAG_CONSOLE_UART1) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) * Get the coremask Linux was booted on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) * Returns Core mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) int octeon_get_boot_coremask(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) return octeon_boot_desc_ptr->core_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * Check the hardware BIST results for a CPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) void octeon_check_cpu_bist(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) const int coreid = cvmx_get_core_num();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) unsigned long long mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) unsigned long long bist_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) /* Check BIST results for COP0 registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) mask = 0x1f00000000ull;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) bist_val = read_octeon_c0_icacheerr();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (bist_val & mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) pr_err("Core%d BIST Failure: CacheErr(icache) = 0x%llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) coreid, bist_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) bist_val = read_octeon_c0_dcacheerr();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if (bist_val & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) pr_err("Core%d L1 Dcache parity error: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) "CacheErr(dcache) = 0x%llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) coreid, bist_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) mask = 0xfc00000000000000ull;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) bist_val = read_c0_cvmmemctl();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (bist_val & mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) pr_err("Core%d BIST Failure: COP0_CVM_MEM_CTL = 0x%llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) coreid, bist_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) write_octeon_c0_dcacheerr(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) * Reboot Octeon
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) * @command: Command to pass to the bootloader. Currently ignored.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) static void octeon_restart(char *command)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) /* Disable all watchdogs before soft reset. They don't get cleared */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) for_each_online_cpu(cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) cvmx_write_csr(CVMX_CIU_WDOGX(cpu_logical_map(cpu)), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) cvmx_write_csr(CVMX_CIU_WDOGX(cvmx_get_core_num()), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) while (1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (OCTEON_IS_OCTEON3())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) cvmx_write_csr(CVMX_RST_SOFT_RST, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) cvmx_write_csr(CVMX_CIU_SOFT_RST, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) * Permanently stop a core.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) * @arg: Ignored.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) static void octeon_kill_core(void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (octeon_is_simulation())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) /* A break instruction causes the simulator stop a core */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) asm volatile ("break" ::: "memory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) local_irq_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) /* Disable watchdog on this core. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) cvmx_write_csr(CVMX_CIU_WDOGX(cvmx_get_core_num()), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) /* Spin in a low power mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) while (true)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) asm volatile ("wait" ::: "memory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) * Halt the system
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) static void octeon_halt(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) smp_call_function(octeon_kill_core, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) switch (octeon_bootinfo->board_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) case CVMX_BOARD_TYPE_NAO38:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) /* Driving a 1 to GPIO 12 shuts off this board */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) cvmx_write_csr(CVMX_GPIO_BIT_CFGX(12), 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) cvmx_write_csr(CVMX_GPIO_TX_SET, 0x1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) octeon_write_lcd("PowerOff");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) octeon_kill_core(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) static char __read_mostly octeon_system_type[80];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) static void __init init_octeon_system_type(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) char const *board_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) board_type = cvmx_board_type_to_string(octeon_bootinfo->board_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (board_type == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) struct device_node *root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) root = of_find_node_by_path("/");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) ret = of_property_read_string(root, "model", &board_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) of_node_put(root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) board_type = "Unsupported Board";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) snprintf(octeon_system_type, sizeof(octeon_system_type), "%s (%s)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) board_type, octeon_model_get_string(read_c0_prid()));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) * Return a string representing the system type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) * Returns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) const char *octeon_board_type_string(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) return octeon_system_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) const char *get_system_type(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) __attribute__ ((alias("octeon_board_type_string")));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) void octeon_user_io_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) union octeon_cvmemctl cvmmemctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) /* Get the current settings for CP0_CVMMEMCTL_REG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) cvmmemctl.u64 = read_c0_cvmmemctl();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) /* R/W If set, marked write-buffer entries time out the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) * as as other entries; if clear, marked write-buffer entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) * use the maximum timeout. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) cvmmemctl.s.dismarkwblongto = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) /* R/W If set, a merged store does not clear the write-buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) * entry timeout state. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) cvmmemctl.s.dismrgclrwbto = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) /* R/W Two bits that are the MSBs of the resultant CVMSEG LM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) * word location for an IOBDMA. The other 8 bits come from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) * SCRADDR field of the IOBDMA. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) cvmmemctl.s.iobdmascrmsb = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) /* R/W If set, SYNCWS and SYNCS only order marked stores; if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) * clear, SYNCWS and SYNCS only order unmarked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) * stores. SYNCWSMARKED has no effect when DISSYNCWS is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) * set. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) cvmmemctl.s.syncwsmarked = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) /* R/W If set, SYNCWS acts as SYNCW and SYNCS acts as SYNC. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) cvmmemctl.s.dissyncws = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) /* R/W If set, no stall happens on write buffer full. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) cvmmemctl.s.diswbfst = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) cvmmemctl.s.diswbfst = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) /* R/W If set (and SX set), supervisor-level loads/stores can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) * use XKPHYS addresses with <48>==0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) cvmmemctl.s.xkmemenas = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) /* R/W If set (and UX set), user-level loads/stores can use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) * XKPHYS addresses with VA<48>==0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) cvmmemctl.s.xkmemenau = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) /* R/W If set (and SX set), supervisor-level loads/stores can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) * use XKPHYS addresses with VA<48>==1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) cvmmemctl.s.xkioenas = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) /* R/W If set (and UX set), user-level loads/stores can use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) * XKPHYS addresses with VA<48>==1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) cvmmemctl.s.xkioenau = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) /* R/W If set, all stores act as SYNCW (NOMERGE must be set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) * when this is set) RW, reset to 0. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) cvmmemctl.s.allsyncw = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) /* R/W If set, no stores merge, and all stores reach the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) * coherent bus in order. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) cvmmemctl.s.nomerge = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) /* R/W Selects the bit in the counter used for DID time-outs 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) * = 231, 1 = 230, 2 = 229, 3 = 214. Actual time-out is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) * between 1x and 2x this interval. For example, with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) * DIDTTO=3, expiration interval is between 16K and 32K. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) cvmmemctl.s.didtto = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) /* R/W If set, the (mem) CSR clock never turns off. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) cvmmemctl.s.csrckalwys = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) /* R/W If set, mclk never turns off. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) cvmmemctl.s.mclkalwys = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) /* R/W Selects the bit in the counter used for write buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) * flush time-outs (WBFLT+11) is the bit position in an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) * internal counter used to determine expiration. The write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) * buffer expires between 1x and 2x this interval. For
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) * example, with WBFLT = 0, a write buffer expires between 2K
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) * and 4K cycles after the write buffer entry is allocated. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) cvmmemctl.s.wbfltime = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) /* R/W If set, do not put Istream in the L2 cache. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) cvmmemctl.s.istrnol2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) * R/W The write buffer threshold. As per erratum Core-14752
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) * for CN63XX, a sc/scd might fail if the write buffer is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) * full. Lowering WBTHRESH greatly lowers the chances of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) * write buffer ever being full and triggering the erratum.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) cvmmemctl.s.wbthresh = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) cvmmemctl.s.wbthresh = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) /* R/W If set, CVMSEG is available for loads/stores in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) * kernel/debug mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) #if CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) cvmmemctl.s.cvmsegenak = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) cvmmemctl.s.cvmsegenak = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) /* R/W If set, CVMSEG is available for loads/stores in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) * supervisor mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) cvmmemctl.s.cvmsegenas = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) /* R/W If set, CVMSEG is available for loads/stores in user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) * mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) cvmmemctl.s.cvmsegenau = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) write_c0_cvmmemctl(cvmmemctl.u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) /* Setup of CVMSEG is done in kernel-entry-init.h */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) if (smp_processor_id() == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) pr_notice("CVMSEG size: %d cache lines (%d bytes)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE * 128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if (octeon_has_feature(OCTEON_FEATURE_FAU)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) union cvmx_iob_fau_timeout fau_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) /* Set a default for the hardware timeouts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) fau_timeout.u64 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) fau_timeout.s.tout_val = 0xfff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) /* Disable tagwait FAU timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) fau_timeout.s.tout_enb = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) cvmx_write_csr(CVMX_IOB_FAU_TIMEOUT, fau_timeout.u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) if ((!OCTEON_IS_MODEL(OCTEON_CN68XX) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) !OCTEON_IS_MODEL(OCTEON_CN7XXX)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) OCTEON_IS_MODEL(OCTEON_CN70XX)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) union cvmx_pow_nw_tim nm_tim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) nm_tim.u64 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) /* 4096 cycles */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) nm_tim.s.nw_tim = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) cvmx_write_csr(CVMX_POW_NW_TIM, nm_tim.u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) write_octeon_c0_icacheerr(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) write_c0_derraddr1(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) * Early entry point for arch setup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) void __init prom_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) struct cvmx_sysinfo *sysinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) const char *arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) u64 t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) int argc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) #ifdef CONFIG_CAVIUM_RESERVE32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) int64_t addr = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) * The bootloader passes a pointer to the boot descriptor in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) * $a3, this is available as fw_arg3.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) octeon_boot_desc_ptr = (struct octeon_boot_descriptor *)fw_arg3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) octeon_bootinfo =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) cvmx_phys_to_ptr(octeon_boot_desc_ptr->cvmx_desc_vaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) cvmx_bootmem_init(cvmx_phys_to_ptr(octeon_bootinfo->phy_mem_desc_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) sysinfo = cvmx_sysinfo_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) memset(sysinfo, 0, sizeof(*sysinfo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) sysinfo->system_dram_size = octeon_bootinfo->dram_size << 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) sysinfo->phy_mem_desc_addr = (u64)phys_to_virt(octeon_bootinfo->phy_mem_desc_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if ((octeon_bootinfo->major_version > 1) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) (octeon_bootinfo->major_version == 1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) octeon_bootinfo->minor_version >= 4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) cvmx_coremask_copy(&sysinfo->core_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) &octeon_bootinfo->ext_core_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) cvmx_coremask_set64(&sysinfo->core_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) octeon_bootinfo->core_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) /* Some broken u-boot pass garbage in upper bits, clear them out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) if (!OCTEON_IS_MODEL(OCTEON_CN78XX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) for (i = 512; i < 1024; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) cvmx_coremask_clear_core(&sysinfo->core_mask, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) sysinfo->exception_base_addr = octeon_bootinfo->exception_base_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) sysinfo->cpu_clock_hz = octeon_bootinfo->eclock_hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) sysinfo->dram_data_rate_hz = octeon_bootinfo->dclock_hz * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) sysinfo->board_type = octeon_bootinfo->board_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) sysinfo->board_rev_major = octeon_bootinfo->board_rev_major;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) sysinfo->board_rev_minor = octeon_bootinfo->board_rev_minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) memcpy(sysinfo->mac_addr_base, octeon_bootinfo->mac_addr_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) sizeof(sysinfo->mac_addr_base));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) sysinfo->mac_addr_count = octeon_bootinfo->mac_addr_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) memcpy(sysinfo->board_serial_number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) octeon_bootinfo->board_serial_number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) sizeof(sysinfo->board_serial_number));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) sysinfo->compact_flash_common_base_addr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) octeon_bootinfo->compact_flash_common_base_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) sysinfo->compact_flash_attribute_base_addr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) octeon_bootinfo->compact_flash_attribute_base_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) sysinfo->led_display_base_addr = octeon_bootinfo->led_display_base_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) sysinfo->dfa_ref_clock_hz = octeon_bootinfo->dfa_ref_clock_hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) sysinfo->bootloader_config_flags = octeon_bootinfo->config_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) if (OCTEON_IS_OCTEON2()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) /* I/O clock runs at a different rate than the CPU. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) union cvmx_mio_rst_boot rst_boot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) rst_boot.u64 = cvmx_read_csr(CVMX_MIO_RST_BOOT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) octeon_io_clock_rate = 50000000 * rst_boot.s.pnr_mul;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) } else if (OCTEON_IS_OCTEON3()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) /* I/O clock runs at a different rate than the CPU. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) union cvmx_rst_boot rst_boot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) rst_boot.u64 = cvmx_read_csr(CVMX_RST_BOOT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) octeon_io_clock_rate = 50000000 * rst_boot.s.pnr_mul;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) octeon_io_clock_rate = sysinfo->cpu_clock_hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) t = read_c0_cvmctl();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) if ((t & (1ull << 27)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) * Setup the multiplier save/restore code if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) * CvmCtl[NOMUL] clear.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) void *save;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) void *save_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) void *restore;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) void *restore_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) int save_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) int restore_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) int save_max = (char *)octeon_mult_save_end -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) (char *)octeon_mult_save;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) int restore_max = (char *)octeon_mult_restore_end -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) (char *)octeon_mult_restore;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (current_cpu_data.cputype == CPU_CAVIUM_OCTEON3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) save = octeon_mult_save3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) save_end = octeon_mult_save3_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) restore = octeon_mult_restore3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) restore_end = octeon_mult_restore3_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) save = octeon_mult_save2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) save_end = octeon_mult_save2_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) restore = octeon_mult_restore2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) restore_end = octeon_mult_restore2_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) save_len = (char *)save_end - (char *)save;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) restore_len = (char *)restore_end - (char *)restore;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) if (!WARN_ON(save_len > save_max ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) restore_len > restore_max)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) memcpy(octeon_mult_save, save, save_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) memcpy(octeon_mult_restore, restore, restore_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) * Only enable the LED controller if we're running on a CN38XX, CN58XX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) * or CN56XX. The CN30XX and CN31XX don't have an LED controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) if (!octeon_is_simulation() &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) octeon_has_feature(OCTEON_FEATURE_LED_CONTROLLER)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) cvmx_write_csr(CVMX_LED_EN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) cvmx_write_csr(CVMX_LED_PRT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) cvmx_write_csr(CVMX_LED_DBG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) cvmx_write_csr(CVMX_LED_PRT_FMT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) cvmx_write_csr(CVMX_LED_UDD_CNTX(0), 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) cvmx_write_csr(CVMX_LED_UDD_CNTX(1), 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) cvmx_write_csr(CVMX_LED_UDD_DATX(0), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) cvmx_write_csr(CVMX_LED_UDD_DATX(1), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) cvmx_write_csr(CVMX_LED_EN, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) #ifdef CONFIG_CAVIUM_RESERVE32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) * We need to temporarily allocate all memory in the reserve32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) * region. This makes sure the kernel doesn't allocate this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) * memory when it is getting memory from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) * bootloader. Later, after the memory allocations are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) * complete, the reserve32 will be freed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) * Allocate memory for RESERVED32 aligned on 2MB boundary. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) * is in case we later use hugetlb entries with it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) addr = cvmx_bootmem_phy_named_block_alloc(CONFIG_CAVIUM_RESERVE32 << 20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 0, 0, 2 << 20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) "CAVIUM_RESERVE32", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) if (addr < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) pr_err("Failed to allocate CAVIUM_RESERVE32 memory area\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) octeon_reserve32_memory = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) #ifdef CONFIG_CAVIUM_OCTEON_LOCK_L2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if (cvmx_read_csr(CVMX_L2D_FUS3) & (3ull << 34)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) pr_info("Skipping L2 locking due to reduced L2 cache size\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) uint32_t __maybe_unused ebase = read_c0_ebase() & 0x3ffff000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) #ifdef CONFIG_CAVIUM_OCTEON_LOCK_L2_TLB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) /* TLB refill */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) cvmx_l2c_lock_mem_region(ebase, 0x100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) #ifdef CONFIG_CAVIUM_OCTEON_LOCK_L2_EXCEPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) /* General exception */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) cvmx_l2c_lock_mem_region(ebase + 0x180, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) #ifdef CONFIG_CAVIUM_OCTEON_LOCK_L2_LOW_LEVEL_INTERRUPT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) /* Interrupt handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) cvmx_l2c_lock_mem_region(ebase + 0x200, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) #ifdef CONFIG_CAVIUM_OCTEON_LOCK_L2_INTERRUPT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) cvmx_l2c_lock_mem_region(__pa_symbol(handle_int), 0x100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) cvmx_l2c_lock_mem_region(__pa_symbol(plat_irq_dispatch), 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) #ifdef CONFIG_CAVIUM_OCTEON_LOCK_L2_MEMCPY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) cvmx_l2c_lock_mem_region(__pa_symbol(memcpy), 0x480);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) octeon_check_cpu_bist();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) octeon_uart = octeon_get_boot_uart();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) octeon_write_lcd("LinuxSMP");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) octeon_write_lcd("Linux");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) octeon_setup_delays();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) * BIST should always be enabled when doing a soft reset. L2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) * Cache locking for instance is not cleared unless BIST is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) * enabled. Unfortunately due to a chip errata G-200 for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) * Cn38XX and CN31XX, BIST must be disabled on these parts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) if (OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) OCTEON_IS_MODEL(OCTEON_CN31XX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) cvmx_write_csr(CVMX_CIU_SOFT_BIST, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) cvmx_write_csr(CVMX_CIU_SOFT_BIST, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) /* Default to 64MB in the simulator to speed things up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) if (octeon_is_simulation())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) max_memory = 64ull << 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) arg = strstr(arcs_cmdline, "mem=");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) if (arg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) max_memory = memparse(arg + 4, &p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) if (max_memory == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) max_memory = 32ull << 30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) if (*p == '@')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) reserve_low_mem = memparse(p + 1, &p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) arcs_cmdline[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) argc = octeon_boot_desc_ptr->argc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) for (i = 0; i < argc; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) const char *arg =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) cvmx_phys_to_ptr(octeon_boot_desc_ptr->argv[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) if ((strncmp(arg, "MEM=", 4) == 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) (strncmp(arg, "mem=", 4) == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) max_memory = memparse(arg + 4, &p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) if (max_memory == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) max_memory = 32ull << 30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) if (*p == '@')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) reserve_low_mem = memparse(p + 1, &p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) #ifdef CONFIG_KEXEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) } else if (strncmp(arg, "crashkernel=", 12) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) crashk_size = memparse(arg+12, &p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) if (*p == '@')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) crashk_base = memparse(p+1, &p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) strcat(arcs_cmdline, " ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) strcat(arcs_cmdline, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) * To do: switch parsing to new style, something like:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) * parse_crashkernel(arg, sysinfo->system_dram_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) * &crashk_size, &crashk_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) } else if (strlen(arcs_cmdline) + strlen(arg) + 1 <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) sizeof(arcs_cmdline) - 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) strcat(arcs_cmdline, " ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) strcat(arcs_cmdline, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) if (strstr(arcs_cmdline, "console=") == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) if (octeon_uart == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) strcat(arcs_cmdline, " console=ttyS1,115200");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) strcat(arcs_cmdline, " console=ttyS0,115200");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) mips_hpt_frequency = octeon_get_clock_rate();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) octeon_init_cvmcount();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) _machine_restart = octeon_restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) _machine_halt = octeon_halt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) #ifdef CONFIG_KEXEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) _machine_kexec_shutdown = octeon_shutdown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) _machine_crash_shutdown = octeon_crash_shutdown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) _machine_kexec_prepare = octeon_kexec_prepare;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) _crash_smp_send_stop = octeon_crash_smp_send_stop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) octeon_user_io_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) octeon_setup_smp();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) /* Exclude a single page from the regions obtained in plat_mem_setup. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) #ifndef CONFIG_CRASH_DUMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) static __init void memory_exclude_page(u64 addr, u64 *mem, u64 *size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) if (addr > *mem && addr < *mem + *size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) u64 inc = addr - *mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) memblock_add(*mem, inc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) *mem += inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) *size -= inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) if (addr == *mem && *size > PAGE_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) *mem += PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) *size -= PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) #endif /* CONFIG_CRASH_DUMP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) void __init fw_init_cmdline(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) octeon_boot_desc_ptr = (struct octeon_boot_descriptor *)fw_arg3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) for (i = 0; i < octeon_boot_desc_ptr->argc; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) const char *arg =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) cvmx_phys_to_ptr(octeon_boot_desc_ptr->argv[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) if (strlen(arcs_cmdline) + strlen(arg) + 1 <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) sizeof(arcs_cmdline) - 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) strcat(arcs_cmdline, " ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) strcat(arcs_cmdline, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) void __init *plat_get_fdt(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) octeon_bootinfo =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) cvmx_phys_to_ptr(octeon_boot_desc_ptr->cvmx_desc_vaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) return phys_to_virt(octeon_bootinfo->fdt_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) void __init plat_mem_setup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) uint64_t mem_alloc_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) uint64_t total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) uint64_t crashk_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) #ifndef CONFIG_CRASH_DUMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) int64_t memory;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) uint64_t kernel_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) uint64_t kernel_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) total = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) crashk_end = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) * The Mips memory init uses the first memory location for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) * some memory vectors. When SPARSEMEM is in use, it doesn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) * verify that the size is big enough for the final
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) * vectors. Making the smallest chuck 4MB seems to be enough
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) * to consistently work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) mem_alloc_size = 4 << 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) if (mem_alloc_size > max_memory)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) mem_alloc_size = max_memory;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) /* Crashkernel ignores bootmem list. It relies on mem=X@Y option */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) #ifdef CONFIG_CRASH_DUMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) memblock_add(reserve_low_mem, max_memory);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) total += max_memory;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) #ifdef CONFIG_KEXEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) if (crashk_size > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) memblock_add(crashk_base, crashk_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) crashk_end = crashk_base + crashk_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) * When allocating memory, we want incrementing addresses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) * which is handled by memblock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) cvmx_bootmem_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) while (total < max_memory) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) memory = cvmx_bootmem_phy_alloc(mem_alloc_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) __pa_symbol(&_end), -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 0x100000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) CVMX_BOOTMEM_FLAG_NO_LOCKING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) if (memory >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) u64 size = mem_alloc_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) #ifdef CONFIG_KEXEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) uint64_t end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) * exclude a page at the beginning and end of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) * the 256MB PCIe 'hole' so the kernel will not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) * try to allocate multi-page buffers that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) * span the discontinuity.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) memory_exclude_page(CVMX_PCIE_BAR1_PHYS_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) &memory, &size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) memory_exclude_page(CVMX_PCIE_BAR1_PHYS_BASE +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) CVMX_PCIE_BAR1_PHYS_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) &memory, &size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) #ifdef CONFIG_KEXEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) end = memory + mem_alloc_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) * This function automatically merges address regions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) * next to each other if they are received in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) * incrementing order
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) if (memory < crashk_base && end > crashk_end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) /* region is fully in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) memblock_add(memory, crashk_base - memory);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) total += crashk_base - memory;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) memblock_add(crashk_end, end - crashk_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) total += end - crashk_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) if (memory >= crashk_base && end <= crashk_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) * Entire memory region is within the new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) * kernel's memory, ignore it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) if (memory > crashk_base && memory < crashk_end &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) end > crashk_end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) * Overlap with the beginning of the region,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) * reserve the beginning.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) mem_alloc_size -= crashk_end - memory;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) memory = crashk_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) } else if (memory < crashk_base && end > crashk_base &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) end < crashk_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) * Overlap with the beginning of the region,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) * chop of end.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) mem_alloc_size -= end - crashk_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) memblock_add(memory, mem_alloc_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) total += mem_alloc_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) /* Recovering mem_alloc_size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) mem_alloc_size = 4 << 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) cvmx_bootmem_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) /* Add the memory region for the kernel. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) kernel_start = (unsigned long) _text;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) kernel_size = _end - _text;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) /* Adjust for physical offset. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) kernel_start &= ~0xffffffff80000000ULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) memblock_add(kernel_start, kernel_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) #endif /* CONFIG_CRASH_DUMP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) #ifdef CONFIG_CAVIUM_RESERVE32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) * Now that we've allocated the kernel memory it is safe to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) * free the reserved region. We free it here so that builtin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) * drivers can use the memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) if (octeon_reserve32_memory)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) cvmx_bootmem_free_named("CAVIUM_RESERVE32");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) #endif /* CONFIG_CAVIUM_RESERVE32 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) if (total == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) panic("Unable to allocate memory from "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) "cvmx_bootmem_phy_alloc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) * Emit one character to the boot UART. Exported for use by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) * watchdog timer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) void prom_putchar(char c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) uint64_t lsrval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) /* Spin until there is room */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) lsrval = cvmx_read_csr(CVMX_MIO_UARTX_LSR(octeon_uart));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) } while ((lsrval & 0x20) == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) /* Write the byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) cvmx_write_csr(CVMX_MIO_UARTX_THR(octeon_uart), c & 0xffull);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) EXPORT_SYMBOL(prom_putchar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) void __init prom_free_prom_memory(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) /* Check for presence of Core-14449 fix. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) u32 insn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) u32 *foo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) foo = &insn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) asm volatile("# before" : : : "memory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) prefetch(foo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) asm volatile(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) ".set push\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) ".set noreorder\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) "bal 1f\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) "nop\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) "1:\tlw %0,-12($31)\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) ".set pop\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) : "=r" (insn) : : "$31", "memory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) if ((insn >> 26) != 0x33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) panic("No PREF instruction at Core-14449 probe point.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) if (((insn >> 16) & 0x1f) != 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) panic("OCTEON II DCache prefetch workaround not in place (%04x).\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) "Please build kernel with proper options (CONFIG_CAVIUM_CN63XXP1).",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) void __init octeon_fill_mac_addresses(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) void __init device_tree_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) const void *fdt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) bool do_prune;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) bool fill_mac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) #ifdef CONFIG_MIPS_ELF_APPENDED_DTB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) if (!fdt_check_header(&__appended_dtb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) fdt = &__appended_dtb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) do_prune = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) fill_mac = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) pr_info("Using appended Device Tree.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) if (octeon_bootinfo->minor_version >= 3 && octeon_bootinfo->fdt_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) fdt = phys_to_virt(octeon_bootinfo->fdt_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) if (fdt_check_header(fdt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) panic("Corrupt Device Tree passed to kernel.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) do_prune = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) fill_mac = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) pr_info("Using passed Device Tree.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) } else if (OCTEON_IS_MODEL(OCTEON_CN68XX)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) fdt = &__dtb_octeon_68xx_begin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) do_prune = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) fill_mac = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) fdt = &__dtb_octeon_3xxx_begin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) do_prune = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) fill_mac = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) initial_boot_params = (void *)fdt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) if (do_prune) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) octeon_prune_device_tree();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) pr_info("Using internal Device Tree.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) if (fill_mac)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) octeon_fill_mac_addresses();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) unflatten_and_copy_device_tree();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) init_octeon_system_type();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) static int __initdata disable_octeon_edac_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) static int __init disable_octeon_edac(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) disable_octeon_edac_p = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) early_param("disable_octeon_edac", disable_octeon_edac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) static char *edac_device_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) "octeon_l2c_edac",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) "octeon_pc_edac",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) static int __init edac_devinit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) struct platform_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) int i, err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) int num_lmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) if (disable_octeon_edac_p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) for (i = 0; i < ARRAY_SIZE(edac_device_names); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) name = edac_device_names[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) dev = platform_device_register_simple(name, -1, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) if (IS_ERR(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) pr_err("Registration of %s failed!\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) err = PTR_ERR(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) num_lmc = OCTEON_IS_MODEL(OCTEON_CN68XX) ? 4 :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) (OCTEON_IS_MODEL(OCTEON_CN56XX) ? 2 : 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) for (i = 0; i < num_lmc; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) dev = platform_device_register_simple("octeon_lmc_edac",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) i, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) if (IS_ERR(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) pr_err("Registration of octeon_lmc_edac %d failed!\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) err = PTR_ERR(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) device_initcall(edac_devinit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) static void __initdata *octeon_dummy_iospace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) static int __init octeon_no_pci_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) * Initially assume there is no PCI. The PCI/PCIe platform code will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) * later re-initialize these to correct values if they are present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) octeon_dummy_iospace = vzalloc(IO_SPACE_LIMIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) set_io_port_base((unsigned long)octeon_dummy_iospace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) ioport_resource.start = MAX_RESOURCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) ioport_resource.end = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) core_initcall(octeon_no_pci_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) static int __init octeon_no_pci_release(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) * Release the allocated memory if a real IO space is there.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) if ((unsigned long)octeon_dummy_iospace != mips_io_port_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) vfree(octeon_dummy_iospace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) late_initcall(octeon_no_pci_release);