Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.18 167 lines 5.6 kB view raw
1/* 2 * Based on Ocelot Linux port, which is 3 * Copyright 2001 MontaVista Software Inc. 4 * Author: jsun@mvista.com or jsun@junsun.net 5 * 6 * Copyright 2003 ICT CAS 7 * Author: Michael Guo <guoyi@ict.ac.cn> 8 * 9 * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology 10 * Author: Fuxin Zhang, zhangfx@lemote.com 11 * 12 * Copyright (C) 2009 Lemote Inc. 13 * Author: Wu Zhangjin, wuzhangjin@gmail.com 14 * 15 * This program is free software; you can redistribute it and/or modify it 16 * under the terms of the GNU General Public License as published by the 17 * Free Software Foundation; either version 2 of the License, or (at your 18 * option) any later version. 19 */ 20#include <linux/module.h> 21#include <asm/bootinfo.h> 22#include <loongson.h> 23#include <boot_param.h> 24 25u32 cpu_clock_freq; 26EXPORT_SYMBOL(cpu_clock_freq); 27struct efi_memory_map_loongson *loongson_memmap; 28struct loongson_system_configuration loongson_sysconf; 29 30u64 loongson_chipcfg[MAX_PACKAGES] = {0xffffffffbfc00180}; 31u64 loongson_freqctrl[MAX_PACKAGES]; 32 33unsigned long long smp_group[4]; 34int cpuhotplug_workaround = 0; 35 36#define parse_even_earlier(res, option, p) \ 37do { \ 38 unsigned int tmp __maybe_unused; \ 39 \ 40 if (strncmp(option, (char *)p, strlen(option)) == 0) \ 41 tmp = kstrtou32((char *)p + strlen(option"="), 10, &res); \ 42} while (0) 43 44void __init prom_init_env(void) 45{ 46 /* pmon passes arguments in 32bit pointers */ 47 unsigned int processor_id; 48 49#ifndef CONFIG_LEFI_FIRMWARE_INTERFACE 50 int *_prom_envp; 51 long l; 52 53 /* firmware arguments are initialized in head.S */ 54 _prom_envp = (int *)fw_arg2; 55 56 l = (long)*_prom_envp; 57 while (l != 0) { 58 parse_even_earlier(cpu_clock_freq, "cpuclock", l); 59 parse_even_earlier(memsize, "memsize", l); 60 parse_even_earlier(highmemsize, "highmemsize", l); 61 _prom_envp++; 62 l = (long)*_prom_envp; 63 } 64 if (memsize == 0) 65 memsize = 256; 66 pr_info("memsize=%u, highmemsize=%u\n", memsize, highmemsize); 67#else 68 struct boot_params *boot_p; 69 struct loongson_params *loongson_p; 70 struct efi_cpuinfo_loongson *ecpu; 71 struct irq_source_routing_table *eirq_source; 72 73 /* firmware arguments are initialized in head.S */ 74 boot_p = (struct boot_params *)fw_arg2; 75 loongson_p = &(boot_p->efi.smbios.lp); 76 77 ecpu = (struct efi_cpuinfo_loongson *) 78 ((u64)loongson_p + loongson_p->cpu_offset); 79 eirq_source = (struct irq_source_routing_table *) 80 ((u64)loongson_p + loongson_p->irq_offset); 81 loongson_memmap = (struct efi_memory_map_loongson *) 82 ((u64)loongson_p + loongson_p->memory_offset); 83 84 cpu_clock_freq = ecpu->cpu_clock_freq; 85 loongson_sysconf.cputype = ecpu->cputype; 86 if (ecpu->cputype == Loongson_3A) { 87 loongson_sysconf.cores_per_node = 4; 88 loongson_sysconf.cores_per_package = 4; 89 smp_group[0] = 0x900000003ff01000; 90 smp_group[1] = 0x900010003ff01000; 91 smp_group[2] = 0x900020003ff01000; 92 smp_group[3] = 0x900030003ff01000; 93 loongson_chipcfg[0] = 0x900000001fe00180; 94 loongson_chipcfg[1] = 0x900010001fe00180; 95 loongson_chipcfg[2] = 0x900020001fe00180; 96 loongson_chipcfg[3] = 0x900030001fe00180; 97 loongson_sysconf.ht_control_base = 0x90000EFDFB000000; 98 } else if (ecpu->cputype == Loongson_3B) { 99 loongson_sysconf.cores_per_node = 4; /* One chip has 2 nodes */ 100 loongson_sysconf.cores_per_package = 8; 101 smp_group[0] = 0x900000003ff01000; 102 smp_group[1] = 0x900010003ff05000; 103 smp_group[2] = 0x900020003ff09000; 104 smp_group[3] = 0x900030003ff0d000; 105 loongson_chipcfg[0] = 0x900000001fe00180; 106 loongson_chipcfg[1] = 0x900020001fe00180; 107 loongson_chipcfg[2] = 0x900040001fe00180; 108 loongson_chipcfg[3] = 0x900060001fe00180; 109 loongson_freqctrl[0] = 0x900000001fe001d0; 110 loongson_freqctrl[1] = 0x900020001fe001d0; 111 loongson_freqctrl[2] = 0x900040001fe001d0; 112 loongson_freqctrl[3] = 0x900060001fe001d0; 113 loongson_sysconf.ht_control_base = 0x90001EFDFB000000; 114 cpuhotplug_workaround = 1; 115 } else { 116 loongson_sysconf.cores_per_node = 1; 117 loongson_sysconf.cores_per_package = 1; 118 loongson_chipcfg[0] = 0x900000001fe00180; 119 } 120 121 loongson_sysconf.nr_cpus = ecpu->nr_cpus; 122 if (ecpu->nr_cpus > NR_CPUS || ecpu->nr_cpus == 0) 123 loongson_sysconf.nr_cpus = NR_CPUS; 124 loongson_sysconf.nr_nodes = (loongson_sysconf.nr_cpus + 125 loongson_sysconf.cores_per_node - 1) / 126 loongson_sysconf.cores_per_node; 127 128 loongson_sysconf.pci_mem_start_addr = eirq_source->pci_mem_start_addr; 129 loongson_sysconf.pci_mem_end_addr = eirq_source->pci_mem_end_addr; 130 loongson_sysconf.pci_io_base = eirq_source->pci_io_start_addr; 131 loongson_sysconf.dma_mask_bits = eirq_source->dma_mask_bits; 132 if (loongson_sysconf.dma_mask_bits < 32 || 133 loongson_sysconf.dma_mask_bits > 64) 134 loongson_sysconf.dma_mask_bits = 32; 135 136 loongson_sysconf.restart_addr = boot_p->reset_system.ResetWarm; 137 loongson_sysconf.poweroff_addr = boot_p->reset_system.Shutdown; 138 loongson_sysconf.suspend_addr = boot_p->reset_system.DoSuspend; 139 140 loongson_sysconf.vgabios_addr = boot_p->efi.smbios.vga_bios; 141 pr_debug("Shutdown Addr: %llx, Restart Addr: %llx, VBIOS Addr: %llx\n", 142 loongson_sysconf.poweroff_addr, loongson_sysconf.restart_addr, 143 loongson_sysconf.vgabios_addr); 144#endif 145 if (cpu_clock_freq == 0) { 146 processor_id = (&current_cpu_data)->processor_id; 147 switch (processor_id & PRID_REV_MASK) { 148 case PRID_REV_LOONGSON2E: 149 cpu_clock_freq = 533080000; 150 break; 151 case PRID_REV_LOONGSON2F: 152 cpu_clock_freq = 797000000; 153 break; 154 case PRID_REV_LOONGSON3A: 155 cpu_clock_freq = 900000000; 156 break; 157 case PRID_REV_LOONGSON3B_R1: 158 case PRID_REV_LOONGSON3B_R2: 159 cpu_clock_freq = 1000000000; 160 break; 161 default: 162 cpu_clock_freq = 100000000; 163 break; 164 } 165 } 166 pr_info("CpuClock = %u\n", cpu_clock_freq); 167}