Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
@@ -0,0 +1,220 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_MACH_LOONGSON64_BOOT_PARAM_H_
#define __ASM_MACH_LOONGSON64_BOOT_PARAM_H_
#include <linux/types.h>
#define SYSTEM_RAM_LOW 1
#define SYSTEM_RAM_HIGH 2
#define SYSTEM_RAM_RESERVED 3
#define PCI_IO 4
#define PCI_MEM 5
#define LOONGSON_CFG_REG 6
#define VIDEO_ROM 7
#define ADAPTER_ROM 8
#define ACPI_TABLE 9
#define SMBIOS_TABLE 10
#define UMA_VIDEO_RAM 11
#define VUMA_VIDEO_RAM 12
#define MAX_MEMORY_TYPE 13
#define MEM_SIZE_IS_IN_BYTES (1 << 31)
#define LOONGSON3_BOOT_MEM_MAP_MAX 128
struct efi_memory_map_loongson {
u16 vers; /* version of efi_memory_map */
u32 nr_map; /* number of memory_maps */
u32 mem_freq; /* memory frequence */
struct mem_map {
u32 node_id; /* node_id which memory attached to */
u32 mem_type; /* system memory, pci memory, pci io, etc. */
u64 mem_start; /* memory map start address */
u32 mem_size; /* each memory_map size, not the total size */
} map[LOONGSON3_BOOT_MEM_MAP_MAX];
} __packed;
enum loongson_cpu_type {
Legacy_2E = 0x0,
Legacy_2F = 0x1,
Legacy_3A = 0x2,
Legacy_3B = 0x3,
Legacy_1A = 0x4,
Legacy_1B = 0x5,
Legacy_2G = 0x6,
Legacy_2H = 0x7,
Legacy_2K = 0x8,
Loongson_1A = 0x100,
Loongson_1B = 0x101,
Loongson_2E = 0x200,
Loongson_2F = 0x201,
Loongson_2G = 0x202,
Loongson_2H = 0x203,
Loongson_2K = 0x204,
Loongson_3A = 0x300,
Loongson_3B = 0x301
};
/*
* Capability and feature descriptor structure for MIPS CPU
*/
struct efi_cpuinfo_loongson {
u16 vers; /* version of efi_cpuinfo_loongson */
u32 processor_id; /* PRID, e.g. 6305, 6306 */
u32 cputype; /* Loongson_3A/3B, etc. */
u32 total_node; /* num of total numa nodes */
u16 cpu_startup_core_id; /* Boot core id */
u16 reserved_cores_mask;
u32 cpu_clock_freq; /* cpu_clock */
u32 nr_cpus;
} __packed;
#define MAX_UARTS 64
struct uart_device {
u32 iotype; /* see include/linux/serial_core.h */
u32 uartclk;
u32 int_offset;
u64 uart_base;
} __packed;
#define MAX_SENSORS 64
#define SENSOR_TEMPER 0x00000001
#define SENSOR_VOLTAGE 0x00000002
#define SENSOR_FAN 0x00000004
struct sensor_device {
char name[32]; /* a formal name */
char label[64]; /* a flexible description */
u32 type; /* SENSOR_* */
u32 id; /* instance id of a sensor-class */
u32 fan_policy; /* see loongson_hwmon.h */
u32 fan_percent;/* only for constant speed policy */
u64 base_addr; /* base address of device registers */
} __packed;
struct system_loongson {
u16 vers; /* version of system_loongson */
u32 ccnuma_smp; /* 0: no numa; 1: has numa */
u32 sing_double_channel; /* 1:single; 2:double */
u32 nr_uarts;
struct uart_device uarts[MAX_UARTS];
u32 nr_sensors;
struct sensor_device sensors[MAX_SENSORS];
char has_ec;
char ec_name[32];
u64 ec_base_addr;
char has_tcm;
char tcm_name[32];
u64 tcm_base_addr;
u64 workarounds; /* see workarounds.h */
} __packed;
struct irq_source_routing_table {
u16 vers;
u16 size;
u16 rtr_bus;
u16 rtr_devfn;
u32 vendor;
u32 device;
u32 PIC_type; /* conform use HT or PCI to route to CPU-PIC */
u64 ht_int_bit; /* 3A: 1<<24; 3B: 1<<16 */
u64 ht_enable; /* irqs used in this PIC */
u32 node_id; /* node id: 0x0-0; 0x1-1; 0x10-2; 0x11-3 */
u64 pci_mem_start_addr;
u64 pci_mem_end_addr;
u64 pci_io_start_addr;
u64 pci_io_end_addr;
u64 pci_config_addr;
u16 dma_mask_bits;
u16 dma_noncoherent;
} __packed;
struct interface_info {
u16 vers; /* version of the specification */
u16 size; /* size of this interface */
u8 flag; /* used or unused */
char description[64]; /* description for each change */
} __packed;
#define MAX_RESOURCE_NUMBER 128
struct resource_loongson {
u64 start; /* resource start address */
u64 end; /* resource end address */
char name[64];
u32 flags;
};
struct archdev_data {}; /* arch specific additions */
struct board_devices {
char name[64]; /* hold the device name */
u32 num_resources; /* number of device_resource */
/* for each device's resource */
struct resource_loongson resource[MAX_RESOURCE_NUMBER];
/* arch specific additions */
struct archdev_data archdata;
};
struct loongson_special_attribute {
u16 vers; /* version of this special */
char special_name[64]; /* special_atribute_name */
u32 loongson_special_type; /* type of special device */
/* for each device's resource */
struct resource_loongson resource[MAX_RESOURCE_NUMBER];
};
struct loongson_params {
u64 memory_offset; /* efi_memory_map_loongson struct offset */
u64 cpu_offset; /* efi_cpuinfo_loongson struct offset */
u64 system_offset; /* system_loongson struct offset */
u64 irq_offset; /* irq_source_routing_table struct offset */
u64 interface_offset; /* interface_info struct offset */
u64 special_offset; /* loongson_special_attribute struct offset */
u64 boarddev_table_offset; /* board_devices offset */
};
struct smbios_tables {
u16 vers; /* version of smbios */
u64 vga_bios; /* vga_bios address */
struct loongson_params lp;
};
struct efi_reset_system_t {
u64 ResetCold;
u64 ResetWarm;
u64 ResetType;
u64 Shutdown;
u64 DoSuspend; /* NULL if not support */
};
struct efi_loongson {
u64 mps; /* MPS table */
u64 acpi; /* ACPI table (IA64 ext 0.71) */
u64 acpi20; /* ACPI table (ACPI 2.0) */
struct smbios_tables smbios; /* SM BIOS table */
u64 sal_systab; /* SAL system table */
u64 boot_info; /* boot info table */
};
struct boot_params {
struct efi_loongson efi;
struct efi_reset_system_t reset_system;
};
enum loongson_bridge_type {
LS7A = 1,
RS780E = 2,
VIRTUAL = 3
};
extern struct efi_memory_map_loongson *loongson_memmap;
extern struct loongson_system_configuration loongson_sysconf;
extern struct board_devices *eboard;
extern struct interface_info *einter;
extern struct loongson_special_attribute *especial;
extern u32 node_id_offset;
extern void ls7a_early_config(void);
extern void rs780e_early_config(void);
extern void virtual_early_config(void);
#endif
@@ -0,0 +1,17 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2019 Jiaxun Yang <jiaxun.yang@flygoat.com>
*
* Built-in Generic dtbs for MACH_LOONGSON64
*/
#ifndef __ASM_MACH_LOONGSON64_BUILTIN_DTBS_H_
#define __ASM_MACH_LOONGSON64_BUILTIN_DTBS_H_
extern u32 __dtb_loongson64_2core_2k1000_begin[];
extern u32 __dtb_loongson64c_4core_ls7a_begin[];
extern u32 __dtb_loongson64c_4core_rs780e_begin[];
extern u32 __dtb_loongson64c_8core_rs780e_begin[];
extern u32 __dtb_loongson64g_4core_ls7a_begin[];
extern u32 __dtb_loongson64v_4core_virtio_begin[];
#endif
@@ -0,0 +1,50 @@
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2009 Wu Zhangjin <wuzhangjin@gmail.com>
* Copyright (C) 2009 Philippe Vachon <philippe@cowpig.ca>
* Copyright (C) 2009 Zhang Le <r0bertz@gentoo.org>
*
* reference: /proc/cpuinfo,
* arch/mips/kernel/cpu-probe.c(cpu_probe_legacy),
* arch/mips/kernel/proc.c(show_cpuinfo),
* loongson2f user manual.
*/
#ifndef __ASM_MACH_LOONGSON64_CPU_FEATURE_OVERRIDES_H
#define __ASM_MACH_LOONGSON64_CPU_FEATURE_OVERRIDES_H
#define cpu_has_32fpr 1
#define cpu_has_3k_cache 0
#define cpu_has_4k_cache 1
#define cpu_has_4kex 1
#define cpu_has_64bits 1
#define cpu_has_cache_cdex_p 0
#define cpu_has_cache_cdex_s 0
#define cpu_has_counter 1
#define cpu_has_dc_aliases (PAGE_SIZE < 0x4000)
#define cpu_has_divec 0
#define cpu_has_inclusive_pcaches 1
#define cpu_has_llsc 1
#define cpu_has_mcheck 0
#define cpu_has_mdmx 0
#define cpu_has_mips16 0
#define cpu_has_mips16e2 0
#define cpu_has_mips3d 0
#define cpu_has_mipsmt 0
#define cpu_has_smartmips 0
#define cpu_has_tlb 1
#define cpu_has_vce 0
#define cpu_has_veic 0
#define cpu_has_vint 0
#define cpu_has_vtag_icache 0
#define cpu_has_wsbh 1
#define cpu_has_ic_fills_f_dc 1
#define cpu_hwrena_impl_bits 0xc0000000
#define cpu_has_mac2008_only 1
#define cpu_has_mips_r2_exec_hazard 0
#define cpu_has_perf_cntr_intr_bit 0
#endif /* __ASM_MACH_LOONGSON64_CPU_FEATURE_OVERRIDES_H */
@@ -0,0 +1,74 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_MACH_LOONGSON64_CPUCFG_EMUL_H_
#define _ASM_MACH_LOONGSON64_CPUCFG_EMUL_H_
#include <asm/cpu-info.h>
#ifdef CONFIG_CPU_LOONGSON3_CPUCFG_EMULATION
#include <loongson_regs.h>
#define LOONGSON_FPREV_MASK 0x7
void loongson3_cpucfg_synthesize_data(struct cpuinfo_mips *c);
static inline bool loongson3_cpucfg_emulation_enabled(struct cpuinfo_mips *c)
{
/* All supported cores have non-zero LOONGSON_CFG1 data. */
return c->loongson3_cpucfg_data[0] != 0;
}
static inline u32 loongson3_cpucfg_read_synthesized(struct cpuinfo_mips *c,
__u64 sel)
{
switch (sel) {
case LOONGSON_CFG0:
return c->processor_id;
case LOONGSON_CFG1:
case LOONGSON_CFG2:
case LOONGSON_CFG3:
return c->loongson3_cpucfg_data[sel - 1];
case LOONGSON_CFG4:
case LOONGSON_CFG5:
/* CPUCFG selects 4 and 5 are related to the input clock
* signal.
*
* Unimplemented for now.
*/
return 0;
case LOONGSON_CFG6:
/* CPUCFG select 6 is for the undocumented Safe Extension. */
return 0;
case LOONGSON_CFG7:
/* CPUCFG select 7 is for the virtualization extension.
* We don't know if the two currently known features are
* supported on older cores according to the public
* documentation, so leave this at zero.
*/
return 0;
}
/*
* Return 0 for unrecognized CPUCFG selects, which is real hardware
* behavior observed on Loongson 3A R4.
*/
return 0;
}
#else
static inline void loongson3_cpucfg_synthesize_data(struct cpuinfo_mips *c)
{
}
static inline bool loongson3_cpucfg_emulation_enabled(struct cpuinfo_mips *c)
{
return false;
}
static inline u32 loongson3_cpucfg_read_synthesized(struct cpuinfo_mips *c,
__u64 sel)
{
return 0;
}
#endif
#endif /* _ASM_MACH_LOONGSON64_CPUCFG_EMUL_H_ */
@@ -0,0 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_MACH_LOONGSON64_IRQ_H_
#define __ASM_MACH_LOONGSON64_IRQ_H_
/* cpu core interrupt numbers */
#define NR_IRQS_LEGACY 16
#define NR_MIPS_CPU_IRQS 8
#define NR_MAX_CHAINED_IRQS 40 /* Chained IRQs means those not directly used by devices */
#define NR_IRQS (NR_IRQS_LEGACY + NR_MIPS_CPU_IRQS + NR_MAX_CHAINED_IRQS + 256)
#define MAX_IO_PICS 1
#define MIPS_CPU_IRQ_BASE NR_IRQS_LEGACY
#define GSI_MIN_CPU_IRQ 0
#include <asm/mach-generic/irq.h>
#endif /* __ASM_MACH_LOONGSON64_IRQ_H_ */
@@ -0,0 +1,105 @@
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2005 Embedded Alley Solutions, Inc
* Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
* Copyright (C) 2009 Jiajie Chen (chenjiajie@cse.buaa.edu.cn)
* Copyright (C) 2012 Huacai Chen (chenhc@lemote.com)
*/
#ifndef __ASM_MACH_LOONGSON64_KERNEL_ENTRY_H
#define __ASM_MACH_LOONGSON64_KERNEL_ENTRY_H
#include <asm/cpu.h>
/*
* Override macros used in arch/mips/kernel/head.S.
*/
.macro kernel_entry_setup
.set push
.set mips64
/* Set ELPA on LOONGSON3 pagegrain */
mfc0 t0, CP0_PAGEGRAIN
or t0, (0x1 << 29)
mtc0 t0, CP0_PAGEGRAIN
/* Enable STFill Buffer */
mfc0 t0, CP0_PRID
/* Loongson-3A R4+ */
andi t1, t0, PRID_IMP_MASK
li t2, PRID_IMP_LOONGSON_64G
beq t1, t2, 1f
nop
/* Loongson-3A R2/R3 */
andi t0, (PRID_IMP_MASK | PRID_REV_MASK)
slti t0, t0, (PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R2_0)
bnez t0, 2f
nop
1:
mfc0 t0, CP0_CONFIG6
or t0, 0x100
mtc0 t0, CP0_CONFIG6
2:
_ehb
.set pop
.endm
/*
* Do SMP slave processor setup.
*/
.macro smp_slave_setup
.set push
.set mips64
/* Set ELPA on LOONGSON3 pagegrain */
mfc0 t0, CP0_PAGEGRAIN
or t0, (0x1 << 29)
mtc0 t0, CP0_PAGEGRAIN
/* Enable STFill Buffer */
mfc0 t0, CP0_PRID
/* Loongson-3A R4+ */
andi t1, t0, PRID_IMP_MASK
li t2, PRID_IMP_LOONGSON_64G
beq t1, t2, 1f
nop
/* Loongson-3A R2/R3 */
andi t0, (PRID_IMP_MASK | PRID_REV_MASK)
slti t0, t0, (PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R2_0)
bnez t0, 2f
nop
1:
mfc0 t0, CP0_CONFIG6
or t0, 0x100
mtc0 t0, CP0_CONFIG6
2:
_ehb
.set pop
.endm
#define USE_KEXEC_SMP_WAIT_FINAL
.macro kexec_smp_wait_final
/* s0:prid s1:initfn */
/* a0:base t1:cpuid t2:node t9:count */
mfc0 t1, CP0_EBASE
andi t1, MIPS_EBASE_CPUNUM
dins a0, t1, 8, 2 /* insert core id*/
dext t2, t1, 2, 2
dins a0, t2, 44, 2 /* insert node id */
mfc0 s0, CP0_PRID
andi s0, s0, (PRID_IMP_MASK | PRID_REV_MASK)
beq s0, (PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3B_R1), 1f
beq s0, (PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3B_R2), 1f
b 2f /* Loongson-3A1000/3A2000/3A3000/3A4000 */
1: dins a0, t2, 14, 2 /* Loongson-3B1000/3B1500 need bit 15~14 */
2: li t9, 0x100 /* wait for init loop */
3: addiu t9, -1 /* limit mailbox access */
bnez t9, 3b
lw s1, 0x20(a0) /* check PC as an indicator */
beqz s1, 2b
ld s1, 0x20(a0) /* get PC via mailbox reg0 */
ld sp, 0x28(a0) /* get SP via mailbox reg1 */
ld gp, 0x30(a0) /* get GP via mailbox reg2 */
ld a1, 0x38(a0)
jr s1 /* jump to initial PC */
.endm
#endif /* __ASM_MACH_LOONGSON64_KERNEL_ENTRY_H */
@@ -0,0 +1,266 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2009 Lemote, Inc.
* Author: Wu Zhangjin <wuzhangjin@gmail.com>
*/
#ifndef __ASM_MACH_LOONGSON64_LOONGSON_H
#define __ASM_MACH_LOONGSON64_LOONGSON_H
#include <linux/io.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <boot_param.h>
enum loongson_fw_interface {
LOONGSON_LEFI,
LOONGSON_DTB,
};
/* machine-specific boot configuration */
struct loongson_system_configuration {
enum loongson_fw_interface fw_interface;
u32 nr_cpus;
u32 nr_nodes;
int cores_per_node;
int cores_per_package;
u16 boot_cpu_id;
u16 reserved_cpus_mask;
enum loongson_cpu_type cputype;
enum loongson_bridge_type bridgetype;
u64 restart_addr;
u64 poweroff_addr;
u64 suspend_addr;
u64 vgabios_addr;
u32 dma_mask_bits;
u64 workarounds;
void (*early_config)(void);
};
/* machine-specific reboot/halt operation */
extern void mach_prepare_reboot(void);
extern void mach_prepare_shutdown(void);
/* environment arguments from bootloader */
extern u32 cpu_clock_freq;
extern u32 memsize, highmemsize;
extern const struct plat_smp_ops loongson3_smp_ops;
/* loongson-specific command line, env and memory initialization */
extern void __init prom_dtb_init_env(void);
extern void __init prom_lefi_init_env(void);
extern void __init szmem(unsigned int node);
extern void *loongson_fdt_blob;
/* irq operation functions */
extern void mach_irq_dispatch(unsigned int pending);
extern int mach_i8259_irq(void);
/* We need this in some places... */
#define delay() ({ \
int x; \
for (x = 0; x < 100000; x++) \
__asm__ __volatile__(""); \
})
#define LOONGSON_REG(x) \
(*(volatile u32 *)((char *)CKSEG1ADDR(LOONGSON_REG_BASE) + (x)))
#define LOONGSON3_REG8(base, x) \
(*(volatile u8 *)((char *)TO_UNCAC(base) + (x)))
#define LOONGSON3_REG32(base, x) \
(*(volatile u32 *)((char *)TO_UNCAC(base) + (x)))
#define LOONGSON_FLASH_BASE 0x1c000000
#define LOONGSON_FLASH_SIZE 0x02000000 /* 32M */
#define LOONGSON_FLASH_TOP (LOONGSON_FLASH_BASE+LOONGSON_FLASH_SIZE-1)
#define LOONGSON_LIO0_BASE 0x1e000000
#define LOONGSON_LIO0_SIZE 0x01C00000 /* 28M */
#define LOONGSON_LIO0_TOP (LOONGSON_LIO0_BASE+LOONGSON_LIO0_SIZE-1)
#define LOONGSON_BOOT_BASE 0x1fc00000
#define LOONGSON_BOOT_SIZE 0x00100000 /* 1M */
#define LOONGSON_BOOT_TOP (LOONGSON_BOOT_BASE+LOONGSON_BOOT_SIZE-1)
#define LOONGSON_REG_BASE 0x1fe00000
#define LOONGSON_REG_SIZE 0x00100000 /* 256Bytes + 256Bytes + ??? */
#define LOONGSON_REG_TOP (LOONGSON_REG_BASE+LOONGSON_REG_SIZE-1)
/* Loongson-3 specific registers */
#define LOONGSON3_REG_BASE 0x3ff00000
#define LOONGSON3_REG_SIZE 0x00100000 /* 256Bytes + 256Bytes + ??? */
#define LOONGSON3_REG_TOP (LOONGSON3_REG_BASE+LOONGSON3_REG_SIZE-1)
#define LOONGSON_LIO1_BASE 0x1ff00000
#define LOONGSON_LIO1_SIZE 0x00100000 /* 1M */
#define LOONGSON_LIO1_TOP (LOONGSON_LIO1_BASE+LOONGSON_LIO1_SIZE-1)
#define LOONGSON_PCILO0_BASE 0x10000000
#define LOONGSON_PCILO1_BASE 0x14000000
#define LOONGSON_PCILO2_BASE 0x18000000
#define LOONGSON_PCILO_BASE LOONGSON_PCILO0_BASE
#define LOONGSON_PCILO_SIZE 0x0c000000 /* 64M * 3 */
#define LOONGSON_PCILO_TOP (LOONGSON_PCILO0_BASE+LOONGSON_PCILO_SIZE-1)
#define LOONGSON_PCICFG_BASE 0x1fe80000
#define LOONGSON_PCICFG_SIZE 0x00000800 /* 2K */
#define LOONGSON_PCICFG_TOP (LOONGSON_PCICFG_BASE+LOONGSON_PCICFG_SIZE-1)
#define LOONGSON_PCIIO_BASE loongson_sysconf.pci_io_base
#define LOONGSON_PCIIO_SIZE 0x00100000 /* 1M */
#define LOONGSON_PCIIO_TOP (LOONGSON_PCIIO_BASE+LOONGSON_PCIIO_SIZE-1)
/* Loongson Register Bases */
#define LOONGSON_PCICONFIGBASE 0x00
#define LOONGSON_REGBASE 0x100
/* PCI Configuration Registers */
#define LOONGSON_PCI_REG(x) LOONGSON_REG(LOONGSON_PCICONFIGBASE + (x))
#define LOONGSON_PCIDID LOONGSON_PCI_REG(0x00)
#define LOONGSON_PCICMD LOONGSON_PCI_REG(0x04)
#define LOONGSON_PCICLASS LOONGSON_PCI_REG(0x08)
#define LOONGSON_PCILTIMER LOONGSON_PCI_REG(0x0c)
#define LOONGSON_PCIBASE0 LOONGSON_PCI_REG(0x10)
#define LOONGSON_PCIBASE1 LOONGSON_PCI_REG(0x14)
#define LOONGSON_PCIBASE2 LOONGSON_PCI_REG(0x18)
#define LOONGSON_PCIBASE3 LOONGSON_PCI_REG(0x1c)
#define LOONGSON_PCIBASE4 LOONGSON_PCI_REG(0x20)
#define LOONGSON_PCIEXPRBASE LOONGSON_PCI_REG(0x30)
#define LOONGSON_PCIINT LOONGSON_PCI_REG(0x3c)
#define LOONGSON_PCI_ISR4C LOONGSON_PCI_REG(0x4c)
#define LOONGSON_PCICMD_PERR_CLR 0x80000000
#define LOONGSON_PCICMD_SERR_CLR 0x40000000
#define LOONGSON_PCICMD_MABORT_CLR 0x20000000
#define LOONGSON_PCICMD_MTABORT_CLR 0x10000000
#define LOONGSON_PCICMD_TABORT_CLR 0x08000000
#define LOONGSON_PCICMD_MPERR_CLR 0x01000000
#define LOONGSON_PCICMD_PERRRESPEN 0x00000040
#define LOONGSON_PCICMD_ASTEPEN 0x00000080
#define LOONGSON_PCICMD_SERREN 0x00000100
#define LOONGSON_PCILTIMER_BUSLATENCY 0x0000ff00
#define LOONGSON_PCILTIMER_BUSLATENCY_SHIFT 8
/* Loongson h/w Configuration */
#define LOONGSON_GENCFG_OFFSET 0x4
#define LOONGSON_GENCFG LOONGSON_REG(LOONGSON_REGBASE + LOONGSON_GENCFG_OFFSET)
#define LOONGSON_GENCFG_DEBUGMODE 0x00000001
#define LOONGSON_GENCFG_SNOOPEN 0x00000002
#define LOONGSON_GENCFG_CPUSELFRESET 0x00000004
#define LOONGSON_GENCFG_FORCE_IRQA 0x00000008
#define LOONGSON_GENCFG_IRQA_ISOUT 0x00000010
#define LOONGSON_GENCFG_IRQA_FROM_INT1 0x00000020
#define LOONGSON_GENCFG_BYTESWAP 0x00000040
#define LOONGSON_GENCFG_UNCACHED 0x00000080
#define LOONGSON_GENCFG_PREFETCHEN 0x00000100
#define LOONGSON_GENCFG_WBEHINDEN 0x00000200
#define LOONGSON_GENCFG_CACHEALG 0x00000c00
#define LOONGSON_GENCFG_CACHEALG_SHIFT 10
#define LOONGSON_GENCFG_PCIQUEUE 0x00001000
#define LOONGSON_GENCFG_CACHESTOP 0x00002000
#define LOONGSON_GENCFG_MSTRBYTESWAP 0x00004000
#define LOONGSON_GENCFG_BUSERREN 0x00008000
#define LOONGSON_GENCFG_NORETRYTIMEOUT 0x00010000
#define LOONGSON_GENCFG_SHORTCOPYTIMEOUT 0x00020000
/* PCI address map control */
#define LOONGSON_PCIMAP LOONGSON_REG(LOONGSON_REGBASE + 0x10)
#define LOONGSON_PCIMEMBASECFG LOONGSON_REG(LOONGSON_REGBASE + 0x14)
#define LOONGSON_PCIMAP_CFG LOONGSON_REG(LOONGSON_REGBASE + 0x18)
/* GPIO Regs - r/w */
#define LOONGSON_GPIODATA LOONGSON_REG(LOONGSON_REGBASE + 0x1c)
#define LOONGSON_GPIOIE LOONGSON_REG(LOONGSON_REGBASE + 0x20)
/* ICU Configuration Regs - r/w */
#define LOONGSON_INTEDGE LOONGSON_REG(LOONGSON_REGBASE + 0x24)
#define LOONGSON_INTSTEER LOONGSON_REG(LOONGSON_REGBASE + 0x28)
#define LOONGSON_INTPOL LOONGSON_REG(LOONGSON_REGBASE + 0x2c)
/* ICU Enable Regs - IntEn & IntISR are r/o. */
#define LOONGSON_INTENSET LOONGSON_REG(LOONGSON_REGBASE + 0x30)
#define LOONGSON_INTENCLR LOONGSON_REG(LOONGSON_REGBASE + 0x34)
#define LOONGSON_INTEN LOONGSON_REG(LOONGSON_REGBASE + 0x38)
#define LOONGSON_INTISR LOONGSON_REG(LOONGSON_REGBASE + 0x3c)
/* ICU */
#define LOONGSON_ICU_MBOXES 0x0000000f
#define LOONGSON_ICU_MBOXES_SHIFT 0
#define LOONGSON_ICU_DMARDY 0x00000010
#define LOONGSON_ICU_DMAEMPTY 0x00000020
#define LOONGSON_ICU_COPYRDY 0x00000040
#define LOONGSON_ICU_COPYEMPTY 0x00000080
#define LOONGSON_ICU_COPYERR 0x00000100
#define LOONGSON_ICU_PCIIRQ 0x00000200
#define LOONGSON_ICU_MASTERERR 0x00000400
#define LOONGSON_ICU_SYSTEMERR 0x00000800
#define LOONGSON_ICU_DRAMPERR 0x00001000
#define LOONGSON_ICU_RETRYERR 0x00002000
#define LOONGSON_ICU_GPIOS 0x01ff0000
#define LOONGSON_ICU_GPIOS_SHIFT 16
#define LOONGSON_ICU_GPINS 0x7e000000
#define LOONGSON_ICU_GPINS_SHIFT 25
#define LOONGSON_ICU_MBOX(N) (1<<(LOONGSON_ICU_MBOXES_SHIFT+(N)))
#define LOONGSON_ICU_GPIO(N) (1<<(LOONGSON_ICU_GPIOS_SHIFT+(N)))
#define LOONGSON_ICU_GPIN(N) (1<<(LOONGSON_ICU_GPINS_SHIFT+(N)))
/* PCI prefetch window base & mask */
#define LOONGSON_MEM_WIN_BASE_L LOONGSON_REG(LOONGSON_REGBASE + 0x40)
#define LOONGSON_MEM_WIN_BASE_H LOONGSON_REG(LOONGSON_REGBASE + 0x44)
#define LOONGSON_MEM_WIN_MASK_L LOONGSON_REG(LOONGSON_REGBASE + 0x48)
#define LOONGSON_MEM_WIN_MASK_H LOONGSON_REG(LOONGSON_REGBASE + 0x4c)
/* PCI_Hit*_Sel_* */
#define LOONGSON_PCI_HIT0_SEL_L LOONGSON_REG(LOONGSON_REGBASE + 0x50)
#define LOONGSON_PCI_HIT0_SEL_H LOONGSON_REG(LOONGSON_REGBASE + 0x54)
#define LOONGSON_PCI_HIT1_SEL_L LOONGSON_REG(LOONGSON_REGBASE + 0x58)
#define LOONGSON_PCI_HIT1_SEL_H LOONGSON_REG(LOONGSON_REGBASE + 0x5c)
#define LOONGSON_PCI_HIT2_SEL_L LOONGSON_REG(LOONGSON_REGBASE + 0x60)
#define LOONGSON_PCI_HIT2_SEL_H LOONGSON_REG(LOONGSON_REGBASE + 0x64)
/* PXArb Config & Status */
#define LOONGSON_PXARB_CFG LOONGSON_REG(LOONGSON_REGBASE + 0x68)
#define LOONGSON_PXARB_STATUS LOONGSON_REG(LOONGSON_REGBASE + 0x6c)
#define MAX_PACKAGES 4
/* Chip Config registor of each physical cpu package, PRid >= Loongson-2F */
extern u64 loongson_chipcfg[MAX_PACKAGES];
#define LOONGSON_CHIPCFG(id) (*(volatile u32 *)(loongson_chipcfg[id]))
/* Chip Temperature registor of each physical cpu package, PRid >= Loongson-3A */
extern u64 loongson_chiptemp[MAX_PACKAGES];
#define LOONGSON_CHIPTEMP(id) (*(volatile u32 *)(loongson_chiptemp[id]))
/* Freq Control register of each physical cpu package, PRid >= Loongson-3B */
extern u64 loongson_freqctrl[MAX_PACKAGES];
#define LOONGSON_FREQCTRL(id) (*(volatile u32 *)(loongson_freqctrl[id]))
/* pcimap */
#define LOONGSON_PCIMAP_PCIMAP_LO0 0x0000003f
#define LOONGSON_PCIMAP_PCIMAP_LO0_SHIFT 0
#define LOONGSON_PCIMAP_PCIMAP_LO1 0x00000fc0
#define LOONGSON_PCIMAP_PCIMAP_LO1_SHIFT 6
#define LOONGSON_PCIMAP_PCIMAP_LO2 0x0003f000
#define LOONGSON_PCIMAP_PCIMAP_LO2_SHIFT 12
#define LOONGSON_PCIMAP_PCIMAP_2 0x00040000
#define LOONGSON_PCIMAP_WIN(WIN, ADDR) \
((((ADDR)>>26) & LOONGSON_PCIMAP_PCIMAP_LO0) << ((WIN)*6))
#endif /* __ASM_MACH_LOONGSON64_LOONGSON_H */
@@ -0,0 +1,56 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __LOONGSON_HWMON_H_
#define __LOONGSON_HWMON_H_
#include <linux/types.h>
#define MIN_TEMP 0
#define MAX_TEMP 255
#define NOT_VALID_TEMP 999
typedef int (*get_temp_fun)(int);
extern int loongson3_cpu_temp(int);
/* 0:Max speed, 1:Manual, 2:Auto */
enum fan_control_mode {
FAN_FULL_MODE = 0,
FAN_MANUAL_MODE = 1,
FAN_AUTO_MODE = 2,
FAN_MODE_END
};
struct temp_range {
u8 low;
u8 high;
u8 level;
};
#define CONSTANT_SPEED_POLICY 0 /* at constant speed */
#define STEP_SPEED_POLICY 1 /* use up/down arrays to describe policy */
#define KERNEL_HELPER_POLICY 2 /* kernel as a helper to fan control */
#define MAX_STEP_NUM 16
#define MAX_FAN_LEVEL 255
/* loongson_fan_policy works when fan work at FAN_AUTO_MODE */
struct loongson_fan_policy {
u8 type;
/* percent only used when type is CONSTANT_SPEED_POLICY */
u8 percent;
/* period between two check. (Unit: S) */
u8 adjust_period;
/* fan adjust usually depend on a temperature input */
get_temp_fun depend_temp;
/* up_step/down_step used when type is STEP_SPEED_POLICY */
u8 up_step_num;
u8 down_step_num;
struct temp_range up_step[MAX_STEP_NUM];
struct temp_range down_step[MAX_STEP_NUM];
struct delayed_work work;
};
#endif /* __LOONGSON_HWMON_H_*/
@@ -0,0 +1,268 @@
/*
* Read/Write Loongson Extension Registers
*/
#ifndef _LOONGSON_REGS_H_
#define _LOONGSON_REGS_H_
#include <linux/types.h>
#include <linux/bits.h>
#include <asm/mipsregs.h>
#include <asm/cpu.h>
static inline bool cpu_has_cfg(void)
{
return ((read_c0_prid() & PRID_IMP_MASK) == PRID_IMP_LOONGSON_64G);
}
static inline u32 read_cpucfg(u32 reg)
{
u32 __res;
__asm__ __volatile__(
_ASM_SET_PARSE_R
"parse_r __res,%0\n\t"
"parse_r reg,%1\n\t"
_ASM_UNSET_PARSE_R
".insn \n\t"
".word (0xc8080118 | (reg << 21) | (__res << 11))\n\t"
:"=r"(__res)
:"r"(reg)
:
);
return __res;
}
/* Bit Domains for CFG registers */
#define LOONGSON_CFG0 0x0
#define LOONGSON_CFG0_PRID GENMASK(31, 0)
#define LOONGSON_CFG1 0x1
#define LOONGSON_CFG1_FP BIT(0)
#define LOONGSON_CFG1_FPREV GENMASK(3, 1)
#define LOONGSON_CFG1_MMI BIT(4)
#define LOONGSON_CFG1_MSA1 BIT(5)
#define LOONGSON_CFG1_MSA2 BIT(6)
#define LOONGSON_CFG1_CGP BIT(7)
#define LOONGSON_CFG1_WRP BIT(8)
#define LOONGSON_CFG1_LSX1 BIT(9)
#define LOONGSON_CFG1_LSX2 BIT(10)
#define LOONGSON_CFG1_LASX BIT(11)
#define LOONGSON_CFG1_R6FXP BIT(12)
#define LOONGSON_CFG1_R6CRCP BIT(13)
#define LOONGSON_CFG1_R6FPP BIT(14)
#define LOONGSON_CFG1_CNT64 BIT(15)
#define LOONGSON_CFG1_LSLDR0 BIT(16)
#define LOONGSON_CFG1_LSPREF BIT(17)
#define LOONGSON_CFG1_LSPREFX BIT(18)
#define LOONGSON_CFG1_LSSYNCI BIT(19)
#define LOONGSON_CFG1_LSUCA BIT(20)
#define LOONGSON_CFG1_LLSYNC BIT(21)
#define LOONGSON_CFG1_TGTSYNC BIT(22)
#define LOONGSON_CFG1_LLEXC BIT(23)
#define LOONGSON_CFG1_SCRAND BIT(24)
#define LOONGSON_CFG1_MUALP BIT(25)
#define LOONGSON_CFG1_KMUALEN BIT(26)
#define LOONGSON_CFG1_ITLBT BIT(27)
#define LOONGSON_CFG1_LSUPERF BIT(28)
#define LOONGSON_CFG1_SFBP BIT(29)
#define LOONGSON_CFG1_CDMAP BIT(30)
#define LOONGSON_CFG1_FPREV_OFFSET 1
#define LOONGSON_CFG2 0x2
#define LOONGSON_CFG2_LEXT1 BIT(0)
#define LOONGSON_CFG2_LEXT2 BIT(1)
#define LOONGSON_CFG2_LEXT3 BIT(2)
#define LOONGSON_CFG2_LSPW BIT(3)
#define LOONGSON_CFG2_LBT1 BIT(4)
#define LOONGSON_CFG2_LBT2 BIT(5)
#define LOONGSON_CFG2_LBT3 BIT(6)
#define LOONGSON_CFG2_LBTMMU BIT(7)
#define LOONGSON_CFG2_LPMP BIT(8)
#define LOONGSON_CFG2_LPMREV GENMASK(11, 9)
#define LOONGSON_CFG2_LAMO BIT(12)
#define LOONGSON_CFG2_LPIXU BIT(13)
#define LOONGSON_CFG2_LPIXNU BIT(14)
#define LOONGSON_CFG2_LVZP BIT(15)
#define LOONGSON_CFG2_LVZREV GENMASK(18, 16)
#define LOONGSON_CFG2_LGFTP BIT(19)
#define LOONGSON_CFG2_LGFTPREV GENMASK(22, 20)
#define LOONGSON_CFG2_LLFTP BIT(23)
#define LOONGSON_CFG2_LLFTPREV GENMASK(26, 24)
#define LOONGSON_CFG2_LCSRP BIT(27)
#define LOONGSON_CFG2_LDISBLIKELY BIT(28)
#define LOONGSON_CFG2_LPMREV_OFFSET 9
#define LOONGSON_CFG2_LPM_REV1 (1 << LOONGSON_CFG2_LPMREV_OFFSET)
#define LOONGSON_CFG2_LPM_REV2 (2 << LOONGSON_CFG2_LPMREV_OFFSET)
#define LOONGSON_CFG2_LVZREV_OFFSET 16
#define LOONGSON_CFG2_LVZ_REV1 (1 << LOONGSON_CFG2_LVZREV_OFFSET)
#define LOONGSON_CFG2_LVZ_REV2 (2 << LOONGSON_CFG2_LVZREV_OFFSET)
#define LOONGSON_CFG3 0x3
#define LOONGSON_CFG3_LCAMP BIT(0)
#define LOONGSON_CFG3_LCAMREV GENMASK(3, 1)
#define LOONGSON_CFG3_LCAMNUM GENMASK(11, 4)
#define LOONGSON_CFG3_LCAMKW GENMASK(19, 12)
#define LOONGSON_CFG3_LCAMVW GENMASK(27, 20)
#define LOONGSON_CFG3_LCAMREV_OFFSET 1
#define LOONGSON_CFG3_LCAM_REV1 (1 << LOONGSON_CFG3_LCAMREV_OFFSET)
#define LOONGSON_CFG3_LCAM_REV2 (2 << LOONGSON_CFG3_LCAMREV_OFFSET)
#define LOONGSON_CFG3_LCAMNUM_OFFSET 4
#define LOONGSON_CFG3_LCAMNUM_REV1 (0x3f << LOONGSON_CFG3_LCAMNUM_OFFSET)
#define LOONGSON_CFG3_LCAMKW_OFFSET 12
#define LOONGSON_CFG3_LCAMKW_REV1 (0x27 << LOONGSON_CFG3_LCAMKW_OFFSET)
#define LOONGSON_CFG3_LCAMVW_OFFSET 20
#define LOONGSON_CFG3_LCAMVW_REV1 (0x3f << LOONGSON_CFG3_LCAMVW_OFFSET)
#define LOONGSON_CFG4 0x4
#define LOONGSON_CFG4_CCFREQ GENMASK(31, 0)
#define LOONGSON_CFG5 0x5
#define LOONGSON_CFG5_CFM GENMASK(15, 0)
#define LOONGSON_CFG5_CFD GENMASK(31, 16)
#define LOONGSON_CFG6 0x6
#define LOONGSON_CFG7 0x7
#define LOONGSON_CFG7_GCCAEQRP BIT(0)
#define LOONGSON_CFG7_UCAWINP BIT(1)
static inline bool cpu_has_csr(void)
{
if (cpu_has_cfg())
return (read_cpucfg(LOONGSON_CFG2) & LOONGSON_CFG2_LCSRP);
return false;
}
static inline u32 csr_readl(u32 reg)
{
u32 __res;
/* RDCSR reg, val */
__asm__ __volatile__(
_ASM_SET_PARSE_R
"parse_r __res,%0\n\t"
"parse_r reg,%1\n\t"
_ASM_UNSET_PARSE_R
".insn \n\t"
".word (0xc8000118 | (reg << 21) | (__res << 11))\n\t"
:"=r"(__res)
:"r"(reg)
:
);
return __res;
}
static inline u64 csr_readq(u32 reg)
{
u64 __res;
/* DRDCSR reg, val */
__asm__ __volatile__(
_ASM_SET_PARSE_R
"parse_r __res,%0\n\t"
"parse_r reg,%1\n\t"
_ASM_UNSET_PARSE_R
".insn \n\t"
".word (0xc8020118 | (reg << 21) | (__res << 11))\n\t"
:"=r"(__res)
:"r"(reg)
:
);
return __res;
}
static inline void csr_writel(u32 val, u32 reg)
{
/* WRCSR reg, val */
__asm__ __volatile__(
_ASM_SET_PARSE_R
"parse_r reg,%0\n\t"
"parse_r val,%1\n\t"
_ASM_UNSET_PARSE_R
".insn \n\t"
".word (0xc8010118 | (reg << 21) | (val << 11))\n\t"
:
:"r"(reg),"r"(val)
:
);
}
static inline void csr_writeq(u64 val, u32 reg)
{
/* DWRCSR reg, val */
__asm__ __volatile__(
_ASM_SET_PARSE_R
"parse_r reg,%0\n\t"
"parse_r val,%1\n\t"
_ASM_UNSET_PARSE_R
".insn \n\t"
".word (0xc8030118 | (reg << 21) | (val << 11))\n\t"
:
:"r"(reg),"r"(val)
:
);
}
/* Public CSR Register can also be accessed with regular addresses */
#define CSR_PUBLIC_MMIO_BASE 0x1fe00000
#define MMIO_CSR(x) (void *)TO_UNCAC(CSR_PUBLIC_MMIO_BASE + x)
#define LOONGSON_CSR_FEATURES 0x8
#define LOONGSON_CSRF_TEMP BIT(0)
#define LOONGSON_CSRF_NODECNT BIT(1)
#define LOONGSON_CSRF_MSI BIT(2)
#define LOONGSON_CSRF_EXTIOI BIT(3)
#define LOONGSON_CSRF_IPI BIT(4)
#define LOONGSON_CSRF_FREQ BIT(5)
#define LOONGSON_CSR_VENDOR 0x10 /* Vendor name string, should be "Loongson" */
#define LOONGSON_CSR_CPUNAME 0x20 /* Processor name string */
#define LOONGSON_CSR_NODECNT 0x408
#define LOONGSON_CSR_CPUTEMP 0x428
/* PerCore CSR, only accessible by local cores */
#define LOONGSON_CSR_IPI_STATUS 0x1000
#define LOONGSON_CSR_IPI_EN 0x1004
#define LOONGSON_CSR_IPI_SET 0x1008
#define LOONGSON_CSR_IPI_CLEAR 0x100c
#define LOONGSON_CSR_IPI_SEND 0x1040
#define CSR_IPI_SEND_IP_SHIFT 0
#define CSR_IPI_SEND_CPU_SHIFT 16
#define CSR_IPI_SEND_BLOCK BIT(31)
#define LOONGSON_CSR_MAIL_BUF0 0x1020
#define LOONGSON_CSR_MAIL_SEND 0x1048
#define CSR_MAIL_SEND_BLOCK BIT_ULL(31)
#define CSR_MAIL_SEND_BOX_LOW(box) (box << 1)
#define CSR_MAIL_SEND_BOX_HIGH(box) ((box << 1) + 1)
#define CSR_MAIL_SEND_BOX_SHIFT 2
#define CSR_MAIL_SEND_CPU_SHIFT 16
#define CSR_MAIL_SEND_BUF_SHIFT 32
#define CSR_MAIL_SEND_H32_MASK 0xFFFFFFFF00000000ULL
static inline u64 drdtime(void)
{
int rID = 0;
u64 val = 0;
__asm__ __volatile__(
_ASM_SET_PARSE_R
"parse_r rID,%0\n\t"
"parse_r val,%1\n\t"
_ASM_UNSET_PARSE_R
".insn \n\t"
".word (0xc8090118 | (rID << 21) | (val << 11))\n\t"
:"=r"(rID),"=r"(val)
:
);
return val;
}
#endif
@@ -0,0 +1,19 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2010 Loongson Inc. & Lemote Inc. &
* Institute of Computing Technology
* Author: Xiang Gao, gaoxiang@ict.ac.cn
* Huacai Chen, chenhc@lemote.com
* Xiaofu Meng, Shuangshuang Zhang
*/
#ifndef _ASM_MACH_LOONGSON64_MMZONE_H
#define _ASM_MACH_LOONGSON64_MMZONE_H
#define NODE_ADDRSPACE_SHIFT 44
#define pa_to_nid(addr) (((addr) & 0xf00000000000) >> NODE_ADDRSPACE_SHIFT)
#define nid_to_addrbase(nid) ((unsigned long)(nid) << NODE_ADDRSPACE_SHIFT)
extern void __init prom_init_numa_memory(void);
#endif /* _ASM_MACH_MMZONE_H */
@@ -0,0 +1,19 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (c) 2008 Zhang Le <r0bertz@gentoo.org>
* Copyright (c) 2009 Wu Zhangjin <wuzhangjin@gmail.com>
*/
#ifndef __ASM_MACH_LOONGSON64_PCI_H_
#define __ASM_MACH_LOONGSON64_PCI_H_
extern struct pci_ops loongson_pci_ops;
/* this is an offset from mips_io_port_base */
#define LOONGSON_PCI_IO_START 0x00004000UL
#define LOONGSON_PCI_MEM_START 0x40000000UL
#define LOONGSON_PCI_MEM_END 0x7effffffUL
#endif /* !__ASM_MACH_LOONGSON64_PCI_H_ */
@@ -0,0 +1,18 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_MACH_LOONGSON64_SPACES_H_
#define __ASM_MACH_LOONGSON64_SPACES_H_
#if defined(CONFIG_64BIT)
#define CAC_BASE _AC(0x9800000000000000, UL)
#endif /* CONFIG_64BIT */
/* Skip 128k to trap NULL pointer dereferences */
#define PCI_PORT_BASE _AC(0xc000000000000000 + SZ_128K, UL)
#define PCI_IOBASE (void __iomem *)PCI_PORT_BASE
#define PCI_IOSIZE SZ_16M
#define MAP_BASE (PCI_PORT_BASE + PCI_IOSIZE)
#define IO_SPACE_LIMIT (PCI_IOSIZE - 1)
#include <asm/mach-generic/spaces.h>
#endif
@@ -0,0 +1,25 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_MACH_TOPOLOGY_H
#define _ASM_MACH_TOPOLOGY_H
#ifdef CONFIG_NUMA
#define cpu_to_node(cpu) (cpu_logical_map(cpu) >> 2)
extern cpumask_t __node_cpumask[];
#define cpumask_of_node(node) ((node) == NUMA_NO_NODE ? cpu_all_mask : &__node_cpumask[node])
struct pci_bus;
extern int pcibus_to_node(struct pci_bus *);
#define cpumask_of_pcibus(bus) (cpu_online_mask)
extern unsigned char __node_distances[MAX_NUMNODES][MAX_NUMNODES];
#define node_distance(from, to) (__node_distances[(from)][(to)])
#endif
#include <asm-generic/topology.h>
#endif /* _ASM_MACH_TOPOLOGY_H */
@@ -0,0 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_MACH_LOONGSON64_WORKAROUNDS_H_
#define __ASM_MACH_LOONGSON64_WORKAROUNDS_H_
#define WORKAROUND_CPUFREQ 0x00000001
#define WORKAROUND_CPUHOTPLUG 0x00000002
#endif