1bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin/* 2bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin * Based on Ocelot Linux port, which is 3bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin * Copyright 2001 MontaVista Software Inc. 4bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin * Author: jsun@mvista.com or jsun@junsun.net 5bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin * 6bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin * Copyright 2003 ICT CAS 7bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin * Author: Michael Guo <guoyi@ict.ac.cn> 8bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin * 9bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology 10bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin * Author: Fuxin Zhang, zhangfx@lemote.com 11bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin * 12f7a904dffe30a02636053d8022498ced7e44d31cWu Zhangjin * Copyright (C) 2009 Lemote Inc. 13f7a904dffe30a02636053d8022498ced7e44d31cWu Zhangjin * Author: Wu Zhangjin, wuzhangjin@gmail.com 14bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin * 157034228792cc561e79ff8600f02884bd4c80e287Ralf Baechle * This program is free software; you can redistribute it and/or modify it 167034228792cc561e79ff8600f02884bd4c80e287Ralf Baechle * under the terms of the GNU General Public License as published by the 17bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin * Free Software Foundation; either version 2 of the License, or (at your 18bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin * option) any later version. 19bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin */ 20f8ede0f700f5478851f242f291d203cde54ca6cfWu Zhangjin#include <linux/module.h> 21bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin#include <asm/bootinfo.h> 225e983ff654ca3df3007b5b558b5271bb4622afa4Wu Zhangjin#include <loongson.h> 231a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen#include <boot_param.h> 245e983ff654ca3df3007b5b558b5271bb4622afa4Wu Zhangjin 251a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chenu32 cpu_clock_freq; 26f8ede0f700f5478851f242f291d203cde54ca6cfWu ZhangjinEXPORT_SYMBOL(cpu_clock_freq); 271a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chenstruct efi_memory_map_loongson *loongson_memmap; 281a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chenstruct loongson_system_configuration loongson_sysconf; 29bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin 30140e39c1e3d29f50e161f55cca60f60b80408c2aHuacai Chenu64 loongson_chipcfg[MAX_PACKAGES] = {0xffffffffbfc00180}; 31e7841be50fe2b8751a51a068b8cdcdcb6611e354Huacai Chenu64 loongson_freqctrl[MAX_PACKAGES]; 32e7841be50fe2b8751a51a068b8cdcdcb6611e354Huacai Chen 33e7841be50fe2b8751a51a068b8cdcdcb6611e354Huacai Chenunsigned long long smp_group[4]; 34e7841be50fe2b8751a51a068b8cdcdcb6611e354Huacai Chenint cpuhotplug_workaround = 0; 35140e39c1e3d29f50e161f55cca60f60b80408c2aHuacai Chen 36bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin#define parse_even_earlier(res, option, p) \ 37bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjindo { \ 38c87444af6fc853dd5571a830efff7e07c46a544eRalf Baechle unsigned int tmp __maybe_unused; \ 39c87444af6fc853dd5571a830efff7e07c46a544eRalf Baechle \ 40bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin if (strncmp(option, (char *)p, strlen(option)) == 0) \ 411a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen tmp = kstrtou32((char *)p + strlen(option"="), 10, &res); \ 42bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin} while (0) 43bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin 44bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjinvoid __init prom_init_env(void) 45bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin{ 46eb11df472d8491fcb28534b59017e1b5465997faWu Zhangjin /* pmon passes arguments in 32bit pointers */ 47eb11df472d8491fcb28534b59017e1b5465997faWu Zhangjin unsigned int processor_id; 481a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen 491a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen#ifndef CONFIG_LEFI_FIRMWARE_INTERFACE 501a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen int *_prom_envp; 51bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin long l; 52bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin 53bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin /* firmware arguments are initialized in head.S */ 54bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin _prom_envp = (int *)fw_arg2; 55bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin 56bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin l = (long)*_prom_envp; 57bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin while (l != 0) { 58bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin parse_even_earlier(cpu_clock_freq, "cpuclock", l); 59bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin parse_even_earlier(memsize, "memsize", l); 60bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin parse_even_earlier(highmemsize, "highmemsize", l); 61bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin _prom_envp++; 62bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin l = (long)*_prom_envp; 63bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin } 64bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin if (memsize == 0) 65bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin memsize = 256; 661a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen pr_info("memsize=%u, highmemsize=%u\n", memsize, highmemsize); 671a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen#else 681a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen struct boot_params *boot_p; 691a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen struct loongson_params *loongson_p; 701a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen struct efi_cpuinfo_loongson *ecpu; 711a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen struct irq_source_routing_table *eirq_source; 721a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen 731a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen /* firmware arguments are initialized in head.S */ 741a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen boot_p = (struct boot_params *)fw_arg2; 751a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen loongson_p = &(boot_p->efi.smbios.lp); 761a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen 771a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen ecpu = (struct efi_cpuinfo_loongson *) 781a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen ((u64)loongson_p + loongson_p->cpu_offset); 791a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen eirq_source = (struct irq_source_routing_table *) 801a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen ((u64)loongson_p + loongson_p->irq_offset); 811a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen loongson_memmap = (struct efi_memory_map_loongson *) 821a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen ((u64)loongson_p + loongson_p->memory_offset); 831a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen 841a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen cpu_clock_freq = ecpu->cpu_clock_freq; 851a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen loongson_sysconf.cputype = ecpu->cputype; 86140e39c1e3d29f50e161f55cca60f60b80408c2aHuacai Chen if (ecpu->cputype == Loongson_3A) { 87c46173183657bbdbe0d54a981c28807581648422Huacai Chen loongson_sysconf.cores_per_node = 4; 88c46173183657bbdbe0d54a981c28807581648422Huacai Chen loongson_sysconf.cores_per_package = 4; 89e7841be50fe2b8751a51a068b8cdcdcb6611e354Huacai Chen smp_group[0] = 0x900000003ff01000; 90e7841be50fe2b8751a51a068b8cdcdcb6611e354Huacai Chen smp_group[1] = 0x900010003ff01000; 91e7841be50fe2b8751a51a068b8cdcdcb6611e354Huacai Chen smp_group[2] = 0x900020003ff01000; 92e7841be50fe2b8751a51a068b8cdcdcb6611e354Huacai Chen smp_group[3] = 0x900030003ff01000; 93140e39c1e3d29f50e161f55cca60f60b80408c2aHuacai Chen loongson_chipcfg[0] = 0x900000001fe00180; 94140e39c1e3d29f50e161f55cca60f60b80408c2aHuacai Chen loongson_chipcfg[1] = 0x900010001fe00180; 95140e39c1e3d29f50e161f55cca60f60b80408c2aHuacai Chen loongson_chipcfg[2] = 0x900020001fe00180; 96140e39c1e3d29f50e161f55cca60f60b80408c2aHuacai Chen loongson_chipcfg[3] = 0x900030001fe00180; 97e7841be50fe2b8751a51a068b8cdcdcb6611e354Huacai Chen loongson_sysconf.ht_control_base = 0x90000EFDFB000000; 98e7841be50fe2b8751a51a068b8cdcdcb6611e354Huacai Chen } else if (ecpu->cputype == Loongson_3B) { 99e7841be50fe2b8751a51a068b8cdcdcb6611e354Huacai Chen loongson_sysconf.cores_per_node = 4; /* One chip has 2 nodes */ 100e7841be50fe2b8751a51a068b8cdcdcb6611e354Huacai Chen loongson_sysconf.cores_per_package = 8; 101e7841be50fe2b8751a51a068b8cdcdcb6611e354Huacai Chen smp_group[0] = 0x900000003ff01000; 102e7841be50fe2b8751a51a068b8cdcdcb6611e354Huacai Chen smp_group[1] = 0x900010003ff05000; 103e7841be50fe2b8751a51a068b8cdcdcb6611e354Huacai Chen smp_group[2] = 0x900020003ff09000; 104e7841be50fe2b8751a51a068b8cdcdcb6611e354Huacai Chen smp_group[3] = 0x900030003ff0d000; 105e7841be50fe2b8751a51a068b8cdcdcb6611e354Huacai Chen loongson_chipcfg[0] = 0x900000001fe00180; 106e7841be50fe2b8751a51a068b8cdcdcb6611e354Huacai Chen loongson_chipcfg[1] = 0x900020001fe00180; 107e7841be50fe2b8751a51a068b8cdcdcb6611e354Huacai Chen loongson_chipcfg[2] = 0x900040001fe00180; 108e7841be50fe2b8751a51a068b8cdcdcb6611e354Huacai Chen loongson_chipcfg[3] = 0x900060001fe00180; 109e7841be50fe2b8751a51a068b8cdcdcb6611e354Huacai Chen loongson_freqctrl[0] = 0x900000001fe001d0; 110e7841be50fe2b8751a51a068b8cdcdcb6611e354Huacai Chen loongson_freqctrl[1] = 0x900020001fe001d0; 111e7841be50fe2b8751a51a068b8cdcdcb6611e354Huacai Chen loongson_freqctrl[2] = 0x900040001fe001d0; 112e7841be50fe2b8751a51a068b8cdcdcb6611e354Huacai Chen loongson_freqctrl[3] = 0x900060001fe001d0; 113e7841be50fe2b8751a51a068b8cdcdcb6611e354Huacai Chen loongson_sysconf.ht_control_base = 0x90001EFDFB000000; 114e7841be50fe2b8751a51a068b8cdcdcb6611e354Huacai Chen cpuhotplug_workaround = 1; 115140e39c1e3d29f50e161f55cca60f60b80408c2aHuacai Chen } else { 116c46173183657bbdbe0d54a981c28807581648422Huacai Chen loongson_sysconf.cores_per_node = 1; 117c46173183657bbdbe0d54a981c28807581648422Huacai Chen loongson_sysconf.cores_per_package = 1; 118140e39c1e3d29f50e161f55cca60f60b80408c2aHuacai Chen loongson_chipcfg[0] = 0x900000001fe00180; 119140e39c1e3d29f50e161f55cca60f60b80408c2aHuacai Chen } 120140e39c1e3d29f50e161f55cca60f60b80408c2aHuacai Chen 1211a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen loongson_sysconf.nr_cpus = ecpu->nr_cpus; 1221a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen if (ecpu->nr_cpus > NR_CPUS || ecpu->nr_cpus == 0) 1231a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen loongson_sysconf.nr_cpus = NR_CPUS; 124c46173183657bbdbe0d54a981c28807581648422Huacai Chen loongson_sysconf.nr_nodes = (loongson_sysconf.nr_cpus + 125c46173183657bbdbe0d54a981c28807581648422Huacai Chen loongson_sysconf.cores_per_node - 1) / 126c46173183657bbdbe0d54a981c28807581648422Huacai Chen loongson_sysconf.cores_per_node; 1271a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen 1281a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen loongson_sysconf.pci_mem_start_addr = eirq_source->pci_mem_start_addr; 1291a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen loongson_sysconf.pci_mem_end_addr = eirq_source->pci_mem_end_addr; 1301a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen loongson_sysconf.pci_io_base = eirq_source->pci_io_start_addr; 1311a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen loongson_sysconf.dma_mask_bits = eirq_source->dma_mask_bits; 1321a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen if (loongson_sysconf.dma_mask_bits < 32 || 1331a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen loongson_sysconf.dma_mask_bits > 64) 1341a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen loongson_sysconf.dma_mask_bits = 32; 1351a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen 1361a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen loongson_sysconf.restart_addr = boot_p->reset_system.ResetWarm; 1371a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen loongson_sysconf.poweroff_addr = boot_p->reset_system.Shutdown; 1381a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen loongson_sysconf.suspend_addr = boot_p->reset_system.DoSuspend; 1391a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen 1401a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen loongson_sysconf.vgabios_addr = boot_p->efi.smbios.vga_bios; 1411a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen pr_debug("Shutdown Addr: %llx, Restart Addr: %llx, VBIOS Addr: %llx\n", 1421a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen loongson_sysconf.poweroff_addr, loongson_sysconf.restart_addr, 1431a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen loongson_sysconf.vgabios_addr); 1441a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen#endif 145eb11df472d8491fcb28534b59017e1b5465997faWu Zhangjin if (cpu_clock_freq == 0) { 146eb11df472d8491fcb28534b59017e1b5465997faWu Zhangjin processor_id = (¤t_cpu_data)->processor_id; 147eb11df472d8491fcb28534b59017e1b5465997faWu Zhangjin switch (processor_id & PRID_REV_MASK) { 148eb11df472d8491fcb28534b59017e1b5465997faWu Zhangjin case PRID_REV_LOONGSON2E: 149eb11df472d8491fcb28534b59017e1b5465997faWu Zhangjin cpu_clock_freq = 533080000; 150eb11df472d8491fcb28534b59017e1b5465997faWu Zhangjin break; 151eb11df472d8491fcb28534b59017e1b5465997faWu Zhangjin case PRID_REV_LOONGSON2F: 152eb11df472d8491fcb28534b59017e1b5465997faWu Zhangjin cpu_clock_freq = 797000000; 153eb11df472d8491fcb28534b59017e1b5465997faWu Zhangjin break; 1541a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen case PRID_REV_LOONGSON3A: 1551a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen cpu_clock_freq = 900000000; 1561a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen break; 157e7841be50fe2b8751a51a068b8cdcdcb6611e354Huacai Chen case PRID_REV_LOONGSON3B_R1: 158e7841be50fe2b8751a51a068b8cdcdcb6611e354Huacai Chen case PRID_REV_LOONGSON3B_R2: 159e7841be50fe2b8751a51a068b8cdcdcb6611e354Huacai Chen cpu_clock_freq = 1000000000; 160e7841be50fe2b8751a51a068b8cdcdcb6611e354Huacai Chen break; 161eb11df472d8491fcb28534b59017e1b5465997faWu Zhangjin default: 162eb11df472d8491fcb28534b59017e1b5465997faWu Zhangjin cpu_clock_freq = 100000000; 163eb11df472d8491fcb28534b59017e1b5465997faWu Zhangjin break; 164eb11df472d8491fcb28534b59017e1b5465997faWu Zhangjin } 165eb11df472d8491fcb28534b59017e1b5465997faWu Zhangjin } 1661a08f1524d2ee4d4239e56ee1b3f6da0df929563Huacai Chen pr_info("CpuClock = %u\n", cpu_clock_freq); 167bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin} 168