1
0
Fork 0

MIPS: Fork loongson2ef from loongson64

As later model of GSx64 family processors including 2-series-soc have
similar design with initial loongson3a while loongson2e/f seems less
identical, we separate loongson2e/f support code out of mach-loongson64
to make our life easier.

This patch contains mostly file moving works.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
[paulburton@kernel.org: Squash in the MAINTAINERS updates]
Signed-off-by: Paul Burton <paulburton@kernel.org>
Cc: linux-mips@vger.kernel.org
Cc: paul.burton@mips.com
alistair/sunxi64-5.5-dsi
Jiaxun Yang 2019-10-20 22:43:14 +08:00 committed by Paul Burton
parent 268a2d6001
commit 71e2f4dd5a
No known key found for this signature in database
GPG Key ID: 3EA79FACB57500DD
71 changed files with 3351 additions and 132 deletions

View File

@ -10871,18 +10871,18 @@ F: arch/mips/include/asm/mach-loongson32/
F: drivers/*/*loongson1*
F: drivers/*/*/*loongson1*
MIPS/LOONGSON2 ARCHITECTURE
MIPS/LOONGSON2EF ARCHITECTURE
M: Jiaxun Yang <jiaxun.yang@flygoat.com>
L: linux-mips@vger.kernel.org
S: Maintained
F: arch/mips/loongson64/fuloong-2e/
F: arch/mips/loongson64/lemote-2f/
F: arch/mips/include/asm/mach-loongson64/
F: arch/mips/loongson2ef/
F: arch/mips/include/asm/mach-loongson2ef/
F: drivers/*/*loongson2*
F: drivers/*/*/*loongson2*
MIPS/LOONGSON3 ARCHITECTURE
MIPS/LOONGSON64 ARCHITECTURE
M: Huacai Chen <chenhc@lemote.com>
M: Jiaxun Yang <jiaxun.yang@flygoat.com>
L: linux-mips@vger.kernel.org
S: Maintained
F: arch/mips/loongson64/

View File

@ -17,6 +17,7 @@ platforms += jazz
platforms += jz4740
platforms += lantiq
platforms += lasat
platforms += loongson2ef
platforms += loongson32
platforms += loongson64
platforms += mti-malta

View File

@ -453,18 +453,18 @@ config MACH_LOONGSON32
the Institute of Computing Technology (ICT), Chinese Academy of
Sciences (CAS).
config MACH_LOONGSON64
bool "Loongson-2/3 family of machines"
config MACH_LOONGSON2EF
bool "Loongson-2E/F family of machines"
select SYS_SUPPORTS_ZBOOT
help
This enables the support of Loongson-2/3 family of machines.
This enables the support of early Loongson-2E/F family of machines.
Loongson-2 is a family of single-core CPUs and Loongson-3 is a
family of multi-core CPUs. They are both 64-bit general-purpose
MIPS-compatible CPUs. Loongson-2/3 are developed by the Institute
of Computing Technology (ICT), Chinese Academy of Sciences (CAS)
in the People's Republic of China. The chief architect is Professor
Weiwu Hu.
config MACH_LOONGSON64
bool "Loongson-2/3 GSx64 family of machines"
select SYS_SUPPORTS_ZBOOT
help
This enables the support of Loongson-2/3 family of processors with
GSx64 microarchitecture.
config MACH_PISTACHIO
bool "IMG Pistachio SoC based boards"
@ -1037,6 +1037,7 @@ source "arch/mips/sibyte/Kconfig"
source "arch/mips/txx9/Kconfig"
source "arch/mips/vr41xx/Kconfig"
source "arch/mips/cavium-octeon/Kconfig"
source "arch/mips/loongson2ef/Kconfig"
source "arch/mips/loongson32/Kconfig"
source "arch/mips/loongson64/Kconfig"
source "arch/mips/netlogic/Kconfig"

View File

@ -15,7 +15,7 @@ CONFIG_EXPERT=y
# CONFIG_COMPAT_BRK is not set
CONFIG_SLAB=y
CONFIG_PROFILING=y
CONFIG_MACH_LOONGSON64=y
CONFIG_MACH_LOONGSON2EF=y
CONFIG_PCI=y
CONFIG_MIPS32_O32=y
CONFIG_MIPS32_N32=y

View File

@ -12,7 +12,7 @@ CONFIG_LOG_BUF_SHIFT=15
CONFIG_BLK_DEV_INITRD=y
CONFIG_EXPERT=y
CONFIG_PROFILING=y
CONFIG_MACH_LOONGSON64=y
CONFIG_MACH_LOONGSON2EF=y
CONFIG_LEMOTE_MACH2F=y
CONFIG_KEXEC=y
# CONFIG_SECCOMP is not set

View File

@ -0,0 +1,221 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_MACH_LOONGSON64_BOOT_PARAM_H_
#define __ASM_MACH_LOONGSON64_BOOT_PARAM_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 MAX_MEMORY_TYPE 11
#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,
Loongson_1A = 0x100,
Loongson_1B = 0x101,
Loongson_2E = 0x200,
Loongson_2F = 0x201,
Loongson_2G = 0x202,
Loongson_2H = 0x203,
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;
u32 dma_mask_bits;
} __packed;
struct interface_info {
u16 vers; /* version of the specificition */
u16 size;
u8 flag;
char description[64];
} __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;
};
struct loongson_system_configuration {
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;
u64 ht_control_base;
u64 pci_mem_start_addr;
u64 pci_mem_end_addr;
u64 pci_io_base;
u64 restart_addr;
u64 poweroff_addr;
u64 suspend_addr;
u64 vgabios_addr;
u32 dma_mask_bits;
char ecname[32];
u32 nr_uarts;
struct uart_device uarts[MAX_UARTS];
u32 nr_sensors;
struct sensor_device sensors[MAX_SENSORS];
u64 workarounds;
};
extern struct efi_memory_map_loongson *loongson_memmap;
extern struct loongson_system_configuration loongson_sysconf;
#endif

View File

@ -0,0 +1,53 @@
/*
* 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_ejtag 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_tx39_cache 0
#define cpu_has_vce 0
#define cpu_has_veic 0
#define cpu_has_vint 0
#define cpu_has_vtag_icache 0
#define cpu_has_watch 1
#ifdef CONFIG_CPU_LOONGSON64
#define cpu_has_wsbh 1
#define cpu_has_ic_fills_f_dc 1
#define cpu_hwrena_impl_bits 0xc0000000
#endif
#endif /* __ASM_MACH_LOONGSON64_CPU_FEATURE_OVERRIDES_H */

View File

@ -0,0 +1,306 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* The header file of cs5536 south bridge.
*
* Copyright (C) 2007 Lemote, Inc.
* Author : jlliu <liujl@lemote.com>
*/
#ifndef _CS5536_H
#define _CS5536_H
#include <linux/types.h>
extern void _rdmsr(u32 msr, u32 *hi, u32 *lo);
extern void _wrmsr(u32 msr, u32 hi, u32 lo);
/*
* MSR module base
*/
#define CS5536_SB_MSR_BASE (0x00000000)
#define CS5536_GLIU_MSR_BASE (0x10000000)
#define CS5536_ILLEGAL_MSR_BASE (0x20000000)
#define CS5536_USB_MSR_BASE (0x40000000)
#define CS5536_IDE_MSR_BASE (0x60000000)
#define CS5536_DIVIL_MSR_BASE (0x80000000)
#define CS5536_ACC_MSR_BASE (0xa0000000)
#define CS5536_UNUSED_MSR_BASE (0xc0000000)
#define CS5536_GLCP_MSR_BASE (0xe0000000)
#define SB_MSR_REG(offset) (CS5536_SB_MSR_BASE | (offset))
#define GLIU_MSR_REG(offset) (CS5536_GLIU_MSR_BASE | (offset))
#define ILLEGAL_MSR_REG(offset) (CS5536_ILLEGAL_MSR_BASE | (offset))
#define USB_MSR_REG(offset) (CS5536_USB_MSR_BASE | (offset))
#define IDE_MSR_REG(offset) (CS5536_IDE_MSR_BASE | (offset))
#define DIVIL_MSR_REG(offset) (CS5536_DIVIL_MSR_BASE | (offset))
#define ACC_MSR_REG(offset) (CS5536_ACC_MSR_BASE | (offset))
#define UNUSED_MSR_REG(offset) (CS5536_UNUSED_MSR_BASE | (offset))
#define GLCP_MSR_REG(offset) (CS5536_GLCP_MSR_BASE | (offset))
/*
* BAR SPACE OF VIRTUAL PCI :
* range for pci probe use, length is the actual size.
*/
/* IO space for all DIVIL modules */
#define CS5536_IRQ_RANGE 0xffffffe0 /* USERD FOR PCI PROBE */
#define CS5536_IRQ_LENGTH 0x20 /* THE REGS ACTUAL LENGTH */
#define CS5536_SMB_RANGE 0xfffffff8
#define CS5536_SMB_LENGTH 0x08
#define CS5536_GPIO_RANGE 0xffffff00
#define CS5536_GPIO_LENGTH 0x100
#define CS5536_MFGPT_RANGE 0xffffffc0
#define CS5536_MFGPT_LENGTH 0x40
#define CS5536_ACPI_RANGE 0xffffffe0
#define CS5536_ACPI_LENGTH 0x20
#define CS5536_PMS_RANGE 0xffffff80
#define CS5536_PMS_LENGTH 0x80
/* IO space for IDE */
#define CS5536_IDE_RANGE 0xfffffff0
#define CS5536_IDE_LENGTH 0x10
/* IO space for ACC */
#define CS5536_ACC_RANGE 0xffffff80
#define CS5536_ACC_LENGTH 0x80
/* MEM space for ALL USB modules */
#define CS5536_OHCI_RANGE 0xfffff000
#define CS5536_OHCI_LENGTH 0x1000
#define CS5536_EHCI_RANGE 0xfffff000
#define CS5536_EHCI_LENGTH 0x1000
/*
* PCI MSR ACCESS
*/
#define PCI_MSR_CTRL 0xF0
#define PCI_MSR_ADDR 0xF4
#define PCI_MSR_DATA_LO 0xF8
#define PCI_MSR_DATA_HI 0xFC
/**************** MSR *****************************/
/*
* GLIU STANDARD MSR
*/
#define GLIU_CAP 0x00
#define GLIU_CONFIG 0x01
#define GLIU_SMI 0x02
#define GLIU_ERROR 0x03
#define GLIU_PM 0x04
#define GLIU_DIAG 0x05
/*
* GLIU SPEC. MSR
*/
#define GLIU_P2D_BM0 0x20
#define GLIU_P2D_BM1 0x21
#define GLIU_P2D_BM2 0x22
#define GLIU_P2D_BMK0 0x23
#define GLIU_P2D_BMK1 0x24
#define GLIU_P2D_BM3 0x25
#define GLIU_P2D_BM4 0x26
#define GLIU_COH 0x80
#define GLIU_PAE 0x81
#define GLIU_ARB 0x82
#define GLIU_ASMI 0x83
#define GLIU_AERR 0x84
#define GLIU_DEBUG 0x85
#define GLIU_PHY_CAP 0x86
#define GLIU_NOUT_RESP 0x87
#define GLIU_NOUT_WDATA 0x88
#define GLIU_WHOAMI 0x8B
#define GLIU_SLV_DIS 0x8C
#define GLIU_IOD_BM0 0xE0
#define GLIU_IOD_BM1 0xE1
#define GLIU_IOD_BM2 0xE2
#define GLIU_IOD_BM3 0xE3
#define GLIU_IOD_BM4 0xE4
#define GLIU_IOD_BM5 0xE5
#define GLIU_IOD_BM6 0xE6
#define GLIU_IOD_BM7 0xE7
#define GLIU_IOD_BM8 0xE8
#define GLIU_IOD_BM9 0xE9
#define GLIU_IOD_SC0 0xEA
#define GLIU_IOD_SC1 0xEB
#define GLIU_IOD_SC2 0xEC
#define GLIU_IOD_SC3 0xED
#define GLIU_IOD_SC4 0xEE
#define GLIU_IOD_SC5 0xEF
#define GLIU_IOD_SC6 0xF0
#define GLIU_IOD_SC7 0xF1
/*
* SB STANDARD
*/
#define SB_CAP 0x00
#define SB_CONFIG 0x01
#define SB_SMI 0x02
#define SB_ERROR 0x03
#define SB_MAR_ERR_EN 0x00000001
#define SB_TAR_ERR_EN 0x00000002
#define SB_RSVD_BIT1 0x00000004
#define SB_EXCEP_ERR_EN 0x00000008
#define SB_SYSE_ERR_EN 0x00000010
#define SB_PARE_ERR_EN 0x00000020
#define SB_TAS_ERR_EN 0x00000040
#define SB_MAR_ERR_FLAG 0x00010000
#define SB_TAR_ERR_FLAG 0x00020000
#define SB_RSVD_BIT2 0x00040000
#define SB_EXCEP_ERR_FLAG 0x00080000
#define SB_SYSE_ERR_FLAG 0x00100000
#define SB_PARE_ERR_FLAG 0x00200000
#define SB_TAS_ERR_FLAG 0x00400000
#define SB_PM 0x04
#define SB_DIAG 0x05
/*
* SB SPEC.
*/
#define SB_CTRL 0x10
#define SB_R0 0x20
#define SB_R1 0x21
#define SB_R2 0x22
#define SB_R3 0x23
#define SB_R4 0x24
#define SB_R5 0x25
#define SB_R6 0x26
#define SB_R7 0x27
#define SB_R8 0x28
#define SB_R9 0x29
#define SB_R10 0x2A
#define SB_R11 0x2B
#define SB_R12 0x2C
#define SB_R13 0x2D
#define SB_R14 0x2E
#define SB_R15 0x2F
/*
* GLCP STANDARD
*/
#define GLCP_CAP 0x00
#define GLCP_CONFIG 0x01
#define GLCP_SMI 0x02
#define GLCP_ERROR 0x03
#define GLCP_PM 0x04
#define GLCP_DIAG 0x05
/*
* GLCP SPEC.
*/
#define GLCP_CLK_DIS_DELAY 0x08
#define GLCP_PM_CLK_DISABLE 0x09
#define GLCP_GLB_PM 0x0B
#define GLCP_DBG_OUT 0x0C
#define GLCP_RSVD1 0x0D
#define GLCP_SOFT_COM 0x0E
#define SOFT_BAR_SMB_FLAG 0x00000001
#define SOFT_BAR_GPIO_FLAG 0x00000002
#define SOFT_BAR_MFGPT_FLAG 0x00000004
#define SOFT_BAR_IRQ_FLAG 0x00000008
#define SOFT_BAR_PMS_FLAG 0x00000010
#define SOFT_BAR_ACPI_FLAG 0x00000020
#define SOFT_BAR_IDE_FLAG 0x00000400
#define SOFT_BAR_ACC_FLAG 0x00000800
#define SOFT_BAR_OHCI_FLAG 0x00001000
#define SOFT_BAR_EHCI_FLAG 0x00002000
#define GLCP_RSVD2 0x0F
#define GLCP_CLK_OFF 0x10
#define GLCP_CLK_ACTIVE 0x11
#define GLCP_CLK_DISABLE 0x12
#define GLCP_CLK4ACK 0x13
#define GLCP_SYS_RST 0x14
#define GLCP_RSVD3 0x15
#define GLCP_DBG_CLK_CTRL 0x16
#define GLCP_CHIP_REV_ID 0x17
/* PIC */
#define PIC_YSEL_LOW 0x20
#define PIC_YSEL_LOW_USB_SHIFT 8
#define PIC_YSEL_LOW_ACC_SHIFT 16
#define PIC_YSEL_LOW_FLASH_SHIFT 24
#define PIC_YSEL_HIGH 0x21
#define PIC_ZSEL_LOW 0x22
#define PIC_ZSEL_HIGH 0x23
#define PIC_IRQM_PRIM 0x24
#define PIC_IRQM_LPC 0x25
#define PIC_XIRR_STS_LOW 0x26
#define PIC_XIRR_STS_HIGH 0x27
#define PCI_SHDW 0x34
/*
* DIVIL STANDARD
*/
#define DIVIL_CAP 0x00
#define DIVIL_CONFIG 0x01
#define DIVIL_SMI 0x02
#define DIVIL_ERROR 0x03
#define DIVIL_PM 0x04
#define DIVIL_DIAG 0x05
/*
* DIVIL SPEC.
*/
#define DIVIL_LBAR_IRQ 0x08
#define DIVIL_LBAR_KEL 0x09
#define DIVIL_LBAR_SMB 0x0B
#define DIVIL_LBAR_GPIO 0x0C
#define DIVIL_LBAR_MFGPT 0x0D
#define DIVIL_LBAR_ACPI 0x0E
#define DIVIL_LBAR_PMS 0x0F
#define DIVIL_LEG_IO 0x14
#define DIVIL_BALL_OPTS 0x15
#define DIVIL_SOFT_IRQ 0x16
#define DIVIL_SOFT_RESET 0x17
/* MFGPT */
#define MFGPT_IRQ 0x28
/*
* IDE STANDARD
*/
#define IDE_CAP 0x00
#define IDE_CONFIG 0x01
#define IDE_SMI 0x02
#define IDE_ERROR 0x03
#define IDE_PM 0x04
#define IDE_DIAG 0x05
/*
* IDE SPEC.
*/
#define IDE_IO_BAR 0x08
#define IDE_CFG 0x10
#define IDE_DTC 0x12
#define IDE_CAST 0x13
#define IDE_ETC 0x14
#define IDE_INTERNAL_PM 0x15
/*
* ACC STANDARD
*/
#define ACC_CAP 0x00
#define ACC_CONFIG 0x01
#define ACC_SMI 0x02
#define ACC_ERROR 0x03
#define ACC_PM 0x04
#define ACC_DIAG 0x05
/*
* USB STANDARD
*/
#define USB_CAP 0x00
#define USB_CONFIG 0x01
#define USB_SMI 0x02
#define USB_ERROR 0x03
#define USB_PM 0x04
#define USB_DIAG 0x05
/*
* USB SPEC.
*/
#define USB_OHCI 0x08
#define USB_EHCI 0x09
/****************** NATIVE ***************************/
/* GPIO : I/O SPACE; REG : 32BITS */
#define GPIOL_OUT_VAL 0x00
#define GPIOL_OUT_EN 0x04
#endif /* _CS5536_H */

View File

@ -0,0 +1,36 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* cs5536 mfgpt header file
*/
#ifndef _CS5536_MFGPT_H
#define _CS5536_MFGPT_H
#include <cs5536/cs5536.h>
#include <cs5536/cs5536_pci.h>
#ifdef CONFIG_CS5536_MFGPT
extern void setup_mfgpt0_timer(void);
extern void disable_mfgpt0_counter(void);
extern void enable_mfgpt0_counter(void);
#else
static inline void __maybe_unused setup_mfgpt0_timer(void)
{
}
static inline void __maybe_unused disable_mfgpt0_counter(void)
{
}
static inline void __maybe_unused enable_mfgpt0_counter(void)
{
}
#endif
#define MFGPT_TICK_RATE 14318000
#define COMPARE ((MFGPT_TICK_RATE + HZ/2) / HZ)
#define MFGPT_BASE mfgpt_base
#define MFGPT0_CMP2 (MFGPT_BASE + 2)
#define MFGPT0_CNT (MFGPT_BASE + 4)
#define MFGPT0_SETUP (MFGPT_BASE + 6)
#endif /*!_CS5536_MFGPT_H */

View File

@ -0,0 +1,153 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* the definition file of cs5536 Virtual Support Module(VSM).
* pci configuration space can be accessed through the VSM, so
* there is no need of the MSR read/write now, except the spec.
* MSR registers which are not implemented yet.
*
* Copyright (C) 2007 Lemote Inc.
* Author : jlliu, liujl@lemote.com
*/
#ifndef _CS5536_PCI_H
#define _CS5536_PCI_H
#include <linux/types.h>
#include <linux/pci_regs.h>
extern void cs5536_pci_conf_write4(int function, int reg, u32 value);
extern u32 cs5536_pci_conf_read4(int function, int reg);
#define CS5536_ACC_INTR 9
#define CS5536_IDE_INTR 14
#define CS5536_USB_INTR 11
#define CS5536_MFGPT_INTR 5
#define CS5536_UART1_INTR 4
#define CS5536_UART2_INTR 3
/************** PCI BUS DEVICE FUNCTION ***************/
/*
* PCI bus device function
*/
#define PCI_BUS_CS5536 0
#define PCI_IDSEL_CS5536 14
/********** STANDARD PCI-2.2 EXPANSION ****************/
/*
* PCI configuration space
* we have to virtualize the PCI configure space head, so we should
* define the necessary IDs and some others.
*/
/* CONFIG of PCI VENDOR ID*/
#define CFG_PCI_VENDOR_ID(mod_dev_id, sys_vendor_id) \
(((mod_dev_id) << 16) | (sys_vendor_id))
/* VENDOR ID */
#define CS5536_VENDOR_ID 0x1022
/* DEVICE ID */
#define CS5536_ISA_DEVICE_ID 0x2090
#define CS5536_IDE_DEVICE_ID 0x209a
#define CS5536_ACC_DEVICE_ID 0x2093
#define CS5536_OHCI_DEVICE_ID 0x2094
#define CS5536_EHCI_DEVICE_ID 0x2095
/* CLASS CODE : CLASS SUB-CLASS INTERFACE */
#define CS5536_ISA_CLASS_CODE 0x060100
#define CS5536_IDE_CLASS_CODE 0x010180
#define CS5536_ACC_CLASS_CODE 0x040100
#define CS5536_OHCI_CLASS_CODE 0x0C0310
#define CS5536_EHCI_CLASS_CODE 0x0C0320
/* BHLC : BIST HEADER-TYPE LATENCY-TIMER CACHE-LINE-SIZE */
#define CFG_PCI_CACHE_LINE_SIZE(header_type, latency_timer) \
((PCI_NONE_BIST << 24) | ((header_type) << 16) \
| ((latency_timer) << 8) | PCI_NORMAL_CACHE_LINE_SIZE);
#define PCI_NONE_BIST 0x00 /* RO not implemented yet. */
#define PCI_BRIDGE_HEADER_TYPE 0x80 /* RO */
#define PCI_NORMAL_HEADER_TYPE 0x00
#define PCI_NORMAL_LATENCY_TIMER 0x00
#define PCI_NORMAL_CACHE_LINE_SIZE 0x08 /* RW */
/* BAR */
#define PCI_BAR0_REG 0x10
#define PCI_BAR1_REG 0x14
#define PCI_BAR2_REG 0x18
#define PCI_BAR3_REG 0x1c
#define PCI_BAR4_REG 0x20
#define PCI_BAR5_REG 0x24
#define PCI_BAR_RANGE_MASK 0xFFFFFFFF
/* CARDBUS CIS POINTER */
#define PCI_CARDBUS_CIS_POINTER 0x00000000
/* SUBSYSTEM VENDOR ID */
#define CS5536_SUB_VENDOR_ID CS5536_VENDOR_ID
/* SUBSYSTEM ID */
#define CS5536_ISA_SUB_ID CS5536_ISA_DEVICE_ID
#define CS5536_IDE_SUB_ID CS5536_IDE_DEVICE_ID
#define CS5536_ACC_SUB_ID CS5536_ACC_DEVICE_ID
#define CS5536_OHCI_SUB_ID CS5536_OHCI_DEVICE_ID
#define CS5536_EHCI_SUB_ID CS5536_EHCI_DEVICE_ID
/* EXPANSION ROM BAR */
#define PCI_EXPANSION_ROM_BAR 0x00000000
/* CAPABILITIES POINTER */
#define PCI_CAPLIST_POINTER 0x00000000
#define PCI_CAPLIST_USB_POINTER 0x40
/* INTERRUPT */
#define CFG_PCI_INTERRUPT_LINE(pin, mod_intr) \
((PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | \
((pin) << 8) | (mod_intr))
#define PCI_MAX_LATENCY 0x40
#define PCI_MIN_GRANT 0x00
#define PCI_DEFAULT_PIN 0x01
/*********** EXPANSION PCI REG ************************/
/*
* ISA EXPANSION
*/
#define PCI_UART1_INT_REG 0x50
#define PCI_UART2_INT_REG 0x54
#define PCI_ISA_FIXUP_REG 0x58
/*
* IDE EXPANSION
*/
#define PCI_IDE_CFG_REG 0x40
#define CS5536_IDE_FLASH_SIGNATURE 0xDEADBEEF
#define PCI_IDE_DTC_REG 0x48
#define PCI_IDE_CAST_REG 0x4C
#define PCI_IDE_ETC_REG 0x50
#define PCI_IDE_PM_REG 0x54
#define PCI_IDE_INT_REG 0x60
/*
* ACC EXPANSION
*/
#define PCI_ACC_INT_REG 0x50
/*
* OHCI EXPANSION : INTTERUPT IS IMPLEMENTED BY THE OHCI
*/
#define PCI_OHCI_PM_REG 0x40
#define PCI_OHCI_INT_REG 0x50
/*
* EHCI EXPANSION
*/
#define PCI_EHCI_LEGSMIEN_REG 0x50
#define PCI_EHCI_LEGSMISTS_REG 0x54
#define PCI_EHCI_FLADJ_REG 0x60
#endif /* _CS5536_PCI_H_ */

View File

@ -0,0 +1,32 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* the read/write interfaces for Virtual Support Module(VSM)
*
* Copyright (C) 2009 Lemote, Inc.
* Author: Wu Zhangjin <wuzhangjin@gmail.com>
*/
#ifndef _CS5536_VSM_H
#define _CS5536_VSM_H
#include <linux/types.h>
typedef void (*cs5536_pci_vsm_write)(int reg, u32 value);
typedef u32 (*cs5536_pci_vsm_read)(int reg);
#define DECLARE_CS5536_MODULE(name) \
extern void pci_##name##_write_reg(int reg, u32 value); \
extern u32 pci_##name##_read_reg(int reg);
/* ide module */
DECLARE_CS5536_MODULE(ide)
/* acc module */
DECLARE_CS5536_MODULE(acc)
/* ohci module */
DECLARE_CS5536_MODULE(ohci)
/* isa module */
DECLARE_CS5536_MODULE(isa)
/* ehci module */
DECLARE_CS5536_MODULE(ehci)
#endif /* _CS5536_VSM_H */

View File

@ -0,0 +1,44 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_MACH_LOONGSON64_IRQ_H_
#define __ASM_MACH_LOONGSON64_IRQ_H_
#include <boot_param.h>
#ifdef CONFIG_CPU_LOONGSON64
/* cpu core interrupt numbers */
#define MIPS_CPU_IRQ_BASE 56
#define LOONGSON_UART_IRQ (MIPS_CPU_IRQ_BASE + 2) /* UART */
#define LOONGSON_BRIDGE_IRQ (MIPS_CPU_IRQ_BASE + 3) /* CASCADE */
#define LOONGSON_TIMER_IRQ (MIPS_CPU_IRQ_BASE + 7) /* CPU Timer */
#define LOONGSON_HT1_CFG_BASE loongson_sysconf.ht_control_base
#define LOONGSON_HT1_INT_VECTOR_BASE (LOONGSON_HT1_CFG_BASE + 0x80)
#define LOONGSON_HT1_INT_EN_BASE (LOONGSON_HT1_CFG_BASE + 0xa0)
#define LOONGSON_HT1_INT_VECTOR(n) \
LOONGSON3_REG32(LOONGSON_HT1_INT_VECTOR_BASE, 4 * (n))
#define LOONGSON_HT1_INTN_EN(n) \
LOONGSON3_REG32(LOONGSON_HT1_INT_EN_BASE, 4 * (n))
#define LOONGSON_INT_ROUTER_OFFSET 0x1400
#define LOONGSON_INT_ROUTER_INTEN \
LOONGSON3_REG32(LOONGSON3_REG_BASE, LOONGSON_INT_ROUTER_OFFSET + 0x24)
#define LOONGSON_INT_ROUTER_INTENSET \
LOONGSON3_REG32(LOONGSON3_REG_BASE, LOONGSON_INT_ROUTER_OFFSET + 0x28)
#define LOONGSON_INT_ROUTER_INTENCLR \
LOONGSON3_REG32(LOONGSON3_REG_BASE, LOONGSON_INT_ROUTER_OFFSET + 0x2c)
#define LOONGSON_INT_ROUTER_ENTRY(n) \
LOONGSON3_REG8(LOONGSON3_REG_BASE, LOONGSON_INT_ROUTER_OFFSET + n)
#define LOONGSON_INT_ROUTER_LPC LOONGSON_INT_ROUTER_ENTRY(0x0a)
#define LOONGSON_INT_ROUTER_HT1(n) LOONGSON_INT_ROUTER_ENTRY(n + 0x18)
#define LOONGSON_INT_COREx_INTy(x, y) (1<<(x) | 1<<(y+4)) /* route to int y of core x */
#endif
extern void fixup_irqs(void);
extern void loongson3_ipi_interrupt(struct pt_regs *regs);
#include_next <irq.h>
#endif /* __ASM_MACH_LOONGSON64_IRQ_H_ */

View File

@ -0,0 +1,90 @@
/*
* 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
#ifdef CONFIG_CPU_LOONGSON64
.set push
.set mips64
/* Set LPA on LOONGSON3 config3 */
mfc0 t0, CP0_CONFIG3
or t0, (0x1 << 7)
mtc0 t0, CP0_CONFIG3
/* 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, (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
#endif
.endm
/*
* Do SMP slave processor setup.
*/
.macro smp_slave_setup
#ifdef CONFIG_CPU_LOONGSON64
.set push
.set mips64
/* Set LPA on LOONGSON3 config3 */
mfc0 t0, CP0_CONFIG3
or t0, (0x1 << 7)
mtc0 t0, CP0_CONFIG3
/* 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, (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
#endif
.endm
#endif /* __ASM_MACH_LOONGSON64_KERNEL_ENTRY_H */

View File

@ -0,0 +1,355 @@
/* 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>
/* loongson internal northbridge initialization */
extern void bonito_irq_init(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_init_memory(void);
extern void __init prom_init_cmdline(void);
extern void __init prom_init_machtype(void);
extern void __init prom_init_env(void);
#ifdef CONFIG_LOONGSON_UART_BASE
extern unsigned long _loongson_uart_base[], loongson_uart_base[];
extern void prom_init_loongson_uart_base(void);
#endif
static inline void prom_init_uart_base(void)
{
#ifdef CONFIG_LOONGSON_UART_BASE
prom_init_loongson_uart_base();
#endif
}
/* irq operation functions */
extern void bonito_irqdispatch(void);
extern void __init bonito_irq_init(void);
extern void __init mach_init_irq(void);
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_IRQ_BASE 32
#define LOONGSON2_PERFCNT_IRQ (MIPS_CPU_IRQ_BASE + 6) /* cpu perf counter */
#include <linux/interrupt.h>
static inline void do_perfcnt_IRQ(void)
{
#if IS_ENABLED(CONFIG_OPROFILE)
do_IRQ(LOONGSON2_PERFCNT_IRQ);
#endif
}
#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)
#ifdef CONFIG_CPU_LOONGSON64
#define LOONGSON_PCIIO_BASE loongson_sysconf.pci_io_base
#else
#define LOONGSON_PCIIO_BASE 0x1fd00000
#endif
#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))
#ifdef CONFIG_CPU_SUPPORTS_CPUFREQ
#include <linux/cpufreq.h>
extern struct cpufreq_frequency_table loongson2_clockmod_table[];
#endif
/*
* address windows configuration module
*
* loongson2e do not have this module
*/
#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
/* address window config module base address */
#define LOONGSON_ADDRWINCFG_BASE 0x3ff00000ul
#define LOONGSON_ADDRWINCFG_SIZE 0x180
extern unsigned long _loongson_addrwincfg_base;
#define LOONGSON_ADDRWINCFG(offset) \
(*(volatile u64 *)(_loongson_addrwincfg_base + (offset)))
#define CPU_WIN0_BASE LOONGSON_ADDRWINCFG(0x00)
#define CPU_WIN1_BASE LOONGSON_ADDRWINCFG(0x08)
#define CPU_WIN2_BASE LOONGSON_ADDRWINCFG(0x10)
#define CPU_WIN3_BASE LOONGSON_ADDRWINCFG(0x18)
#define CPU_WIN0_MASK LOONGSON_ADDRWINCFG(0x20)
#define CPU_WIN1_MASK LOONGSON_ADDRWINCFG(0x28)
#define CPU_WIN2_MASK LOONGSON_ADDRWINCFG(0x30)
#define CPU_WIN3_MASK LOONGSON_ADDRWINCFG(0x38)
#define CPU_WIN0_MMAP LOONGSON_ADDRWINCFG(0x40)
#define CPU_WIN1_MMAP LOONGSON_ADDRWINCFG(0x48)
#define CPU_WIN2_MMAP LOONGSON_ADDRWINCFG(0x50)
#define CPU_WIN3_MMAP LOONGSON_ADDRWINCFG(0x58)
#define PCIDMA_WIN0_BASE LOONGSON_ADDRWINCFG(0x60)
#define PCIDMA_WIN1_BASE LOONGSON_ADDRWINCFG(0x68)
#define PCIDMA_WIN2_BASE LOONGSON_ADDRWINCFG(0x70)
#define PCIDMA_WIN3_BASE LOONGSON_ADDRWINCFG(0x78)
#define PCIDMA_WIN0_MASK LOONGSON_ADDRWINCFG(0x80)
#define PCIDMA_WIN1_MASK LOONGSON_ADDRWINCFG(0x88)
#define PCIDMA_WIN2_MASK LOONGSON_ADDRWINCFG(0x90)
#define PCIDMA_WIN3_MASK LOONGSON_ADDRWINCFG(0x98)
#define PCIDMA_WIN0_MMAP LOONGSON_ADDRWINCFG(0xa0)
#define PCIDMA_WIN1_MMAP LOONGSON_ADDRWINCFG(0xa8)
#define PCIDMA_WIN2_MMAP LOONGSON_ADDRWINCFG(0xb0)
#define PCIDMA_WIN3_MMAP LOONGSON_ADDRWINCFG(0xb8)
#define ADDRWIN_WIN0 0
#define ADDRWIN_WIN1 1
#define ADDRWIN_WIN2 2
#define ADDRWIN_WIN3 3
#define ADDRWIN_MAP_DST_DDR 0
#define ADDRWIN_MAP_DST_PCI 1
#define ADDRWIN_MAP_DST_LIO 1
/*
* s: CPU, PCIDMA
* d: DDR, PCI, LIO
* win: 0, 1, 2, 3
* src: map source
* dst: map destination
* size: ~mask + 1
*/
#define LOONGSON_ADDRWIN_CFG(s, d, w, src, dst, size) do {\
s##_WIN##w##_BASE = (src); \
s##_WIN##w##_MMAP = (dst) | ADDRWIN_MAP_DST_##d; \
s##_WIN##w##_MASK = ~(size-1); \
} while (0)
#define LOONGSON_ADDRWIN_CPUTOPCI(win, src, dst, size) \
LOONGSON_ADDRWIN_CFG(CPU, PCI, win, src, dst, size)
#define LOONGSON_ADDRWIN_CPUTODDR(win, src, dst, size) \
LOONGSON_ADDRWIN_CFG(CPU, DDR, win, src, dst, size)
#define LOONGSON_ADDRWIN_PCITODDR(win, src, dst, size) \
LOONGSON_ADDRWIN_CFG(PCIDMA, DDR, win, src, dst, size)
#endif /* ! CONFIG_CPU_SUPPORTS_ADDRWINCFG */
#endif /* __ASM_MACH_LOONGSON64_LOONGSON_H */

View File

@ -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 temprature 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_*/

View File

@ -0,0 +1,227 @@
/*
* 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__(
"parse_r __res,%0\n\t"
"parse_r reg,%1\n\t"
".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_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_LPMPREV GENMASK(11, 9)
#define LOONGSON_CFG2_LAMO BIT(12)
#define LOONGSON_CFG2_LPIXU BIT(13)
#define LOONGSON_CFG2_LPIXUN BIT(14)
#define LOONGSON_CFG2_LZVP BIT(15)
#define LOONGSON_CFG2_LZVREV 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_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_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__(
"parse_r __res,%0\n\t"
"parse_r reg,%1\n\t"
".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;
/* DWRCSR reg, val */
__asm__ __volatile__(
"parse_r __res,%0\n\t"
"parse_r reg,%1\n\t"
".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__(
"parse_r reg,%0\n\t"
"parse_r val,%1\n\t"
".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__(
"parse_r reg,%0\n\t"
"parse_r val,%1\n\t"
".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 accessable 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)
static inline u64 drdtime(void)
{
int rID = 0;
u64 val = 0;
__asm__ __volatile__(
"parse_r rID,%0\n\t"
"parse_r val,%1\n\t"
".insn \n\t"
".word (0xc8090118 | (rID << 21) | (val << 11))\n\t"
:"=r"(rID),"=r"(val)
:
);
return val;
}
#endif

View File

@ -0,0 +1,29 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2009 Lemote, Inc.
* Author: Wu Zhangjin <wuzhangjin@gmail.com>
*/
#ifndef __ASM_MACH_LOONGSON64_MACHINE_H
#define __ASM_MACH_LOONGSON64_MACHINE_H
#ifdef CONFIG_LEMOTE_FULOONG2E
#define LOONGSON_MACHTYPE MACH_LEMOTE_FL2E
#endif
/* use fuloong2f as the default machine of LEMOTE_MACH2F */
#ifdef CONFIG_LEMOTE_MACH2F
#define LOONGSON_MACHTYPE MACH_LEMOTE_FL2F
#endif
#ifdef CONFIG_LOONGSON_MACH3X
#define LOONGSON_MACHTYPE MACH_LOONGSON_GENERIC
#endif /* CONFIG_LOONGSON_MACH3X */
#endif /* __ASM_MACH_LOONGSON64_MACHINE_H */

View File

@ -0,0 +1,36 @@
/*
* 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) 1998, 2001, 03, 07 by Ralf Baechle (ralf@linux-mips.org)
*
* RTC routines for PC style attached Dallas chip.
*/
#ifndef __ASM_MACH_LOONGSON64_MC146818RTC_H
#define __ASM_MACH_LOONGSON64_MC146818RTC_H
#include <linux/io.h>
#define RTC_PORT(x) (0x70 + (x))
#define RTC_IRQ 8
static inline unsigned char CMOS_READ(unsigned long addr)
{
outb_p(addr, RTC_PORT(0));
return inb_p(RTC_PORT(1));
}
static inline void CMOS_WRITE(unsigned char data, unsigned long addr)
{
outb_p(addr, RTC_PORT(0));
outb_p(data, RTC_PORT(1));
}
#define RTC_ALWAYS_BCD 0
#ifndef mc146818_decode_year
#define mc146818_decode_year(year) ((year) < 70 ? (year) + 2000 : (year) + 1970)
#endif
#endif /* __ASM_MACH_LOONGSON64_MC146818RTC_H */

View File

@ -0,0 +1,37 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2009 Lemote, Inc.
* Author: Wu Zhangjin <wuzhangjin@gmail.com>
*/
#ifndef __ASM_MACH_LOONGSON64_MEM_H
#define __ASM_MACH_LOONGSON64_MEM_H
/*
* high memory space
*
* in loongson2e, starts from 512M
* in loongson2f, starts from 2G 256M
*/
#ifdef CONFIG_CPU_LOONGSON2E
#define LOONGSON_HIGHMEM_START 0x20000000
#else
#define LOONGSON_HIGHMEM_START 0x90000000
#endif
/*
* the peripheral registers(MMIO):
*
* On the Lemote Loongson 2e system, reside between 0x1000:0000 and 0x2000:0000.
* On the Lemote Loongson 2f system, reside between 0x1000:0000 and 0x8000:0000.
*/
#define LOONGSON_MMIO_MEM_START 0x10000000
#ifdef CONFIG_CPU_LOONGSON2E
#define LOONGSON_MMIO_MEM_END 0x20000000
#else
#define LOONGSON_MMIO_MEM_END 0x80000000
#endif
#endif /* __ASM_MACH_LOONGSON64_MEM_H */

View File

@ -0,0 +1,50 @@
/* 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_MMZONE_H
#define _ASM_MACH_MMZONE_H
#include <boot_param.h>
#define NODE_ADDRSPACE_SHIFT 44
#define NODE0_ADDRSPACE_OFFSET 0x000000000000UL
#define NODE1_ADDRSPACE_OFFSET 0x100000000000UL
#define NODE2_ADDRSPACE_OFFSET 0x200000000000UL
#define NODE3_ADDRSPACE_OFFSET 0x300000000000UL
#define pa_to_nid(addr) (((addr) & 0xf00000000000) >> NODE_ADDRSPACE_SHIFT)
#define nid_to_addrbase(nid) ((nid) << NODE_ADDRSPACE_SHIFT)
#define LEVELS_PER_SLICE 128
struct slice_data {
unsigned long irq_enable_mask[2];
int level_to_irq[LEVELS_PER_SLICE];
};
struct hub_data {
cpumask_t h_cpus;
unsigned long slice_map;
unsigned long irq_alloc_mask[2];
struct slice_data slice[2];
};
struct node_data {
struct pglist_data pglist;
struct hub_data hub;
cpumask_t cpumask;
};
extern struct node_data *__node_data[];
#define NODE_DATA(n) (&__node_data[(n)]->pglist)
#define hub_data(n) (&__node_data[(n)]->hub)
extern void setup_zero_pages(void);
extern void __init prom_init_numa_memory(void);
#endif /* _ASM_MACH_MMZONE_H */

View File

@ -0,0 +1,50 @@
/* 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
#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
/*
* we use address window2 to map cpu address space to pci space
* window2: cpu [1G, 2G] -> pci [1G, 2G]
* why not use window 0 & 1? because they are used by cpu when booting.
* window0: cpu [0, 256M] -> ddr [0, 256M]
* window1: cpu [256M, 512M] -> pci [256M, 512M]
*/
/* the smallest LOONGSON_CPU_MEM_SRC can be 512M */
#define LOONGSON_CPU_MEM_SRC 0x40000000ul /* 1G */
#define LOONGSON_PCI_MEM_DST LOONGSON_CPU_MEM_SRC
#define LOONGSON_PCI_MEM_START LOONGSON_PCI_MEM_DST
#define LOONGSON_PCI_MEM_END (0x80000000ul-1) /* 2G */
#define MMAP_CPUTOPCI_SIZE (LOONGSON_PCI_MEM_END - \
LOONGSON_PCI_MEM_START + 1)
#else /* loongson2f/32bit & loongson2e */
/* this pci memory space is mapped by pcimap in pci.c */
#ifdef CONFIG_CPU_LOONGSON64
#define LOONGSON_PCI_MEM_START 0x40000000UL
#define LOONGSON_PCI_MEM_END 0x7effffffUL
#else
#define LOONGSON_PCI_MEM_START LOONGSON_PCILO1_BASE
#define LOONGSON_PCI_MEM_END (LOONGSON_PCILO1_BASE + 0x04000000 * 2)
#endif
/* this is an offset from mips_io_port_base */
#define LOONGSON_PCI_IO_START 0x00004000UL
#endif /* !CONFIG_CPU_SUPPORTS_ADDRWINCFG */
#endif /* !__ASM_MACH_LOONGSON64_PCI_H_ */

View File

@ -0,0 +1,10 @@
/* 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 */
#include <asm/mach-generic/spaces.h>
#endif

View File

@ -0,0 +1,23 @@
/* 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)
#define cpumask_of_node(node) (&__node_data[(node)]->cpumask)
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 */

View File

@ -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

View File

@ -0,0 +1,96 @@
# SPDX-License-Identifier: GPL-2.0
if MACH_LOONGSON2EF
choice
prompt "Machine Type"
config LEMOTE_FULOONG2E
bool "Lemote Fuloong(2e) mini-PC"
select ARCH_SPARSEMEM_ENABLE
select ARCH_MIGHT_HAVE_PC_PARPORT
select ARCH_MIGHT_HAVE_PC_SERIO
select CEVT_R4K
select CSRC_R4K
select SYS_HAS_CPU_LOONGSON2E
select DMA_NONCOHERENT
select BOOT_ELF32
select BOARD_SCACHE
select FORCE_PCI
select I8259
select ISA
select IRQ_MIPS_CPU
select SYS_SUPPORTS_64BIT_KERNEL
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_SUPPORTS_HIGHMEM
select SYS_HAS_EARLY_PRINTK
select GENERIC_ISA_DMA_SUPPORT_BROKEN
select CPU_HAS_WB
select LOONGSON_MC146818
help
Lemote Fuloong(2e) mini-PC board based on the Chinese Loongson-2E CPU and
an FPGA northbridge
Lemote Fuloong(2e) mini PC have a VIA686B south bridge.
config LEMOTE_MACH2F
bool "Lemote Loongson 2F family machines"
select ARCH_SPARSEMEM_ENABLE
select ARCH_MIGHT_HAVE_PC_PARPORT
select ARCH_MIGHT_HAVE_PC_SERIO
select BOARD_SCACHE
select BOOT_ELF32
select CEVT_R4K if ! MIPS_EXTERNAL_TIMER
select CPU_HAS_WB
select CS5536
select CSRC_R4K if ! MIPS_EXTERNAL_TIMER
select DMA_NONCOHERENT
select GENERIC_ISA_DMA_SUPPORT_BROKEN
select HAVE_CLK
select FORCE_PCI
select I8259
select IRQ_MIPS_CPU
select ISA
select SYS_HAS_CPU_LOONGSON2F
select SYS_HAS_EARLY_PRINTK
select SYS_SUPPORTS_64BIT_KERNEL
select SYS_SUPPORTS_HIGHMEM
select SYS_SUPPORTS_LITTLE_ENDIAN
select LOONGSON_MC146818
help
Lemote Loongson 2F family machines utilize the 2F revision of
Loongson processor and the AMD CS5536 south bridge.
These family machines include fuloong2f mini PC, yeeloong2f notebook,
LingLoong allinone PC and so forth.
endchoice
config CS5536
bool
config CS5536_MFGPT
bool "CS5536 MFGPT Timer"
depends on CS5536 && !HIGH_RES_TIMERS
select MIPS_EXTERNAL_TIMER
help
This option enables the mfgpt0 timer of AMD CS5536. With this timer
switched on you can not use high resolution timers.
If you want to enable the Loongson2 CPUFreq Driver, Please enable
this option at first, otherwise, You will get wrong system time.
If unsure, say Yes.
config LOONGSON_UART_BASE
bool
default y
depends on EARLY_PRINTK || SERIAL_8250
config LOONGSON_MC146818
bool
default n
config LEFI_FIRMWARE_INTERFACE
bool
endif # MACH_LOONGSON2EF

View File

@ -0,0 +1,18 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# Common code for all Loongson based systems
#
obj-$(CONFIG_MACH_LOONGSON2EF) += common/
#
# Lemote Fuloong mini-PC (Loongson 2E-based)
#
obj-$(CONFIG_LEMOTE_FULOONG2E) += fuloong-2e/
#
# Lemote loongson2f family machines
#
obj-$(CONFIG_LEMOTE_MACH2F) += lemote-2f/

View File

@ -0,0 +1,32 @@
#
# Loongson Processors' Support
#
# Only gcc >= 4.4 have Loongson specific support
cflags-$(CONFIG_CPU_LOONGSON2EF) += -Wa,--trap
cflags-$(CONFIG_CPU_LOONGSON2E) += \
$(call cc-option,-march=loongson2e,-march=r4600)
cflags-$(CONFIG_CPU_LOONGSON2F) += \
$(call cc-option,-march=loongson2f,-march=r4600)
# Enable the workarounds for Loongson2f
ifdef CONFIG_CPU_LOONGSON2F_WORKAROUNDS
ifeq ($(call as-option,-Wa$(comma)-mfix-loongson2f-nop,),)
$(error only binutils >= 2.20.2 have needed option -mfix-loongson2f-nop)
else
cflags-$(CONFIG_CPU_NOP_WORKAROUNDS) += -Wa$(comma)-mfix-loongson2f-nop
endif
ifeq ($(call as-option,-Wa$(comma)-mfix-loongson2f-jump,),)
$(error only binutils >= 2.20.2 have needed option -mfix-loongson2f-jump)
else
cflags-$(CONFIG_CPU_JUMP_WORKAROUNDS) += -Wa$(comma)-mfix-loongson2f-jump
endif
endif
#
# Loongson Machines' Support
#
platform-$(CONFIG_MACH_LOONGSON2EF) += loongson2ef/
cflags-$(CONFIG_MACH_LOONGSON2EF) += -I$(srctree)/arch/mips/include/asm/mach-loongson2ef -mno-branch-likely
load-$(CONFIG_LEMOTE_FULOONG2E) += 0xffffffff80100000
load-$(CONFIG_LEMOTE_MACH2F) += 0xffffffff80200000

View File

@ -0,0 +1,27 @@
# SPDX-License-Identifier: GPL-2.0
#
# Makefile for loongson based machines.
#
obj-y += setup.o init.o cmdline.o env.o time.o reset.o irq.o \
bonito-irq.o mem.o machtype.o platform.o serial.o
obj-$(CONFIG_PCI) += pci.o
#
# Serial port support
#
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_LOONGSON_UART_BASE) += uart_base.o
obj-$(CONFIG_LOONGSON_MC146818) += rtc.o
#
# Enable CS5536 Virtual Support Module(VSM) to virtulize the PCI configure
# space
#
obj-$(CONFIG_CS5536) += cs5536/
#
# Suspend Support
#
obj-$(CONFIG_SUSPEND) += pm.o

View File

@ -0,0 +1,49 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright 2001 MontaVista Software Inc.
* Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
* Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org)
*
* Copyright (C) 2007 Lemote Inc. & Institute of Computing Technology
* Author: Fuxin Zhang, zhangfx@lemote.com
*/
#include <linux/interrupt.h>
#include <linux/compiler.h>
#include <loongson.h>
static inline void bonito_irq_enable(struct irq_data *d)
{
LOONGSON_INTENSET = (1 << (d->irq - LOONGSON_IRQ_BASE));
mmiowb();
}
static inline void bonito_irq_disable(struct irq_data *d)
{
LOONGSON_INTENCLR = (1 << (d->irq - LOONGSON_IRQ_BASE));
mmiowb();
}
static struct irq_chip bonito_irq_type = {
.name = "bonito_irq",
.irq_mask = bonito_irq_disable,
.irq_unmask = bonito_irq_enable,
};
static struct irqaction __maybe_unused dma_timeout_irqaction = {
.handler = no_action,
.name = "dma_timeout",
};
void bonito_irq_init(void)
{
u32 i;
for (i = LOONGSON_IRQ_BASE; i < LOONGSON_IRQ_BASE + 32; i++)
irq_set_chip_and_handler(i, &bonito_irq_type,
handle_level_irq);
#ifdef CONFIG_CPU_LOONGSON2E
setup_irq(LOONGSON_IRQ_BASE + 10, &dma_timeout_irqaction);
#endif
}

View File

@ -0,0 +1,44 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Based on Ocelot Linux port, which is
* Copyright 2001 MontaVista Software Inc.
* Author: jsun@mvista.com or jsun@junsun.net
*
* Copyright 2003 ICT CAS
* Author: Michael Guo <guoyi@ict.ac.cn>
*
* Copyright (C) 2007 Lemote Inc. & Institute of Computing Technology
* Author: Fuxin Zhang, zhangfx@lemote.com
*
* Copyright (C) 2009 Lemote Inc.
* Author: Wu Zhangjin, wuzhangjin@gmail.com
*/
#include <asm/bootinfo.h>
#include <loongson.h>
void __init prom_init_cmdline(void)
{
int prom_argc;
/* pmon passes arguments in 32bit pointers */
int *_prom_argv;
int i;
long l;
/* firmware arguments are initialized in head.S */
prom_argc = fw_arg0;
_prom_argv = (int *)fw_arg1;
/* arg[0] is "g", the rest is boot parameters */
arcs_cmdline[0] = '\0';
for (i = 1; i < prom_argc; i++) {
l = (long)_prom_argv[i];
if (strlen(arcs_cmdline) + strlen(((char *)l) + 1)
>= sizeof(arcs_cmdline))
break;
strcat(arcs_cmdline, ((char *)l));
strcat(arcs_cmdline, " ");
}
prom_init_machtype();
}

View File

@ -0,0 +1,38 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/* early printk support
*
* Copyright (c) 2009 Philippe Vachon <philippe@cowpig.ca>
* Copyright (c) 2009 Lemote Inc.
* Author: Wu Zhangjin, wuzhangjin@gmail.com
*/
#include <linux/serial_reg.h>
#include <asm/setup.h>
#include <loongson.h>
#define PORT(base, offset) (u8 *)(base + offset)
static inline unsigned int serial_in(unsigned char *base, int offset)
{
return readb(PORT(base, offset));
}
static inline void serial_out(unsigned char *base, int offset, int value)
{
writeb(value, PORT(base, offset));
}
void prom_putchar(char c)
{
int timeout;
unsigned char *uart_base;
uart_base = (unsigned char *)_loongson_uart_base[0];
timeout = 1024;
while (((serial_in(uart_base, UART_LSR) & UART_LSR_THRE) == 0) &&
(timeout-- > 0))
;
serial_out(uart_base, UART_TX, c);
}

View File

@ -0,0 +1,212 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Based on Ocelot Linux port, which is
* Copyright 2001 MontaVista Software Inc.
* Author: jsun@mvista.com or jsun@junsun.net
*
* Copyright 2003 ICT CAS
* Author: Michael Guo <guoyi@ict.ac.cn>
*
* Copyright (C) 2007 Lemote Inc. & Institute of Computing Technology
* Author: Fuxin Zhang, zhangfx@lemote.com
*
* Copyright (C) 2009 Lemote Inc.
* Author: Wu Zhangjin, wuzhangjin@gmail.com
*/
#include <linux/export.h>
#include <asm/bootinfo.h>
#include <loongson.h>
#include <boot_param.h>
#include <workarounds.h>
u32 cpu_clock_freq;
EXPORT_SYMBOL(cpu_clock_freq);
struct efi_memory_map_loongson *loongson_memmap;
struct loongson_system_configuration loongson_sysconf;
u64 loongson_chipcfg[MAX_PACKAGES] = {0xffffffffbfc00180};
u64 loongson_chiptemp[MAX_PACKAGES];
u64 loongson_freqctrl[MAX_PACKAGES];
unsigned long long smp_group[4];
#define parse_even_earlier(res, option, p) \
do { \
unsigned int tmp __maybe_unused; \
\
if (strncmp(option, (char *)p, strlen(option)) == 0) \
tmp = kstrtou32((char *)p + strlen(option"="), 10, &res); \
} while (0)
void __init prom_init_env(void)
{
/* pmon passes arguments in 32bit pointers */
unsigned int processor_id;
#ifndef CONFIG_LEFI_FIRMWARE_INTERFACE
int *_prom_envp;
long l;
/* firmware arguments are initialized in head.S */
_prom_envp = (int *)fw_arg2;
l = (long)*_prom_envp;
while (l != 0) {
parse_even_earlier(cpu_clock_freq, "cpuclock", l);
parse_even_earlier(memsize, "memsize", l);
parse_even_earlier(highmemsize, "highmemsize", l);
_prom_envp++;
l = (long)*_prom_envp;
}
if (memsize == 0)
memsize = 256;
loongson_sysconf.nr_uarts = 1;
pr_info("memsize=%u, highmemsize=%u\n", memsize, highmemsize);
#else
struct boot_params *boot_p;
struct loongson_params *loongson_p;
struct system_loongson *esys;
struct efi_cpuinfo_loongson *ecpu;
struct irq_source_routing_table *eirq_source;
/* firmware arguments are initialized in head.S */
boot_p = (struct boot_params *)fw_arg2;
loongson_p = &(boot_p->efi.smbios.lp);
esys = (struct system_loongson *)
((u64)loongson_p + loongson_p->system_offset);
ecpu = (struct efi_cpuinfo_loongson *)
((u64)loongson_p + loongson_p->cpu_offset);
eirq_source = (struct irq_source_routing_table *)
((u64)loongson_p + loongson_p->irq_offset);
loongson_memmap = (struct efi_memory_map_loongson *)
((u64)loongson_p + loongson_p->memory_offset);
cpu_clock_freq = ecpu->cpu_clock_freq;
loongson_sysconf.cputype = ecpu->cputype;
switch (ecpu->cputype) {
case Legacy_3A:
case Loongson_3A:
loongson_sysconf.cores_per_node = 4;
loongson_sysconf.cores_per_package = 4;
smp_group[0] = 0x900000003ff01000;
smp_group[1] = 0x900010003ff01000;
smp_group[2] = 0x900020003ff01000;
smp_group[3] = 0x900030003ff01000;
loongson_chipcfg[0] = 0x900000001fe00180;
loongson_chipcfg[1] = 0x900010001fe00180;
loongson_chipcfg[2] = 0x900020001fe00180;
loongson_chipcfg[3] = 0x900030001fe00180;
loongson_chiptemp[0] = 0x900000001fe0019c;
loongson_chiptemp[1] = 0x900010001fe0019c;
loongson_chiptemp[2] = 0x900020001fe0019c;
loongson_chiptemp[3] = 0x900030001fe0019c;
loongson_freqctrl[0] = 0x900000001fe001d0;
loongson_freqctrl[1] = 0x900010001fe001d0;
loongson_freqctrl[2] = 0x900020001fe001d0;
loongson_freqctrl[3] = 0x900030001fe001d0;
loongson_sysconf.ht_control_base = 0x90000EFDFB000000;
loongson_sysconf.workarounds = WORKAROUND_CPUFREQ;
break;
case Legacy_3B:
case Loongson_3B:
loongson_sysconf.cores_per_node = 4; /* One chip has 2 nodes */
loongson_sysconf.cores_per_package = 8;
smp_group[0] = 0x900000003ff01000;
smp_group[1] = 0x900010003ff05000;
smp_group[2] = 0x900020003ff09000;
smp_group[3] = 0x900030003ff0d000;
loongson_chipcfg[0] = 0x900000001fe00180;
loongson_chipcfg[1] = 0x900020001fe00180;
loongson_chipcfg[2] = 0x900040001fe00180;
loongson_chipcfg[3] = 0x900060001fe00180;
loongson_chiptemp[0] = 0x900000001fe0019c;
loongson_chiptemp[1] = 0x900020001fe0019c;
loongson_chiptemp[2] = 0x900040001fe0019c;
loongson_chiptemp[3] = 0x900060001fe0019c;
loongson_freqctrl[0] = 0x900000001fe001d0;
loongson_freqctrl[1] = 0x900020001fe001d0;
loongson_freqctrl[2] = 0x900040001fe001d0;
loongson_freqctrl[3] = 0x900060001fe001d0;
loongson_sysconf.ht_control_base = 0x90001EFDFB000000;
loongson_sysconf.workarounds = WORKAROUND_CPUHOTPLUG;
break;
default:
loongson_sysconf.cores_per_node = 1;
loongson_sysconf.cores_per_package = 1;
loongson_chipcfg[0] = 0x900000001fe00180;
}
loongson_sysconf.nr_cpus = ecpu->nr_cpus;
loongson_sysconf.boot_cpu_id = ecpu->cpu_startup_core_id;
loongson_sysconf.reserved_cpus_mask = ecpu->reserved_cores_mask;
if (ecpu->nr_cpus > NR_CPUS || ecpu->nr_cpus == 0)
loongson_sysconf.nr_cpus = NR_CPUS;
loongson_sysconf.nr_nodes = (loongson_sysconf.nr_cpus +
loongson_sysconf.cores_per_node - 1) /
loongson_sysconf.cores_per_node;
loongson_sysconf.pci_mem_start_addr = eirq_source->pci_mem_start_addr;
loongson_sysconf.pci_mem_end_addr = eirq_source->pci_mem_end_addr;
loongson_sysconf.pci_io_base = eirq_source->pci_io_start_addr;
loongson_sysconf.dma_mask_bits = eirq_source->dma_mask_bits;
if (loongson_sysconf.dma_mask_bits < 32 ||
loongson_sysconf.dma_mask_bits > 64)
loongson_sysconf.dma_mask_bits = 32;
loongson_sysconf.restart_addr = boot_p->reset_system.ResetWarm;
loongson_sysconf.poweroff_addr = boot_p->reset_system.Shutdown;
loongson_sysconf.suspend_addr = boot_p->reset_system.DoSuspend;
loongson_sysconf.vgabios_addr = boot_p->efi.smbios.vga_bios;
pr_debug("Shutdown Addr: %llx, Restart Addr: %llx, VBIOS Addr: %llx\n",
loongson_sysconf.poweroff_addr, loongson_sysconf.restart_addr,
loongson_sysconf.vgabios_addr);
memset(loongson_sysconf.ecname, 0, 32);
if (esys->has_ec)
memcpy(loongson_sysconf.ecname, esys->ec_name, 32);
loongson_sysconf.workarounds |= esys->workarounds;
loongson_sysconf.nr_uarts = esys->nr_uarts;
if (esys->nr_uarts < 1 || esys->nr_uarts > MAX_UARTS)
loongson_sysconf.nr_uarts = 1;
memcpy(loongson_sysconf.uarts, esys->uarts,
sizeof(struct uart_device) * loongson_sysconf.nr_uarts);
loongson_sysconf.nr_sensors = esys->nr_sensors;
if (loongson_sysconf.nr_sensors > MAX_SENSORS)
loongson_sysconf.nr_sensors = 0;
if (loongson_sysconf.nr_sensors)
memcpy(loongson_sysconf.sensors, esys->sensors,
sizeof(struct sensor_device) * loongson_sysconf.nr_sensors);
#endif
if (cpu_clock_freq == 0) {
processor_id = (&current_cpu_data)->processor_id;
switch (processor_id & PRID_REV_MASK) {
case PRID_REV_LOONGSON2E:
cpu_clock_freq = 533080000;
break;
case PRID_REV_LOONGSON2F:
cpu_clock_freq = 797000000;
break;
case PRID_REV_LOONGSON3A_R1:
case PRID_REV_LOONGSON3A_R2_0:
case PRID_REV_LOONGSON3A_R2_1:
case PRID_REV_LOONGSON3A_R3_0:
case PRID_REV_LOONGSON3A_R3_1:
cpu_clock_freq = 900000000;
break;
case PRID_REV_LOONGSON3B_R1:
case PRID_REV_LOONGSON3B_R2:
cpu_clock_freq = 1000000000;
break;
default:
cpu_clock_freq = 100000000;
break;
}
}
pr_info("CpuClock = %u\n", cpu_clock_freq);
}

View File

@ -0,0 +1,56 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2009 Lemote Inc.
* Author: Wu Zhangjin, wuzhangjin@gmail.com
*/
#include <linux/memblock.h>
#include <asm/bootinfo.h>
#include <asm/traps.h>
#include <asm/smp-ops.h>
#include <asm/cacheflush.h>
#include <loongson.h>
/* Loongson CPU address windows config space base address */
unsigned long __maybe_unused _loongson_addrwincfg_base;
static void __init mips_nmi_setup(void)
{
void *base;
extern char except_vec_nmi;
base = (void *)(CAC_BASE + 0x380);
memcpy(base, &except_vec_nmi, 0x80);
flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
}
void __init prom_init(void)
{
#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
_loongson_addrwincfg_base = (unsigned long)
ioremap(LOONGSON_ADDRWINCFG_BASE, LOONGSON_ADDRWINCFG_SIZE);
#endif
prom_init_cmdline();
prom_init_env();
/* init base address of io space */
set_io_port_base((unsigned long)
ioremap(LOONGSON_PCIIO_BASE, LOONGSON_PCIIO_SIZE));
#ifdef CONFIG_NUMA
prom_init_numa_memory();
#else
prom_init_memory();
#endif
/*init the uart base address */
prom_init_uart_base();
register_smp_ops(&loongson3_smp_ops);
board_nmi_handler_setup = mips_nmi_setup;
}
void __init prom_free_prom_memory(void)
{
}

View File

@ -0,0 +1,63 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2007 Lemote Inc. & Institute of Computing Technology
* Author: Fuxin Zhang, zhangfx@lemote.com
*/
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <loongson.h>
/*
* the first level int-handler will jump here if it is a bonito irq
*/
void bonito_irqdispatch(void)
{
u32 int_status;
int i;
/* workaround the IO dma problem: let cpu looping to allow DMA finish */
int_status = LOONGSON_INTISR;
while (int_status & (1 << 10)) {
udelay(1);
int_status = LOONGSON_INTISR;
}
/* Get pending sources, masked by current enables */
int_status = LOONGSON_INTISR & LOONGSON_INTEN;
if (int_status) {
i = __ffs(int_status);
do_IRQ(LOONGSON_IRQ_BASE + i);
}
}
asmlinkage void plat_irq_dispatch(void)
{
unsigned int pending;
pending = read_c0_cause() & read_c0_status() & ST0_IM;
/* machine-specific plat_irq_dispatch */
mach_irq_dispatch(pending);
}
void __init arch_init_irq(void)
{
/*
* Clear all of the interrupts while we change the able around a bit.
* int-handler is not on bootstrap
*/
clear_c0_status(ST0_IM | ST0_BEV);
/* no steer */
LOONGSON_INTSTEER = 0;
/*
* Mask out all interrupt by writing "1" to all bit position in
* the interrupt reset reg.
*/
LOONGSON_INTENCLR = ~0;
/* machine specific irq init */
mach_init_irq();
}

View File

@ -0,0 +1,63 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2009 Lemote Inc.
* Author: Wu Zhangjin, wuzhangjin@gmail.com
*
* Copyright (c) 2009 Zhang Le <r0bertz@gentoo.org>
*/
#include <linux/errno.h>
#include <asm/bootinfo.h>
#include <loongson.h>
#include <machine.h>
/* please ensure the length of the machtype string is less than 50 */
#define MACHTYPE_LEN 50
static const char *system_types[] = {
[MACH_LOONGSON_UNKNOWN] = "unknown loongson machine",
[MACH_LEMOTE_FL2E] = "lemote-fuloong-2e-box",
[MACH_LEMOTE_FL2F] = "lemote-fuloong-2f-box",
[MACH_LEMOTE_ML2F7] = "lemote-mengloong-2f-7inches",
[MACH_LEMOTE_YL2F89] = "lemote-yeeloong-2f-8.9inches",
[MACH_DEXXON_GDIUM2F10] = "dexxon-gdium-2f",
[MACH_LEMOTE_NAS] = "lemote-nas-2f",
[MACH_LEMOTE_LL2F] = "lemote-lynloong-2f",
[MACH_LOONGSON_GENERIC] = "generic-loongson-machine",
[MACH_LOONGSON_END] = NULL,
};
const char *get_system_type(void)
{
return system_types[mips_machtype];
}
void __weak __init mach_prom_init_machtype(void)
{
}
void __init prom_init_machtype(void)
{
char *p, str[MACHTYPE_LEN + 1];
int machtype = MACH_LEMOTE_FL2E;
mips_machtype = LOONGSON_MACHTYPE;
p = strstr(arcs_cmdline, "machtype=");
if (!p) {
mach_prom_init_machtype();
return;
}
p += strlen("machtype=");
strncpy(str, p, MACHTYPE_LEN);
str[MACHTYPE_LEN] = '\0';
p = strstr(str, " ");
if (p)
*p = '\0';
for (; system_types[machtype]; machtype++)
if (strstr(system_types[machtype], str)) {
mips_machtype = machtype;
break;
}
}

View File

@ -0,0 +1,157 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
*/
#include <linux/fs.h>
#include <linux/fcntl.h>
#include <linux/memblock.h>
#include <linux/mm.h>
#include <asm/bootinfo.h>
#include <loongson.h>
#include <boot_param.h>
#include <mem.h>
#include <pci.h>
#ifndef CONFIG_LEFI_FIRMWARE_INTERFACE
u32 memsize, highmemsize;
void __init prom_init_memory(void)
{
add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM);
add_memory_region(memsize << 20, LOONGSON_PCI_MEM_START - (memsize <<
20), BOOT_MEM_RESERVED);
#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
{
int bit;
bit = fls(memsize + highmemsize);
if (bit != ffs(memsize + highmemsize))
bit += 20;
else
bit = bit + 20 - 1;
/* set cpu window3 to map CPU to DDR: 2G -> 2G */
LOONGSON_ADDRWIN_CPUTODDR(ADDRWIN_WIN3, 0x80000000ul,
0x80000000ul, (1 << bit));
mmiowb();
}
#endif /* !CONFIG_CPU_SUPPORTS_ADDRWINCFG */
#ifdef CONFIG_64BIT
if (highmemsize > 0)
add_memory_region(LOONGSON_HIGHMEM_START,
highmemsize << 20, BOOT_MEM_RAM);
add_memory_region(LOONGSON_PCI_MEM_END + 1, LOONGSON_HIGHMEM_START -
LOONGSON_PCI_MEM_END - 1, BOOT_MEM_RESERVED);
#endif /* !CONFIG_64BIT */
}
#else /* CONFIG_LEFI_FIRMWARE_INTERFACE */
void __init prom_init_memory(void)
{
int i;
u32 node_id;
u32 mem_type;
/* parse memory information */
for (i = 0; i < loongson_memmap->nr_map; i++) {
node_id = loongson_memmap->map[i].node_id;
mem_type = loongson_memmap->map[i].mem_type;
if (node_id != 0)
continue;
switch (mem_type) {
case SYSTEM_RAM_LOW:
memblock_add(loongson_memmap->map[i].mem_start,
(u64)loongson_memmap->map[i].mem_size << 20);
break;
case SYSTEM_RAM_HIGH:
memblock_add(loongson_memmap->map[i].mem_start,
(u64)loongson_memmap->map[i].mem_size << 20);
break;
case SYSTEM_RAM_RESERVED:
memblock_reserve(loongson_memmap->map[i].mem_start,
(u64)loongson_memmap->map[i].mem_size << 20);
break;
}
}
}
#endif /* CONFIG_LEFI_FIRMWARE_INTERFACE */
/* override of arch/mips/mm/cache.c: __uncached_access */
int __uncached_access(struct file *file, unsigned long addr)
{
if (file->f_flags & O_DSYNC)
return 1;
return addr >= __pa(high_memory) ||
((addr >= LOONGSON_MMIO_MEM_START) &&
(addr < LOONGSON_MMIO_MEM_END));
}
#ifdef CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED
#include <linux/pci.h>
#include <linux/sched.h>
#include <asm/current.h>
static unsigned long uca_start, uca_end;
pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
unsigned long size, pgprot_t vma_prot)
{
unsigned long offset = pfn << PAGE_SHIFT;
unsigned long end = offset + size;
if (__uncached_access(file, offset)) {
if (uca_start && (offset >= uca_start) &&
(end <= uca_end))
return __pgprot((pgprot_val(vma_prot) &
~_CACHE_MASK) |
_CACHE_UNCACHED_ACCELERATED);
else
return pgprot_noncached(vma_prot);
}
return vma_prot;
}
static int __init find_vga_mem_init(void)
{
struct pci_dev *dev = 0;
struct resource *r;
int idx;
if (uca_start)
return 0;
for_each_pci_dev(dev) {
if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) {
r = &dev->resource[idx];
if (!r->start && r->end)
continue;
if (r->flags & IORESOURCE_IO)
continue;
if (r->flags & IORESOURCE_MEM) {
uca_start = r->start;
uca_end = r->end;
return 0;
}
}
}
}
return 0;
}
late_initcall(find_vga_mem_init);
#endif /* !CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED */

View File

@ -0,0 +1,97 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
* Author: Fuxin Zhang, zhangfx@lemote.com
*/
#include <linux/pci.h>
#include <pci.h>
#include <loongson.h>
#include <boot_param.h>
static struct resource loongson_pci_mem_resource = {
.name = "pci memory space",
.start = LOONGSON_PCI_MEM_START,
.end = LOONGSON_PCI_MEM_END,
.flags = IORESOURCE_MEM,
};
static struct resource loongson_pci_io_resource = {
.name = "pci io space",
.start = LOONGSON_PCI_IO_START,
.end = IO_SPACE_LIMIT,
.flags = IORESOURCE_IO,
};
static struct pci_controller loongson_pci_controller = {
.pci_ops = &loongson_pci_ops,
.io_resource = &loongson_pci_io_resource,
.mem_resource = &loongson_pci_mem_resource,
.mem_offset = 0x00000000UL,
.io_offset = 0x00000000UL,
};
static void __init setup_pcimap(void)
{
/*
* local to PCI mapping for CPU accessing PCI space
* CPU address space [256M,448M] is window for accessing pci space
* we set pcimap_lo[0,1,2] to map it to pci space[0M,64M], [320M,448M]
*
* pcimap: PCI_MAP2 PCI_Mem_Lo2 PCI_Mem_Lo1 PCI_Mem_Lo0
* [<2G] [384M,448M] [320M,384M] [0M,64M]
*/
LOONGSON_PCIMAP = LOONGSON_PCIMAP_PCIMAP_2 |
LOONGSON_PCIMAP_WIN(2, LOONGSON_PCILO2_BASE) |
LOONGSON_PCIMAP_WIN(1, LOONGSON_PCILO1_BASE) |
LOONGSON_PCIMAP_WIN(0, 0);
/*
* PCI-DMA to local mapping: [2G,2G+256M] -> [0M,256M]
*/
LOONGSON_PCIBASE0 = 0x80000000ul; /* base: 2G -> mmap: 0M */
/* size: 256M, burst transmission, pre-fetch enable, 64bit */
LOONGSON_PCI_HIT0_SEL_L = 0xc000000cul;
LOONGSON_PCI_HIT0_SEL_H = 0xfffffffful;
LOONGSON_PCI_HIT1_SEL_L = 0x00000006ul; /* set this BAR as invalid */
LOONGSON_PCI_HIT1_SEL_H = 0x00000000ul;
LOONGSON_PCI_HIT2_SEL_L = 0x00000006ul; /* set this BAR as invalid */
LOONGSON_PCI_HIT2_SEL_H = 0x00000000ul;
/* avoid deadlock of PCI reading/writing lock operation */
LOONGSON_PCI_ISR4C = 0xd2000001ul;
/* can not change gnt to break pci transfer when device's gnt not
deassert for some broken device */
LOONGSON_PXARB_CFG = 0x00fe0105ul;
#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
/*
* set cpu addr window2 to map CPU address space to PCI address space
*/
LOONGSON_ADDRWIN_CPUTOPCI(ADDRWIN_WIN2, LOONGSON_CPU_MEM_SRC,
LOONGSON_PCI_MEM_DST, MMAP_CPUTOPCI_SIZE);
#endif
}
extern int sbx00_acpi_init(void);
static int __init pcibios_init(void)
{
setup_pcimap();
loongson_pci_controller.io_map_base = mips_io_port_base;
#ifdef CONFIG_LEFI_FIRMWARE_INTERFACE
loongson_pci_mem_resource.start = loongson_sysconf.pci_mem_start_addr;
loongson_pci_mem_resource.end = loongson_sysconf.pci_mem_end_addr;
#endif
register_pci_controller(&loongson_pci_controller);
#ifdef CONFIG_CPU_LOONGSON64
sbx00_acpi_init();
#endif
return 0;
}
arch_initcall(pcibios_init);

View File

@ -0,0 +1,27 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2009 Lemote Inc.
* Author: Wu Zhangjin, wuzhangjin@gmail.com
*/
#include <linux/err.h>
#include <linux/smp.h>
#include <linux/platform_device.h>
static struct platform_device loongson2_cpufreq_device = {
.name = "loongson2_cpufreq",
.id = -1,
};
static int __init loongson2_cpufreq_init(void)
{
struct cpuinfo_mips *c = &current_cpu_data;
/* Only 2F revision and it's successors support CPUFreq */
if ((c->processor_id & PRID_REV_MASK) >= PRID_REV_LOONGSON2F)
return platform_device_register(&loongson2_cpufreq_device);
return -ENODEV;
}
arch_initcall(loongson2_cpufreq_init);

View File

@ -0,0 +1,157 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* loongson-specific suspend support
*
* Copyright (C) 2009 Lemote Inc.
* Author: Wu Zhangjin <wuzhangjin@gmail.com>
*/
#include <linux/suspend.h>
#include <linux/interrupt.h>
#include <linux/pm.h>
#include <asm/i8259.h>
#include <asm/mipsregs.h>
#include <loongson.h>
static unsigned int __maybe_unused cached_master_mask; /* i8259A */
static unsigned int __maybe_unused cached_slave_mask;
static unsigned int __maybe_unused cached_bonito_irq_mask; /* bonito */
void arch_suspend_disable_irqs(void)
{
/* disable all mips events */
local_irq_disable();
#ifdef CONFIG_I8259
/* disable all events of i8259A */
cached_slave_mask = inb(PIC_SLAVE_IMR);
cached_master_mask = inb(PIC_MASTER_IMR);
outb(0xff, PIC_SLAVE_IMR);
inb(PIC_SLAVE_IMR);
outb(0xff, PIC_MASTER_IMR);
inb(PIC_MASTER_IMR);
#endif
/* disable all events of bonito */
cached_bonito_irq_mask = LOONGSON_INTEN;
LOONGSON_INTENCLR = 0xffff;
(void)LOONGSON_INTENCLR;
}
void arch_suspend_enable_irqs(void)
{
/* enable all mips events */
local_irq_enable();
#ifdef CONFIG_I8259
/* only enable the cached events of i8259A */
outb(cached_slave_mask, PIC_SLAVE_IMR);
outb(cached_master_mask, PIC_MASTER_IMR);
#endif
/* enable all cached events of bonito */
LOONGSON_INTENSET = cached_bonito_irq_mask;
(void)LOONGSON_INTENSET;
}
/*
* Setup the board-specific events for waking up loongson from wait mode
*/
void __weak setup_wakeup_events(void)
{
}
/*
* Check wakeup events
*/
int __weak wakeup_loongson(void)
{
return 1;
}
/*
* If the events are really what we want to wakeup the CPU, wake it up
* otherwise put the CPU asleep again.
*/
static void wait_for_wakeup_events(void)
{
while (!wakeup_loongson())
LOONGSON_CHIPCFG(0) &= ~0x7;
}
/*
* Stop all perf counters
*
* $24 is the control register of Loongson perf counter
*/
static inline void stop_perf_counters(void)
{
__write_64bit_c0_register($24, 0, 0);
}
static void loongson_suspend_enter(void)
{
static unsigned int cached_cpu_freq;
/* setup wakeup events via enabling the IRQs */
setup_wakeup_events();
stop_perf_counters();
cached_cpu_freq = LOONGSON_CHIPCFG(0);
/* Put CPU into wait mode */
LOONGSON_CHIPCFG(0) &= ~0x7;
/* wait for the given events to wakeup cpu from wait mode */
wait_for_wakeup_events();
LOONGSON_CHIPCFG(0) = cached_cpu_freq;
mmiowb();
}
void __weak mach_suspend(void)
{
}
void __weak mach_resume(void)
{
}
static int loongson_pm_enter(suspend_state_t state)
{
mach_suspend();
/* processor specific suspend */
loongson_suspend_enter();
mach_resume();
return 0;
}
static int loongson_pm_valid_state(suspend_state_t state)
{
switch (state) {
case PM_SUSPEND_ON:
case PM_SUSPEND_STANDBY:
case PM_SUSPEND_MEM:
return 1;
default:
return 0;
}
}
static const struct platform_suspend_ops loongson_pm_ops = {
.valid = loongson_pm_valid_state,
.enter = loongson_pm_enter,
};
static int __init loongson_pm_init(void)
{
suspend_set_ops(&loongson_pm_ops);
return 0;
}
arch_initcall(loongson_pm_init);

View File

@ -0,0 +1,94 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
*
* Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
* Author: Fuxin Zhang, zhangfx@lemote.com
* Copyright (C) 2009 Lemote, Inc.
* Author: Zhangjin Wu, wuzhangjin@gmail.com
*/
#include <linux/init.h>
#include <linux/pm.h>
#include <asm/idle.h>
#include <asm/reboot.h>
#include <loongson.h>
#include <boot_param.h>
static inline void loongson_reboot(void)
{
#ifndef CONFIG_CPU_JUMP_WORKAROUNDS
((void (*)(void))ioremap_nocache(LOONGSON_BOOT_BASE, 4)) ();
#else
void (*func)(void);
func = (void *)ioremap_nocache(LOONGSON_BOOT_BASE, 4);
__asm__ __volatile__(
" .set noat \n"
" jr %[func] \n"
" .set at \n"
: /* No outputs */
: [func] "r" (func));
#endif
}
static void loongson_restart(char *command)
{
#ifndef CONFIG_LEFI_FIRMWARE_INTERFACE
/* do preparation for reboot */
mach_prepare_reboot();
/* reboot via jumping to boot base address */
loongson_reboot();
#else
void (*fw_restart)(void) = (void *)loongson_sysconf.restart_addr;
fw_restart();
while (1) {
if (cpu_wait)
cpu_wait();
}
#endif
}
static void loongson_poweroff(void)
{
#ifndef CONFIG_LEFI_FIRMWARE_INTERFACE
mach_prepare_shutdown();
/*
* It needs a wait loop here, but mips/kernel/reset.c already calls
* a generic delay loop, machine_hang(), so simply return.
*/
return;
#else
void (*fw_poweroff)(void) = (void *)loongson_sysconf.poweroff_addr;
fw_poweroff();
while (1) {
if (cpu_wait)
cpu_wait();
}
#endif
}
static void loongson_halt(void)
{
pr_notice("\n\n** You can safely turn off the power now **\n\n");
while (1) {
if (cpu_wait)
cpu_wait();
}
}
static int __init mips_reboot_setup(void)
{
_machine_restart = loongson_restart;
_machine_halt = loongson_halt;
pm_power_off = loongson_poweroff;
return 0;
}
arch_initcall(mips_reboot_setup);

View File

@ -0,0 +1,39 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Lemote Fuloong platform support
*
* Copyright(c) 2010 Arnaud Patard <apatard@mandriva.com>
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/mc146818rtc.h>
static struct resource loongson_rtc_resources[] = {
{
.start = RTC_PORT(0),
.end = RTC_PORT(1),
.flags = IORESOURCE_IO,
}, {
.start = RTC_IRQ,
.end = RTC_IRQ,
.flags = IORESOURCE_IRQ,
}
};
static struct platform_device loongson_rtc_device = {
.name = "rtc_cmos",
.id = -1,
.resource = loongson_rtc_resources,
.num_resources = ARRAY_SIZE(loongson_rtc_resources),
};
static int __init loongson_rtc_platform_init(void)
{
platform_device_register(&loongson_rtc_device);
return 0;
}
device_initcall(loongson_rtc_platform_init);

View File

@ -0,0 +1,117 @@
/*
* 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) 2007 Ralf Baechle (ralf@linux-mips.org)
*
* Copyright (C) 2009 Lemote, Inc.
* Author: Yan hua (yanhua@lemote.com)
* Author: Wu Zhangjin (wuzhangjin@gmail.com)
*/
#include <linux/io.h>
#include <linux/module.h>
#include <linux/serial_8250.h>
#include <asm/bootinfo.h>
#include <loongson.h>
#include <machine.h>
#define PORT(int, clk) \
{ \
.irq = int, \
.uartclk = clk, \
.iotype = UPIO_PORT, \
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, \
.regshift = 0, \
}
#define PORT_M(int, clk) \
{ \
.irq = MIPS_CPU_IRQ_BASE + (int), \
.uartclk = clk, \
.iotype = UPIO_MEM, \
.membase = (void __iomem *)NULL, \
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, \
.regshift = 0, \
}
static struct plat_serial8250_port uart8250_data[][MAX_UARTS + 1] = {
[MACH_LOONGSON_UNKNOWN] = {},
[MACH_LEMOTE_FL2E] = {PORT(4, 1843200), {} },
[MACH_LEMOTE_FL2F] = {PORT(3, 1843200), {} },
[MACH_LEMOTE_ML2F7] = {PORT_M(3, 3686400), {} },
[MACH_LEMOTE_YL2F89] = {PORT_M(3, 3686400), {} },
[MACH_DEXXON_GDIUM2F10] = {PORT_M(3, 3686400), {} },
[MACH_LEMOTE_NAS] = {PORT_M(3, 3686400), {} },
[MACH_LEMOTE_LL2F] = {PORT(3, 1843200), {} },
[MACH_LOONGSON_GENERIC] = {PORT_M(2, 25000000), {} },
[MACH_LOONGSON_END] = {},
};
static struct platform_device uart8250_device = {
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM,
};
static int __init serial_init(void)
{
int i;
unsigned char iotype;
iotype = uart8250_data[mips_machtype][0].iotype;
if (UPIO_MEM == iotype) {
uart8250_data[mips_machtype][0].mapbase =
loongson_uart_base[0];
uart8250_data[mips_machtype][0].membase =
(void __iomem *)_loongson_uart_base[0];
}
else if (UPIO_PORT == iotype)
uart8250_data[mips_machtype][0].iobase =
loongson_uart_base[0] - LOONGSON_PCIIO_BASE;
if (loongson_sysconf.uarts[0].uartclk)
uart8250_data[mips_machtype][0].uartclk =
loongson_sysconf.uarts[0].uartclk;
for (i = 1; i < loongson_sysconf.nr_uarts; i++) {
iotype = loongson_sysconf.uarts[i].iotype;
uart8250_data[mips_machtype][i].iotype = iotype;
loongson_uart_base[i] = loongson_sysconf.uarts[i].uart_base;
if (UPIO_MEM == iotype) {
uart8250_data[mips_machtype][i].irq =
MIPS_CPU_IRQ_BASE + loongson_sysconf.uarts[i].int_offset;
uart8250_data[mips_machtype][i].mapbase =
loongson_uart_base[i];
uart8250_data[mips_machtype][i].membase =
ioremap_nocache(loongson_uart_base[i], 8);
} else if (UPIO_PORT == iotype) {
uart8250_data[mips_machtype][i].irq =
loongson_sysconf.uarts[i].int_offset;
uart8250_data[mips_machtype][i].iobase =
loongson_uart_base[i] - LOONGSON_PCIIO_BASE;
}
uart8250_data[mips_machtype][i].uartclk =
loongson_sysconf.uarts[i].uartclk;
uart8250_data[mips_machtype][i].flags =
UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
}
memset(&uart8250_data[mips_machtype][loongson_sysconf.nr_uarts],
0, sizeof(struct plat_serial8250_port));
uart8250_device.dev.platform_data = uart8250_data[mips_machtype];
return platform_device_register(&uart8250_device);
}
module_init(serial_init);
static void __exit serial_exit(void)
{
platform_device_unregister(&uart8250_device);
}
module_exit(serial_exit);

View File

@ -0,0 +1,51 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2007 Lemote Inc. & Institute of Computing Technology
* Author: Fuxin Zhang, zhangfx@lemote.com
*/
#include <linux/export.h>
#include <linux/init.h>
#include <asm/wbflush.h>
#include <asm/bootinfo.h>
#include <loongson.h>
#ifdef CONFIG_VT
#include <linux/console.h>
#include <linux/screen_info.h>
#endif
static void wbflush_loongson(void)
{
asm(".set\tpush\n\t"
".set\tnoreorder\n\t"
".set mips3\n\t"
"sync\n\t"
"nop\n\t"
".set\tpop\n\t"
".set mips0\n\t");
}
void (*__wbflush)(void) = wbflush_loongson;
EXPORT_SYMBOL(__wbflush);
void __init plat_mem_setup(void)
{
#ifdef CONFIG_VT
#if defined(CONFIG_VGA_CONSOLE)
conswitchp = &vga_con;
screen_info = (struct screen_info) {
.orig_x = 0,
.orig_y = 25,
.orig_video_cols = 80,
.orig_video_lines = 25,
.orig_video_isVGA = VIDEO_TYPE_VGAC,
.orig_video_points = 16,
};
#elif defined(CONFIG_DUMMY_CONSOLE)
conswitchp = &dummy_con;
#endif
#endif
}

View File

@ -0,0 +1,32 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
* Author: Fuxin Zhang, zhangfx@lemote.com
*
* Copyright (C) 2009 Lemote Inc.
* Author: Wu Zhangjin, wuzhangjin@gmail.com
*/
#include <asm/mc146818-time.h>
#include <asm/time.h>
#include <asm/hpet.h>
#include <loongson.h>
#include <cs5536/cs5536_mfgpt.h>
void __init plat_time_init(void)
{
/* setup mips r4k timer */
mips_hpt_frequency = cpu_clock_freq / 2;
#ifdef CONFIG_RS780_HPET
setup_hpet_timer();
#else
setup_mfgpt0_timer();
#endif
}
void read_persistent_clock64(struct timespec64 *ts)
{
ts->tv_sec = mc146818_get_cmos_time();
ts->tv_nsec = 0;
}

View File

@ -0,0 +1,46 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2009 Lemote Inc.
* Author: Wu Zhangjin, wuzhangjin@gmail.com
*/
#include <linux/export.h>
#include <asm/bootinfo.h>
#include <loongson.h>
/* raw */
unsigned long loongson_uart_base[MAX_UARTS] = {};
/* ioremapped */
unsigned long _loongson_uart_base[MAX_UARTS] = {};
EXPORT_SYMBOL(loongson_uart_base);
EXPORT_SYMBOL(_loongson_uart_base);
void prom_init_loongson_uart_base(void)
{
switch (mips_machtype) {
case MACH_LOONGSON_GENERIC:
/* The CPU provided serial port (CPU) */
loongson_uart_base[0] = LOONGSON_REG_BASE + 0x1e0;
break;
case MACH_LEMOTE_FL2E:
loongson_uart_base[0] = LOONGSON_PCIIO_BASE + 0x3f8;
break;
case MACH_LEMOTE_FL2F:
case MACH_LEMOTE_LL2F:
loongson_uart_base[0] = LOONGSON_PCIIO_BASE + 0x2f8;
break;
case MACH_LEMOTE_ML2F7:
case MACH_LEMOTE_YL2F89:
case MACH_DEXXON_GDIUM2F10:
case MACH_LEMOTE_NAS:
default:
/* The CPU provided serial port (LPC) */
loongson_uart_base[0] = LOONGSON_LIO1_BASE + 0x3f8;
break;
}
_loongson_uart_base[0] =
(unsigned long)ioremap_nocache(loongson_uart_base[0], 8);
}

View File

@ -15,7 +15,7 @@
#include <linux/spinlock.h>
#include <asm/clock.h>
#include <asm/mach-loongson64/loongson.h>
#include <asm/mach-loongson2ef/loongson.h>
static LIST_HEAD(clock_list);
static DEFINE_SPINLOCK(clock_lock);

View File

@ -4,65 +4,6 @@ if MACH_LOONGSON64
choice
prompt "Machine Type"
config LEMOTE_FULOONG2E
bool "Lemote Fuloong(2e) mini-PC"
select ARCH_SPARSEMEM_ENABLE
select ARCH_MIGHT_HAVE_PC_PARPORT
select ARCH_MIGHT_HAVE_PC_SERIO
select CEVT_R4K
select CSRC_R4K
select SYS_HAS_CPU_LOONGSON2E
select DMA_NONCOHERENT
select BOOT_ELF32
select BOARD_SCACHE
select HAVE_PCI
select I8259
select ISA
select IRQ_MIPS_CPU
select SYS_SUPPORTS_64BIT_KERNEL
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_SUPPORTS_HIGHMEM
select SYS_HAS_EARLY_PRINTK
select GENERIC_ISA_DMA_SUPPORT_BROKEN
select CPU_HAS_WB
select LOONGSON_MC146818
help
Lemote Fuloong(2e) mini-PC board based on the Chinese Loongson-2E CPU and
an FPGA northbridge
Lemote Fuloong(2e) mini PC have a VIA686B south bridge.
config LEMOTE_MACH2F
bool "Lemote Loongson 2F family machines"
select ARCH_SPARSEMEM_ENABLE
select ARCH_MIGHT_HAVE_PC_PARPORT
select ARCH_MIGHT_HAVE_PC_SERIO
select BOARD_SCACHE
select BOOT_ELF32
select CEVT_R4K if ! MIPS_EXTERNAL_TIMER
select CPU_HAS_WB
select CS5536
select CSRC_R4K if ! MIPS_EXTERNAL_TIMER
select DMA_NONCOHERENT
select GENERIC_ISA_DMA_SUPPORT_BROKEN
select HAVE_CLK
select HAVE_PCI
select I8259
select IRQ_MIPS_CPU
select ISA
select SYS_HAS_CPU_LOONGSON2F
select SYS_HAS_EARLY_PRINTK
select SYS_SUPPORTS_64BIT_KERNEL
select SYS_SUPPORTS_HIGHMEM
select SYS_SUPPORTS_LITTLE_ENDIAN
select LOONGSON_MC146818
help
Lemote Loongson 2F family machines utilize the 2F revision of
Loongson processor and the AMD CS5536 south bridge.
These family machines include fuloong2f mini PC, yeeloong2f notebook,
LingLoong allinone PC and so forth.
config LOONGSON_MACH3X
bool "Generic Loongson 3 family machines"
select ARCH_SPARSEMEM_ENABLE
@ -95,22 +36,6 @@ config LOONGSON_MACH3X
of Loongson processor and RS780/SBX00 chipset.
endchoice
config CS5536
bool
config CS5536_MFGPT
bool "CS5536 MFGPT Timer"
depends on CS5536 && !HIGH_RES_TIMERS
select MIPS_EXTERNAL_TIMER
help
This option enables the mfgpt0 timer of AMD CS5536. With this timer
switched on you can not use high resolution timers.
If you want to enable the Loongson2 CPUFreq Driver, Please enable
this option at first, otherwise, You will get wrong system time.
If unsure, say Yes.
config RS780_HPET
bool "RS780/SBX00 HPET Timer"
depends on LOONGSON_MACH3X

View File

@ -5,18 +5,6 @@
obj-$(CONFIG_MACH_LOONGSON64) += common/
#
# Lemote Fuloong mini-PC (Loongson 2E-based)
#
obj-$(CONFIG_LEMOTE_FULOONG2E) += fuloong-2e/
#
# Lemote loongson2f family machines
#
obj-$(CONFIG_LEMOTE_MACH2F) += lemote-2f/
#
# All Loongson-3 family machines
#

View File

@ -2,25 +2,6 @@
# Loongson Processors' Support
#
# Only gcc >= 4.4 have Loongson specific support
cflags-$(CONFIG_CPU_LOONGSON2EF) += -Wa,--trap
cflags-$(CONFIG_CPU_LOONGSON2E) += \
$(call cc-option,-march=loongson2e,-march=r4600)
cflags-$(CONFIG_CPU_LOONGSON2F) += \
$(call cc-option,-march=loongson2f,-march=r4600)
# Enable the workarounds for Loongson2f
ifdef CONFIG_CPU_LOONGSON2F_WORKAROUNDS
ifeq ($(call as-option,-Wa$(comma)-mfix-loongson2f-nop,),)
$(error only binutils >= 2.20.2 have needed option -mfix-loongson2f-nop)
else
cflags-$(CONFIG_CPU_NOP_WORKAROUNDS) += -Wa$(comma)-mfix-loongson2f-nop
endif
ifeq ($(call as-option,-Wa$(comma)-mfix-loongson2f-jump,),)
$(error only binutils >= 2.20.2 have needed option -mfix-loongson2f-jump)
else
cflags-$(CONFIG_CPU_JUMP_WORKAROUNDS) += -Wa$(comma)-mfix-loongson2f-jump
endif
endif
cflags-$(CONFIG_CPU_LOONGSON64) += -Wa,--trap
@ -72,6 +53,4 @@ endif
platform-$(CONFIG_MACH_LOONGSON64) += loongson64/
cflags-$(CONFIG_MACH_LOONGSON64) += -I$(srctree)/arch/mips/include/asm/mach-loongson64 -mno-branch-likely
load-$(CONFIG_LEMOTE_FULOONG2E) += 0xffffffff80100000
load-$(CONFIG_LEMOTE_MACH2F) += 0xffffffff80200000
load-$(CONFIG_LOONGSON_MACH3X) += 0xffffffff80200000

View File

@ -14,12 +14,6 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_LOONGSON_UART_BASE) += uart_base.o
obj-$(CONFIG_LOONGSON_MC146818) += rtc.o
#
# Enable CS5536 Virtual Support Module(VSM) to virtulize the PCI configure
# space
#
obj-$(CONFIG_CS5536) += cs5536/
#
# Suspend Support
#

View File

@ -23,7 +23,7 @@
#include <asm/clock.h>
#include <asm/idle.h>
#include <asm/mach-loongson64/loongson.h>
#include <asm/mach-loongson2ef/loongson.h>
static uint nowait;