From: Huacai Chen Date: Tue, 21 Apr 2015 02:00:35 +0000 (+0800) Subject: MIPS: Loongson: Naming style cleanup and rework X-Git-Tag: drm-fsl-dcu-for-next~2979^2~44 X-Git-Url: http://git.agner.ch/gitweb/?p=linux-drm-fsl-dcu.git;a=commitdiff_plain;h=30ad29bb48881ee11f5daf30c6fc50292ae08c57 MIPS: Loongson: Naming style cleanup and rework Currently, code of Loongson-2/3 is under loongson directory and code of Loongson-1 is under loongson1 directory. Besides, there are Kconfig options such as MACH_LOONGSON and MACH_LOONGSON1. This naming style is very ugly and confusing. Since Loongson-2/3 are both 64-bit general- purpose CPU while Loongson-1 is 32-bit SoC, we rename both file names and Kconfig symbols from loongson/loongson1 to loongson64/loongson32. [ralf@linux-mips.org: Resolve a number of simple conflicts.] Signed-off-by: Huacai Chen Cc: Steven J. Hill Cc: linux-mips@linux-mips.org Cc: Fuxin Zhang Cc: Zhangjin Wu Cc: Kelvin Cheung Patchwork: https://patchwork.linux-mips.org/patch/9790/ Signed-off-by: Ralf Baechle --- diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms index 39cf40da5f14..a424e46b50af 100644 --- a/arch/mips/Kbuild.platforms +++ b/arch/mips/Kbuild.platforms @@ -15,8 +15,8 @@ platforms += jazz platforms += jz4740 platforms += lantiq platforms += lasat -platforms += loongson -platforms += loongson1 +platforms += loongson32 +platforms += loongson64 platforms += mti-malta platforms += mti-sead3 platforms += netlogic diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 0ee59e8cdb57..733f6ac97f28 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -26,7 +26,7 @@ config MIPS select HAVE_SYSCALL_TRACEPOINTS select ARCH_HAS_ELF_RANDOMIZE select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES && 64BIT - select RTC_LIB if !MACH_LOONGSON + select RTC_LIB if !MACH_LOONGSON64 select GENERIC_ATOMIC64 if !64BIT select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE select HAVE_DMA_ATTRS @@ -346,26 +346,28 @@ config LASAT select SYS_SUPPORTS_64BIT_KERNEL if BROKEN select SYS_SUPPORTS_LITTLE_ENDIAN -config MACH_LOONGSON - bool "Loongson family of machines" +config MACH_LOONGSON32 + bool "Loongson-1 family of machines" select SYS_SUPPORTS_ZBOOT help - This enables the support of Loongson family of machines. + This enables support for the Loongson-1 family of machines. - Loongson is a family of general-purpose MIPS-compatible CPUs. - developed at Institute of Computing Technology (ICT), - Chinese Academy of Sciences (CAS) in the People's Republic - of China. The chief architect is Professor Weiwu Hu. + Loongson-1 is a family of 32-bit MIPS-compatible SoCs developed by + the Institute of Computing Technology (ICT), Chinese Academy of + Sciences (CAS). -config MACH_LOONGSON1 - bool "Loongson 1 family of machines" +config MACH_LOONGSON64 + bool "Loongson-2/3 family of machines" select SYS_SUPPORTS_ZBOOT help - This enables support for the Loongson 1 based machines. + This enables the support of Loongson-2/3 family of machines. - Loongson 1 is a family of 32-bit MIPS-compatible SoCs developed by - the ICT (Institute of Computing Technology) and the Chinese Academy - of Sciences. + 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_PISTACHIO bool "IMG Pistachio SoC based boards" @@ -948,8 +950,8 @@ source "arch/mips/sibyte/Kconfig" source "arch/mips/txx9/Kconfig" source "arch/mips/vr41xx/Kconfig" source "arch/mips/cavium-octeon/Kconfig" -source "arch/mips/loongson/Kconfig" -source "arch/mips/loongson1/Kconfig" +source "arch/mips/loongson32/Kconfig" +source "arch/mips/loongson64/Kconfig" source "arch/mips/netlogic/Kconfig" source "arch/mips/paravirt/Kconfig" diff --git a/arch/mips/boot/compressed/uart-16550.c b/arch/mips/boot/compressed/uart-16550.c index 237494b7a21a..408799a839b4 100644 --- a/arch/mips/boot/compressed/uart-16550.c +++ b/arch/mips/boot/compressed/uart-16550.c @@ -7,7 +7,7 @@ #include -#if defined(CONFIG_MACH_LOONGSON) || defined(CONFIG_MIPS_MALTA) +#if defined(CONFIG_MACH_LOONGSON64) || defined(CONFIG_MIPS_MALTA) #define UART_BASE 0x1fd003f8 #define PORT(offset) (CKSEG1ADDR(UART_BASE) + (offset)) #endif diff --git a/arch/mips/configs/fuloong2e_defconfig b/arch/mips/configs/fuloong2e_defconfig index b2a577ebce0b..a75c65da08b4 100644 --- a/arch/mips/configs/fuloong2e_defconfig +++ b/arch/mips/configs/fuloong2e_defconfig @@ -1,4 +1,4 @@ -CONFIG_MACH_LOONGSON=y +CONFIG_MACH_LOONGSON64=y CONFIG_64BIT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y diff --git a/arch/mips/configs/lemote2f_defconfig b/arch/mips/configs/lemote2f_defconfig index 0cbc9863c7c8..54cc3853d259 100644 --- a/arch/mips/configs/lemote2f_defconfig +++ b/arch/mips/configs/lemote2f_defconfig @@ -1,4 +1,4 @@ -CONFIG_MACH_LOONGSON=y +CONFIG_MACH_LOONGSON64=y CONFIG_LEMOTE_MACH2F=y CONFIG_CS5536_MFGPT=y CONFIG_64BIT=y diff --git a/arch/mips/configs/loongson3_defconfig b/arch/mips/configs/loongson3_defconfig index c8442997477b..f8bf915c6d6b 100644 --- a/arch/mips/configs/loongson3_defconfig +++ b/arch/mips/configs/loongson3_defconfig @@ -1,4 +1,4 @@ -CONFIG_MACH_LOONGSON=y +CONFIG_MACH_LOONGSON64=y CONFIG_SWIOTLB=y CONFIG_LOONGSON_MACH3X=y CONFIG_CPU_LOONGSON3=y diff --git a/arch/mips/configs/ls1b_defconfig b/arch/mips/configs/ls1b_defconfig index 7eb75543ca1a..1b2cc1fb26a1 100644 --- a/arch/mips/configs/ls1b_defconfig +++ b/arch/mips/configs/ls1b_defconfig @@ -1,4 +1,4 @@ -CONFIG_MACH_LOONGSON1=y +CONFIG_MACH_LOONGSON32=y CONFIG_PREEMPT=y # CONFIG_SECCOMP is not set CONFIG_EXPERIMENTAL=y diff --git a/arch/mips/include/asm/mach-loongson/boot_param.h b/arch/mips/include/asm/mach-loongson/boot_param.h deleted file mode 100644 index fa802926523f..000000000000 --- a/arch/mips/include/asm/mach-loongson/boot_param.h +++ /dev/null @@ -1,210 +0,0 @@ -#ifndef __ASM_MACH_LOONGSON_BOOT_PARAM_H_ -#define __ASM_MACH_LOONGSON_BOOT_PARAM_H_ - -#define SYSTEM_RAM_LOW 1 -#define SYSTEM_RAM_HIGH 2 -#define MEM_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 { - Loongson_2E = 0, - Loongson_2F = 1, - Loongson_3A = 2, - Loongson_3B = 3, - Loongson_1A = 4, - Loongson_1B = 5 -}; - -/* - * 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 diff --git a/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h b/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h deleted file mode 100644 index acc376897e46..000000000000 --- a/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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 - * Copyright (C) 2009 Philippe Vachon - * Copyright (C) 2009 Zhang Le - * - * 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_LOONGSON_CPU_FEATURE_OVERRIDES_H -#define __ASM_MACH_LOONGSON_CPU_FEATURE_OVERRIDES_H - -#define cpu_dcache_line_size() 32 -#define cpu_icache_line_size() 32 -#define cpu_scache_line_size() 32 - - -#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_dsp 0 -#define cpu_has_dsp2 0 -#define cpu_has_ejtag 0 -#define cpu_has_ic_fills_f_dc 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_mips32r2 0 -#define cpu_has_mips3d 0 -#define cpu_has_mips64r2 0 -#define cpu_has_mipsmt 0 -#define cpu_has_prefetch 0 -#define cpu_has_smartmips 0 -#define cpu_has_tlb 1 -#define cpu_has_tx39_cache 0 -#define cpu_has_userlocal 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 -#define cpu_has_local_ebase 0 - -#define cpu_has_wsbh IS_ENABLED(CONFIG_CPU_LOONGSON3) - -#endif /* __ASM_MACH_LOONGSON_CPU_FEATURE_OVERRIDES_H */ diff --git a/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h b/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h deleted file mode 100644 index a0ee0cb775ad..000000000000 --- a/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h +++ /dev/null @@ -1,305 +0,0 @@ -/* - * The header file of cs5536 south bridge. - * - * Copyright (C) 2007 Lemote, Inc. - * Author : jlliu - */ - -#ifndef _CS5536_H -#define _CS5536_H - -#include - -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 */ diff --git a/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h b/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h deleted file mode 100644 index 021d0172dad6..000000000000 --- a/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * cs5536 mfgpt header file - */ - -#ifndef _CS5536_MFGPT_H -#define _CS5536_MFGPT_H - -#include -#include - -#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 */ diff --git a/arch/mips/include/asm/mach-loongson/cs5536/cs5536_pci.h b/arch/mips/include/asm/mach-loongson/cs5536/cs5536_pci.h deleted file mode 100644 index 8a7ecb4d5c64..000000000000 --- a/arch/mips/include/asm/mach-loongson/cs5536/cs5536_pci.h +++ /dev/null @@ -1,153 +0,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 -#include - -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_COUNT 6 -#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_ */ diff --git a/arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h b/arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h deleted file mode 100644 index 1f17c1815ee5..000000000000 --- a/arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * the read/write interfaces for Virtual Support Module(VSM) - * - * Copyright (C) 2009 Lemote, Inc. - * Author: Wu Zhangjin - */ - -#ifndef _CS5536_VSM_H -#define _CS5536_VSM_H - -#include - -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 */ diff --git a/arch/mips/include/asm/mach-loongson/dma-coherence.h b/arch/mips/include/asm/mach-loongson/dma-coherence.h deleted file mode 100644 index 4bf4e19f72e8..000000000000 --- a/arch/mips/include/asm/mach-loongson/dma-coherence.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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) 2006, 07 Ralf Baechle - * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology - * Author: Fuxin Zhang, zhangfx@lemote.com - * - */ -#ifndef __ASM_MACH_LOONGSON_DMA_COHERENCE_H -#define __ASM_MACH_LOONGSON_DMA_COHERENCE_H - -#ifdef CONFIG_SWIOTLB -#include -#endif - -struct device; - -extern dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr); -extern phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr); -static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, - size_t size) -{ -#ifdef CONFIG_CPU_LOONGSON3 - return phys_to_dma(dev, virt_to_phys(addr)); -#else - return virt_to_phys(addr) | 0x80000000; -#endif -} - -static inline dma_addr_t plat_map_dma_mem_page(struct device *dev, - struct page *page) -{ -#ifdef CONFIG_CPU_LOONGSON3 - return phys_to_dma(dev, page_to_phys(page)); -#else - return page_to_phys(page) | 0x80000000; -#endif -} - -static inline unsigned long plat_dma_addr_to_phys(struct device *dev, - dma_addr_t dma_addr) -{ -#if defined(CONFIG_CPU_LOONGSON3) && defined(CONFIG_64BIT) - return dma_to_phys(dev, dma_addr); -#elif defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) - return (dma_addr > 0x8fffffff) ? dma_addr : (dma_addr & 0x0fffffff); -#else - return dma_addr & 0x7fffffff; -#endif -} - -static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr, - size_t size, enum dma_data_direction direction) -{ -} - -static inline int plat_dma_supported(struct device *dev, u64 mask) -{ - /* - * we fall back to GFP_DMA when the mask isn't all 1s, - * so we can't guarantee allocations that must be - * within a tighter range than GFP_DMA.. - */ - if (mask < DMA_BIT_MASK(24)) - return 0; - - return 1; -} - -static inline int plat_device_is_coherent(struct device *dev) -{ -#ifdef CONFIG_DMA_NONCOHERENT - return 0; -#else - return 1; -#endif /* CONFIG_DMA_NONCOHERENT */ -} - -static inline void plat_post_dma_flush(struct device *dev) -{ -} - -#endif /* __ASM_MACH_LOONGSON_DMA_COHERENCE_H */ diff --git a/arch/mips/include/asm/mach-loongson/gpio.h b/arch/mips/include/asm/mach-loongson/gpio.h deleted file mode 100644 index b3b216904a9a..000000000000 --- a/arch/mips/include/asm/mach-loongson/gpio.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Loongson GPIO Support - * - * Copyright (c) 2008 Richard Liu, STMicroelectronics - * Copyright (c) 2008-2010 Arnaud Patard - * Copyright (c) 2014 Huacai Chen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#ifndef __LOONGSON_GPIO_H -#define __LOONGSON_GPIO_H - -#include - -#define gpio_get_value __gpio_get_value -#define gpio_set_value __gpio_set_value -#define gpio_cansleep __gpio_cansleep - -/* The chip can do interrupt - * but it has not been tested and doc not clear - */ -static inline int gpio_to_irq(int gpio) -{ - return -EINVAL; -} - -static inline int irq_to_gpio(int gpio) -{ - return -EINVAL; -} - -#endif /* __LOONGSON_GPIO_H */ diff --git a/arch/mips/include/asm/mach-loongson/irq.h b/arch/mips/include/asm/mach-loongson/irq.h deleted file mode 100644 index a281cca5f2fb..000000000000 --- a/arch/mips/include/asm/mach-loongson/irq.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef __ASM_MACH_LOONGSON_IRQ_H_ -#define __ASM_MACH_LOONGSON_IRQ_H_ - -#include - -#ifdef CONFIG_CPU_LOONGSON3 - -/* cpu core interrupt numbers */ -#define MIPS_CPU_IRQ_BASE 56 - -#define LOONGSON_UART_IRQ (MIPS_CPU_IRQ_BASE + 2) /* UART */ -#define LOONGSON_HT1_IRQ (MIPS_CPU_IRQ_BASE + 3) /* HT1 */ -#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 -#endif /* __ASM_MACH_LOONGSON_IRQ_H_ */ diff --git a/arch/mips/include/asm/mach-loongson/kernel-entry-init.h b/arch/mips/include/asm/mach-loongson/kernel-entry-init.h deleted file mode 100644 index df5fca8eeb80..000000000000 --- a/arch/mips/include/asm/mach-loongson/kernel-entry-init.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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_LOONGSON_KERNEL_ENTRY_H -#define __ASM_MACH_LOONGSON_KERNEL_ENTRY_H - -/* - * Override macros used in arch/mips/kernel/head.S. - */ - .macro kernel_entry_setup -#ifdef CONFIG_CPU_LOONGSON3 - .set push - .set mips64 - /* Set LPA on LOONGSON3 config3 */ - mfc0 t0, $16, 3 - or t0, (0x1 << 7) - mtc0 t0, $16, 3 - /* Set ELPA on LOONGSON3 pagegrain */ - li t0, (0x1 << 29) - mtc0 t0, $5, 1 - _ehb - .set pop -#endif - .endm - -/* - * Do SMP slave processor setup. - */ - .macro smp_slave_setup -#ifdef CONFIG_CPU_LOONGSON3 - .set push - .set mips64 - /* Set LPA on LOONGSON3 config3 */ - mfc0 t0, $16, 3 - or t0, (0x1 << 7) - mtc0 t0, $16, 3 - /* Set ELPA on LOONGSON3 pagegrain */ - li t0, (0x1 << 29) - mtc0 t0, $5, 1 - _ehb - .set pop -#endif - .endm - -#endif /* __ASM_MACH_LOONGSON_KERNEL_ENTRY_H */ diff --git a/arch/mips/include/asm/mach-loongson/loongson.h b/arch/mips/include/asm/mach-loongson/loongson.h deleted file mode 100644 index 9783103fd6f6..000000000000 --- a/arch/mips/include/asm/mach-loongson/loongson.h +++ /dev/null @@ -1,360 +0,0 @@ -/* - * Copyright (C) 2009 Lemote, Inc. - * Author: Wu Zhangjin - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#ifndef __ASM_MACH_LOONGSON_LOONGSON_H -#define __ASM_MACH_LOONGSON_LOONGSON_H - -#include -#include -#include -#include -#include - -/* 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 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 -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) - -#if defined(CONFIG_HT_PCI) -#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 -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_LOONGSON_LOONGSON_H */ diff --git a/arch/mips/include/asm/mach-loongson/loongson_hwmon.h b/arch/mips/include/asm/mach-loongson/loongson_hwmon.h deleted file mode 100644 index 4431fc54a36c..000000000000 --- a/arch/mips/include/asm/mach-loongson/loongson_hwmon.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef __LOONGSON_HWMON_H_ -#define __LOONGSON_HWMON_H_ - -#include - -#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 constent 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_*/ diff --git a/arch/mips/include/asm/mach-loongson/machine.h b/arch/mips/include/asm/mach-loongson/machine.h deleted file mode 100644 index cb2b60249cd2..000000000000 --- a/arch/mips/include/asm/mach-loongson/machine.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2009 Lemote, Inc. - * Author: Wu Zhangjin - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#ifndef __ASM_MACH_LOONGSON_MACHINE_H -#define __ASM_MACH_LOONGSON_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_LOONGSON_MACHINE_H */ diff --git a/arch/mips/include/asm/mach-loongson/mc146818rtc.h b/arch/mips/include/asm/mach-loongson/mc146818rtc.h deleted file mode 100644 index ed7fe978335a..000000000000 --- a/arch/mips/include/asm/mach-loongson/mc146818rtc.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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_LOONGSON_MC146818RTC_H -#define __ASM_MACH_LOONGSON_MC146818RTC_H - -#include - -#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_LOONGSON_MC146818RTC_H */ diff --git a/arch/mips/include/asm/mach-loongson/mem.h b/arch/mips/include/asm/mach-loongson/mem.h deleted file mode 100644 index f4a36d7dbfab..000000000000 --- a/arch/mips/include/asm/mach-loongson/mem.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2009 Lemote, Inc. - * Author: Wu Zhangjin - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#ifndef __ASM_MACH_LOONGSON_MEM_H -#define __ASM_MACH_LOONGSON_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_LOONGSON_MEM_H */ diff --git a/arch/mips/include/asm/mach-loongson/mmzone.h b/arch/mips/include/asm/mach-loongson/mmzone.h deleted file mode 100644 index 37c08a27b4f0..000000000000 --- a/arch/mips/include/asm/mach-loongson/mmzone.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2010 Loongson Inc. & Lemote Inc. & - * Insititute of Computing Technology - * Author: Xiang Gao, gaoxiang@ict.ac.cn - * Huacai Chen, chenhc@lemote.com - * Xiaofu Meng, Shuangshuang Zhang - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#ifndef _ASM_MACH_MMZONE_H -#define _ASM_MACH_MMZONE_H - -#include -#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 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 */ diff --git a/arch/mips/include/asm/mach-loongson/pci.h b/arch/mips/include/asm/mach-loongson/pci.h deleted file mode 100644 index 1212774f66ef..000000000000 --- a/arch/mips/include/asm/mach-loongson/pci.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2008 Zhang Le - * Copyright (c) 2009 Wu Zhangjin - * - * This program is free software; you can redistribute it - * and/or modify it under the terms of the GNU General - * Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#ifndef __ASM_MACH_LOONGSON_PCI_H_ -#define __ASM_MACH_LOONGSON_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_LOONGSON3 -#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_LOONGSON_PCI_H_ */ diff --git a/arch/mips/include/asm/mach-loongson/spaces.h b/arch/mips/include/asm/mach-loongson/spaces.h deleted file mode 100644 index e2506ee90044..000000000000 --- a/arch/mips/include/asm/mach-loongson/spaces.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __ASM_MACH_LOONGSON_SPACES_H_ -#define __ASM_MACH_LOONGSON_SPACES_H_ - -#if defined(CONFIG_64BIT) -#define CAC_BASE _AC(0x9800000000000000, UL) -#endif /* CONFIG_64BIT */ - -#include -#endif diff --git a/arch/mips/include/asm/mach-loongson/topology.h b/arch/mips/include/asm/mach-loongson/topology.h deleted file mode 100644 index 0d8f3b55bdbc..000000000000 --- a/arch/mips/include/asm/mach-loongson/topology.h +++ /dev/null @@ -1,23 +0,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 parent_node(node) (node) -#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 - -#endif /* _ASM_MACH_TOPOLOGY_H */ diff --git a/arch/mips/include/asm/mach-loongson/workarounds.h b/arch/mips/include/asm/mach-loongson/workarounds.h deleted file mode 100644 index e180c1422eae..000000000000 --- a/arch/mips/include/asm/mach-loongson/workarounds.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __ASM_MACH_LOONGSON_WORKAROUNDS_H_ -#define __ASM_MACH_LOONGSON_WORKAROUNDS_H_ - -#define WORKAROUND_CPUFREQ 0x00000001 -#define WORKAROUND_CPUHOTPLUG 0x00000002 - -#endif diff --git a/arch/mips/include/asm/mach-loongson1/cpufreq.h b/arch/mips/include/asm/mach-loongson1/cpufreq.h deleted file mode 100644 index e7765ce30bcf..000000000000 --- a/arch/mips/include/asm/mach-loongson1/cpufreq.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2014 Zhang, Keguang - * - * Loongson 1 CPUFreq platform support. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - - -#ifndef __ASM_MACH_LOONGSON1_CPUFREQ_H -#define __ASM_MACH_LOONGSON1_CPUFREQ_H - -struct plat_ls1x_cpufreq { - const char *clk_name; /* CPU clk */ - const char *osc_clk_name; /* OSC clk */ - unsigned int max_freq; /* in kHz */ - unsigned int min_freq; /* in kHz */ -}; - -#endif /* __ASM_MACH_LOONGSON1_CPUFREQ_H */ diff --git a/arch/mips/include/asm/mach-loongson1/irq.h b/arch/mips/include/asm/mach-loongson1/irq.h deleted file mode 100644 index 96bfb1c1c73d..000000000000 --- a/arch/mips/include/asm/mach-loongson1/irq.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2011 Zhang, Keguang - * - * IRQ mappings for Loongson 1 - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - - -#ifndef __ASM_MACH_LOONGSON1_IRQ_H -#define __ASM_MACH_LOONGSON1_IRQ_H - -/* - * CPU core Interrupt Numbers - */ -#define MIPS_CPU_IRQ_BASE 0 -#define MIPS_CPU_IRQ(x) (MIPS_CPU_IRQ_BASE + (x)) - -#define SOFTINT0_IRQ MIPS_CPU_IRQ(0) -#define SOFTINT1_IRQ MIPS_CPU_IRQ(1) -#define INT0_IRQ MIPS_CPU_IRQ(2) -#define INT1_IRQ MIPS_CPU_IRQ(3) -#define INT2_IRQ MIPS_CPU_IRQ(4) -#define INT3_IRQ MIPS_CPU_IRQ(5) -#define INT4_IRQ MIPS_CPU_IRQ(6) -#define TIMER_IRQ MIPS_CPU_IRQ(7) /* cpu timer */ - -#define MIPS_CPU_IRQS (MIPS_CPU_IRQ(7) + 1 - MIPS_CPU_IRQ_BASE) - -/* - * INT0~3 Interrupt Numbers - */ -#define LS1X_IRQ_BASE MIPS_CPU_IRQS -#define LS1X_IRQ(n, x) (LS1X_IRQ_BASE + (n << 5) + (x)) - -#define LS1X_UART0_IRQ LS1X_IRQ(0, 2) -#define LS1X_UART1_IRQ LS1X_IRQ(0, 3) -#define LS1X_UART2_IRQ LS1X_IRQ(0, 4) -#define LS1X_UART3_IRQ LS1X_IRQ(0, 5) -#define LS1X_CAN0_IRQ LS1X_IRQ(0, 6) -#define LS1X_CAN1_IRQ LS1X_IRQ(0, 7) -#define LS1X_SPI0_IRQ LS1X_IRQ(0, 8) -#define LS1X_SPI1_IRQ LS1X_IRQ(0, 9) -#define LS1X_AC97_IRQ LS1X_IRQ(0, 10) -#define LS1X_DMA0_IRQ LS1X_IRQ(0, 13) -#define LS1X_DMA1_IRQ LS1X_IRQ(0, 14) -#define LS1X_DMA2_IRQ LS1X_IRQ(0, 15) -#define LS1X_PWM0_IRQ LS1X_IRQ(0, 17) -#define LS1X_PWM1_IRQ LS1X_IRQ(0, 18) -#define LS1X_PWM2_IRQ LS1X_IRQ(0, 19) -#define LS1X_PWM3_IRQ LS1X_IRQ(0, 20) -#define LS1X_RTC_INT0_IRQ LS1X_IRQ(0, 21) -#define LS1X_RTC_INT1_IRQ LS1X_IRQ(0, 22) -#define LS1X_RTC_INT2_IRQ LS1X_IRQ(0, 23) -#define LS1X_TOY_INT0_IRQ LS1X_IRQ(0, 24) -#define LS1X_TOY_INT1_IRQ LS1X_IRQ(0, 25) -#define LS1X_TOY_INT2_IRQ LS1X_IRQ(0, 26) -#define LS1X_RTC_TICK_IRQ LS1X_IRQ(0, 27) -#define LS1X_TOY_TICK_IRQ LS1X_IRQ(0, 28) - -#define LS1X_EHCI_IRQ LS1X_IRQ(1, 0) -#define LS1X_OHCI_IRQ LS1X_IRQ(1, 1) -#define LS1X_GMAC0_IRQ LS1X_IRQ(1, 2) -#define LS1X_GMAC1_IRQ LS1X_IRQ(1, 3) - -#define LS1X_IRQS (LS1X_IRQ(4, 31) + 1 - LS1X_IRQ_BASE) - -#define NR_IRQS (MIPS_CPU_IRQS + LS1X_IRQS) - -#endif /* __ASM_MACH_LOONGSON1_IRQ_H */ diff --git a/arch/mips/include/asm/mach-loongson1/loongson1.h b/arch/mips/include/asm/mach-loongson1/loongson1.h deleted file mode 100644 index 20e0c2b155dd..000000000000 --- a/arch/mips/include/asm/mach-loongson1/loongson1.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2011 Zhang, Keguang - * - * Register mappings for Loongson 1 - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - - -#ifndef __ASM_MACH_LOONGSON1_LOONGSON1_H -#define __ASM_MACH_LOONGSON1_LOONGSON1_H - -#define DEFAULT_MEMSIZE 256 /* If no memsize provided */ - -/* Loongson 1 Register Bases */ -#define LS1X_MUX_BASE 0x1fd00420 -#define LS1X_INTC_BASE 0x1fd01040 -#define LS1X_EHCI_BASE 0x1fe00000 -#define LS1X_OHCI_BASE 0x1fe08000 -#define LS1X_GMAC0_BASE 0x1fe10000 -#define LS1X_GMAC1_BASE 0x1fe20000 - -#define LS1X_UART0_BASE 0x1fe40000 -#define LS1X_UART1_BASE 0x1fe44000 -#define LS1X_UART2_BASE 0x1fe48000 -#define LS1X_UART3_BASE 0x1fe4c000 -#define LS1X_CAN0_BASE 0x1fe50000 -#define LS1X_CAN1_BASE 0x1fe54000 -#define LS1X_I2C0_BASE 0x1fe58000 -#define LS1X_I2C1_BASE 0x1fe68000 -#define LS1X_I2C2_BASE 0x1fe70000 -#define LS1X_PWM0_BASE 0x1fe5c000 -#define LS1X_PWM1_BASE 0x1fe5c010 -#define LS1X_PWM2_BASE 0x1fe5c020 -#define LS1X_PWM3_BASE 0x1fe5c030 -#define LS1X_WDT_BASE 0x1fe5c060 -#define LS1X_RTC_BASE 0x1fe64000 -#define LS1X_AC97_BASE 0x1fe74000 -#define LS1X_NAND_BASE 0x1fe78000 -#define LS1X_CLK_BASE 0x1fe78030 - -#include -#include -#include -#include - -#endif /* __ASM_MACH_LOONGSON1_LOONGSON1_H */ diff --git a/arch/mips/include/asm/mach-loongson1/platform.h b/arch/mips/include/asm/mach-loongson1/platform.h deleted file mode 100644 index 47de55e0c835..000000000000 --- a/arch/mips/include/asm/mach-loongson1/platform.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2011 Zhang, Keguang - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - - -#ifndef __ASM_MACH_LOONGSON1_PLATFORM_H -#define __ASM_MACH_LOONGSON1_PLATFORM_H - -#include - -extern struct platform_device ls1x_uart_pdev; -extern struct platform_device ls1x_cpufreq_pdev; -extern struct platform_device ls1x_eth0_pdev; -extern struct platform_device ls1x_eth1_pdev; -extern struct platform_device ls1x_ehci_pdev; -extern struct platform_device ls1x_rtc_pdev; - -extern void __init ls1x_clk_init(void); -extern void __init ls1x_serial_setup(struct platform_device *pdev); - -#endif /* __ASM_MACH_LOONGSON1_PLATFORM_H */ diff --git a/arch/mips/include/asm/mach-loongson1/prom.h b/arch/mips/include/asm/mach-loongson1/prom.h deleted file mode 100644 index 34859a4d4ac4..000000000000 --- a/arch/mips/include/asm/mach-loongson1/prom.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2011 Zhang, Keguang - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#ifndef __ASM_MACH_LOONGSON1_PROM_H -#define __ASM_MACH_LOONGSON1_PROM_H - -#include -#include -#include - -/* environment arguments from bootloader */ -extern unsigned long memsize, highmemsize; - -/* loongson-specific command line, env and memory initialization */ -extern char *prom_getenv(char *name); -extern void __init prom_init_cmdline(void); - -#endif /* __ASM_MACH_LOONGSON1_PROM_H */ diff --git a/arch/mips/include/asm/mach-loongson1/regs-clk.h b/arch/mips/include/asm/mach-loongson1/regs-clk.h deleted file mode 100644 index ee2445b10fc3..000000000000 --- a/arch/mips/include/asm/mach-loongson1/regs-clk.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2011 Zhang, Keguang - * - * Loongson 1 Clock Register Definitions. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#ifndef __ASM_MACH_LOONGSON1_REGS_CLK_H -#define __ASM_MACH_LOONGSON1_REGS_CLK_H - -#define LS1X_CLK_REG(x) \ - ((void __iomem *)KSEG1ADDR(LS1X_CLK_BASE + (x))) - -#define LS1X_CLK_PLL_FREQ LS1X_CLK_REG(0x0) -#define LS1X_CLK_PLL_DIV LS1X_CLK_REG(0x4) - -/* Clock PLL Divisor Register Bits */ -#define DIV_DC_EN (0x1 << 31) -#define DIV_DC_RST (0x1 << 30) -#define DIV_CPU_EN (0x1 << 25) -#define DIV_CPU_RST (0x1 << 24) -#define DIV_DDR_EN (0x1 << 19) -#define DIV_DDR_RST (0x1 << 18) -#define RST_DC_EN (0x1 << 5) -#define RST_DC (0x1 << 4) -#define RST_DDR_EN (0x1 << 3) -#define RST_DDR (0x1 << 2) -#define RST_CPU_EN (0x1 << 1) -#define RST_CPU 0x1 - -#define DIV_DC_SHIFT 26 -#define DIV_CPU_SHIFT 20 -#define DIV_DDR_SHIFT 14 - -#define DIV_DC_WIDTH 4 -#define DIV_CPU_WIDTH 4 -#define DIV_DDR_WIDTH 4 - -#define BYPASS_DC_SHIFT 12 -#define BYPASS_DDR_SHIFT 10 -#define BYPASS_CPU_SHIFT 8 - -#define BYPASS_DC_WIDTH 1 -#define BYPASS_DDR_WIDTH 1 -#define BYPASS_CPU_WIDTH 1 - -#endif /* __ASM_MACH_LOONGSON1_REGS_CLK_H */ diff --git a/arch/mips/include/asm/mach-loongson1/regs-mux.h b/arch/mips/include/asm/mach-loongson1/regs-mux.h deleted file mode 100644 index fb1e36efaa19..000000000000 --- a/arch/mips/include/asm/mach-loongson1/regs-mux.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2014 Zhang, Keguang - * - * Loongson 1 MUX Register Definitions. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#ifndef __ASM_MACH_LOONGSON1_REGS_MUX_H -#define __ASM_MACH_LOONGSON1_REGS_MUX_H - -#define LS1X_MUX_REG(x) \ - ((void __iomem *)KSEG1ADDR(LS1X_MUX_BASE + (x))) - -#define LS1X_MUX_CTRL0 LS1X_MUX_REG(0x0) -#define LS1X_MUX_CTRL1 LS1X_MUX_REG(0x4) - -/* MUX CTRL0 Register Bits */ -#define UART0_USE_PWM23 (0x1 << 28) -#define UART0_USE_PWM01 (0x1 << 27) -#define UART1_USE_LCD0_5_6_11 (0x1 << 26) -#define I2C2_USE_CAN1 (0x1 << 25) -#define I2C1_USE_CAN0 (0x1 << 24) -#define NAND3_USE_UART5 (0x1 << 23) -#define NAND3_USE_UART4 (0x1 << 22) -#define NAND3_USE_UART1_DAT (0x1 << 21) -#define NAND3_USE_UART1_CTS (0x1 << 20) -#define NAND3_USE_PWM23 (0x1 << 19) -#define NAND3_USE_PWM01 (0x1 << 18) -#define NAND2_USE_UART5 (0x1 << 17) -#define NAND2_USE_UART4 (0x1 << 16) -#define NAND2_USE_UART1_DAT (0x1 << 15) -#define NAND2_USE_UART1_CTS (0x1 << 14) -#define NAND2_USE_PWM23 (0x1 << 13) -#define NAND2_USE_PWM01 (0x1 << 12) -#define NAND1_USE_UART5 (0x1 << 11) -#define NAND1_USE_UART4 (0x1 << 10) -#define NAND1_USE_UART1_DAT (0x1 << 9) -#define NAND1_USE_UART1_CTS (0x1 << 8) -#define NAND1_USE_PWM23 (0x1 << 7) -#define NAND1_USE_PWM01 (0x1 << 6) -#define GMAC1_USE_UART1 (0x1 << 4) -#define GMAC1_USE_UART0 (0x1 << 3) -#define LCD_USE_UART0_DAT (0x1 << 2) -#define LCD_USE_UART15 (0x1 << 1) -#define LCD_USE_UART0 0x1 - -/* MUX CTRL1 Register Bits */ -#define USB_RESET (0x1 << 31) -#define SPI1_CS_USE_PWM01 (0x1 << 24) -#define SPI1_USE_CAN (0x1 << 23) -#define DISABLE_DDR_CONFSPACE (0x1 << 20) -#define DDR32TO16EN (0x1 << 16) -#define GMAC1_SHUT (0x1 << 13) -#define GMAC0_SHUT (0x1 << 12) -#define USB_SHUT (0x1 << 11) -#define UART1_3_USE_CAN1 (0x1 << 5) -#define UART1_2_USE_CAN0 (0x1 << 4) -#define GMAC1_USE_TXCLK (0x1 << 3) -#define GMAC0_USE_TXCLK (0x1 << 2) -#define GMAC1_USE_PWM23 (0x1 << 1) -#define GMAC0_USE_PWM01 0x1 - -#endif /* __ASM_MACH_LOONGSON1_REGS_MUX_H */ diff --git a/arch/mips/include/asm/mach-loongson1/regs-pwm.h b/arch/mips/include/asm/mach-loongson1/regs-pwm.h deleted file mode 100644 index 99f2bcc586f0..000000000000 --- a/arch/mips/include/asm/mach-loongson1/regs-pwm.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2014 Zhang, Keguang - * - * Loongson 1 PWM Register Definitions. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#ifndef __ASM_MACH_LOONGSON1_REGS_PWM_H -#define __ASM_MACH_LOONGSON1_REGS_PWM_H - -/* Loongson 1 PWM Timer Register Definitions */ -#define PWM_CNT 0x0 -#define PWM_HRC 0x4 -#define PWM_LRC 0x8 -#define PWM_CTRL 0xc - -/* PWM Control Register Bits */ -#define CNT_RST (0x1 << 7) -#define INT_SR (0x1 << 6) -#define INT_EN (0x1 << 5) -#define PWM_SINGLE (0x1 << 4) -#define PWM_OE (0x1 << 3) -#define CNT_EN 0x1 - -#endif /* __ASM_MACH_LOONGSON1_REGS_PWM_H */ diff --git a/arch/mips/include/asm/mach-loongson1/regs-wdt.h b/arch/mips/include/asm/mach-loongson1/regs-wdt.h deleted file mode 100644 index c39ee982ad3b..000000000000 --- a/arch/mips/include/asm/mach-loongson1/regs-wdt.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2011 Zhang, Keguang - * - * Loongson 1 Watchdog Register Definitions. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#ifndef __ASM_MACH_LOONGSON1_REGS_WDT_H -#define __ASM_MACH_LOONGSON1_REGS_WDT_H - -#define WDT_EN 0x0 -#define WDT_TIMER 0x4 -#define WDT_SET 0x8 - -#endif /* __ASM_MACH_LOONGSON1_REGS_WDT_H */ diff --git a/arch/mips/include/asm/mach-loongson32/cpufreq.h b/arch/mips/include/asm/mach-loongson32/cpufreq.h new file mode 100644 index 000000000000..6843fa1a608d --- /dev/null +++ b/arch/mips/include/asm/mach-loongson32/cpufreq.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2014 Zhang, Keguang + * + * Loongson 1 CPUFreq platform support. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + + +#ifndef __ASM_MACH_LOONGSON32_CPUFREQ_H +#define __ASM_MACH_LOONGSON32_CPUFREQ_H + +struct plat_ls1x_cpufreq { + const char *clk_name; /* CPU clk */ + const char *osc_clk_name; /* OSC clk */ + unsigned int max_freq; /* in kHz */ + unsigned int min_freq; /* in kHz */ +}; + +#endif /* __ASM_MACH_LOONGSON32_CPUFREQ_H */ diff --git a/arch/mips/include/asm/mach-loongson32/irq.h b/arch/mips/include/asm/mach-loongson32/irq.h new file mode 100644 index 000000000000..0d35b994e8d2 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson32/irq.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2011 Zhang, Keguang + * + * IRQ mappings for Loongson 1 + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + + +#ifndef __ASM_MACH_LOONGSON32_IRQ_H +#define __ASM_MACH_LOONGSON32_IRQ_H + +/* + * CPU core Interrupt Numbers + */ +#define MIPS_CPU_IRQ_BASE 0 +#define MIPS_CPU_IRQ(x) (MIPS_CPU_IRQ_BASE + (x)) + +#define SOFTINT0_IRQ MIPS_CPU_IRQ(0) +#define SOFTINT1_IRQ MIPS_CPU_IRQ(1) +#define INT0_IRQ MIPS_CPU_IRQ(2) +#define INT1_IRQ MIPS_CPU_IRQ(3) +#define INT2_IRQ MIPS_CPU_IRQ(4) +#define INT3_IRQ MIPS_CPU_IRQ(5) +#define INT4_IRQ MIPS_CPU_IRQ(6) +#define TIMER_IRQ MIPS_CPU_IRQ(7) /* cpu timer */ + +#define MIPS_CPU_IRQS (MIPS_CPU_IRQ(7) + 1 - MIPS_CPU_IRQ_BASE) + +/* + * INT0~3 Interrupt Numbers + */ +#define LS1X_IRQ_BASE MIPS_CPU_IRQS +#define LS1X_IRQ(n, x) (LS1X_IRQ_BASE + (n << 5) + (x)) + +#define LS1X_UART0_IRQ LS1X_IRQ(0, 2) +#define LS1X_UART1_IRQ LS1X_IRQ(0, 3) +#define LS1X_UART2_IRQ LS1X_IRQ(0, 4) +#define LS1X_UART3_IRQ LS1X_IRQ(0, 5) +#define LS1X_CAN0_IRQ LS1X_IRQ(0, 6) +#define LS1X_CAN1_IRQ LS1X_IRQ(0, 7) +#define LS1X_SPI0_IRQ LS1X_IRQ(0, 8) +#define LS1X_SPI1_IRQ LS1X_IRQ(0, 9) +#define LS1X_AC97_IRQ LS1X_IRQ(0, 10) +#define LS1X_DMA0_IRQ LS1X_IRQ(0, 13) +#define LS1X_DMA1_IRQ LS1X_IRQ(0, 14) +#define LS1X_DMA2_IRQ LS1X_IRQ(0, 15) +#define LS1X_PWM0_IRQ LS1X_IRQ(0, 17) +#define LS1X_PWM1_IRQ LS1X_IRQ(0, 18) +#define LS1X_PWM2_IRQ LS1X_IRQ(0, 19) +#define LS1X_PWM3_IRQ LS1X_IRQ(0, 20) +#define LS1X_RTC_INT0_IRQ LS1X_IRQ(0, 21) +#define LS1X_RTC_INT1_IRQ LS1X_IRQ(0, 22) +#define LS1X_RTC_INT2_IRQ LS1X_IRQ(0, 23) +#define LS1X_TOY_INT0_IRQ LS1X_IRQ(0, 24) +#define LS1X_TOY_INT1_IRQ LS1X_IRQ(0, 25) +#define LS1X_TOY_INT2_IRQ LS1X_IRQ(0, 26) +#define LS1X_RTC_TICK_IRQ LS1X_IRQ(0, 27) +#define LS1X_TOY_TICK_IRQ LS1X_IRQ(0, 28) + +#define LS1X_EHCI_IRQ LS1X_IRQ(1, 0) +#define LS1X_OHCI_IRQ LS1X_IRQ(1, 1) +#define LS1X_GMAC0_IRQ LS1X_IRQ(1, 2) +#define LS1X_GMAC1_IRQ LS1X_IRQ(1, 3) + +#define LS1X_IRQS (LS1X_IRQ(4, 31) + 1 - LS1X_IRQ_BASE) + +#define NR_IRQS (MIPS_CPU_IRQS + LS1X_IRQS) + +#endif /* __ASM_MACH_LOONGSON32_IRQ_H */ diff --git a/arch/mips/include/asm/mach-loongson32/loongson1.h b/arch/mips/include/asm/mach-loongson32/loongson1.h new file mode 100644 index 000000000000..12aa129aad80 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson32/loongson1.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2011 Zhang, Keguang + * + * Register mappings for Loongson 1 + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + + +#ifndef __ASM_MACH_LOONGSON32_LOONGSON1_H +#define __ASM_MACH_LOONGSON32_LOONGSON1_H + +#define DEFAULT_MEMSIZE 256 /* If no memsize provided */ + +/* Loongson 1 Register Bases */ +#define LS1X_MUX_BASE 0x1fd00420 +#define LS1X_INTC_BASE 0x1fd01040 +#define LS1X_EHCI_BASE 0x1fe00000 +#define LS1X_OHCI_BASE 0x1fe08000 +#define LS1X_GMAC0_BASE 0x1fe10000 +#define LS1X_GMAC1_BASE 0x1fe20000 + +#define LS1X_UART0_BASE 0x1fe40000 +#define LS1X_UART1_BASE 0x1fe44000 +#define LS1X_UART2_BASE 0x1fe48000 +#define LS1X_UART3_BASE 0x1fe4c000 +#define LS1X_CAN0_BASE 0x1fe50000 +#define LS1X_CAN1_BASE 0x1fe54000 +#define LS1X_I2C0_BASE 0x1fe58000 +#define LS1X_I2C1_BASE 0x1fe68000 +#define LS1X_I2C2_BASE 0x1fe70000 +#define LS1X_PWM0_BASE 0x1fe5c000 +#define LS1X_PWM1_BASE 0x1fe5c010 +#define LS1X_PWM2_BASE 0x1fe5c020 +#define LS1X_PWM3_BASE 0x1fe5c030 +#define LS1X_WDT_BASE 0x1fe5c060 +#define LS1X_RTC_BASE 0x1fe64000 +#define LS1X_AC97_BASE 0x1fe74000 +#define LS1X_NAND_BASE 0x1fe78000 +#define LS1X_CLK_BASE 0x1fe78030 + +#include +#include +#include +#include + +#endif /* __ASM_MACH_LOONGSON32_LOONGSON1_H */ diff --git a/arch/mips/include/asm/mach-loongson32/platform.h b/arch/mips/include/asm/mach-loongson32/platform.h new file mode 100644 index 000000000000..c32f03f3f72c --- /dev/null +++ b/arch/mips/include/asm/mach-loongson32/platform.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2011 Zhang, Keguang + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + + +#ifndef __ASM_MACH_LOONGSON32_PLATFORM_H +#define __ASM_MACH_LOONGSON32_PLATFORM_H + +#include + +extern struct platform_device ls1x_uart_pdev; +extern struct platform_device ls1x_cpufreq_pdev; +extern struct platform_device ls1x_eth0_pdev; +extern struct platform_device ls1x_eth1_pdev; +extern struct platform_device ls1x_ehci_pdev; +extern struct platform_device ls1x_rtc_pdev; + +extern void __init ls1x_clk_init(void); +extern void __init ls1x_serial_setup(struct platform_device *pdev); + +#endif /* __ASM_MACH_LOONGSON32_PLATFORM_H */ diff --git a/arch/mips/include/asm/mach-loongson32/prom.h b/arch/mips/include/asm/mach-loongson32/prom.h new file mode 100644 index 000000000000..a08503c0ba20 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson32/prom.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2011 Zhang, Keguang + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __ASM_MACH_LOONGSON32_PROM_H +#define __ASM_MACH_LOONGSON32_PROM_H + +#include +#include +#include + +/* environment arguments from bootloader */ +extern unsigned long memsize, highmemsize; + +/* loongson-specific command line, env and memory initialization */ +extern char *prom_getenv(char *name); +extern void __init prom_init_cmdline(void); + +#endif /* __ASM_MACH_LOONGSON32_PROM_H */ diff --git a/arch/mips/include/asm/mach-loongson32/regs-clk.h b/arch/mips/include/asm/mach-loongson32/regs-clk.h new file mode 100644 index 000000000000..1f5a715ac841 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson32/regs-clk.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2011 Zhang, Keguang + * + * Loongson 1 Clock Register Definitions. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __ASM_MACH_LOONGSON32_REGS_CLK_H +#define __ASM_MACH_LOONGSON32_REGS_CLK_H + +#define LS1X_CLK_REG(x) \ + ((void __iomem *)KSEG1ADDR(LS1X_CLK_BASE + (x))) + +#define LS1X_CLK_PLL_FREQ LS1X_CLK_REG(0x0) +#define LS1X_CLK_PLL_DIV LS1X_CLK_REG(0x4) + +/* Clock PLL Divisor Register Bits */ +#define DIV_DC_EN (0x1 << 31) +#define DIV_DC_RST (0x1 << 30) +#define DIV_CPU_EN (0x1 << 25) +#define DIV_CPU_RST (0x1 << 24) +#define DIV_DDR_EN (0x1 << 19) +#define DIV_DDR_RST (0x1 << 18) +#define RST_DC_EN (0x1 << 5) +#define RST_DC (0x1 << 4) +#define RST_DDR_EN (0x1 << 3) +#define RST_DDR (0x1 << 2) +#define RST_CPU_EN (0x1 << 1) +#define RST_CPU 0x1 + +#define DIV_DC_SHIFT 26 +#define DIV_CPU_SHIFT 20 +#define DIV_DDR_SHIFT 14 + +#define DIV_DC_WIDTH 4 +#define DIV_CPU_WIDTH 4 +#define DIV_DDR_WIDTH 4 + +#define BYPASS_DC_SHIFT 12 +#define BYPASS_DDR_SHIFT 10 +#define BYPASS_CPU_SHIFT 8 + +#define BYPASS_DC_WIDTH 1 +#define BYPASS_DDR_WIDTH 1 +#define BYPASS_CPU_WIDTH 1 + +#endif /* __ASM_MACH_LOONGSON32_REGS_CLK_H */ diff --git a/arch/mips/include/asm/mach-loongson32/regs-mux.h b/arch/mips/include/asm/mach-loongson32/regs-mux.h new file mode 100644 index 000000000000..8302d92f2da2 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson32/regs-mux.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2014 Zhang, Keguang + * + * Loongson 1 MUX Register Definitions. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __ASM_MACH_LOONGSON32_REGS_MUX_H +#define __ASM_MACH_LOONGSON32_REGS_MUX_H + +#define LS1X_MUX_REG(x) \ + ((void __iomem *)KSEG1ADDR(LS1X_MUX_BASE + (x))) + +#define LS1X_MUX_CTRL0 LS1X_MUX_REG(0x0) +#define LS1X_MUX_CTRL1 LS1X_MUX_REG(0x4) + +/* MUX CTRL0 Register Bits */ +#define UART0_USE_PWM23 (0x1 << 28) +#define UART0_USE_PWM01 (0x1 << 27) +#define UART1_USE_LCD0_5_6_11 (0x1 << 26) +#define I2C2_USE_CAN1 (0x1 << 25) +#define I2C1_USE_CAN0 (0x1 << 24) +#define NAND3_USE_UART5 (0x1 << 23) +#define NAND3_USE_UART4 (0x1 << 22) +#define NAND3_USE_UART1_DAT (0x1 << 21) +#define NAND3_USE_UART1_CTS (0x1 << 20) +#define NAND3_USE_PWM23 (0x1 << 19) +#define NAND3_USE_PWM01 (0x1 << 18) +#define NAND2_USE_UART5 (0x1 << 17) +#define NAND2_USE_UART4 (0x1 << 16) +#define NAND2_USE_UART1_DAT (0x1 << 15) +#define NAND2_USE_UART1_CTS (0x1 << 14) +#define NAND2_USE_PWM23 (0x1 << 13) +#define NAND2_USE_PWM01 (0x1 << 12) +#define NAND1_USE_UART5 (0x1 << 11) +#define NAND1_USE_UART4 (0x1 << 10) +#define NAND1_USE_UART1_DAT (0x1 << 9) +#define NAND1_USE_UART1_CTS (0x1 << 8) +#define NAND1_USE_PWM23 (0x1 << 7) +#define NAND1_USE_PWM01 (0x1 << 6) +#define GMAC1_USE_UART1 (0x1 << 4) +#define GMAC1_USE_UART0 (0x1 << 3) +#define LCD_USE_UART0_DAT (0x1 << 2) +#define LCD_USE_UART15 (0x1 << 1) +#define LCD_USE_UART0 0x1 + +/* MUX CTRL1 Register Bits */ +#define USB_RESET (0x1 << 31) +#define SPI1_CS_USE_PWM01 (0x1 << 24) +#define SPI1_USE_CAN (0x1 << 23) +#define DISABLE_DDR_CONFSPACE (0x1 << 20) +#define DDR32TO16EN (0x1 << 16) +#define GMAC1_SHUT (0x1 << 13) +#define GMAC0_SHUT (0x1 << 12) +#define USB_SHUT (0x1 << 11) +#define UART1_3_USE_CAN1 (0x1 << 5) +#define UART1_2_USE_CAN0 (0x1 << 4) +#define GMAC1_USE_TXCLK (0x1 << 3) +#define GMAC0_USE_TXCLK (0x1 << 2) +#define GMAC1_USE_PWM23 (0x1 << 1) +#define GMAC0_USE_PWM01 0x1 + +#endif /* __ASM_MACH_LOONGSON32_REGS_MUX_H */ diff --git a/arch/mips/include/asm/mach-loongson32/regs-pwm.h b/arch/mips/include/asm/mach-loongson32/regs-pwm.h new file mode 100644 index 000000000000..69f174ed13a4 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson32/regs-pwm.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2014 Zhang, Keguang + * + * Loongson 1 PWM Register Definitions. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __ASM_MACH_LOONGSON32_REGS_PWM_H +#define __ASM_MACH_LOONGSON32_REGS_PWM_H + +/* Loongson 1 PWM Timer Register Definitions */ +#define PWM_CNT 0x0 +#define PWM_HRC 0x4 +#define PWM_LRC 0x8 +#define PWM_CTRL 0xc + +/* PWM Control Register Bits */ +#define CNT_RST (0x1 << 7) +#define INT_SR (0x1 << 6) +#define INT_EN (0x1 << 5) +#define PWM_SINGLE (0x1 << 4) +#define PWM_OE (0x1 << 3) +#define CNT_EN 0x1 + +#endif /* __ASM_MACH_LOONGSON32_REGS_PWM_H */ diff --git a/arch/mips/include/asm/mach-loongson32/regs-wdt.h b/arch/mips/include/asm/mach-loongson32/regs-wdt.h new file mode 100644 index 000000000000..6644ab6d3391 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson32/regs-wdt.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2011 Zhang, Keguang + * + * Loongson 1 Watchdog Register Definitions. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __ASM_MACH_LOONGSON32_REGS_WDT_H +#define __ASM_MACH_LOONGSON32_REGS_WDT_H + +#define WDT_EN 0x0 +#define WDT_TIMER 0x4 +#define WDT_SET 0x8 + +#endif /* __ASM_MACH_LOONGSON32_REGS_WDT_H */ diff --git a/arch/mips/include/asm/mach-loongson64/boot_param.h b/arch/mips/include/asm/mach-loongson64/boot_param.h new file mode 100644 index 000000000000..d3f3258b7cd4 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/boot_param.h @@ -0,0 +1,210 @@ +#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 MEM_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 { + Loongson_2E = 0, + Loongson_2F = 1, + Loongson_3A = 2, + Loongson_3B = 3, + Loongson_1A = 4, + Loongson_1B = 5 +}; + +/* + * 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 diff --git a/arch/mips/include/asm/mach-loongson64/cpu-feature-overrides.h b/arch/mips/include/asm/mach-loongson64/cpu-feature-overrides.h new file mode 100644 index 000000000000..98963c2c7be4 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/cpu-feature-overrides.h @@ -0,0 +1,61 @@ +/* + * 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 + * Copyright (C) 2009 Philippe Vachon + * Copyright (C) 2009 Zhang Le + * + * 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_dcache_line_size() 32 +#define cpu_icache_line_size() 32 +#define cpu_scache_line_size() 32 + + +#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_dsp 0 +#define cpu_has_dsp2 0 +#define cpu_has_ejtag 0 +#define cpu_has_ic_fills_f_dc 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_mips32r2 0 +#define cpu_has_mips3d 0 +#define cpu_has_mips64r2 0 +#define cpu_has_mipsmt 0 +#define cpu_has_prefetch 0 +#define cpu_has_smartmips 0 +#define cpu_has_tlb 1 +#define cpu_has_tx39_cache 0 +#define cpu_has_userlocal 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 +#define cpu_has_local_ebase 0 + +#define cpu_has_wsbh IS_ENABLED(CONFIG_CPU_LOONGSON3) + +#endif /* __ASM_MACH_LOONGSON64_CPU_FEATURE_OVERRIDES_H */ diff --git a/arch/mips/include/asm/mach-loongson64/cs5536/cs5536.h b/arch/mips/include/asm/mach-loongson64/cs5536/cs5536.h new file mode 100644 index 000000000000..a0ee0cb775ad --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/cs5536/cs5536.h @@ -0,0 +1,305 @@ +/* + * The header file of cs5536 south bridge. + * + * Copyright (C) 2007 Lemote, Inc. + * Author : jlliu + */ + +#ifndef _CS5536_H +#define _CS5536_H + +#include + +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 */ diff --git a/arch/mips/include/asm/mach-loongson64/cs5536/cs5536_mfgpt.h b/arch/mips/include/asm/mach-loongson64/cs5536/cs5536_mfgpt.h new file mode 100644 index 000000000000..021d0172dad6 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/cs5536/cs5536_mfgpt.h @@ -0,0 +1,35 @@ +/* + * cs5536 mfgpt header file + */ + +#ifndef _CS5536_MFGPT_H +#define _CS5536_MFGPT_H + +#include +#include + +#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 */ diff --git a/arch/mips/include/asm/mach-loongson64/cs5536/cs5536_pci.h b/arch/mips/include/asm/mach-loongson64/cs5536/cs5536_pci.h new file mode 100644 index 000000000000..8a7ecb4d5c64 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/cs5536/cs5536_pci.h @@ -0,0 +1,153 @@ +/* + * 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 +#include + +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_COUNT 6 +#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_ */ diff --git a/arch/mips/include/asm/mach-loongson64/cs5536/cs5536_vsm.h b/arch/mips/include/asm/mach-loongson64/cs5536/cs5536_vsm.h new file mode 100644 index 000000000000..1f17c1815ee5 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/cs5536/cs5536_vsm.h @@ -0,0 +1,31 @@ +/* + * the read/write interfaces for Virtual Support Module(VSM) + * + * Copyright (C) 2009 Lemote, Inc. + * Author: Wu Zhangjin + */ + +#ifndef _CS5536_VSM_H +#define _CS5536_VSM_H + +#include + +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 */ diff --git a/arch/mips/include/asm/mach-loongson64/dma-coherence.h b/arch/mips/include/asm/mach-loongson64/dma-coherence.h new file mode 100644 index 000000000000..1602a9e9e8c2 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/dma-coherence.h @@ -0,0 +1,85 @@ +/* + * 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) 2006, 07 Ralf Baechle + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + */ +#ifndef __ASM_MACH_LOONGSON64_DMA_COHERENCE_H +#define __ASM_MACH_LOONGSON64_DMA_COHERENCE_H + +#ifdef CONFIG_SWIOTLB +#include +#endif + +struct device; + +extern dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr); +extern phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr); +static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, + size_t size) +{ +#ifdef CONFIG_CPU_LOONGSON3 + return phys_to_dma(dev, virt_to_phys(addr)); +#else + return virt_to_phys(addr) | 0x80000000; +#endif +} + +static inline dma_addr_t plat_map_dma_mem_page(struct device *dev, + struct page *page) +{ +#ifdef CONFIG_CPU_LOONGSON3 + return phys_to_dma(dev, page_to_phys(page)); +#else + return page_to_phys(page) | 0x80000000; +#endif +} + +static inline unsigned long plat_dma_addr_to_phys(struct device *dev, + dma_addr_t dma_addr) +{ +#if defined(CONFIG_CPU_LOONGSON3) && defined(CONFIG_64BIT) + return dma_to_phys(dev, dma_addr); +#elif defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) + return (dma_addr > 0x8fffffff) ? dma_addr : (dma_addr & 0x0fffffff); +#else + return dma_addr & 0x7fffffff; +#endif +} + +static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr, + size_t size, enum dma_data_direction direction) +{ +} + +static inline int plat_dma_supported(struct device *dev, u64 mask) +{ + /* + * we fall back to GFP_DMA when the mask isn't all 1s, + * so we can't guarantee allocations that must be + * within a tighter range than GFP_DMA.. + */ + if (mask < DMA_BIT_MASK(24)) + return 0; + + return 1; +} + +static inline int plat_device_is_coherent(struct device *dev) +{ +#ifdef CONFIG_DMA_NONCOHERENT + return 0; +#else + return 1; +#endif /* CONFIG_DMA_NONCOHERENT */ +} + +static inline void plat_post_dma_flush(struct device *dev) +{ +} + +#endif /* __ASM_MACH_LOONGSON64_DMA_COHERENCE_H */ diff --git a/arch/mips/include/asm/mach-loongson64/gpio.h b/arch/mips/include/asm/mach-loongson64/gpio.h new file mode 100644 index 000000000000..b3b216904a9a --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/gpio.h @@ -0,0 +1,36 @@ +/* + * Loongson GPIO Support + * + * Copyright (c) 2008 Richard Liu, STMicroelectronics + * Copyright (c) 2008-2010 Arnaud Patard + * Copyright (c) 2014 Huacai Chen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __LOONGSON_GPIO_H +#define __LOONGSON_GPIO_H + +#include + +#define gpio_get_value __gpio_get_value +#define gpio_set_value __gpio_set_value +#define gpio_cansleep __gpio_cansleep + +/* The chip can do interrupt + * but it has not been tested and doc not clear + */ +static inline int gpio_to_irq(int gpio) +{ + return -EINVAL; +} + +static inline int irq_to_gpio(int gpio) +{ + return -EINVAL; +} + +#endif /* __LOONGSON_GPIO_H */ diff --git a/arch/mips/include/asm/mach-loongson64/irq.h b/arch/mips/include/asm/mach-loongson64/irq.h new file mode 100644 index 000000000000..d18c45c7c394 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/irq.h @@ -0,0 +1,43 @@ +#ifndef __ASM_MACH_LOONGSON64_IRQ_H_ +#define __ASM_MACH_LOONGSON64_IRQ_H_ + +#include + +#ifdef CONFIG_CPU_LOONGSON3 + +/* cpu core interrupt numbers */ +#define MIPS_CPU_IRQ_BASE 56 + +#define LOONGSON_UART_IRQ (MIPS_CPU_IRQ_BASE + 2) /* UART */ +#define LOONGSON_HT1_IRQ (MIPS_CPU_IRQ_BASE + 3) /* HT1 */ +#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 +#endif /* __ASM_MACH_LOONGSON64_IRQ_H_ */ diff --git a/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h b/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h new file mode 100644 index 000000000000..3f2f84f6c401 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h @@ -0,0 +1,52 @@ +/* + * 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 + +/* + * Override macros used in arch/mips/kernel/head.S. + */ + .macro kernel_entry_setup +#ifdef CONFIG_CPU_LOONGSON3 + .set push + .set mips64 + /* Set LPA on LOONGSON3 config3 */ + mfc0 t0, $16, 3 + or t0, (0x1 << 7) + mtc0 t0, $16, 3 + /* Set ELPA on LOONGSON3 pagegrain */ + li t0, (0x1 << 29) + mtc0 t0, $5, 1 + _ehb + .set pop +#endif + .endm + +/* + * Do SMP slave processor setup. + */ + .macro smp_slave_setup +#ifdef CONFIG_CPU_LOONGSON3 + .set push + .set mips64 + /* Set LPA on LOONGSON3 config3 */ + mfc0 t0, $16, 3 + or t0, (0x1 << 7) + mtc0 t0, $16, 3 + /* Set ELPA on LOONGSON3 pagegrain */ + li t0, (0x1 << 29) + mtc0 t0, $5, 1 + _ehb + .set pop +#endif + .endm + +#endif /* __ASM_MACH_LOONGSON64_KERNEL_ENTRY_H */ diff --git a/arch/mips/include/asm/mach-loongson64/loongson.h b/arch/mips/include/asm/mach-loongson64/loongson.h new file mode 100644 index 000000000000..d1ff774ac4b6 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/loongson.h @@ -0,0 +1,360 @@ +/* + * Copyright (C) 2009 Lemote, Inc. + * Author: Wu Zhangjin + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __ASM_MACH_LOONGSON64_LOONGSON_H +#define __ASM_MACH_LOONGSON64_LOONGSON_H + +#include +#include +#include +#include +#include + +/* 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 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 +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) + +#if defined(CONFIG_HT_PCI) +#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 +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 */ diff --git a/arch/mips/include/asm/mach-loongson64/loongson_hwmon.h b/arch/mips/include/asm/mach-loongson64/loongson_hwmon.h new file mode 100644 index 000000000000..4431fc54a36c --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/loongson_hwmon.h @@ -0,0 +1,55 @@ +#ifndef __LOONGSON_HWMON_H_ +#define __LOONGSON_HWMON_H_ + +#include + +#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 constent 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_*/ diff --git a/arch/mips/include/asm/mach-loongson64/machine.h b/arch/mips/include/asm/mach-loongson64/machine.h new file mode 100644 index 000000000000..c52549bb4e56 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/machine.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2009 Lemote, Inc. + * Author: Wu Zhangjin + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#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 */ diff --git a/arch/mips/include/asm/mach-loongson64/mc146818rtc.h b/arch/mips/include/asm/mach-loongson64/mc146818rtc.h new file mode 100644 index 000000000000..ebdccfee50be --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/mc146818rtc.h @@ -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 + +#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 */ diff --git a/arch/mips/include/asm/mach-loongson64/mem.h b/arch/mips/include/asm/mach-loongson64/mem.h new file mode 100644 index 000000000000..75c16bead536 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/mem.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2009 Lemote, Inc. + * Author: Wu Zhangjin + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#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 */ diff --git a/arch/mips/include/asm/mach-loongson64/mmzone.h b/arch/mips/include/asm/mach-loongson64/mmzone.h new file mode 100644 index 000000000000..37c08a27b4f0 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/mmzone.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2010 Loongson Inc. & Lemote Inc. & + * Insititute of Computing Technology + * Author: Xiang Gao, gaoxiang@ict.ac.cn + * Huacai Chen, chenhc@lemote.com + * Xiaofu Meng, Shuangshuang Zhang + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#ifndef _ASM_MACH_MMZONE_H +#define _ASM_MACH_MMZONE_H + +#include +#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 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 */ diff --git a/arch/mips/include/asm/mach-loongson64/pci.h b/arch/mips/include/asm/mach-loongson64/pci.h new file mode 100644 index 000000000000..3401f557434a --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/pci.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2008 Zhang Le + * Copyright (c) 2009 Wu Zhangjin + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#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_LOONGSON3 +#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_ */ diff --git a/arch/mips/include/asm/mach-loongson64/spaces.h b/arch/mips/include/asm/mach-loongson64/spaces.h new file mode 100644 index 000000000000..c6040b9fcf94 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/spaces.h @@ -0,0 +1,9 @@ +#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 +#endif diff --git a/arch/mips/include/asm/mach-loongson64/topology.h b/arch/mips/include/asm/mach-loongson64/topology.h new file mode 100644 index 000000000000..0d8f3b55bdbc --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/topology.h @@ -0,0 +1,23 @@ +#ifndef _ASM_MACH_TOPOLOGY_H +#define _ASM_MACH_TOPOLOGY_H + +#ifdef CONFIG_NUMA + +#define cpu_to_node(cpu) (cpu_logical_map(cpu) >> 2) +#define parent_node(node) (node) +#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 + +#endif /* _ASM_MACH_TOPOLOGY_H */ diff --git a/arch/mips/include/asm/mach-loongson64/workarounds.h b/arch/mips/include/asm/mach-loongson64/workarounds.h new file mode 100644 index 000000000000..e659f041e116 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/workarounds.h @@ -0,0 +1,7 @@ +#ifndef __ASM_MACH_LOONGSON64_WORKAROUNDS_H_ +#define __ASM_MACH_LOONGSON64_WORKAROUNDS_H_ + +#define WORKAROUND_CPUFREQ 0x00000001 +#define WORKAROUND_CPUHOTPLUG 0x00000002 + +#endif diff --git a/arch/mips/loongson/Kconfig b/arch/mips/loongson/Kconfig deleted file mode 100644 index 506414915463..000000000000 --- a/arch/mips/loongson/Kconfig +++ /dev/null @@ -1,158 +0,0 @@ -if MACH_LOONGSON - -choice - prompt "Machine Type" - -config LEMOTE_FULOONG2E - bool "Lemote Fuloong(2e) mini-PC" - select ARCH_SPARSEMEM_ENABLE - select CEVT_R4K - select CSRC_R4K - select SYS_HAS_CPU_LOONGSON2E - select DMA_NONCOHERENT - select BOOT_ELF32 - select BOARD_SCACHE - select HW_HAS_PCI - select I8259 - select ISA - select IRQ_MIPS_CPU - select SYS_SUPPORTS_32BIT_KERNEL - 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 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 HW_HAS_PCI - select I8259 - select IRQ_MIPS_CPU - select ISA - select SYS_HAS_CPU_LOONGSON2F - select SYS_HAS_EARLY_PRINTK - select SYS_SUPPORTS_32BIT_KERNEL - 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 - select GENERIC_ISA_DMA_SUPPORT_BROKEN - select BOOT_ELF32 - select BOARD_SCACHE - select CSRC_R4K - select CEVT_R4K - select CPU_HAS_WB - select HW_HAS_PCI - select ISA - select HT_PCI - select I8259 - select IRQ_MIPS_CPU - select NR_CPUS_DEFAULT_4 - select SYS_HAS_CPU_LOONGSON3 - select SYS_HAS_EARLY_PRINTK - select SYS_SUPPORTS_SMP - select SYS_SUPPORTS_HOTPLUG_CPU - select SYS_SUPPORTS_NUMA - select SYS_SUPPORTS_64BIT_KERNEL - select SYS_SUPPORTS_HIGHMEM - select SYS_SUPPORTS_LITTLE_ENDIAN - select LOONGSON_MC146818 - select ZONE_DMA32 - select LEFI_FIRMWARE_INTERFACE - select PHYS48_TO_HT40 - help - Generic Loongson 3 family machines utilize the 3A/3B revision - 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 - select MIPS_EXTERNAL_TIMER - help - This option enables the hpet timer of AMD RS780/SBX00. - - If you want to enable the Loongson3 CPUFreq Driver, Please enable - this option at first, otherwise, You will get wrong system time. - - If unsure, say Yes. - -config LOONGSON_SUSPEND - bool - default y - depends on CPU_SUPPORTS_CPUFREQ && SUSPEND - -config LOONGSON_UART_BASE - bool - default y - depends on EARLY_PRINTK || SERIAL_8250 - -config IOMMU_HELPER - bool - -config NEED_SG_DMA_LENGTH - bool - -config SWIOTLB - bool "Soft IOMMU Support for All-Memory DMA" - default y - depends on CPU_LOONGSON3 - select IOMMU_HELPER - select NEED_SG_DMA_LENGTH - select NEED_DMA_MAP_STATE - -config PHYS48_TO_HT40 - bool - default y if CPU_LOONGSON3 - -config LOONGSON_MC146818 - bool - default n - -config LEFI_FIRMWARE_INTERFACE - bool - -endif # MACH_LOONGSON diff --git a/arch/mips/loongson/Makefile b/arch/mips/loongson/Makefile deleted file mode 100644 index 7429994e7604..000000000000 --- a/arch/mips/loongson/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# -# Common code for all Loongson based systems -# - -obj-$(CONFIG_MACH_LOONGSON) += 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 -# - -obj-$(CONFIG_CPU_LOONGSON3) += loongson-3/ diff --git a/arch/mips/loongson/Platform b/arch/mips/loongson/Platform deleted file mode 100644 index 0ac20eb84ecc..000000000000 --- a/arch/mips/loongson/Platform +++ /dev/null @@ -1,33 +0,0 @@ -# -# Loongson Processors' Support -# - -# Only gcc >= 4.4 have Loongson specific support -cflags-$(CONFIG_CPU_LOONGSON2) += -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_LOONGSON) += loongson/ -cflags-$(CONFIG_MACH_LOONGSON) += -I$(srctree)/arch/mips/include/asm/mach-loongson -mno-branch-likely -load-$(CONFIG_LEMOTE_FULOONG2E) += 0xffffffff80100000 -load-$(CONFIG_LEMOTE_MACH2F) += 0xffffffff80200000 -load-$(CONFIG_LOONGSON_MACH3X) += 0xffffffff80200000 diff --git a/arch/mips/loongson/common/Makefile b/arch/mips/loongson/common/Makefile deleted file mode 100644 index f2e8153e44f5..000000000000 --- a/arch/mips/loongson/common/Makefile +++ /dev/null @@ -1,31 +0,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_LOONGSON_SUSPEND) += pm.o - -# -# Big Memory (SWIOTLB) Support -# -obj-$(CONFIG_SWIOTLB) += dma-swiotlb.o diff --git a/arch/mips/loongson/common/bonito-irq.c b/arch/mips/loongson/common/bonito-irq.c deleted file mode 100644 index cc0e4fd548e6..000000000000 --- a/arch/mips/loongson/common/bonito-irq.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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. & Insititute of Computing Technology - * Author: Fuxin Zhang, zhangfx@lemote.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include -#include - -#include - -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 -} diff --git a/arch/mips/loongson/common/cmdline.c b/arch/mips/loongson/common/cmdline.c deleted file mode 100644 index 72fed003a536..000000000000 --- a/arch/mips/loongson/common/cmdline.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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 - * - * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology - * Author: Fuxin Zhang, zhangfx@lemote.com - * - * Copyright (C) 2009 Lemote Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include - -#include - -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(); -} diff --git a/arch/mips/loongson/common/cs5536/Makefile b/arch/mips/loongson/common/cs5536/Makefile deleted file mode 100644 index f12e64007347..000000000000 --- a/arch/mips/loongson/common/cs5536/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# -# Makefile for CS5536 support. -# - -obj-$(CONFIG_CS5536) += cs5536_pci.o cs5536_ide.o cs5536_acc.o cs5536_ohci.o \ - cs5536_isa.o cs5536_ehci.o - -# -# Enable cs5536 mfgpt Timer -# -obj-$(CONFIG_CS5536_MFGPT) += cs5536_mfgpt.o diff --git a/arch/mips/loongson/common/cs5536/cs5536_acc.c b/arch/mips/loongson/common/cs5536/cs5536_acc.c deleted file mode 100644 index ab4d6cc57384..000000000000 --- a/arch/mips/loongson/common/cs5536/cs5536_acc.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * the ACC Virtual Support Module of AMD CS5536 - * - * Copyright (C) 2007 Lemote, Inc. - * Author : jlliu, liujl@lemote.com - * - * Copyright (C) 2009 Lemote, Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include - -void pci_acc_write_reg(int reg, u32 value) -{ - u32 hi = 0, lo = value; - - switch (reg) { - case PCI_COMMAND: - _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); - if (value & PCI_COMMAND_MASTER) - lo |= (0x03 << 8); - else - lo &= ~(0x03 << 8); - _wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo); - break; - case PCI_STATUS: - if (value & PCI_STATUS_PARITY) { - _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); - if (lo & SB_PARE_ERR_FLAG) { - lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; - _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); - } - } - break; - case PCI_BAR0_REG: - if (value == PCI_BAR_RANGE_MASK) { - _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); - lo |= SOFT_BAR_ACC_FLAG; - _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); - } else if (value & 0x01) { - value &= 0xfffffffc; - hi = 0xA0000000 | ((value & 0x000ff000) >> 12); - lo = 0x000fff80 | ((value & 0x00000fff) << 20); - _wrmsr(GLIU_MSR_REG(GLIU_IOD_BM1), hi, lo); - } - break; - case PCI_ACC_INT_REG: - _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); - /* disable all the usb interrupt in PIC */ - lo &= ~(0xf << PIC_YSEL_LOW_ACC_SHIFT); - if (value) /* enable all the acc interrupt in PIC */ - lo |= (CS5536_ACC_INTR << PIC_YSEL_LOW_ACC_SHIFT); - _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo); - break; - default: - break; - } -} - -u32 pci_acc_read_reg(int reg) -{ - u32 hi, lo; - u32 conf_data = 0; - - switch (reg) { - case PCI_VENDOR_ID: - conf_data = - CFG_PCI_VENDOR_ID(CS5536_ACC_DEVICE_ID, CS5536_VENDOR_ID); - break; - case PCI_COMMAND: - _rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo); - if (((lo & 0xfff00000) || (hi & 0x000000ff)) - && ((hi & 0xf0000000) == 0xa0000000)) - conf_data |= PCI_COMMAND_IO; - _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); - if ((lo & 0x300) == 0x300) - conf_data |= PCI_COMMAND_MASTER; - break; - case PCI_STATUS: - conf_data |= PCI_STATUS_66MHZ; - conf_data |= PCI_STATUS_FAST_BACK; - _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); - if (lo & SB_PARE_ERR_FLAG) - conf_data |= PCI_STATUS_PARITY; - conf_data |= PCI_STATUS_DEVSEL_MEDIUM; - break; - case PCI_CLASS_REVISION: - _rdmsr(ACC_MSR_REG(ACC_CAP), &hi, &lo); - conf_data = lo & 0x000000ff; - conf_data |= (CS5536_ACC_CLASS_CODE << 8); - break; - case PCI_CACHE_LINE_SIZE: - conf_data = - CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, - PCI_NORMAL_LATENCY_TIMER); - break; - case PCI_BAR0_REG: - _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); - if (lo & SOFT_BAR_ACC_FLAG) { - conf_data = CS5536_ACC_RANGE | - PCI_BASE_ADDRESS_SPACE_IO; - lo &= ~SOFT_BAR_ACC_FLAG; - _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); - } else { - _rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo); - conf_data = (hi & 0x000000ff) << 12; - conf_data |= (lo & 0xfff00000) >> 20; - conf_data |= 0x01; - conf_data &= ~0x02; - } - break; - case PCI_CARDBUS_CIS: - conf_data = PCI_CARDBUS_CIS_POINTER; - break; - case PCI_SUBSYSTEM_VENDOR_ID: - conf_data = - CFG_PCI_VENDOR_ID(CS5536_ACC_SUB_ID, CS5536_SUB_VENDOR_ID); - break; - case PCI_ROM_ADDRESS: - conf_data = PCI_EXPANSION_ROM_BAR; - break; - case PCI_CAPABILITY_LIST: - conf_data = PCI_CAPLIST_USB_POINTER; - break; - case PCI_INTERRUPT_LINE: - conf_data = - CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_ACC_INTR); - break; - default: - break; - } - - return conf_data; -} diff --git a/arch/mips/loongson/common/cs5536/cs5536_ehci.c b/arch/mips/loongson/common/cs5536/cs5536_ehci.c deleted file mode 100644 index ec2e360267a8..000000000000 --- a/arch/mips/loongson/common/cs5536/cs5536_ehci.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * the EHCI Virtual Support Module of AMD CS5536 - * - * Copyright (C) 2007 Lemote, Inc. - * Author : jlliu, liujl@lemote.com - * - * Copyright (C) 2009 Lemote, Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include - -void pci_ehci_write_reg(int reg, u32 value) -{ - u32 hi = 0, lo = value; - - switch (reg) { - case PCI_COMMAND: - _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); - if (value & PCI_COMMAND_MASTER) - hi |= PCI_COMMAND_MASTER; - else - hi &= ~PCI_COMMAND_MASTER; - - if (value & PCI_COMMAND_MEMORY) - hi |= PCI_COMMAND_MEMORY; - else - hi &= ~PCI_COMMAND_MEMORY; - _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); - break; - case PCI_STATUS: - if (value & PCI_STATUS_PARITY) { - _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); - if (lo & SB_PARE_ERR_FLAG) { - lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; - _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); - } - } - break; - case PCI_BAR0_REG: - if (value == PCI_BAR_RANGE_MASK) { - _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); - lo |= SOFT_BAR_EHCI_FLAG; - _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); - } else if ((value & 0x01) == 0x00) { - _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); - lo = value; - _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); - - value &= 0xfffffff0; - hi = 0x40000000 | ((value & 0xff000000) >> 24); - lo = 0x000fffff | ((value & 0x00fff000) << 8); - _wrmsr(GLIU_MSR_REG(GLIU_P2D_BM4), hi, lo); - } - break; - case PCI_EHCI_LEGSMIEN_REG: - _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); - hi &= 0x003f0000; - hi |= (value & 0x3f) << 16; - _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); - break; - case PCI_EHCI_FLADJ_REG: - _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); - hi &= ~0x00003f00; - hi |= value & 0x00003f00; - _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); - break; - default: - break; - } -} - -u32 pci_ehci_read_reg(int reg) -{ - u32 conf_data = 0; - u32 hi, lo; - - switch (reg) { - case PCI_VENDOR_ID: - conf_data = - CFG_PCI_VENDOR_ID(CS5536_EHCI_DEVICE_ID, CS5536_VENDOR_ID); - break; - case PCI_COMMAND: - _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); - if (hi & PCI_COMMAND_MASTER) - conf_data |= PCI_COMMAND_MASTER; - if (hi & PCI_COMMAND_MEMORY) - conf_data |= PCI_COMMAND_MEMORY; - break; - case PCI_STATUS: - conf_data |= PCI_STATUS_66MHZ; - conf_data |= PCI_STATUS_FAST_BACK; - _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); - if (lo & SB_PARE_ERR_FLAG) - conf_data |= PCI_STATUS_PARITY; - conf_data |= PCI_STATUS_DEVSEL_MEDIUM; - break; - case PCI_CLASS_REVISION: - _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo); - conf_data = lo & 0x000000ff; - conf_data |= (CS5536_EHCI_CLASS_CODE << 8); - break; - case PCI_CACHE_LINE_SIZE: - conf_data = - CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, - PCI_NORMAL_LATENCY_TIMER); - break; - case PCI_BAR0_REG: - _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); - if (lo & SOFT_BAR_EHCI_FLAG) { - conf_data = CS5536_EHCI_RANGE | - PCI_BASE_ADDRESS_SPACE_MEMORY; - lo &= ~SOFT_BAR_EHCI_FLAG; - _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); - } else { - _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); - conf_data = lo & 0xfffff000; - } - break; - case PCI_CARDBUS_CIS: - conf_data = PCI_CARDBUS_CIS_POINTER; - break; - case PCI_SUBSYSTEM_VENDOR_ID: - conf_data = - CFG_PCI_VENDOR_ID(CS5536_EHCI_SUB_ID, CS5536_SUB_VENDOR_ID); - break; - case PCI_ROM_ADDRESS: - conf_data = PCI_EXPANSION_ROM_BAR; - break; - case PCI_CAPABILITY_LIST: - conf_data = PCI_CAPLIST_USB_POINTER; - break; - case PCI_INTERRUPT_LINE: - conf_data = - CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR); - break; - case PCI_EHCI_LEGSMIEN_REG: - _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); - conf_data = (hi & 0x003f0000) >> 16; - break; - case PCI_EHCI_LEGSMISTS_REG: - _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); - conf_data = (hi & 0x3f000000) >> 24; - break; - case PCI_EHCI_FLADJ_REG: - _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); - conf_data = hi & 0x00003f00; - break; - default: - break; - } - - return conf_data; -} diff --git a/arch/mips/loongson/common/cs5536/cs5536_ide.c b/arch/mips/loongson/common/cs5536/cs5536_ide.c deleted file mode 100644 index a73414d9ee51..000000000000 --- a/arch/mips/loongson/common/cs5536/cs5536_ide.c +++ /dev/null @@ -1,192 +0,0 @@ -/* - * the IDE Virtual Support Module of AMD CS5536 - * - * Copyright (C) 2007 Lemote, Inc. - * Author : jlliu, liujl@lemote.com - * - * Copyright (C) 2009 Lemote, Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include - -void pci_ide_write_reg(int reg, u32 value) -{ - u32 hi = 0, lo = value; - - switch (reg) { - case PCI_COMMAND: - _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); - if (value & PCI_COMMAND_MASTER) - lo |= (0x03 << 4); - else - lo &= ~(0x03 << 4); - _wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo); - break; - case PCI_STATUS: - if (value & PCI_STATUS_PARITY) { - _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); - if (lo & SB_PARE_ERR_FLAG) { - lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; - _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); - } - } - break; - case PCI_CACHE_LINE_SIZE: - value &= 0x0000ff00; - _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); - hi &= 0xffffff00; - hi |= (value >> 8); - _wrmsr(SB_MSR_REG(SB_CTRL), hi, lo); - break; - case PCI_BAR4_REG: - if (value == PCI_BAR_RANGE_MASK) { - _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); - lo |= SOFT_BAR_IDE_FLAG; - _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); - } else if (value & 0x01) { - _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo); - lo = (value & 0xfffffff0) | 0x1; - _wrmsr(IDE_MSR_REG(IDE_IO_BAR), hi, lo); - - value &= 0xfffffffc; - hi = 0x60000000 | ((value & 0x000ff000) >> 12); - lo = 0x000ffff0 | ((value & 0x00000fff) << 20); - _wrmsr(GLIU_MSR_REG(GLIU_IOD_BM2), hi, lo); - } - break; - case PCI_IDE_CFG_REG: - if (value == CS5536_IDE_FLASH_SIGNATURE) { - _rdmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), &hi, &lo); - lo |= 0x01; - _wrmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), hi, lo); - } else { - _rdmsr(IDE_MSR_REG(IDE_CFG), &hi, &lo); - lo = value; - _wrmsr(IDE_MSR_REG(IDE_CFG), hi, lo); - } - break; - case PCI_IDE_DTC_REG: - _rdmsr(IDE_MSR_REG(IDE_DTC), &hi, &lo); - lo = value; - _wrmsr(IDE_MSR_REG(IDE_DTC), hi, lo); - break; - case PCI_IDE_CAST_REG: - _rdmsr(IDE_MSR_REG(IDE_CAST), &hi, &lo); - lo = value; - _wrmsr(IDE_MSR_REG(IDE_CAST), hi, lo); - break; - case PCI_IDE_ETC_REG: - _rdmsr(IDE_MSR_REG(IDE_ETC), &hi, &lo); - lo = value; - _wrmsr(IDE_MSR_REG(IDE_ETC), hi, lo); - break; - case PCI_IDE_PM_REG: - _rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo); - lo = value; - _wrmsr(IDE_MSR_REG(IDE_INTERNAL_PM), hi, lo); - break; - default: - break; - } -} - -u32 pci_ide_read_reg(int reg) -{ - u32 conf_data = 0; - u32 hi, lo; - - switch (reg) { - case PCI_VENDOR_ID: - conf_data = - CFG_PCI_VENDOR_ID(CS5536_IDE_DEVICE_ID, CS5536_VENDOR_ID); - break; - case PCI_COMMAND: - _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo); - if (lo & 0xfffffff0) - conf_data |= PCI_COMMAND_IO; - _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); - if ((lo & 0x30) == 0x30) - conf_data |= PCI_COMMAND_MASTER; - break; - case PCI_STATUS: - conf_data |= PCI_STATUS_66MHZ; - conf_data |= PCI_STATUS_FAST_BACK; - _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); - if (lo & SB_PARE_ERR_FLAG) - conf_data |= PCI_STATUS_PARITY; - conf_data |= PCI_STATUS_DEVSEL_MEDIUM; - break; - case PCI_CLASS_REVISION: - _rdmsr(IDE_MSR_REG(IDE_CAP), &hi, &lo); - conf_data = lo & 0x000000ff; - conf_data |= (CS5536_IDE_CLASS_CODE << 8); - break; - case PCI_CACHE_LINE_SIZE: - _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); - hi &= 0x000000f8; - conf_data = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, hi); - break; - case PCI_BAR4_REG: - _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); - if (lo & SOFT_BAR_IDE_FLAG) { - conf_data = CS5536_IDE_RANGE | - PCI_BASE_ADDRESS_SPACE_IO; - lo &= ~SOFT_BAR_IDE_FLAG; - _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); - } else { - _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo); - conf_data = lo & 0xfffffff0; - conf_data |= 0x01; - conf_data &= ~0x02; - } - break; - case PCI_CARDBUS_CIS: - conf_data = PCI_CARDBUS_CIS_POINTER; - break; - case PCI_SUBSYSTEM_VENDOR_ID: - conf_data = - CFG_PCI_VENDOR_ID(CS5536_IDE_SUB_ID, CS5536_SUB_VENDOR_ID); - break; - case PCI_ROM_ADDRESS: - conf_data = PCI_EXPANSION_ROM_BAR; - break; - case PCI_CAPABILITY_LIST: - conf_data = PCI_CAPLIST_POINTER; - break; - case PCI_INTERRUPT_LINE: - conf_data = - CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_IDE_INTR); - break; - case PCI_IDE_CFG_REG: - _rdmsr(IDE_MSR_REG(IDE_CFG), &hi, &lo); - conf_data = lo; - break; - case PCI_IDE_DTC_REG: - _rdmsr(IDE_MSR_REG(IDE_DTC), &hi, &lo); - conf_data = lo; - break; - case PCI_IDE_CAST_REG: - _rdmsr(IDE_MSR_REG(IDE_CAST), &hi, &lo); - conf_data = lo; - break; - case PCI_IDE_ETC_REG: - _rdmsr(IDE_MSR_REG(IDE_ETC), &hi, &lo); - conf_data = lo; - break; - case PCI_IDE_PM_REG: - _rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo); - conf_data = lo; - break; - default: - break; - } - - return conf_data; -} diff --git a/arch/mips/loongson/common/cs5536/cs5536_isa.c b/arch/mips/loongson/common/cs5536/cs5536_isa.c deleted file mode 100644 index 924be39e7733..000000000000 --- a/arch/mips/loongson/common/cs5536/cs5536_isa.c +++ /dev/null @@ -1,330 +0,0 @@ -/* - * the ISA Virtual Support Module of AMD CS5536 - * - * Copyright (C) 2007 Lemote, Inc. - * Author : jlliu, liujl@lemote.com - * - * Copyright (C) 2009 Lemote, Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include - -/* common variables for PCI_ISA_READ/WRITE_BAR */ -static const u32 divil_msr_reg[6] = { - DIVIL_MSR_REG(DIVIL_LBAR_SMB), DIVIL_MSR_REG(DIVIL_LBAR_GPIO), - DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), DIVIL_MSR_REG(DIVIL_LBAR_IRQ), - DIVIL_MSR_REG(DIVIL_LBAR_PMS), DIVIL_MSR_REG(DIVIL_LBAR_ACPI), -}; - -static const u32 soft_bar_flag[6] = { - SOFT_BAR_SMB_FLAG, SOFT_BAR_GPIO_FLAG, SOFT_BAR_MFGPT_FLAG, - SOFT_BAR_IRQ_FLAG, SOFT_BAR_PMS_FLAG, SOFT_BAR_ACPI_FLAG, -}; - -static const u32 sb_msr_reg[6] = { - SB_MSR_REG(SB_R0), SB_MSR_REG(SB_R1), SB_MSR_REG(SB_R2), - SB_MSR_REG(SB_R3), SB_MSR_REG(SB_R4), SB_MSR_REG(SB_R5), -}; - -static const u32 bar_space_range[6] = { - CS5536_SMB_RANGE, CS5536_GPIO_RANGE, CS5536_MFGPT_RANGE, - CS5536_IRQ_RANGE, CS5536_PMS_RANGE, CS5536_ACPI_RANGE, -}; - -static const int bar_space_len[6] = { - CS5536_SMB_LENGTH, CS5536_GPIO_LENGTH, CS5536_MFGPT_LENGTH, - CS5536_IRQ_LENGTH, CS5536_PMS_LENGTH, CS5536_ACPI_LENGTH, -}; - -/* - * enable the divil module bar space. - * - * For all the DIVIL module LBAR, you should control the DIVIL LBAR reg - * and the RCONFx(0~5) reg to use the modules. - */ -static void divil_lbar_enable(void) -{ - u32 hi, lo; - int offset; - - /* - * The DIVIL IRQ is not used yet. and make the RCONF0 reserved. - */ - - for (offset = DIVIL_LBAR_SMB; offset <= DIVIL_LBAR_PMS; offset++) { - _rdmsr(DIVIL_MSR_REG(offset), &hi, &lo); - hi |= 0x01; - _wrmsr(DIVIL_MSR_REG(offset), hi, lo); - } -} - -/* - * disable the divil module bar space. - */ -static void divil_lbar_disable(void) -{ - u32 hi, lo; - int offset; - - for (offset = DIVIL_LBAR_SMB; offset <= DIVIL_LBAR_PMS; offset++) { - _rdmsr(DIVIL_MSR_REG(offset), &hi, &lo); - hi &= ~0x01; - _wrmsr(DIVIL_MSR_REG(offset), hi, lo); - } -} - -/* - * BAR write: write value to the n BAR - */ - -void pci_isa_write_bar(int n, u32 value) -{ - u32 hi = 0, lo = value; - - if (value == PCI_BAR_RANGE_MASK) { - _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); - lo |= soft_bar_flag[n]; - _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); - } else if (value & 0x01) { - /* NATIVE reg */ - hi = 0x0000f001; - lo &= bar_space_range[n]; - _wrmsr(divil_msr_reg[n], hi, lo); - - /* RCONFx is 4bytes in units for I/O space */ - hi = ((value & 0x000ffffc) << 12) | - ((bar_space_len[n] - 4) << 12) | 0x01; - lo = ((value & 0x000ffffc) << 12) | 0x01; - _wrmsr(sb_msr_reg[n], hi, lo); - } -} - -/* - * BAR read: read the n BAR - */ - -u32 pci_isa_read_bar(int n) -{ - u32 conf_data = 0; - u32 hi, lo; - - _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); - if (lo & soft_bar_flag[n]) { - conf_data = bar_space_range[n] | PCI_BASE_ADDRESS_SPACE_IO; - lo &= ~soft_bar_flag[n]; - _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); - } else { - _rdmsr(divil_msr_reg[n], &hi, &lo); - conf_data = lo & bar_space_range[n]; - conf_data |= 0x01; - conf_data &= ~0x02; - } - return conf_data; -} - -/* - * isa_write: ISA write transfer - * - * We assume that this is not a bus master transfer. - */ -void pci_isa_write_reg(int reg, u32 value) -{ - u32 hi = 0, lo = value; - u32 temp; - - switch (reg) { - case PCI_COMMAND: - if (value & PCI_COMMAND_IO) - divil_lbar_enable(); - else - divil_lbar_disable(); - break; - case PCI_STATUS: - _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); - temp = lo & 0x0000ffff; - if ((value & PCI_STATUS_SIG_TARGET_ABORT) && - (lo & SB_TAS_ERR_EN)) - temp |= SB_TAS_ERR_FLAG; - - if ((value & PCI_STATUS_REC_TARGET_ABORT) && - (lo & SB_TAR_ERR_EN)) - temp |= SB_TAR_ERR_FLAG; - - if ((value & PCI_STATUS_REC_MASTER_ABORT) - && (lo & SB_MAR_ERR_EN)) - temp |= SB_MAR_ERR_FLAG; - - if ((value & PCI_STATUS_DETECTED_PARITY) - && (lo & SB_PARE_ERR_EN)) - temp |= SB_PARE_ERR_FLAG; - - lo = temp; - _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); - break; - case PCI_CACHE_LINE_SIZE: - value &= 0x0000ff00; - _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); - hi &= 0xffffff00; - hi |= (value >> 8); - _wrmsr(SB_MSR_REG(SB_CTRL), hi, lo); - break; - case PCI_BAR0_REG: - pci_isa_write_bar(0, value); - break; - case PCI_BAR1_REG: - pci_isa_write_bar(1, value); - break; - case PCI_BAR2_REG: - pci_isa_write_bar(2, value); - break; - case PCI_BAR3_REG: - pci_isa_write_bar(3, value); - break; - case PCI_BAR4_REG: - pci_isa_write_bar(4, value); - break; - case PCI_BAR5_REG: - pci_isa_write_bar(5, value); - break; - case PCI_UART1_INT_REG: - _rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo); - /* disable uart1 interrupt in PIC */ - lo &= ~(0xf << 24); - if (value) /* enable uart1 interrupt in PIC */ - lo |= (CS5536_UART1_INTR << 24); - _wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo); - break; - case PCI_UART2_INT_REG: - _rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo); - /* disable uart2 interrupt in PIC */ - lo &= ~(0xf << 28); - if (value) /* enable uart2 interrupt in PIC */ - lo |= (CS5536_UART2_INTR << 28); - _wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo); - break; - case PCI_ISA_FIXUP_REG: - if (value) { - /* enable the TARGET ABORT/MASTER ABORT etc. */ - _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); - lo |= 0x00000063; - _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); - } - - default: - /* ALL OTHER PCI CONFIG SPACE HEADER IS NOT IMPLEMENTED. */ - break; - } -} - -/* - * isa_read: ISA read transfers - * - * We assume that this is not a bus master transfer. - */ -u32 pci_isa_read_reg(int reg) -{ - u32 conf_data = 0; - u32 hi, lo; - - switch (reg) { - case PCI_VENDOR_ID: - conf_data = - CFG_PCI_VENDOR_ID(CS5536_ISA_DEVICE_ID, CS5536_VENDOR_ID); - break; - case PCI_COMMAND: - /* we just check the first LBAR for the IO enable bit, */ - /* maybe we should changed later. */ - _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), &hi, &lo); - if (hi & 0x01) - conf_data |= PCI_COMMAND_IO; - break; - case PCI_STATUS: - conf_data |= PCI_STATUS_66MHZ; - conf_data |= PCI_STATUS_DEVSEL_MEDIUM; - conf_data |= PCI_STATUS_FAST_BACK; - - _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); - if (lo & SB_TAS_ERR_FLAG) - conf_data |= PCI_STATUS_SIG_TARGET_ABORT; - if (lo & SB_TAR_ERR_FLAG) - conf_data |= PCI_STATUS_REC_TARGET_ABORT; - if (lo & SB_MAR_ERR_FLAG) - conf_data |= PCI_STATUS_REC_MASTER_ABORT; - if (lo & SB_PARE_ERR_FLAG) - conf_data |= PCI_STATUS_DETECTED_PARITY; - break; - case PCI_CLASS_REVISION: - _rdmsr(GLCP_MSR_REG(GLCP_CHIP_REV_ID), &hi, &lo); - conf_data = lo & 0x000000ff; - conf_data |= (CS5536_ISA_CLASS_CODE << 8); - break; - case PCI_CACHE_LINE_SIZE: - _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); - hi &= 0x000000f8; - conf_data = CFG_PCI_CACHE_LINE_SIZE(PCI_BRIDGE_HEADER_TYPE, hi); - break; - /* - * we only use the LBAR of DIVIL, no RCONF used. - * all of them are IO space. - */ - case PCI_BAR0_REG: - return pci_isa_read_bar(0); - break; - case PCI_BAR1_REG: - return pci_isa_read_bar(1); - break; - case PCI_BAR2_REG: - return pci_isa_read_bar(2); - break; - case PCI_BAR3_REG: - break; - case PCI_BAR4_REG: - return pci_isa_read_bar(4); - break; - case PCI_BAR5_REG: - return pci_isa_read_bar(5); - break; - case PCI_CARDBUS_CIS: - conf_data = PCI_CARDBUS_CIS_POINTER; - break; - case PCI_SUBSYSTEM_VENDOR_ID: - conf_data = - CFG_PCI_VENDOR_ID(CS5536_ISA_SUB_ID, CS5536_SUB_VENDOR_ID); - break; - case PCI_ROM_ADDRESS: - conf_data = PCI_EXPANSION_ROM_BAR; - break; - case PCI_CAPABILITY_LIST: - conf_data = PCI_CAPLIST_POINTER; - break; - case PCI_INTERRUPT_LINE: - /* no interrupt used here */ - conf_data = CFG_PCI_INTERRUPT_LINE(0x00, 0x00); - break; - default: - break; - } - - return conf_data; -} - -/* - * The mfgpt timer interrupt is running early, so we must keep the south bridge - * mmio always enabled. Otherwise we may race with the PCI configuration which - * may temporarily disable it. When that happens and the timer interrupt fires, - * we are not able to clear it and the system will hang. - */ -static void cs5536_isa_mmio_always_on(struct pci_dev *dev) -{ - dev->mmio_always_on = 1; -} -DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, - PCI_CLASS_BRIDGE_ISA, 8, cs5536_isa_mmio_always_on); diff --git a/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c b/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c deleted file mode 100644 index 12c75db23420..000000000000 --- a/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * CS5536 General timer functions - * - * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology - * Author: Yanhua, yanh@lemote.com - * - * Copyright (C) 2009 Lemote Inc. - * Author: Wu zhangjin, wuzhangjin@gmail.com - * - * Reference: AMD Geode(TM) CS5536 Companion Device Data Book - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -static DEFINE_RAW_SPINLOCK(mfgpt_lock); - -static u32 mfgpt_base; - -/* - * Initialize the MFGPT timer. - * - * This is also called after resume to bring the MFGPT into operation again. - */ - -/* disable counter */ -void disable_mfgpt0_counter(void) -{ - outw(inw(MFGPT0_SETUP) & 0x7fff, MFGPT0_SETUP); -} -EXPORT_SYMBOL(disable_mfgpt0_counter); - -/* enable counter, comparator2 to event mode, 14.318MHz clock */ -void enable_mfgpt0_counter(void) -{ - outw(0xe310, MFGPT0_SETUP); -} -EXPORT_SYMBOL(enable_mfgpt0_counter); - -static void init_mfgpt_timer(enum clock_event_mode mode, - struct clock_event_device *evt) -{ - raw_spin_lock(&mfgpt_lock); - - switch (mode) { - case CLOCK_EVT_MODE_PERIODIC: - outw(COMPARE, MFGPT0_CMP2); /* set comparator2 */ - outw(0, MFGPT0_CNT); /* set counter to 0 */ - enable_mfgpt0_counter(); - break; - - case CLOCK_EVT_MODE_SHUTDOWN: - case CLOCK_EVT_MODE_UNUSED: - if (evt->mode == CLOCK_EVT_MODE_PERIODIC || - evt->mode == CLOCK_EVT_MODE_ONESHOT) - disable_mfgpt0_counter(); - break; - - case CLOCK_EVT_MODE_ONESHOT: - /* The oneshot mode have very high deviation, Not use it! */ - break; - - case CLOCK_EVT_MODE_RESUME: - /* Nothing to do here */ - break; - } - raw_spin_unlock(&mfgpt_lock); -} - -static struct clock_event_device mfgpt_clockevent = { - .name = "mfgpt", - .features = CLOCK_EVT_FEAT_PERIODIC, - .set_mode = init_mfgpt_timer, - .irq = CS5536_MFGPT_INTR, -}; - -static irqreturn_t timer_interrupt(int irq, void *dev_id) -{ - u32 basehi; - - /* - * get MFGPT base address - * - * NOTE: do not remove me, it's need for the value of mfgpt_base is - * variable - */ - _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), &basehi, &mfgpt_base); - - /* ack */ - outw(inw(MFGPT0_SETUP) | 0x4000, MFGPT0_SETUP); - - mfgpt_clockevent.event_handler(&mfgpt_clockevent); - - return IRQ_HANDLED; -} - -static struct irqaction irq5 = { - .handler = timer_interrupt, - .flags = IRQF_NOBALANCING | IRQF_TIMER, - .name = "timer" -}; - -/* - * Initialize the conversion factor and the min/max deltas of the clock event - * structure and register the clock event source with the framework. - */ -void __init setup_mfgpt0_timer(void) -{ - u32 basehi; - struct clock_event_device *cd = &mfgpt_clockevent; - unsigned int cpu = smp_processor_id(); - - cd->cpumask = cpumask_of(cpu); - clockevent_set_clock(cd, MFGPT_TICK_RATE); - cd->max_delta_ns = clockevent_delta2ns(0xffff, cd); - cd->min_delta_ns = clockevent_delta2ns(0xf, cd); - - /* Enable MFGPT0 Comparator 2 Output to the Interrupt Mapper */ - _wrmsr(DIVIL_MSR_REG(MFGPT_IRQ), 0, 0x100); - - /* Enable Interrupt Gate 5 */ - _wrmsr(DIVIL_MSR_REG(PIC_ZSEL_LOW), 0, 0x50000); - - /* get MFGPT base address */ - _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), &basehi, &mfgpt_base); - - clockevents_register_device(cd); - - setup_irq(CS5536_MFGPT_INTR, &irq5); -} - -/* - * Since the MFGPT overflows every tick, its not very useful - * to just read by itself. So use jiffies to emulate a free - * running counter: - */ -static cycle_t mfgpt_read(struct clocksource *cs) -{ - unsigned long flags; - int count; - u32 jifs; - static int old_count; - static u32 old_jifs; - - raw_spin_lock_irqsave(&mfgpt_lock, flags); - /* - * Although our caller may have the read side of xtime_lock, - * this is now a seqlock, and we are cheating in this routine - * by having side effects on state that we cannot undo if - * there is a collision on the seqlock and our caller has to - * retry. (Namely, old_jifs and old_count.) So we must treat - * jiffies as volatile despite the lock. We read jiffies - * before latching the timer count to guarantee that although - * the jiffies value might be older than the count (that is, - * the counter may underflow between the last point where - * jiffies was incremented and the point where we latch the - * count), it cannot be newer. - */ - jifs = jiffies; - /* read the count */ - count = inw(MFGPT0_CNT); - - /* - * It's possible for count to appear to go the wrong way for this - * reason: - * - * The timer counter underflows, but we haven't handled the resulting - * interrupt and incremented jiffies yet. - * - * Previous attempts to handle these cases intelligently were buggy, so - * we just do the simple thing now. - */ - if (count < old_count && jifs == old_jifs) - count = old_count; - - old_count = count; - old_jifs = jifs; - - raw_spin_unlock_irqrestore(&mfgpt_lock, flags); - - return (cycle_t) (jifs * COMPARE) + count; -} - -static struct clocksource clocksource_mfgpt = { - .name = "mfgpt", - .rating = 120, /* Functional for real use, but not desired */ - .read = mfgpt_read, - .mask = CLOCKSOURCE_MASK(32), -}; - -int __init init_mfgpt_clocksource(void) -{ - if (num_possible_cpus() > 1) /* MFGPT does not scale! */ - return 0; - - return clocksource_register_hz(&clocksource_mfgpt, MFGPT_TICK_RATE); -} - -arch_initcall(init_mfgpt_clocksource); diff --git a/arch/mips/loongson/common/cs5536/cs5536_ohci.c b/arch/mips/loongson/common/cs5536/cs5536_ohci.c deleted file mode 100644 index f7c905e50dc4..000000000000 --- a/arch/mips/loongson/common/cs5536/cs5536_ohci.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * the OHCI Virtual Support Module of AMD CS5536 - * - * Copyright (C) 2007 Lemote, Inc. - * Author : jlliu, liujl@lemote.com - * - * Copyright (C) 2009 Lemote, Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include - -void pci_ohci_write_reg(int reg, u32 value) -{ - u32 hi = 0, lo = value; - - switch (reg) { - case PCI_COMMAND: - _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); - if (value & PCI_COMMAND_MASTER) - hi |= PCI_COMMAND_MASTER; - else - hi &= ~PCI_COMMAND_MASTER; - - if (value & PCI_COMMAND_MEMORY) - hi |= PCI_COMMAND_MEMORY; - else - hi &= ~PCI_COMMAND_MEMORY; - _wrmsr(USB_MSR_REG(USB_OHCI), hi, lo); - break; - case PCI_STATUS: - if (value & PCI_STATUS_PARITY) { - _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); - if (lo & SB_PARE_ERR_FLAG) { - lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; - _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); - } - } - break; - case PCI_BAR0_REG: - if (value == PCI_BAR_RANGE_MASK) { - _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); - lo |= SOFT_BAR_OHCI_FLAG; - _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); - } else if ((value & 0x01) == 0x00) { - _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); - lo = value; - _wrmsr(USB_MSR_REG(USB_OHCI), hi, lo); - - value &= 0xfffffff0; - hi = 0x40000000 | ((value & 0xff000000) >> 24); - lo = 0x000fffff | ((value & 0x00fff000) << 8); - _wrmsr(GLIU_MSR_REG(GLIU_P2D_BM3), hi, lo); - } - break; - case PCI_OHCI_INT_REG: - _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); - lo &= ~(0xf << PIC_YSEL_LOW_USB_SHIFT); - if (value) /* enable all the usb interrupt in PIC */ - lo |= (CS5536_USB_INTR << PIC_YSEL_LOW_USB_SHIFT); - _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo); - break; - default: - break; - } -} - -u32 pci_ohci_read_reg(int reg) -{ - u32 conf_data = 0; - u32 hi, lo; - - switch (reg) { - case PCI_VENDOR_ID: - conf_data = - CFG_PCI_VENDOR_ID(CS5536_OHCI_DEVICE_ID, CS5536_VENDOR_ID); - break; - case PCI_COMMAND: - _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); - if (hi & PCI_COMMAND_MASTER) - conf_data |= PCI_COMMAND_MASTER; - if (hi & PCI_COMMAND_MEMORY) - conf_data |= PCI_COMMAND_MEMORY; - break; - case PCI_STATUS: - conf_data |= PCI_STATUS_66MHZ; - conf_data |= PCI_STATUS_FAST_BACK; - _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); - if (lo & SB_PARE_ERR_FLAG) - conf_data |= PCI_STATUS_PARITY; - conf_data |= PCI_STATUS_DEVSEL_MEDIUM; - break; - case PCI_CLASS_REVISION: - _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo); - conf_data = lo & 0x000000ff; - conf_data |= (CS5536_OHCI_CLASS_CODE << 8); - break; - case PCI_CACHE_LINE_SIZE: - conf_data = - CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, - PCI_NORMAL_LATENCY_TIMER); - break; - case PCI_BAR0_REG: - _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); - if (lo & SOFT_BAR_OHCI_FLAG) { - conf_data = CS5536_OHCI_RANGE | - PCI_BASE_ADDRESS_SPACE_MEMORY; - lo &= ~SOFT_BAR_OHCI_FLAG; - _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); - } else { - _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); - conf_data = lo & 0xffffff00; - conf_data &= ~0x0000000f; /* 32bit mem */ - } - break; - case PCI_CARDBUS_CIS: - conf_data = PCI_CARDBUS_CIS_POINTER; - break; - case PCI_SUBSYSTEM_VENDOR_ID: - conf_data = - CFG_PCI_VENDOR_ID(CS5536_OHCI_SUB_ID, CS5536_SUB_VENDOR_ID); - break; - case PCI_ROM_ADDRESS: - conf_data = PCI_EXPANSION_ROM_BAR; - break; - case PCI_CAPABILITY_LIST: - conf_data = PCI_CAPLIST_USB_POINTER; - break; - case PCI_INTERRUPT_LINE: - conf_data = - CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR); - break; - case PCI_OHCI_INT_REG: - _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); - if ((lo & 0x00000f00) == CS5536_USB_INTR) - conf_data = 1; - break; - default: - break; - } - - return conf_data; -} diff --git a/arch/mips/loongson/common/cs5536/cs5536_pci.c b/arch/mips/loongson/common/cs5536/cs5536_pci.c deleted file mode 100644 index b739723205f8..000000000000 --- a/arch/mips/loongson/common/cs5536/cs5536_pci.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * read/write operation to the PCI config space of CS5536 - * - * Copyright (C) 2007 Lemote, Inc. - * Author : jlliu, liujl@lemote.com - * - * Copyright (C) 2009 Lemote, Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * the Virtual Support Module(VSM) for virtulizing the PCI - * configure space are defined in cs5536_modulename.c respectively, - * - * after this virtulizing, user can access the PCI configure space - * directly as a normal multi-function PCI device which follows - * the PCI-2.2 spec. - */ - -#include -#include -#include - -enum { - CS5536_FUNC_START = -1, - CS5536_ISA_FUNC, - reserved_func, - CS5536_IDE_FUNC, - CS5536_ACC_FUNC, - CS5536_OHCI_FUNC, - CS5536_EHCI_FUNC, - CS5536_FUNC_END, -}; - -static const cs5536_pci_vsm_write vsm_conf_write[] = { - [CS5536_ISA_FUNC] = pci_isa_write_reg, - [reserved_func] = NULL, - [CS5536_IDE_FUNC] = pci_ide_write_reg, - [CS5536_ACC_FUNC] = pci_acc_write_reg, - [CS5536_OHCI_FUNC] = pci_ohci_write_reg, - [CS5536_EHCI_FUNC] = pci_ehci_write_reg, -}; - -static const cs5536_pci_vsm_read vsm_conf_read[] = { - [CS5536_ISA_FUNC] = pci_isa_read_reg, - [reserved_func] = NULL, - [CS5536_IDE_FUNC] = pci_ide_read_reg, - [CS5536_ACC_FUNC] = pci_acc_read_reg, - [CS5536_OHCI_FUNC] = pci_ohci_read_reg, - [CS5536_EHCI_FUNC] = pci_ehci_read_reg, -}; - -/* - * write to PCI config space and transfer it to MSR write. - */ -void cs5536_pci_conf_write4(int function, int reg, u32 value) -{ - if ((function <= CS5536_FUNC_START) || (function >= CS5536_FUNC_END)) - return; - if ((reg < 0) || (reg > 0x100) || ((reg & 0x03) != 0)) - return; - - if (vsm_conf_write[function] != NULL) - vsm_conf_write[function](reg, value); -} - -/* - * read PCI config space and transfer it to MSR access. - */ -u32 cs5536_pci_conf_read4(int function, int reg) -{ - u32 data = 0; - - if ((function <= CS5536_FUNC_START) || (function >= CS5536_FUNC_END)) - return 0; - if ((reg < 0) || ((reg & 0x03) != 0)) - return 0; - if (reg > 0x100) - return 0xffffffff; - - if (vsm_conf_read[function] != NULL) - data = vsm_conf_read[function](reg); - - return data; -} diff --git a/arch/mips/loongson/common/dma-swiotlb.c b/arch/mips/loongson/common/dma-swiotlb.c deleted file mode 100644 index 2c6b989c1bc4..000000000000 --- a/arch/mips/loongson/common/dma-swiotlb.c +++ /dev/null @@ -1,150 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -static void *loongson_dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t gfp, struct dma_attrs *attrs) -{ - void *ret; - - if (dma_alloc_from_coherent(dev, size, dma_handle, &ret)) - return ret; - - /* ignore region specifiers */ - gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM); - -#ifdef CONFIG_ISA - if (dev == NULL) - gfp |= __GFP_DMA; - else -#endif -#ifdef CONFIG_ZONE_DMA - if (dev->coherent_dma_mask < DMA_BIT_MASK(32)) - gfp |= __GFP_DMA; - else -#endif -#ifdef CONFIG_ZONE_DMA32 - if (dev->coherent_dma_mask < DMA_BIT_MASK(40)) - gfp |= __GFP_DMA32; - else -#endif - ; - gfp |= __GFP_NORETRY; - - ret = swiotlb_alloc_coherent(dev, size, dma_handle, gfp); - mb(); - return ret; -} - -static void loongson_dma_free_coherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle, struct dma_attrs *attrs) -{ - int order = get_order(size); - - if (dma_release_from_coherent(dev, order, vaddr)) - return; - - swiotlb_free_coherent(dev, size, vaddr, dma_handle); -} - -static dma_addr_t loongson_dma_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t size, - enum dma_data_direction dir, - struct dma_attrs *attrs) -{ - dma_addr_t daddr = swiotlb_map_page(dev, page, offset, size, - dir, attrs); - mb(); - return daddr; -} - -static int loongson_dma_map_sg(struct device *dev, struct scatterlist *sg, - int nents, enum dma_data_direction dir, - struct dma_attrs *attrs) -{ - int r = swiotlb_map_sg_attrs(dev, sg, nents, dir, NULL); - mb(); - - return r; -} - -static void loongson_dma_sync_single_for_device(struct device *dev, - dma_addr_t dma_handle, size_t size, - enum dma_data_direction dir) -{ - swiotlb_sync_single_for_device(dev, dma_handle, size, dir); - mb(); -} - -static void loongson_dma_sync_sg_for_device(struct device *dev, - struct scatterlist *sg, int nents, - enum dma_data_direction dir) -{ - swiotlb_sync_sg_for_device(dev, sg, nents, dir); - mb(); -} - -static int loongson_dma_set_mask(struct device *dev, u64 mask) -{ - if (mask > DMA_BIT_MASK(loongson_sysconf.dma_mask_bits)) { - *dev->dma_mask = DMA_BIT_MASK(loongson_sysconf.dma_mask_bits); - return -EIO; - } - - *dev->dma_mask = mask; - - return 0; -} - -dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) -{ - long nid; -#ifdef CONFIG_PHYS48_TO_HT40 - /* We extract 2bit node id (bit 44~47, only bit 44~45 used now) from - * Loongson-3's 48bit address space and embed it into 40bit */ - nid = (paddr >> 44) & 0x3; - paddr = ((nid << 44) ^ paddr) | (nid << 37); -#endif - return paddr; -} - -phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) -{ - long nid; -#ifdef CONFIG_PHYS48_TO_HT40 - /* We extract 2bit node id (bit 44~47, only bit 44~45 used now) from - * Loongson-3's 48bit address space and embed it into 40bit */ - nid = (daddr >> 37) & 0x3; - daddr = ((nid << 37) ^ daddr) | (nid << 44); -#endif - return daddr; -} - -static struct dma_map_ops loongson_dma_map_ops = { - .alloc = loongson_dma_alloc_coherent, - .free = loongson_dma_free_coherent, - .map_page = loongson_dma_map_page, - .unmap_page = swiotlb_unmap_page, - .map_sg = loongson_dma_map_sg, - .unmap_sg = swiotlb_unmap_sg_attrs, - .sync_single_for_cpu = swiotlb_sync_single_for_cpu, - .sync_single_for_device = loongson_dma_sync_single_for_device, - .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu, - .sync_sg_for_device = loongson_dma_sync_sg_for_device, - .mapping_error = swiotlb_dma_mapping_error, - .dma_supported = swiotlb_dma_supported, - .set_dma_mask = loongson_dma_set_mask -}; - -void __init plat_swiotlb_setup(void) -{ - swiotlb_init(1); - mips_dma_map_ops = &loongson_dma_map_ops; -} diff --git a/arch/mips/loongson/common/early_printk.c b/arch/mips/loongson/common/early_printk.c deleted file mode 100644 index 6ca632e529dc..000000000000 --- a/arch/mips/loongson/common/early_printk.c +++ /dev/null @@ -1,41 +0,0 @@ -/* early printk support - * - * Copyright (c) 2009 Philippe Vachon - * Copyright (c) 2009 Lemote Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include - -#include - -#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); -} diff --git a/arch/mips/loongson/common/env.c b/arch/mips/loongson/common/env.c deleted file mode 100644 index 22f04ca2ff3e..000000000000 --- a/arch/mips/loongson/common/env.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - * 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 - * - * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology - * Author: Fuxin Zhang, zhangfx@lemote.com - * - * Copyright (C) 2009 Lemote Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include -#include -#include -#include -#include - -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; - 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; - if (ecpu->cputype == 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_sysconf.ht_control_base = 0x90000EFDFB000000; - loongson_sysconf.workarounds = WORKAROUND_CPUFREQ; - } else if (ecpu->cputype == 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; - } else { - 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 = (¤t_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: - 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); -} diff --git a/arch/mips/loongson/common/init.c b/arch/mips/loongson/common/init.c deleted file mode 100644 index 9b987fe98b5b..000000000000 --- a/arch/mips/loongson/common/init.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2009 Lemote Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include - -#include - -/* Loongson CPU address windows config space base address */ -unsigned long __maybe_unused _loongson_addrwincfg_base; - -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); -} - -void __init prom_free_prom_memory(void) -{ -} diff --git a/arch/mips/loongson/common/irq.c b/arch/mips/loongson/common/irq.c deleted file mode 100644 index 687003b19b45..000000000000 --- a/arch/mips/loongson/common/irq.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology - * Author: Fuxin Zhang, zhangfx@lemote.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include -#include - -#include -/* - * 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(); -} diff --git a/arch/mips/loongson/common/machtype.c b/arch/mips/loongson/common/machtype.c deleted file mode 100644 index f2807bc662a3..000000000000 --- a/arch/mips/loongson/common/machtype.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2009 Lemote Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * Copyright (c) 2009 Zhang Le - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include -#include - -#include -#include - -/* 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; - } -} diff --git a/arch/mips/loongson/common/mem.c b/arch/mips/loongson/common/mem.c deleted file mode 100644 index b01d52473da8..000000000000 --- a/arch/mips/loongson/common/mem.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include -#include -#include - -#include - -#include -#include -#include -#include - -#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) { - switch (mem_type) { - case SYSTEM_RAM_LOW: - add_memory_region(loongson_memmap->map[i].mem_start, - (u64)loongson_memmap->map[i].mem_size << 20, - BOOT_MEM_RAM); - break; - case SYSTEM_RAM_HIGH: - add_memory_region(loongson_memmap->map[i].mem_start, - (u64)loongson_memmap->map[i].mem_size << 20, - BOOT_MEM_RAM); - break; - case MEM_RESERVED: - add_memory_region(loongson_memmap->map[i].mem_start, - (u64)loongson_memmap->map[i].mem_size << 20, - BOOT_MEM_RESERVED); - 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 -#include -#include - -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 */ diff --git a/arch/mips/loongson/common/pci.c b/arch/mips/loongson/common/pci.c deleted file mode 100644 index 4e2575643781..000000000000 --- a/arch/mips/loongson/common/pci.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology - * Author: Fuxin Zhang, zhangfx@lemote.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include - -#include -#include -#include - -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_LOONGSON3 - sbx00_acpi_init(); -#endif - - return 0; -} - -arch_initcall(pcibios_init); diff --git a/arch/mips/loongson/common/platform.c b/arch/mips/loongson/common/platform.c deleted file mode 100644 index 0ed38321a9a2..000000000000 --- a/arch/mips/loongson/common/platform.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2009 Lemote Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include - -static struct platform_device loongson2_cpufreq_device = { - .name = "loongson2_cpufreq", - .id = -1, -}; - -static int __init loongson2_cpufreq_init(void) -{ - struct cpuinfo_mips *c = ¤t_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); diff --git a/arch/mips/loongson/common/pm.c b/arch/mips/loongson/common/pm.c deleted file mode 100644 index a6b67ccfc811..000000000000 --- a/arch/mips/loongson/common/pm.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * loongson-specific suspend support - * - * Copyright (C) 2009 Lemote Inc. - * Author: Wu Zhangjin - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ -#include -#include -#include - -#include -#include - -#include - -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); diff --git a/arch/mips/loongson/common/reset.c b/arch/mips/loongson/common/reset.c deleted file mode 100644 index a60715e11306..000000000000 --- a/arch/mips/loongson/common/reset.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * 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 -#include - -#include -#include - -#include -#include - -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(); - unreachable(); -#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); diff --git a/arch/mips/loongson/common/rtc.c b/arch/mips/loongson/common/rtc.c deleted file mode 100644 index b5709af09f7f..000000000000 --- a/arch/mips/loongson/common/rtc.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Lemote Fuloong platform support - * - * Copyright(c) 2010 Arnaud Patard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include -#include -#include -#include - -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); diff --git a/arch/mips/loongson/common/serial.c b/arch/mips/loongson/common/serial.c deleted file mode 100644 index c23fa1373729..000000000000 --- a/arch/mips/loongson/common/serial.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * 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 -#include -#include - -#include - -#include -#include - -#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); -} - -device_initcall(serial_init); diff --git a/arch/mips/loongson/common/setup.c b/arch/mips/loongson/common/setup.c deleted file mode 100644 index d477dd6bb326..000000000000 --- a/arch/mips/loongson/common/setup.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology - * Author: Fuxin Zhang, zhangfx@lemote.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include - -#include -#include - -#include - -#ifdef CONFIG_VT -#include -#include -#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 -} diff --git a/arch/mips/loongson/common/time.c b/arch/mips/loongson/common/time.c deleted file mode 100644 index e1a5382ad47e..000000000000 --- a/arch/mips/loongson/common/time.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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 - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include -#include -#include - -#include -#include - -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_clock(struct timespec *ts) -{ - ts->tv_sec = mc146818_get_cmos_time(); - ts->tv_nsec = 0; -} diff --git a/arch/mips/loongson/common/uart_base.c b/arch/mips/loongson/common/uart_base.c deleted file mode 100644 index 9de559d58e1f..000000000000 --- a/arch/mips/loongson/common/uart_base.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2009 Lemote Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include - -#include - -/* 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); -} diff --git a/arch/mips/loongson/fuloong-2e/Makefile b/arch/mips/loongson/fuloong-2e/Makefile deleted file mode 100644 index b7622720c1ad..000000000000 --- a/arch/mips/loongson/fuloong-2e/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for Lemote Fuloong2e mini-PC board. -# - -obj-y += irq.o reset.o diff --git a/arch/mips/loongson/fuloong-2e/irq.c b/arch/mips/loongson/fuloong-2e/irq.c deleted file mode 100644 index ef5ec8f3de5f..000000000000 --- a/arch/mips/loongson/fuloong-2e/irq.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology - * Author: Fuxin Zhang, zhangfx@lemote.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include - -#include -#include - -#include - -static void i8259_irqdispatch(void) -{ - int irq; - - irq = i8259_irq(); - if (irq >= 0) - do_IRQ(irq); - else - spurious_interrupt(); -} - -asmlinkage void mach_irq_dispatch(unsigned int pending) -{ - if (pending & CAUSEF_IP7) - do_IRQ(MIPS_CPU_IRQ_BASE + 7); - else if (pending & CAUSEF_IP6) /* perf counter loverflow */ - do_perfcnt_IRQ(); - else if (pending & CAUSEF_IP5) - i8259_irqdispatch(); - else if (pending & CAUSEF_IP2) - bonito_irqdispatch(); - else - spurious_interrupt(); -} - -static struct irqaction cascade_irqaction = { - .handler = no_action, - .name = "cascade", - .flags = IRQF_NO_THREAD, -}; - -void __init mach_init_irq(void) -{ - /* init all controller - * 0-15 ------> i8259 interrupt - * 16-23 ------> mips cpu interrupt - * 32-63 ------> bonito irq - */ - - /* most bonito irq should be level triggered */ - LOONGSON_INTEDGE = LOONGSON_ICU_SYSTEMERR | LOONGSON_ICU_MASTERERR | - LOONGSON_ICU_RETRYERR | LOONGSON_ICU_MBOXES; - - /* Sets the first-level interrupt dispatcher. */ - mips_cpu_irq_init(); - init_i8259_irqs(); - bonito_irq_init(); - - /* bonito irq at IP2 */ - setup_irq(MIPS_CPU_IRQ_BASE + 2, &cascade_irqaction); - /* 8259 irq at IP5 */ - setup_irq(MIPS_CPU_IRQ_BASE + 5, &cascade_irqaction); -} diff --git a/arch/mips/loongson/fuloong-2e/reset.c b/arch/mips/loongson/fuloong-2e/reset.c deleted file mode 100644 index da4d2ae2a1f8..000000000000 --- a/arch/mips/loongson/fuloong-2e/reset.c +++ /dev/null @@ -1,23 +0,0 @@ -/* Board-specific reboot/shutdown routines - * Copyright (c) 2009 Philippe Vachon - * - * Copyright (C) 2009 Lemote Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include - -void mach_prepare_reboot(void) -{ - LOONGSON_GENCFG &= ~(1 << 2); - LOONGSON_GENCFG |= (1 << 2); -} - -void mach_prepare_shutdown(void) -{ -} diff --git a/arch/mips/loongson/lemote-2f/Makefile b/arch/mips/loongson/lemote-2f/Makefile deleted file mode 100644 index 4f9eaa328a16..000000000000 --- a/arch/mips/loongson/lemote-2f/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# -# Makefile for lemote loongson2f family machines -# - -obj-y += clock.o machtype.o irq.o reset.o ec_kb3310b.o - -# -# Suspend Support -# - -obj-$(CONFIG_LOONGSON_SUSPEND) += pm.o diff --git a/arch/mips/loongson/lemote-2f/clock.c b/arch/mips/loongson/lemote-2f/clock.c deleted file mode 100644 index 462e34d46b4a..000000000000 --- a/arch/mips/loongson/lemote-2f/clock.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2006 - 2008 Lemote Inc. & Insititute of Computing Technology - * Author: Yanhua, yanh@lemote.com - * - * 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. - */ -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -static LIST_HEAD(clock_list); -static DEFINE_SPINLOCK(clock_lock); -static DEFINE_MUTEX(clock_list_sem); - -/* Minimum CLK support */ -enum { - DC_ZERO, DC_25PT = 2, DC_37PT, DC_50PT, DC_62PT, DC_75PT, - DC_87PT, DC_DISABLE, DC_RESV -}; - -struct cpufreq_frequency_table loongson2_clockmod_table[] = { - {0, DC_RESV, CPUFREQ_ENTRY_INVALID}, - {0, DC_ZERO, CPUFREQ_ENTRY_INVALID}, - {0, DC_25PT, 0}, - {0, DC_37PT, 0}, - {0, DC_50PT, 0}, - {0, DC_62PT, 0}, - {0, DC_75PT, 0}, - {0, DC_87PT, 0}, - {0, DC_DISABLE, 0}, - {0, DC_RESV, CPUFREQ_TABLE_END}, -}; -EXPORT_SYMBOL_GPL(loongson2_clockmod_table); - -static struct clk cpu_clk = { - .name = "cpu_clk", - .flags = CLK_ALWAYS_ENABLED | CLK_RATE_PROPAGATES, - .rate = 800000000, -}; - -struct clk *clk_get(struct device *dev, const char *id) -{ - return &cpu_clk; -} -EXPORT_SYMBOL(clk_get); - -static void propagate_rate(struct clk *clk) -{ - struct clk *clkp; - - list_for_each_entry(clkp, &clock_list, node) { - if (likely(clkp->parent != clk)) - continue; - if (likely(clkp->ops && clkp->ops->recalc)) - clkp->ops->recalc(clkp); - if (unlikely(clkp->flags & CLK_RATE_PROPAGATES)) - propagate_rate(clkp); - } -} - -int clk_enable(struct clk *clk) -{ - return 0; -} -EXPORT_SYMBOL(clk_enable); - -void clk_disable(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_disable); - -unsigned long clk_get_rate(struct clk *clk) -{ - return (unsigned long)clk->rate; -} -EXPORT_SYMBOL(clk_get_rate); - -void clk_put(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_put); - -int clk_set_rate(struct clk *clk, unsigned long rate) -{ - unsigned int rate_khz = rate / 1000; - struct cpufreq_frequency_table *pos; - int ret = 0; - int regval; - - if (likely(clk->ops && clk->ops->set_rate)) { - unsigned long flags; - - spin_lock_irqsave(&clock_lock, flags); - ret = clk->ops->set_rate(clk, rate, 0); - spin_unlock_irqrestore(&clock_lock, flags); - } - - if (unlikely(clk->flags & CLK_RATE_PROPAGATES)) - propagate_rate(clk); - - cpufreq_for_each_valid_entry(pos, loongson2_clockmod_table) - if (rate_khz == pos->frequency) - break; - if (rate_khz != pos->frequency) - return -ENOTSUPP; - - clk->rate = rate; - - regval = LOONGSON_CHIPCFG(0); - regval = (regval & ~0x7) | (pos->driver_data - 1); - LOONGSON_CHIPCFG(0) = regval; - - return ret; -} -EXPORT_SYMBOL_GPL(clk_set_rate); - -long clk_round_rate(struct clk *clk, unsigned long rate) -{ - if (likely(clk->ops && clk->ops->round_rate)) { - unsigned long flags, rounded; - - spin_lock_irqsave(&clock_lock, flags); - rounded = clk->ops->round_rate(clk, rate); - spin_unlock_irqrestore(&clock_lock, flags); - - return rounded; - } - - return rate; -} -EXPORT_SYMBOL_GPL(clk_round_rate); diff --git a/arch/mips/loongson/lemote-2f/ec_kb3310b.c b/arch/mips/loongson/lemote-2f/ec_kb3310b.c deleted file mode 100644 index 2b666d3a3947..000000000000 --- a/arch/mips/loongson/lemote-2f/ec_kb3310b.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Basic KB3310B Embedded Controller support for the YeeLoong 2F netbook - * - * Copyright (C) 2008 Lemote Inc. - * Author: liujl , 2008-04-20 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include -#include -#include - -#include "ec_kb3310b.h" - -static DEFINE_SPINLOCK(index_access_lock); -static DEFINE_SPINLOCK(port_access_lock); - -unsigned char ec_read(unsigned short addr) -{ - unsigned char value; - unsigned long flags; - - spin_lock_irqsave(&index_access_lock, flags); - outb((addr & 0xff00) >> 8, EC_IO_PORT_HIGH); - outb((addr & 0x00ff), EC_IO_PORT_LOW); - value = inb(EC_IO_PORT_DATA); - spin_unlock_irqrestore(&index_access_lock, flags); - - return value; -} -EXPORT_SYMBOL_GPL(ec_read); - -void ec_write(unsigned short addr, unsigned char val) -{ - unsigned long flags; - - spin_lock_irqsave(&index_access_lock, flags); - outb((addr & 0xff00) >> 8, EC_IO_PORT_HIGH); - outb((addr & 0x00ff), EC_IO_PORT_LOW); - outb(val, EC_IO_PORT_DATA); - /* flush the write action */ - inb(EC_IO_PORT_DATA); - spin_unlock_irqrestore(&index_access_lock, flags); -} -EXPORT_SYMBOL_GPL(ec_write); - -/* - * This function is used for EC command writes and corresponding status queries. - */ -int ec_query_seq(unsigned char cmd) -{ - int timeout; - unsigned char status; - unsigned long flags; - int ret = 0; - - spin_lock_irqsave(&port_access_lock, flags); - - /* make chip goto reset mode */ - udelay(EC_REG_DELAY); - outb(cmd, EC_CMD_PORT); - udelay(EC_REG_DELAY); - - /* check if the command is received by ec */ - timeout = EC_CMD_TIMEOUT; - status = inb(EC_STS_PORT); - while (timeout-- && (status & (1 << 1))) { - status = inb(EC_STS_PORT); - udelay(EC_REG_DELAY); - } - - spin_unlock_irqrestore(&port_access_lock, flags); - - if (timeout <= 0) { - printk(KERN_ERR "%s: deadable error : timeout...\n", __func__); - ret = -EINVAL; - } else - printk(KERN_INFO - "(%x/%d)ec issued command %d status : 0x%x\n", - timeout, EC_CMD_TIMEOUT - timeout, cmd, status); - - return ret; -} -EXPORT_SYMBOL_GPL(ec_query_seq); - -/* - * Send query command to EC to get the proper event number - */ -int ec_query_event_num(void) -{ - return ec_query_seq(CMD_GET_EVENT_NUM); -} -EXPORT_SYMBOL(ec_query_event_num); - -/* - * Get event number from EC - * - * NOTE: This routine must follow the query_event_num function in the - * interrupt. - */ -int ec_get_event_num(void) -{ - int timeout = 100; - unsigned char value; - unsigned char status; - - udelay(EC_REG_DELAY); - status = inb(EC_STS_PORT); - udelay(EC_REG_DELAY); - while (timeout-- && !(status & (1 << 0))) { - status = inb(EC_STS_PORT); - udelay(EC_REG_DELAY); - } - if (timeout <= 0) { - pr_info("%s: get event number timeout.\n", __func__); - - return -EINVAL; - } - value = inb(EC_DAT_PORT); - udelay(EC_REG_DELAY); - - return value; -} -EXPORT_SYMBOL(ec_get_event_num); diff --git a/arch/mips/loongson/lemote-2f/ec_kb3310b.h b/arch/mips/loongson/lemote-2f/ec_kb3310b.h deleted file mode 100644 index 5a3f1860d4d2..000000000000 --- a/arch/mips/loongson/lemote-2f/ec_kb3310b.h +++ /dev/null @@ -1,188 +0,0 @@ -/* - * KB3310B Embedded Controller - * - * Copyright (C) 2008 Lemote Inc. - * Author: liujl , 2008-03-14 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#ifndef _EC_KB3310B_H -#define _EC_KB3310B_H - -extern unsigned char ec_read(unsigned short addr); -extern void ec_write(unsigned short addr, unsigned char val); -extern int ec_query_seq(unsigned char cmd); -extern int ec_query_event_num(void); -extern int ec_get_event_num(void); - -typedef int (*sci_handler) (int status); -extern sci_handler yeeloong_report_lid_status; - -#define SCI_IRQ_NUM 0x0A - -/* - * The following registers are determined by the EC index configuration. - * 1, fill the PORT_HIGH as EC register high part. - * 2, fill the PORT_LOW as EC register low part. - * 3, fill the PORT_DATA as EC register write data or get the data from it. - */ -#define EC_IO_PORT_HIGH 0x0381 -#define EC_IO_PORT_LOW 0x0382 -#define EC_IO_PORT_DATA 0x0383 - -/* - * EC delay time is 500us for register and status access - */ -#define EC_REG_DELAY 500 /* unit : us */ -#define EC_CMD_TIMEOUT 0x1000 - -/* - * EC access port for SCI communication - */ -#define EC_CMD_PORT 0x66 -#define EC_STS_PORT 0x66 -#define EC_DAT_PORT 0x62 -#define CMD_INIT_IDLE_MODE 0xdd -#define CMD_EXIT_IDLE_MODE 0xdf -#define CMD_INIT_RESET_MODE 0xd8 -#define CMD_REBOOT_SYSTEM 0x8c -#define CMD_GET_EVENT_NUM 0x84 -#define CMD_PROGRAM_PIECE 0xda - -/* temperature & fan registers */ -#define REG_TEMPERATURE_VALUE 0xF458 -#define REG_FAN_AUTO_MAN_SWITCH 0xF459 -#define BIT_FAN_AUTO 0 -#define BIT_FAN_MANUAL 1 -#define REG_FAN_CONTROL 0xF4D2 -#define BIT_FAN_CONTROL_ON (1 << 0) -#define BIT_FAN_CONTROL_OFF (0 << 0) -#define REG_FAN_STATUS 0xF4DA -#define BIT_FAN_STATUS_ON (1 << 0) -#define BIT_FAN_STATUS_OFF (0 << 0) -#define REG_FAN_SPEED_HIGH 0xFE22 -#define REG_FAN_SPEED_LOW 0xFE23 -#define REG_FAN_SPEED_LEVEL 0xF4CC -/* fan speed divider */ -#define FAN_SPEED_DIVIDER 480000 /* (60*1000*1000/62.5/2)*/ - -/* battery registers */ -#define REG_BAT_DESIGN_CAP_HIGH 0xF77D -#define REG_BAT_DESIGN_CAP_LOW 0xF77E -#define REG_BAT_FULLCHG_CAP_HIGH 0xF780 -#define REG_BAT_FULLCHG_CAP_LOW 0xF781 -#define REG_BAT_DESIGN_VOL_HIGH 0xF782 -#define REG_BAT_DESIGN_VOL_LOW 0xF783 -#define REG_BAT_CURRENT_HIGH 0xF784 -#define REG_BAT_CURRENT_LOW 0xF785 -#define REG_BAT_VOLTAGE_HIGH 0xF786 -#define REG_BAT_VOLTAGE_LOW 0xF787 -#define REG_BAT_TEMPERATURE_HIGH 0xF788 -#define REG_BAT_TEMPERATURE_LOW 0xF789 -#define REG_BAT_RELATIVE_CAP_HIGH 0xF492 -#define REG_BAT_RELATIVE_CAP_LOW 0xF493 -#define REG_BAT_VENDOR 0xF4C4 -#define FLAG_BAT_VENDOR_SANYO 0x01 -#define FLAG_BAT_VENDOR_SIMPLO 0x02 -#define REG_BAT_CELL_COUNT 0xF4C6 -#define FLAG_BAT_CELL_3S1P 0x03 -#define FLAG_BAT_CELL_3S2P 0x06 -#define REG_BAT_CHARGE 0xF4A2 -#define FLAG_BAT_CHARGE_DISCHARGE 0x01 -#define FLAG_BAT_CHARGE_CHARGE 0x02 -#define FLAG_BAT_CHARGE_ACPOWER 0x00 -#define REG_BAT_STATUS 0xF4B0 -#define BIT_BAT_STATUS_LOW (1 << 5) -#define BIT_BAT_STATUS_DESTROY (1 << 2) -#define BIT_BAT_STATUS_FULL (1 << 1) -#define BIT_BAT_STATUS_IN (1 << 0) -#define REG_BAT_CHARGE_STATUS 0xF4B1 -#define BIT_BAT_CHARGE_STATUS_OVERTEMP (1 << 2) -#define BIT_BAT_CHARGE_STATUS_PRECHG (1 << 1) -#define REG_BAT_STATE 0xF482 -#define BIT_BAT_STATE_CHARGING (1 << 1) -#define BIT_BAT_STATE_DISCHARGING (1 << 0) -#define REG_BAT_POWER 0xF440 -#define BIT_BAT_POWER_S3 (1 << 2) -#define BIT_BAT_POWER_ON (1 << 1) -#define BIT_BAT_POWER_ACIN (1 << 0) - -/* other registers */ -/* Audio: rd/wr */ -#define REG_AUDIO_VOLUME 0xF46C -#define REG_AUDIO_MUTE 0xF4E7 -#define REG_AUDIO_BEEP 0xF4D0 -/* USB port power or not: rd/wr */ -#define REG_USB0_FLAG 0xF461 -#define REG_USB1_FLAG 0xF462 -#define REG_USB2_FLAG 0xF463 -#define BIT_USB_FLAG_ON 1 -#define BIT_USB_FLAG_OFF 0 -/* LID */ -#define REG_LID_DETECT 0xF4BD -#define BIT_LID_DETECT_ON 1 -#define BIT_LID_DETECT_OFF 0 -/* CRT */ -#define REG_CRT_DETECT 0xF4AD -#define BIT_CRT_DETECT_PLUG 1 -#define BIT_CRT_DETECT_UNPLUG 0 -/* LCD backlight brightness adjust: 9 levels */ -#define REG_DISPLAY_BRIGHTNESS 0xF4F5 -/* Black screen Status */ -#define BIT_DISPLAY_LCD_ON 1 -#define BIT_DISPLAY_LCD_OFF 0 -/* LCD backlight control: off/restore */ -#define REG_BACKLIGHT_CTRL 0xF7BD -#define BIT_BACKLIGHT_ON 1 -#define BIT_BACKLIGHT_OFF 0 -/* Reset the machine auto-clear: rd/wr */ -#define REG_RESET 0xF4EC -#define BIT_RESET_ON 1 -/* Light the led: rd/wr */ -#define REG_LED 0xF4C8 -#define BIT_LED_RED_POWER (1 << 0) -#define BIT_LED_ORANGE_POWER (1 << 1) -#define BIT_LED_GREEN_CHARGE (1 << 2) -#define BIT_LED_RED_CHARGE (1 << 3) -#define BIT_LED_NUMLOCK (1 << 4) -/* Test led mode, all led on/off */ -#define REG_LED_TEST 0xF4C2 -#define BIT_LED_TEST_IN 1 -#define BIT_LED_TEST_OUT 0 -/* Camera on/off */ -#define REG_CAMERA_STATUS 0xF46A -#define BIT_CAMERA_STATUS_ON 1 -#define BIT_CAMERA_STATUS_OFF 0 -#define REG_CAMERA_CONTROL 0xF7B7 -#define BIT_CAMERA_CONTROL_OFF 0 -#define BIT_CAMERA_CONTROL_ON 1 -/* Wlan Status */ -#define REG_WLAN 0xF4FA -#define BIT_WLAN_ON 1 -#define BIT_WLAN_OFF 0 -#define REG_DISPLAY_LCD 0xF79F - -/* SCI Event Number from EC */ -enum { - EVENT_LID = 0x23, /* LID open/close */ - EVENT_DISPLAY_TOGGLE, /* Fn+F3 for display switch */ - EVENT_SLEEP, /* Fn+F1 for entering sleep mode */ - EVENT_OVERTEMP, /* Over-temperature happened */ - EVENT_CRT_DETECT, /* CRT is connected */ - EVENT_CAMERA, /* Camera on/off */ - EVENT_USB_OC2, /* USB2 Over Current occurred */ - EVENT_USB_OC0, /* USB0 Over Current occurred */ - EVENT_BLACK_SCREEN, /* Turn on/off backlight */ - EVENT_AUDIO_MUTE, /* Mute on/off */ - EVENT_DISPLAY_BRIGHTNESS,/* LCD backlight brightness adjust */ - EVENT_AC_BAT, /* AC & Battery relative issue */ - EVENT_AUDIO_VOLUME, /* Volume adjust */ - EVENT_WLAN, /* Wlan on/off */ - EVENT_END -}; - -#endif /* !_EC_KB3310B_H */ diff --git a/arch/mips/loongson/lemote-2f/irq.c b/arch/mips/loongson/lemote-2f/irq.c deleted file mode 100644 index cab5f43e0e29..000000000000 --- a/arch/mips/loongson/lemote-2f/irq.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) 2007 Lemote Inc. - * Author: Fuxin Zhang, zhangfx@lemote.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include - -#include -#include -#include - -#include -#include - -#define LOONGSON_TIMER_IRQ (MIPS_CPU_IRQ_BASE + 7) /* cpu timer */ -#define LOONGSON_NORTH_BRIDGE_IRQ (MIPS_CPU_IRQ_BASE + 6) /* bonito */ -#define LOONGSON_UART_IRQ (MIPS_CPU_IRQ_BASE + 3) /* cpu serial port */ -#define LOONGSON_SOUTH_BRIDGE_IRQ (MIPS_CPU_IRQ_BASE + 2) /* i8259 */ - -#define LOONGSON_INT_BIT_INT0 (1 << 11) -#define LOONGSON_INT_BIT_INT1 (1 << 12) - -/* - * The generic i8259_irq() make the kernel hang on booting. Since we cannot - * get the irq via the IRR directly, we access the ISR instead. - */ -int mach_i8259_irq(void) -{ - int irq, isr; - - irq = -1; - - if ((LOONGSON_INTISR & LOONGSON_INTEN) & LOONGSON_INT_BIT_INT0) { - raw_spin_lock(&i8259A_lock); - isr = inb(PIC_MASTER_CMD) & - ~inb(PIC_MASTER_IMR) & ~(1 << PIC_CASCADE_IR); - if (!isr) - isr = (inb(PIC_SLAVE_CMD) & ~inb(PIC_SLAVE_IMR)) << 8; - irq = ffs(isr) - 1; - if (unlikely(irq == 7)) { - /* - * This may be a spurious interrupt. - * - * Read the interrupt status register (ISR). If the most - * significant bit is not set then there is no valid - * interrupt. - */ - outb(0x0B, PIC_MASTER_ISR); /* ISR register */ - if (~inb(PIC_MASTER_ISR) & 0x80) - irq = -1; - } - raw_spin_unlock(&i8259A_lock); - } - - return irq; -} -EXPORT_SYMBOL(mach_i8259_irq); - -static void i8259_irqdispatch(void) -{ - int irq; - - irq = mach_i8259_irq(); - if (irq >= 0) - do_IRQ(irq); - else - spurious_interrupt(); -} - -void mach_irq_dispatch(unsigned int pending) -{ - if (pending & CAUSEF_IP7) - do_IRQ(LOONGSON_TIMER_IRQ); - else if (pending & CAUSEF_IP6) { /* North Bridge, Perf counter */ - do_perfcnt_IRQ(); - bonito_irqdispatch(); - } else if (pending & CAUSEF_IP3) /* CPU UART */ - do_IRQ(LOONGSON_UART_IRQ); - else if (pending & CAUSEF_IP2) /* South Bridge */ - i8259_irqdispatch(); - else - spurious_interrupt(); -} - -static irqreturn_t ip6_action(int cpl, void *dev_id) -{ - return IRQ_HANDLED; -} - -static struct irqaction ip6_irqaction = { - .handler = ip6_action, - .name = "cascade", - .flags = IRQF_SHARED | IRQF_NO_THREAD, -}; - -static struct irqaction cascade_irqaction = { - .handler = no_action, - .name = "cascade", - .flags = IRQF_NO_THREAD, -}; - -void __init mach_init_irq(void) -{ - /* init all controller - * 0-15 ------> i8259 interrupt - * 16-23 ------> mips cpu interrupt - * 32-63 ------> bonito irq - */ - - /* setup cs5536 as high level trigger */ - LOONGSON_INTPOL = LOONGSON_INT_BIT_INT0 | LOONGSON_INT_BIT_INT1; - LOONGSON_INTEDGE &= ~(LOONGSON_INT_BIT_INT0 | LOONGSON_INT_BIT_INT1); - - /* Sets the first-level interrupt dispatcher. */ - mips_cpu_irq_init(); - init_i8259_irqs(); - bonito_irq_init(); - - /* setup north bridge irq (bonito) */ - setup_irq(LOONGSON_NORTH_BRIDGE_IRQ, &ip6_irqaction); - /* setup source bridge irq (i8259) */ - setup_irq(LOONGSON_SOUTH_BRIDGE_IRQ, &cascade_irqaction); -} diff --git a/arch/mips/loongson/lemote-2f/machtype.c b/arch/mips/loongson/lemote-2f/machtype.c deleted file mode 100644 index b55e6eece5e0..000000000000 --- a/arch/mips/loongson/lemote-2f/machtype.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2009 Lemote Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include - -#include - -void __init mach_prom_init_machtype(void) -{ - /* We share the same kernel image file among Lemote 2F family - * of machines, and provide the machtype= kernel command line - * to users to indicate their machine, this command line will - * be passed by the latest PMON automatically. and fortunately, - * up to now, we can get the machine type from the PMON_VER= - * commandline directly except the NAS machine, In the old - * machines, this will help the users a lot. - * - * If no "machtype=" passed, get machine type from "PMON_VER=". - * PMON_VER=LM8089 Lemote 8.9'' netbook - * LM8101 Lemote 10.1'' netbook - * (The above two netbooks have the same kernel support) - * LM6XXX Lemote FuLoong(2F) box series - * LM9XXX Lemote LynLoong PC series - */ - if (strstr(arcs_cmdline, "PMON_VER=LM")) { - if (strstr(arcs_cmdline, "PMON_VER=LM8")) - mips_machtype = MACH_LEMOTE_YL2F89; - else if (strstr(arcs_cmdline, "PMON_VER=LM6")) - mips_machtype = MACH_LEMOTE_FL2F; - else if (strstr(arcs_cmdline, "PMON_VER=LM9")) - mips_machtype = MACH_LEMOTE_LL2F; - else - mips_machtype = MACH_LEMOTE_NAS; - - strcat(arcs_cmdline, " machtype="); - strcat(arcs_cmdline, get_system_type()); - strcat(arcs_cmdline, " "); - } -} diff --git a/arch/mips/loongson/lemote-2f/pm.c b/arch/mips/loongson/lemote-2f/pm.c deleted file mode 100644 index cac4d382ea73..000000000000 --- a/arch/mips/loongson/lemote-2f/pm.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Lemote loongson2f family machines' specific suspend support - * - * Copyright (C) 2009 Lemote Inc. - * Author: Wu Zhangjin - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include -#include "ec_kb3310b.h" - -#define I8042_KBD_IRQ 1 -#define I8042_CTR_KBDINT 0x01 -#define I8042_CTR_KBDDIS 0x10 - -static unsigned char i8042_ctr; - -static int i8042_enable_kbd_port(void) -{ - if (i8042_command(&i8042_ctr, I8042_CMD_CTL_RCTR)) { - pr_err("i8042.c: Can't read CTR while enabling i8042 kbd port." - "\n"); - return -EIO; - } - - i8042_ctr &= ~I8042_CTR_KBDDIS; - i8042_ctr |= I8042_CTR_KBDINT; - - if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { - i8042_ctr &= ~I8042_CTR_KBDINT; - i8042_ctr |= I8042_CTR_KBDDIS; - pr_err("i8042.c: Failed to enable KBD port.\n"); - - return -EIO; - } - - return 0; -} - -void setup_wakeup_events(void) -{ - int irq_mask; - - switch (mips_machtype) { - case MACH_LEMOTE_ML2F7: - case MACH_LEMOTE_YL2F89: - /* open the keyboard irq in i8259A */ - outb((0xff & ~(1 << I8042_KBD_IRQ)), PIC_MASTER_IMR); - irq_mask = inb(PIC_MASTER_IMR); - - /* enable keyboard port */ - i8042_enable_kbd_port(); - - /* Wakeup CPU via SCI lid open event */ - outb(irq_mask & ~(1 << PIC_CASCADE_IR), PIC_MASTER_IMR); - inb(PIC_MASTER_IMR); - outb(0xff & ~(1 << (SCI_IRQ_NUM - 8)), PIC_SLAVE_IMR); - inb(PIC_SLAVE_IMR); - - break; - - default: - break; - } -} - -static struct delayed_work lid_task; -static int initialized; -/* yeeloong_report_lid_status will be implemented in yeeloong_laptop.c */ -sci_handler yeeloong_report_lid_status; -EXPORT_SYMBOL(yeeloong_report_lid_status); -static void yeeloong_lid_update_task(struct work_struct *work) -{ - if (yeeloong_report_lid_status) - yeeloong_report_lid_status(BIT_LID_DETECT_ON); -} - -int wakeup_loongson(void) -{ - int irq; - - /* query the interrupt number */ - irq = mach_i8259_irq(); - if (irq < 0) - return 0; - - printk(KERN_INFO "%s: irq = %d\n", __func__, irq); - - if (irq == I8042_KBD_IRQ) - return 1; - else if (irq == SCI_IRQ_NUM) { - int ret, sci_event; - /* query the event number */ - ret = ec_query_seq(CMD_GET_EVENT_NUM); - if (ret < 0) - return 0; - sci_event = ec_get_event_num(); - if (sci_event < 0) - return 0; - if (sci_event == EVENT_LID) { - int lid_status; - /* check the LID status */ - lid_status = ec_read(REG_LID_DETECT); - /* wakeup cpu when people open the LID */ - if (lid_status == BIT_LID_DETECT_ON) { - /* If we call it directly here, the WARNING - * will be sent out by getnstimeofday - * via "WARN_ON(timekeeping_suspended);" - * because we can not schedule in suspend mode. - */ - if (initialized == 0) { - INIT_DELAYED_WORK(&lid_task, - yeeloong_lid_update_task); - initialized = 1; - } - schedule_delayed_work(&lid_task, 1); - return 1; - } - } - } - - return 0; -} - -void __weak mach_suspend(void) -{ - disable_mfgpt0_counter(); -} - -void __weak mach_resume(void) -{ - enable_mfgpt0_counter(); -} diff --git a/arch/mips/loongson/lemote-2f/reset.c b/arch/mips/loongson/lemote-2f/reset.c deleted file mode 100644 index a26ca7fcd7e0..000000000000 --- a/arch/mips/loongson/lemote-2f/reset.c +++ /dev/null @@ -1,159 +0,0 @@ -/* Board-specific reboot/shutdown routines - * - * Copyright (c) 2009 Philippe Vachon - * - * Copyright (C) 2009 Lemote Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include - -#include - -#include - -#include -#include "ec_kb3310b.h" - -static void reset_cpu(void) -{ - /* - * reset cpu to full speed, this is needed when enabling cpu frequency - * scalling - */ - LOONGSON_CHIPCFG(0) |= 0x7; -} - -/* reset support for fuloong2f */ - -static void fl2f_reboot(void) -{ - reset_cpu(); - - /* send a reset signal to south bridge. - * - * NOTE: if enable "Power Management" in kernel, rtl8169 will not reset - * normally with this reset operation and it will not work in PMON, but - * you can type halt command and then reboot, seems the hardware reset - * logic not work normally. - */ - { - u32 hi, lo; - _rdmsr(DIVIL_MSR_REG(DIVIL_SOFT_RESET), &hi, &lo); - lo |= 0x00000001; - _wrmsr(DIVIL_MSR_REG(DIVIL_SOFT_RESET), hi, lo); - } -} - -static void fl2f_shutdown(void) -{ - u32 hi, lo, val; - int gpio_base; - - /* get gpio base */ - _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &lo); - gpio_base = lo & 0xff00; - - /* make cs5536 gpio13 output enable */ - val = inl(gpio_base + GPIOL_OUT_EN); - val &= ~(1 << (16 + 13)); - val |= (1 << 13); - outl(val, gpio_base + GPIOL_OUT_EN); - mmiowb(); - /* make cs5536 gpio13 output low level voltage. */ - val = inl(gpio_base + GPIOL_OUT_VAL) & ~(1 << (13)); - val |= (1 << (16 + 13)); - outl(val, gpio_base + GPIOL_OUT_VAL); - mmiowb(); -} - -/* reset support for yeeloong2f and mengloong2f notebook */ - -static void ml2f_reboot(void) -{ - reset_cpu(); - - /* sending an reset signal to EC(embedded controller) */ - ec_write(REG_RESET, BIT_RESET_ON); -} - -#define yl2f89_reboot ml2f_reboot - -/* menglong(7inches) laptop has different shutdown logic from 8.9inches */ -#define EC_SHUTDOWN_IO_PORT_HIGH 0xff2d -#define EC_SHUTDOWN_IO_PORT_LOW 0xff2e -#define EC_SHUTDOWN_IO_PORT_DATA 0xff2f -#define REG_SHUTDOWN_HIGH 0xFC -#define REG_SHUTDOWN_LOW 0x29 -#define BIT_SHUTDOWN_ON (1 << 1) - -static void ml2f_shutdown(void) -{ - u8 val; - u64 i; - - outb(REG_SHUTDOWN_HIGH, EC_SHUTDOWN_IO_PORT_HIGH); - outb(REG_SHUTDOWN_LOW, EC_SHUTDOWN_IO_PORT_LOW); - mmiowb(); - val = inb(EC_SHUTDOWN_IO_PORT_DATA); - outb(val & (~BIT_SHUTDOWN_ON), EC_SHUTDOWN_IO_PORT_DATA); - mmiowb(); - /* need enough wait here... how many microseconds needs? */ - for (i = 0; i < 0x10000; i++) - delay(); - outb(val | BIT_SHUTDOWN_ON, EC_SHUTDOWN_IO_PORT_DATA); - mmiowb(); -} - -static void yl2f89_shutdown(void) -{ - /* cpu-gpio0 output low */ - LOONGSON_GPIODATA &= ~0x00000001; - /* cpu-gpio0 as output */ - LOONGSON_GPIOIE &= ~0x00000001; -} - -void mach_prepare_reboot(void) -{ - switch (mips_machtype) { - case MACH_LEMOTE_FL2F: - case MACH_LEMOTE_NAS: - case MACH_LEMOTE_LL2F: - fl2f_reboot(); - break; - case MACH_LEMOTE_ML2F7: - ml2f_reboot(); - break; - case MACH_LEMOTE_YL2F89: - yl2f89_reboot(); - break; - default: - break; - } -} - -void mach_prepare_shutdown(void) -{ - switch (mips_machtype) { - case MACH_LEMOTE_FL2F: - case MACH_LEMOTE_NAS: - case MACH_LEMOTE_LL2F: - fl2f_shutdown(); - break; - case MACH_LEMOTE_ML2F7: - ml2f_shutdown(); - break; - case MACH_LEMOTE_YL2F89: - yl2f89_shutdown(); - break; - default: - break; - } -} diff --git a/arch/mips/loongson/loongson-3/Makefile b/arch/mips/loongson/loongson-3/Makefile deleted file mode 100644 index 622fead5ebc9..000000000000 --- a/arch/mips/loongson/loongson-3/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# -# Makefile for Loongson-3 family machines -# -obj-y += irq.o cop2-ex.o platform.o - -obj-$(CONFIG_SMP) += smp.o - -obj-$(CONFIG_NUMA) += numa.o - -obj-$(CONFIG_RS780_HPET) += hpet.o diff --git a/arch/mips/loongson/loongson-3/cop2-ex.c b/arch/mips/loongson/loongson-3/cop2-ex.c deleted file mode 100644 index ea13764d0a03..000000000000 --- a/arch/mips/loongson/loongson-3/cop2-ex.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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) 2014 Lemote Corporation. - * written by Huacai Chen - * - * based on arch/mips/cavium-octeon/cpu.c - * Copyright (C) 2009 Wind River Systems, - * written by Ralf Baechle - */ -#include -#include -#include - -#include -#include -#include -#include - -static int loongson_cu2_call(struct notifier_block *nfb, unsigned long action, - void *data) -{ - int fpu_owned; - int fr = !test_thread_flag(TIF_32BIT_FPREGS); - - switch (action) { - case CU2_EXCEPTION: - preempt_disable(); - fpu_owned = __is_fpu_owner(); - if (!fr) - set_c0_status(ST0_CU1 | ST0_CU2); - else - set_c0_status(ST0_CU1 | ST0_CU2 | ST0_FR); - enable_fpu_hazard(); - KSTK_STATUS(current) |= (ST0_CU1 | ST0_CU2); - if (fr) - KSTK_STATUS(current) |= ST0_FR; - else - KSTK_STATUS(current) &= ~ST0_FR; - /* If FPU is owned, we needn't init or restore fp */ - if (!fpu_owned) { - set_thread_flag(TIF_USEDFPU); - if (!used_math()) { - _init_fpu(current->thread.fpu.fcr31); - set_used_math(); - } else - _restore_fp(current); - } - preempt_enable(); - - return NOTIFY_STOP; /* Don't call default notifier */ - } - - return NOTIFY_OK; /* Let default notifier send signals */ -} - -static int __init loongson_cu2_setup(void) -{ - return cu2_notifier(loongson_cu2_call, 0); -} -early_initcall(loongson_cu2_setup); diff --git a/arch/mips/loongson/loongson-3/hpet.c b/arch/mips/loongson/loongson-3/hpet.c deleted file mode 100644 index 5c21cd3bd339..000000000000 --- a/arch/mips/loongson/loongson-3/hpet.c +++ /dev/null @@ -1,257 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include -#include - -#define SMBUS_CFG_BASE (loongson_sysconf.ht_control_base + 0x0300a000) -#define SMBUS_PCI_REG40 0x40 -#define SMBUS_PCI_REG64 0x64 -#define SMBUS_PCI_REGB4 0xb4 - -static DEFINE_SPINLOCK(hpet_lock); -DEFINE_PER_CPU(struct clock_event_device, hpet_clockevent_device); - -static unsigned int smbus_read(int offset) -{ - return *(volatile unsigned int *)(SMBUS_CFG_BASE + offset); -} - -static void smbus_write(int offset, int data) -{ - *(volatile unsigned int *)(SMBUS_CFG_BASE + offset) = data; -} - -static void smbus_enable(int offset, int bit) -{ - unsigned int cfg = smbus_read(offset); - - cfg |= bit; - smbus_write(offset, cfg); -} - -static int hpet_read(int offset) -{ - return *(volatile unsigned int *)(HPET_MMIO_ADDR + offset); -} - -static void hpet_write(int offset, int data) -{ - *(volatile unsigned int *)(HPET_MMIO_ADDR + offset) = data; -} - -static void hpet_start_counter(void) -{ - unsigned int cfg = hpet_read(HPET_CFG); - - cfg |= HPET_CFG_ENABLE; - hpet_write(HPET_CFG, cfg); -} - -static void hpet_stop_counter(void) -{ - unsigned int cfg = hpet_read(HPET_CFG); - - cfg &= ~HPET_CFG_ENABLE; - hpet_write(HPET_CFG, cfg); -} - -static void hpet_reset_counter(void) -{ - hpet_write(HPET_COUNTER, 0); - hpet_write(HPET_COUNTER + 4, 0); -} - -static void hpet_restart_counter(void) -{ - hpet_stop_counter(); - hpet_reset_counter(); - hpet_start_counter(); -} - -static void hpet_enable_legacy_int(void) -{ - /* Do nothing on Loongson-3 */ -} - -static void hpet_set_mode(enum clock_event_mode mode, - struct clock_event_device *evt) -{ - int cfg = 0; - - spin_lock(&hpet_lock); - switch (mode) { - case CLOCK_EVT_MODE_PERIODIC: - pr_info("set clock event to periodic mode!\n"); - /* stop counter */ - hpet_stop_counter(); - - /* enables the timer0 to generate a periodic interrupt */ - cfg = hpet_read(HPET_T0_CFG); - cfg &= ~HPET_TN_LEVEL; - cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC | - HPET_TN_SETVAL | HPET_TN_32BIT; - hpet_write(HPET_T0_CFG, cfg); - - /* set the comparator */ - hpet_write(HPET_T0_CMP, HPET_COMPARE_VAL); - udelay(1); - hpet_write(HPET_T0_CMP, HPET_COMPARE_VAL); - - /* start counter */ - hpet_start_counter(); - break; - case CLOCK_EVT_MODE_SHUTDOWN: - case CLOCK_EVT_MODE_UNUSED: - cfg = hpet_read(HPET_T0_CFG); - cfg &= ~HPET_TN_ENABLE; - hpet_write(HPET_T0_CFG, cfg); - break; - case CLOCK_EVT_MODE_ONESHOT: - pr_info("set clock event to one shot mode!\n"); - cfg = hpet_read(HPET_T0_CFG); - /* set timer0 type - * 1 : periodic interrupt - * 0 : non-periodic(oneshot) interrupt - */ - cfg &= ~HPET_TN_PERIODIC; - cfg |= HPET_TN_ENABLE | HPET_TN_32BIT; - hpet_write(HPET_T0_CFG, cfg); - break; - case CLOCK_EVT_MODE_RESUME: - hpet_enable_legacy_int(); - break; - } - spin_unlock(&hpet_lock); -} - -static int hpet_next_event(unsigned long delta, - struct clock_event_device *evt) -{ - unsigned int cnt; - int res; - - cnt = hpet_read(HPET_COUNTER); - cnt += delta; - hpet_write(HPET_T0_CMP, cnt); - - res = ((int)(hpet_read(HPET_COUNTER) - cnt) > 0) ? -ETIME : 0; - return res; -} - -static irqreturn_t hpet_irq_handler(int irq, void *data) -{ - int is_irq; - struct clock_event_device *cd; - unsigned int cpu = smp_processor_id(); - - is_irq = hpet_read(HPET_STATUS); - if (is_irq & HPET_T0_IRS) { - /* clear the TIMER0 irq status register */ - hpet_write(HPET_STATUS, HPET_T0_IRS); - cd = &per_cpu(hpet_clockevent_device, cpu); - cd->event_handler(cd); - return IRQ_HANDLED; - } - return IRQ_NONE; -} - -static struct irqaction hpet_irq = { - .handler = hpet_irq_handler, - .flags = IRQF_NOBALANCING | IRQF_TIMER, - .name = "hpet", -}; - -/* - * hpet address assignation and irq setting should be done in bios. - * but pmon don't do this, we just setup here directly. - * The operation under is normal. unfortunately, hpet_setup process - * is before pci initialize. - * - * { - * struct pci_dev *pdev; - * - * pdev = pci_get_device(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS, NULL); - * pci_write_config_word(pdev, SMBUS_PCI_REGB4, HPET_ADDR); - * - * ... - * } - */ -static void hpet_setup(void) -{ - /* set hpet base address */ - smbus_write(SMBUS_PCI_REGB4, HPET_ADDR); - - /* enable decodeing of access to HPET MMIO*/ - smbus_enable(SMBUS_PCI_REG40, (1 << 28)); - - /* HPET irq enable */ - smbus_enable(SMBUS_PCI_REG64, (1 << 10)); - - hpet_enable_legacy_int(); -} - -void __init setup_hpet_timer(void) -{ - unsigned int cpu = smp_processor_id(); - struct clock_event_device *cd; - - hpet_setup(); - - cd = &per_cpu(hpet_clockevent_device, cpu); - cd->name = "hpet"; - cd->rating = 320; - cd->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; - cd->set_mode = hpet_set_mode; - cd->set_next_event = hpet_next_event; - cd->irq = HPET_T0_IRQ; - cd->cpumask = cpumask_of(cpu); - clockevent_set_clock(cd, HPET_FREQ); - cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); - cd->min_delta_ns = 5000; - - clockevents_register_device(cd); - setup_irq(HPET_T0_IRQ, &hpet_irq); - pr_info("hpet clock event device register\n"); -} - -static cycle_t hpet_read_counter(struct clocksource *cs) -{ - return (cycle_t)hpet_read(HPET_COUNTER); -} - -static void hpet_suspend(struct clocksource *cs) -{ -} - -static void hpet_resume(struct clocksource *cs) -{ - hpet_setup(); - hpet_restart_counter(); -} - -static struct clocksource csrc_hpet = { - .name = "hpet", - /* mips clocksource rating is less than 300, so hpet is better. */ - .rating = 300, - .read = hpet_read_counter, - .mask = CLOCKSOURCE_MASK(32), - /* oneshot mode work normal with this flag */ - .flags = CLOCK_SOURCE_IS_CONTINUOUS, - .suspend = hpet_suspend, - .resume = hpet_resume, - .mult = 0, - .shift = 10, -}; - -int __init init_hpet_clocksource(void) -{ - csrc_hpet.mult = clocksource_hz2mult(HPET_FREQ, csrc_hpet.shift); - return clocksource_register_hz(&csrc_hpet, HPET_FREQ); -} - -arch_initcall(init_hpet_clocksource); diff --git a/arch/mips/loongson/loongson-3/irq.c b/arch/mips/loongson/loongson-3/irq.c deleted file mode 100644 index 0f75b6b3d218..000000000000 --- a/arch/mips/loongson/loongson-3/irq.c +++ /dev/null @@ -1,143 +0,0 @@ -#include -#include -#include -#include - -#include -#include -#include - -#include "smp.h" - -unsigned int ht_irq[] = {0, 1, 3, 4, 5, 6, 7, 8, 12, 14, 15}; - -static void ht_irqdispatch(void) -{ - unsigned int i, irq; - - irq = LOONGSON_HT1_INT_VECTOR(0); - LOONGSON_HT1_INT_VECTOR(0) = irq; /* Acknowledge the IRQs */ - - for (i = 0; i < ARRAY_SIZE(ht_irq); i++) { - if (irq & (0x1 << ht_irq[i])) - do_IRQ(ht_irq[i]); - } -} - -void mach_irq_dispatch(unsigned int pending) -{ - if (pending & CAUSEF_IP7) - do_IRQ(LOONGSON_TIMER_IRQ); -#if defined(CONFIG_SMP) - else if (pending & CAUSEF_IP6) - loongson3_ipi_interrupt(NULL); -#endif - else if (pending & CAUSEF_IP3) - ht_irqdispatch(); - else if (pending & CAUSEF_IP2) - do_IRQ(LOONGSON_UART_IRQ); - else { - pr_err("%s : spurious interrupt\n", __func__); - spurious_interrupt(); - } -} - -static struct irqaction cascade_irqaction = { - .handler = no_action, - .flags = IRQF_NO_SUSPEND, - .name = "cascade", -}; - -static inline void mask_loongson_irq(struct irq_data *d) -{ - clear_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE)); - irq_disable_hazard(); - - /* Workaround: UART IRQ may deliver to any core */ - if (d->irq == LOONGSON_UART_IRQ) { - int cpu = smp_processor_id(); - int node_id = cpu_logical_map(cpu) / loongson_sysconf.cores_per_node; - int core_id = cpu_logical_map(cpu) % loongson_sysconf.cores_per_node; - u64 intenclr_addr = smp_group[node_id] | - (u64)(&LOONGSON_INT_ROUTER_INTENCLR); - u64 introuter_lpc_addr = smp_group[node_id] | - (u64)(&LOONGSON_INT_ROUTER_LPC); - - *(volatile u32 *)intenclr_addr = 1 << 10; - *(volatile u8 *)introuter_lpc_addr = 0x10 + (1<irq == LOONGSON_UART_IRQ) { - int cpu = smp_processor_id(); - int node_id = cpu_logical_map(cpu) / loongson_sysconf.cores_per_node; - int core_id = cpu_logical_map(cpu) % loongson_sysconf.cores_per_node; - u64 intenset_addr = smp_group[node_id] | - (u64)(&LOONGSON_INT_ROUTER_INTENSET); - u64 introuter_lpc_addr = smp_group[node_id] | - (u64)(&LOONGSON_INT_ROUTER_LPC); - - *(volatile u32 *)intenset_addr = 1 << 10; - *(volatile u8 *)introuter_lpc_addr = 0x10 + (1<irq - MIPS_CPU_IRQ_BASE)); - irq_enable_hazard(); -} - - /* For MIPS IRQs which shared by all cores */ -static struct irq_chip loongson_irq_chip = { - .name = "Loongson", - .irq_ack = mask_loongson_irq, - .irq_mask = mask_loongson_irq, - .irq_mask_ack = mask_loongson_irq, - .irq_unmask = unmask_loongson_irq, - .irq_eoi = unmask_loongson_irq, -}; - -void irq_router_init(void) -{ - int i; - - /* route LPC int to cpu core0 int 0 */ - LOONGSON_INT_ROUTER_LPC = - LOONGSON_INT_COREx_INTy(loongson_sysconf.boot_cpu_id, 0); - /* route HT1 int0 ~ int7 to cpu core0 INT1*/ - for (i = 0; i < 8; i++) - LOONGSON_INT_ROUTER_HT1(i) = - LOONGSON_INT_COREx_INTy(loongson_sysconf.boot_cpu_id, 1); - /* enable HT1 interrupt */ - LOONGSON_HT1_INTN_EN(0) = 0xffffffff; - /* enable router interrupt intenset */ - LOONGSON_INT_ROUTER_INTENSET = - LOONGSON_INT_ROUTER_INTEN | (0xffff << 16) | 0x1 << 10; -} - -void __init mach_init_irq(void) -{ - clear_c0_status(ST0_IM | ST0_BEV); - - irq_router_init(); - mips_cpu_irq_init(); - init_i8259_irqs(); - irq_set_chip_and_handler(LOONGSON_UART_IRQ, - &loongson_irq_chip, handle_level_irq); - - /* setup HT1 irq */ - setup_irq(LOONGSON_HT1_IRQ, &cascade_irqaction); - - set_c0_status(STATUSF_IP2 | STATUSF_IP6); -} - -#ifdef CONFIG_HOTPLUG_CPU - -void fixup_irqs(void) -{ - irq_cpu_offline(); - clear_c0_status(ST0_IM); -} - -#endif diff --git a/arch/mips/loongson/loongson-3/numa.c b/arch/mips/loongson/loongson-3/numa.c deleted file mode 100644 index 12d14ed48778..000000000000 --- a/arch/mips/loongson/loongson-3/numa.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * Copyright (C) 2010 Loongson Inc. & Lemote Inc. & - * Insititute of Computing Technology - * Author: Xiang Gao, gaoxiang@ict.ac.cn - * Huacai Chen, chenhc@lemote.com - * Xiaofu Meng, Shuangshuang Zhang - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static struct node_data prealloc__node_data[MAX_NUMNODES]; -unsigned char __node_distances[MAX_NUMNODES][MAX_NUMNODES]; -EXPORT_SYMBOL(__node_distances); -struct node_data *__node_data[MAX_NUMNODES]; -EXPORT_SYMBOL(__node_data); - -static void enable_lpa(void) -{ - unsigned long value; - - value = __read_32bit_c0_register($16, 3); - value |= 0x00000080; - __write_32bit_c0_register($16, 3, value); - value = __read_32bit_c0_register($16, 3); - pr_info("CP0_Config3: CP0 16.3 (0x%lx)\n", value); - - value = __read_32bit_c0_register($5, 1); - value |= 0x20000000; - __write_32bit_c0_register($5, 1, value); - value = __read_32bit_c0_register($5, 1); - pr_info("CP0_PageGrain: CP0 5.1 (0x%lx)\n", value); -} - -static void cpu_node_probe(void) -{ - int i; - - nodes_clear(node_possible_map); - nodes_clear(node_online_map); - for (i = 0; i < loongson_sysconf.nr_nodes; i++) { - node_set_state(num_online_nodes(), N_POSSIBLE); - node_set_online(num_online_nodes()); - } - - pr_info("NUMA: Discovered %d cpus on %d nodes\n", - loongson_sysconf.nr_cpus, num_online_nodes()); -} - -static int __init compute_node_distance(int row, int col) -{ - int package_row = row * loongson_sysconf.cores_per_node / - loongson_sysconf.cores_per_package; - int package_col = col * loongson_sysconf.cores_per_node / - loongson_sysconf.cores_per_package; - - if (col == row) - return 0; - else if (package_row == package_col) - return 40; - else - return 100; -} - -static void __init init_topology_matrix(void) -{ - int row, col; - - for (row = 0; row < MAX_NUMNODES; row++) - for (col = 0; col < MAX_NUMNODES; col++) - __node_distances[row][col] = -1; - - for_each_online_node(row) { - for_each_online_node(col) { - __node_distances[row][col] = - compute_node_distance(row, col); - } - } -} - -static unsigned long nid_to_addroffset(unsigned int nid) -{ - unsigned long result; - switch (nid) { - case 0: - default: - result = NODE0_ADDRSPACE_OFFSET; - break; - case 1: - result = NODE1_ADDRSPACE_OFFSET; - break; - case 2: - result = NODE2_ADDRSPACE_OFFSET; - break; - case 3: - result = NODE3_ADDRSPACE_OFFSET; - break; - } - return result; -} - -static void __init szmem(unsigned int node) -{ - u32 i, mem_type; - static unsigned long num_physpages = 0; - u64 node_id, node_psize, start_pfn, end_pfn, mem_start, mem_size; - - /* Parse memory information and activate */ - for (i = 0; i < loongson_memmap->nr_map; i++) { - node_id = loongson_memmap->map[i].node_id; - if (node_id != node) - continue; - - mem_type = loongson_memmap->map[i].mem_type; - mem_size = loongson_memmap->map[i].mem_size; - mem_start = loongson_memmap->map[i].mem_start; - - switch (mem_type) { - case SYSTEM_RAM_LOW: - start_pfn = ((node_id << 44) + mem_start) >> PAGE_SHIFT; - node_psize = (mem_size << 20) >> PAGE_SHIFT; - end_pfn = start_pfn + node_psize; - num_physpages += node_psize; - pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx MB\n", - (u32)node_id, mem_type, mem_start, mem_size); - pr_info(" start_pfn:0x%llx, end_pfn:0x%llx, num_physpages:0x%lx\n", - start_pfn, end_pfn, num_physpages); - add_memory_region((node_id << 44) + mem_start, - (u64)mem_size << 20, BOOT_MEM_RAM); - memblock_add_node(PFN_PHYS(start_pfn), - PFN_PHYS(end_pfn - start_pfn), node); - break; - case SYSTEM_RAM_HIGH: - start_pfn = ((node_id << 44) + mem_start) >> PAGE_SHIFT; - node_psize = (mem_size << 20) >> PAGE_SHIFT; - end_pfn = start_pfn + node_psize; - num_physpages += node_psize; - pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx MB\n", - (u32)node_id, mem_type, mem_start, mem_size); - pr_info(" start_pfn:0x%llx, end_pfn:0x%llx, num_physpages:0x%lx\n", - start_pfn, end_pfn, num_physpages); - add_memory_region((node_id << 44) + mem_start, - (u64)mem_size << 20, BOOT_MEM_RAM); - memblock_add_node(PFN_PHYS(start_pfn), - PFN_PHYS(end_pfn - start_pfn), node); - break; - case MEM_RESERVED: - pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx MB\n", - (u32)node_id, mem_type, mem_start, mem_size); - add_memory_region((node_id << 44) + mem_start, - (u64)mem_size << 20, BOOT_MEM_RESERVED); - memblock_reserve(((node_id << 44) + mem_start), - mem_size << 20); - break; - } - } -} - -static void __init node_mem_init(unsigned int node) -{ - unsigned long bootmap_size; - unsigned long node_addrspace_offset; - unsigned long start_pfn, end_pfn, freepfn; - - node_addrspace_offset = nid_to_addroffset(node); - pr_info("Node%d's addrspace_offset is 0x%lx\n", - node, node_addrspace_offset); - - get_pfn_range_for_nid(node, &start_pfn, &end_pfn); - freepfn = start_pfn; - if (node == 0) - freepfn = PFN_UP(__pa_symbol(&_end)); /* kernel end address */ - pr_info("Node%d: start_pfn=0x%lx, end_pfn=0x%lx, freepfn=0x%lx\n", - node, start_pfn, end_pfn, freepfn); - - __node_data[node] = prealloc__node_data + node; - - NODE_DATA(node)->bdata = &bootmem_node_data[node]; - NODE_DATA(node)->node_start_pfn = start_pfn; - NODE_DATA(node)->node_spanned_pages = end_pfn - start_pfn; - - bootmap_size = init_bootmem_node(NODE_DATA(node), freepfn, - start_pfn, end_pfn); - free_bootmem_with_active_regions(node, end_pfn); - if (node == 0) /* used by finalize_initrd() */ - max_low_pfn = end_pfn; - - /* This is reserved for the kernel and bdata->node_bootmem_map */ - reserve_bootmem_node(NODE_DATA(node), start_pfn << PAGE_SHIFT, - ((freepfn - start_pfn) << PAGE_SHIFT) + bootmap_size, - BOOTMEM_DEFAULT); - - if (node == 0 && node_end_pfn(0) >= (0xffffffff >> PAGE_SHIFT)) { - /* Reserve 0xff800000~0xffffffff for RS780E integrated GPU */ - reserve_bootmem_node(NODE_DATA(node), - (node_addrspace_offset | 0xff800000), - 8 << 20, BOOTMEM_DEFAULT); - } - - sparse_memory_present_with_active_regions(node); -} - -static __init void prom_meminit(void) -{ - unsigned int node, cpu, active_cpu = 0; - - cpu_node_probe(); - init_topology_matrix(); - - for (node = 0; node < loongson_sysconf.nr_nodes; node++) { - if (node_online(node)) { - szmem(node); - node_mem_init(node); - cpumask_clear(&__node_data[(node)]->cpumask); - } - } - for (cpu = 0; cpu < loongson_sysconf.nr_cpus; cpu++) { - node = cpu / loongson_sysconf.cores_per_node; - if (node >= num_online_nodes()) - node = 0; - - if (loongson_sysconf.reserved_cpus_mask & (1<cpumask); - pr_info("NUMA: set cpumask cpu %d on node %d\n", active_cpu, node); - - active_cpu++; - } -} - -void __init paging_init(void) -{ - unsigned node; - unsigned long zones_size[MAX_NR_ZONES] = {0, }; - - pagetable_init(); - - for_each_online_node(node) { - unsigned long start_pfn, end_pfn; - - get_pfn_range_for_nid(node, &start_pfn, &end_pfn); - - if (end_pfn > max_low_pfn) - max_low_pfn = end_pfn; - } -#ifdef CONFIG_ZONE_DMA32 - zones_size[ZONE_DMA32] = MAX_DMA32_PFN; -#endif - zones_size[ZONE_NORMAL] = max_low_pfn; - free_area_init_nodes(zones_size); -} - -void __init mem_init(void) -{ - high_memory = (void *) __va(get_num_physpages() << PAGE_SHIFT); - free_all_bootmem(); - setup_zero_pages(); /* This comes from node 0 */ - mem_init_print_info(NULL); -} - -/* All PCI device belongs to logical Node-0 */ -int pcibus_to_node(struct pci_bus *bus) -{ - return 0; -} -EXPORT_SYMBOL(pcibus_to_node); - -void __init prom_init_numa_memory(void) -{ - enable_lpa(); - prom_meminit(); -} -EXPORT_SYMBOL(prom_init_numa_memory); diff --git a/arch/mips/loongson/loongson-3/platform.c b/arch/mips/loongson/loongson-3/platform.c deleted file mode 100644 index 25a97cc0ee33..000000000000 --- a/arch/mips/loongson/loongson-3/platform.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2009 Lemote Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * Xiang Yu, xiangy@lemote.com - * Chen Huacai, chenhc@lemote.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include - -static int __init loongson3_platform_init(void) -{ - int i; - struct platform_device *pdev; - - if (loongson_sysconf.ecname[0] != '\0') - platform_device_register_simple(loongson_sysconf.ecname, -1, NULL, 0); - - for (i = 0; i < loongson_sysconf.nr_sensors; i++) { - if (loongson_sysconf.sensors[i].type > SENSOR_FAN) - continue; - - pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL); - pdev->name = loongson_sysconf.sensors[i].name; - pdev->id = loongson_sysconf.sensors[i].id; - pdev->dev.platform_data = &loongson_sysconf.sensors[i]; - platform_device_register(pdev); - } - - return 0; -} - -arch_initcall(loongson3_platform_init); diff --git a/arch/mips/loongson/loongson-3/smp.c b/arch/mips/loongson/loongson-3/smp.c deleted file mode 100644 index 509877c6e9d9..000000000000 --- a/arch/mips/loongson/loongson-3/smp.c +++ /dev/null @@ -1,652 +0,0 @@ -/* - * Copyright (C) 2010, 2011, 2012, Lemote, Inc. - * Author: Chen Huacai, chenhc@lemote.com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "smp.h" - -DEFINE_PER_CPU(int, cpu_state); -DEFINE_PER_CPU(uint32_t, core0_c0count); - -static void *ipi_set0_regs[16]; -static void *ipi_clear0_regs[16]; -static void *ipi_status0_regs[16]; -static void *ipi_en0_regs[16]; -static void *ipi_mailbox_buf[16]; - -/* read a 32bit value from ipi register */ -#define loongson3_ipi_read32(addr) readl(addr) -/* read a 64bit value from ipi register */ -#define loongson3_ipi_read64(addr) readq(addr) -/* write a 32bit value to ipi register */ -#define loongson3_ipi_write32(action, addr) \ - do { \ - writel(action, addr); \ - __wbflush(); \ - } while (0) -/* write a 64bit value to ipi register */ -#define loongson3_ipi_write64(action, addr) \ - do { \ - writeq(action, addr); \ - __wbflush(); \ - } while (0) - -static void ipi_set0_regs_init(void) -{ - ipi_set0_regs[0] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + SET0); - ipi_set0_regs[1] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + SET0); - ipi_set0_regs[2] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + SET0); - ipi_set0_regs[3] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + SET0); - ipi_set0_regs[4] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + SET0); - ipi_set0_regs[5] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + SET0); - ipi_set0_regs[6] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + SET0); - ipi_set0_regs[7] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + SET0); - ipi_set0_regs[8] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + SET0); - ipi_set0_regs[9] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + SET0); - ipi_set0_regs[10] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + SET0); - ipi_set0_regs[11] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + SET0); - ipi_set0_regs[12] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + SET0); - ipi_set0_regs[13] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + SET0); - ipi_set0_regs[14] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + SET0); - ipi_set0_regs[15] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + SET0); -} - -static void ipi_clear0_regs_init(void) -{ - ipi_clear0_regs[0] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + CLEAR0); - ipi_clear0_regs[1] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + CLEAR0); - ipi_clear0_regs[2] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + CLEAR0); - ipi_clear0_regs[3] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + CLEAR0); - ipi_clear0_regs[4] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + CLEAR0); - ipi_clear0_regs[5] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + CLEAR0); - ipi_clear0_regs[6] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + CLEAR0); - ipi_clear0_regs[7] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + CLEAR0); - ipi_clear0_regs[8] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + CLEAR0); - ipi_clear0_regs[9] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + CLEAR0); - ipi_clear0_regs[10] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + CLEAR0); - ipi_clear0_regs[11] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + CLEAR0); - ipi_clear0_regs[12] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + CLEAR0); - ipi_clear0_regs[13] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + CLEAR0); - ipi_clear0_regs[14] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + CLEAR0); - ipi_clear0_regs[15] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + CLEAR0); -} - -static void ipi_status0_regs_init(void) -{ - ipi_status0_regs[0] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + STATUS0); - ipi_status0_regs[1] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + STATUS0); - ipi_status0_regs[2] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + STATUS0); - ipi_status0_regs[3] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + STATUS0); - ipi_status0_regs[4] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + STATUS0); - ipi_status0_regs[5] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + STATUS0); - ipi_status0_regs[6] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + STATUS0); - ipi_status0_regs[7] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + STATUS0); - ipi_status0_regs[8] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + STATUS0); - ipi_status0_regs[9] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + STATUS0); - ipi_status0_regs[10] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + STATUS0); - ipi_status0_regs[11] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + STATUS0); - ipi_status0_regs[12] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + STATUS0); - ipi_status0_regs[13] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + STATUS0); - ipi_status0_regs[14] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + STATUS0); - ipi_status0_regs[15] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + STATUS0); -} - -static void ipi_en0_regs_init(void) -{ - ipi_en0_regs[0] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + EN0); - ipi_en0_regs[1] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + EN0); - ipi_en0_regs[2] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + EN0); - ipi_en0_regs[3] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + EN0); - ipi_en0_regs[4] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + EN0); - ipi_en0_regs[5] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + EN0); - ipi_en0_regs[6] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + EN0); - ipi_en0_regs[7] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + EN0); - ipi_en0_regs[8] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + EN0); - ipi_en0_regs[9] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + EN0); - ipi_en0_regs[10] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + EN0); - ipi_en0_regs[11] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + EN0); - ipi_en0_regs[12] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + EN0); - ipi_en0_regs[13] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + EN0); - ipi_en0_regs[14] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + EN0); - ipi_en0_regs[15] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + EN0); -} - -static void ipi_mailbox_buf_init(void) -{ - ipi_mailbox_buf[0] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + BUF); - ipi_mailbox_buf[1] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + BUF); - ipi_mailbox_buf[2] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + BUF); - ipi_mailbox_buf[3] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + BUF); - ipi_mailbox_buf[4] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + BUF); - ipi_mailbox_buf[5] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + BUF); - ipi_mailbox_buf[6] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + BUF); - ipi_mailbox_buf[7] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + BUF); - ipi_mailbox_buf[8] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + BUF); - ipi_mailbox_buf[9] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + BUF); - ipi_mailbox_buf[10] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + BUF); - ipi_mailbox_buf[11] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + BUF); - ipi_mailbox_buf[12] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + BUF); - ipi_mailbox_buf[13] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + BUF); - ipi_mailbox_buf[14] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + BUF); - ipi_mailbox_buf[15] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + BUF); -} - -/* - * Simple enough, just poke the appropriate ipi register - */ -static void loongson3_send_ipi_single(int cpu, unsigned int action) -{ - loongson3_ipi_write32((u32)action, ipi_set0_regs[cpu_logical_map(cpu)]); -} - -static void -loongson3_send_ipi_mask(const struct cpumask *mask, unsigned int action) -{ - unsigned int i; - - for_each_cpu(i, mask) - loongson3_ipi_write32((u32)action, ipi_set0_regs[cpu_logical_map(i)]); -} - -void loongson3_ipi_interrupt(struct pt_regs *regs) -{ - int i, cpu = smp_processor_id(); - unsigned int action, c0count; - - /* Load the ipi register to figure out what we're supposed to do */ - action = loongson3_ipi_read32(ipi_status0_regs[cpu_logical_map(cpu)]); - - /* Clear the ipi register to clear the interrupt */ - loongson3_ipi_write32((u32)action, ipi_clear0_regs[cpu_logical_map(cpu)]); - - if (action & SMP_RESCHEDULE_YOURSELF) - scheduler_ipi(); - - if (action & SMP_CALL_FUNCTION) - smp_call_function_interrupt(); - - if (action & SMP_ASK_C0COUNT) { - BUG_ON(cpu != 0); - c0count = read_c0_count(); - for (i = 1; i < num_possible_cpus(); i++) - per_cpu(core0_c0count, i) = c0count; - } -} - -#define MAX_LOOPS 1111 -/* - * SMP init and finish on secondary CPUs - */ -static void loongson3_init_secondary(void) -{ - int i; - uint32_t initcount; - unsigned int cpu = smp_processor_id(); - unsigned int imask = STATUSF_IP7 | STATUSF_IP6 | - STATUSF_IP3 | STATUSF_IP2; - - /* Set interrupt mask, but don't enable */ - change_c0_status(ST0_IM, imask); - - for (i = 0; i < num_possible_cpus(); i++) - loongson3_ipi_write32(0xffffffff, ipi_en0_regs[cpu_logical_map(i)]); - - per_cpu(cpu_state, cpu) = CPU_ONLINE; - cpu_data[cpu].core = - cpu_logical_map(cpu) % loongson_sysconf.cores_per_package; - cpu_data[cpu].package = - cpu_logical_map(cpu) / loongson_sysconf.cores_per_package; - - i = 0; - __this_cpu_write(core0_c0count, 0); - loongson3_send_ipi_single(0, SMP_ASK_C0COUNT); - while (!__this_cpu_read(core0_c0count)) { - i++; - cpu_relax(); - } - - if (i > MAX_LOOPS) - i = MAX_LOOPS; - initcount = __this_cpu_read(core0_c0count) + i; - write_c0_count(initcount); -} - -static void loongson3_smp_finish(void) -{ - int cpu = smp_processor_id(); - - write_c0_compare(read_c0_count() + mips_hpt_frequency/HZ); - local_irq_enable(); - loongson3_ipi_write64(0, - (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x0)); - pr_info("CPU#%d finished, CP0_ST=%x\n", - smp_processor_id(), read_c0_status()); -} - -static void __init loongson3_smp_setup(void) -{ - int i = 0, num = 0; /* i: physical id, num: logical id */ - - init_cpu_possible(cpu_none_mask); - - /* For unified kernel, NR_CPUS is the maximum possible value, - * loongson_sysconf.nr_cpus is the really present value */ - while (i < loongson_sysconf.nr_cpus) { - if (loongson_sysconf.reserved_cpus_mask & (1< - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include - -#include -#include - -#define LS1X_INTC_REG(n, x) \ - ((void __iomem *)KSEG1ADDR(LS1X_INTC_BASE + (n * 0x18) + (x))) - -#define LS1X_INTC_INTISR(n) LS1X_INTC_REG(n, 0x0) -#define LS1X_INTC_INTIEN(n) LS1X_INTC_REG(n, 0x4) -#define LS1X_INTC_INTSET(n) LS1X_INTC_REG(n, 0x8) -#define LS1X_INTC_INTCLR(n) LS1X_INTC_REG(n, 0xc) -#define LS1X_INTC_INTPOL(n) LS1X_INTC_REG(n, 0x10) -#define LS1X_INTC_INTEDGE(n) LS1X_INTC_REG(n, 0x14) - -static void ls1x_irq_ack(struct irq_data *d) -{ - unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f; - unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5; - - __raw_writel(__raw_readl(LS1X_INTC_INTCLR(n)) - | (1 << bit), LS1X_INTC_INTCLR(n)); -} - -static void ls1x_irq_mask(struct irq_data *d) -{ - unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f; - unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5; - - __raw_writel(__raw_readl(LS1X_INTC_INTIEN(n)) - & ~(1 << bit), LS1X_INTC_INTIEN(n)); -} - -static void ls1x_irq_mask_ack(struct irq_data *d) -{ - unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f; - unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5; - - __raw_writel(__raw_readl(LS1X_INTC_INTIEN(n)) - & ~(1 << bit), LS1X_INTC_INTIEN(n)); - __raw_writel(__raw_readl(LS1X_INTC_INTCLR(n)) - | (1 << bit), LS1X_INTC_INTCLR(n)); -} - -static void ls1x_irq_unmask(struct irq_data *d) -{ - unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f; - unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5; - - __raw_writel(__raw_readl(LS1X_INTC_INTIEN(n)) - | (1 << bit), LS1X_INTC_INTIEN(n)); -} - -static struct irq_chip ls1x_irq_chip = { - .name = "LS1X-INTC", - .irq_ack = ls1x_irq_ack, - .irq_mask = ls1x_irq_mask, - .irq_mask_ack = ls1x_irq_mask_ack, - .irq_unmask = ls1x_irq_unmask, -}; - -static void ls1x_irq_dispatch(int n) -{ - u32 int_status, irq; - - /* Get pending sources, masked by current enables */ - int_status = __raw_readl(LS1X_INTC_INTISR(n)) & - __raw_readl(LS1X_INTC_INTIEN(n)); - - if (int_status) { - irq = LS1X_IRQ(n, __ffs(int_status)); - do_IRQ(irq); - } -} - -asmlinkage void plat_irq_dispatch(void) -{ - unsigned int pending; - - pending = read_c0_cause() & read_c0_status() & ST0_IM; - - if (pending & CAUSEF_IP7) - do_IRQ(TIMER_IRQ); - else if (pending & CAUSEF_IP2) - ls1x_irq_dispatch(0); /* INT0 */ - else if (pending & CAUSEF_IP3) - ls1x_irq_dispatch(1); /* INT1 */ - else if (pending & CAUSEF_IP4) - ls1x_irq_dispatch(2); /* INT2 */ - else if (pending & CAUSEF_IP5) - ls1x_irq_dispatch(3); /* INT3 */ - else if (pending & CAUSEF_IP6) - ls1x_irq_dispatch(4); /* INT4 */ - else - spurious_interrupt(); - -} - -struct irqaction cascade_irqaction = { - .handler = no_action, - .name = "cascade", - .flags = IRQF_NO_THREAD, -}; - -static void __init ls1x_irq_init(int base) -{ - int n; - - /* Disable interrupts and clear pending, - * setup all IRQs as high level triggered - */ - for (n = 0; n < 4; n++) { - __raw_writel(0x0, LS1X_INTC_INTIEN(n)); - __raw_writel(0xffffffff, LS1X_INTC_INTCLR(n)); - __raw_writel(0xffffffff, LS1X_INTC_INTPOL(n)); - /* set DMA0, DMA1 and DMA2 to edge trigger */ - __raw_writel(n ? 0x0 : 0xe000, LS1X_INTC_INTEDGE(n)); - } - - - for (n = base; n < LS1X_IRQS; n++) { - irq_set_chip_and_handler(n, &ls1x_irq_chip, - handle_level_irq); - } - - setup_irq(INT0_IRQ, &cascade_irqaction); - setup_irq(INT1_IRQ, &cascade_irqaction); - setup_irq(INT2_IRQ, &cascade_irqaction); - setup_irq(INT3_IRQ, &cascade_irqaction); -} - -void __init arch_init_irq(void) -{ - mips_cpu_irq_init(); - ls1x_irq_init(LS1X_IRQ_BASE); -} diff --git a/arch/mips/loongson1/common/platform.c b/arch/mips/loongson1/common/platform.c deleted file mode 100644 index ddf1d4cbf31e..000000000000 --- a/arch/mips/loongson1/common/platform.c +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright (c) 2011 Zhang, Keguang - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -/* 8250/16550 compatible UART */ -#define LS1X_UART(_id) \ - { \ - .mapbase = LS1X_UART ## _id ## _BASE, \ - .irq = LS1X_UART ## _id ## _IRQ, \ - .iotype = UPIO_MEM, \ - .flags = UPF_IOREMAP | UPF_FIXED_TYPE, \ - .type = PORT_16550A, \ - } - -static struct plat_serial8250_port ls1x_serial8250_pdata[] = { - LS1X_UART(0), - LS1X_UART(1), - LS1X_UART(2), - LS1X_UART(3), - {}, -}; - -struct platform_device ls1x_uart_pdev = { - .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM, - .dev = { - .platform_data = ls1x_serial8250_pdata, - }, -}; - -void __init ls1x_serial_setup(struct platform_device *pdev) -{ - struct clk *clk; - struct plat_serial8250_port *p; - - clk = clk_get(&pdev->dev, pdev->name); - if (IS_ERR(clk)) { - pr_err("unable to get %s clock, err=%ld", - pdev->name, PTR_ERR(clk)); - return; - } - clk_prepare_enable(clk); - - for (p = pdev->dev.platform_data; p->flags != 0; ++p) - p->uartclk = clk_get_rate(clk); -} - -/* CPUFreq */ -static struct plat_ls1x_cpufreq ls1x_cpufreq_pdata = { - .clk_name = "cpu_clk", - .osc_clk_name = "osc_33m_clk", - .max_freq = 266 * 1000, - .min_freq = 33 * 1000, -}; - -struct platform_device ls1x_cpufreq_pdev = { - .name = "ls1x-cpufreq", - .dev = { - .platform_data = &ls1x_cpufreq_pdata, - }, -}; - -/* Synopsys Ethernet GMAC */ -static struct stmmac_mdio_bus_data ls1x_mdio_bus_data = { - .phy_mask = 0, -}; - -static struct stmmac_dma_cfg ls1x_eth_dma_cfg = { - .pbl = 1, -}; - -int ls1x_eth_mux_init(struct platform_device *pdev, void *priv) -{ - struct plat_stmmacenet_data *plat_dat = NULL; - u32 val; - - val = __raw_readl(LS1X_MUX_CTRL1); - - plat_dat = dev_get_platdata(&pdev->dev); - if (plat_dat->bus_id) { - __raw_writel(__raw_readl(LS1X_MUX_CTRL0) | GMAC1_USE_UART1 | - GMAC1_USE_UART0, LS1X_MUX_CTRL0); - switch (plat_dat->interface) { - case PHY_INTERFACE_MODE_RGMII: - val &= ~(GMAC1_USE_TXCLK | GMAC1_USE_PWM23); - break; - case PHY_INTERFACE_MODE_MII: - val |= (GMAC1_USE_TXCLK | GMAC1_USE_PWM23); - break; - default: - pr_err("unsupported mii mode %d\n", - plat_dat->interface); - return -ENOTSUPP; - } - val &= ~GMAC1_SHUT; - } else { - switch (plat_dat->interface) { - case PHY_INTERFACE_MODE_RGMII: - val &= ~(GMAC0_USE_TXCLK | GMAC0_USE_PWM01); - break; - case PHY_INTERFACE_MODE_MII: - val |= (GMAC0_USE_TXCLK | GMAC0_USE_PWM01); - break; - default: - pr_err("unsupported mii mode %d\n", - plat_dat->interface); - return -ENOTSUPP; - } - val &= ~GMAC0_SHUT; - } - __raw_writel(val, LS1X_MUX_CTRL1); - - return 0; -} - -static struct plat_stmmacenet_data ls1x_eth0_pdata = { - .bus_id = 0, - .phy_addr = -1, - .interface = PHY_INTERFACE_MODE_MII, - .mdio_bus_data = &ls1x_mdio_bus_data, - .dma_cfg = &ls1x_eth_dma_cfg, - .has_gmac = 1, - .tx_coe = 1, - .init = ls1x_eth_mux_init, -}; - -static struct resource ls1x_eth0_resources[] = { - [0] = { - .start = LS1X_GMAC0_BASE, - .end = LS1X_GMAC0_BASE + SZ_64K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .name = "macirq", - .start = LS1X_GMAC0_IRQ, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device ls1x_eth0_pdev = { - .name = "stmmaceth", - .id = 0, - .num_resources = ARRAY_SIZE(ls1x_eth0_resources), - .resource = ls1x_eth0_resources, - .dev = { - .platform_data = &ls1x_eth0_pdata, - }, -}; - -static struct plat_stmmacenet_data ls1x_eth1_pdata = { - .bus_id = 1, - .phy_addr = -1, - .interface = PHY_INTERFACE_MODE_MII, - .mdio_bus_data = &ls1x_mdio_bus_data, - .dma_cfg = &ls1x_eth_dma_cfg, - .has_gmac = 1, - .tx_coe = 1, - .init = ls1x_eth_mux_init, -}; - -static struct resource ls1x_eth1_resources[] = { - [0] = { - .start = LS1X_GMAC1_BASE, - .end = LS1X_GMAC1_BASE + SZ_64K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .name = "macirq", - .start = LS1X_GMAC1_IRQ, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device ls1x_eth1_pdev = { - .name = "stmmaceth", - .id = 1, - .num_resources = ARRAY_SIZE(ls1x_eth1_resources), - .resource = ls1x_eth1_resources, - .dev = { - .platform_data = &ls1x_eth1_pdata, - }, -}; - -/* USB EHCI */ -static u64 ls1x_ehci_dmamask = DMA_BIT_MASK(32); - -static struct resource ls1x_ehci_resources[] = { - [0] = { - .start = LS1X_EHCI_BASE, - .end = LS1X_EHCI_BASE + SZ_32K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = LS1X_EHCI_IRQ, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct usb_ehci_pdata ls1x_ehci_pdata = { -}; - -struct platform_device ls1x_ehci_pdev = { - .name = "ehci-platform", - .id = -1, - .num_resources = ARRAY_SIZE(ls1x_ehci_resources), - .resource = ls1x_ehci_resources, - .dev = { - .dma_mask = &ls1x_ehci_dmamask, - .platform_data = &ls1x_ehci_pdata, - }, -}; - -/* Real Time Clock */ -struct platform_device ls1x_rtc_pdev = { - .name = "ls1x-rtc", - .id = -1, -}; diff --git a/arch/mips/loongson1/common/prom.c b/arch/mips/loongson1/common/prom.c deleted file mode 100644 index 68600980ea49..000000000000 --- a/arch/mips/loongson1/common/prom.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2011 Zhang, Keguang - * - * Modified from arch/mips/pnx833x/common/prom.c. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include - -#include -#include - -int prom_argc; -char **prom_argv, **prom_envp; -unsigned long memsize, highmemsize; - -char *prom_getenv(char *envname) -{ - char **env = prom_envp; - int i; - - i = strlen(envname); - - while (*env) { - if (strncmp(envname, *env, i) == 0 && *(*env + i) == '=') - return *env + i + 1; - env++; - } - - return 0; -} - -static inline unsigned long env_or_default(char *env, unsigned long dfl) -{ - char *str = prom_getenv(env); - return str ? simple_strtol(str, 0, 0) : dfl; -} - -void __init prom_init_cmdline(void) -{ - char *c = &(arcs_cmdline[0]); - int i; - - for (i = 1; i < prom_argc; i++) { - strcpy(c, prom_argv[i]); - c += strlen(prom_argv[i]); - if (i < prom_argc - 1) - *c++ = ' '; - } - *c = 0; -} - -void __init prom_init(void) -{ - void __iomem *uart_base; - prom_argc = fw_arg0; - prom_argv = (char **)fw_arg1; - prom_envp = (char **)fw_arg2; - - prom_init_cmdline(); - - memsize = env_or_default("memsize", DEFAULT_MEMSIZE); - highmemsize = env_or_default("highmemsize", 0x0); - - if (strstr(arcs_cmdline, "console=ttyS3")) - uart_base = ioremap_nocache(LS1X_UART3_BASE, 0x0f); - else if (strstr(arcs_cmdline, "console=ttyS2")) - uart_base = ioremap_nocache(LS1X_UART2_BASE, 0x0f); - else if (strstr(arcs_cmdline, "console=ttyS1")) - uart_base = ioremap_nocache(LS1X_UART1_BASE, 0x0f); - else - uart_base = ioremap_nocache(LS1X_UART0_BASE, 0x0f); - setup_8250_early_printk_port((unsigned long)uart_base, 0, 0); -} - -void __init prom_free_prom_memory(void) -{ -} diff --git a/arch/mips/loongson1/common/reset.c b/arch/mips/loongson1/common/reset.c deleted file mode 100644 index c41e4ca56ab4..000000000000 --- a/arch/mips/loongson1/common/reset.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2011 Zhang, Keguang - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include - -#include - -static void __iomem *wdt_base; - -static void ls1x_halt(void) -{ - while (1) { - if (cpu_wait) - cpu_wait(); - } -} - -static void ls1x_restart(char *command) -{ - __raw_writel(0x1, wdt_base + WDT_EN); - __raw_writel(0x1, wdt_base + WDT_TIMER); - __raw_writel(0x1, wdt_base + WDT_SET); - - ls1x_halt(); -} - -static void ls1x_power_off(void) -{ - ls1x_halt(); -} - -static int __init ls1x_reboot_setup(void) -{ - wdt_base = ioremap_nocache(LS1X_WDT_BASE, 0x0f); - if (!wdt_base) - panic("Failed to remap watchdog registers"); - - _machine_restart = ls1x_restart; - _machine_halt = ls1x_halt; - pm_power_off = ls1x_power_off; - - return 0; -} - -arch_initcall(ls1x_reboot_setup); diff --git a/arch/mips/loongson1/common/setup.c b/arch/mips/loongson1/common/setup.c deleted file mode 100644 index 62f41afee241..000000000000 --- a/arch/mips/loongson1/common/setup.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2011 Zhang, Keguang - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include - -#include - -void __init plat_mem_setup(void) -{ - add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM); -} - -const char *get_system_type(void) -{ - unsigned int processor_id = (¤t_cpu_data)->processor_id; - - switch (processor_id & PRID_REV_MASK) { - case PRID_REV_LOONGSON1B: - return "LOONGSON LS1B"; - default: - return "LOONGSON (unknown)"; - } -} diff --git a/arch/mips/loongson1/common/time.c b/arch/mips/loongson1/common/time.c deleted file mode 100644 index df0f850d6a5f..000000000000 --- a/arch/mips/loongson1/common/time.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (c) 2014 Zhang, Keguang - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include - -#include -#include - -#ifdef CONFIG_CEVT_CSRC_LS1X - -#if defined(CONFIG_TIMER_USE_PWM1) -#define LS1X_TIMER_BASE LS1X_PWM1_BASE -#define LS1X_TIMER_IRQ LS1X_PWM1_IRQ - -#elif defined(CONFIG_TIMER_USE_PWM2) -#define LS1X_TIMER_BASE LS1X_PWM2_BASE -#define LS1X_TIMER_IRQ LS1X_PWM2_IRQ - -#elif defined(CONFIG_TIMER_USE_PWM3) -#define LS1X_TIMER_BASE LS1X_PWM3_BASE -#define LS1X_TIMER_IRQ LS1X_PWM3_IRQ - -#else -#define LS1X_TIMER_BASE LS1X_PWM0_BASE -#define LS1X_TIMER_IRQ LS1X_PWM0_IRQ -#endif - -DEFINE_RAW_SPINLOCK(ls1x_timer_lock); - -static void __iomem *timer_base; -static uint32_t ls1x_jiffies_per_tick; - -static inline void ls1x_pwmtimer_set_period(uint32_t period) -{ - __raw_writel(period, timer_base + PWM_HRC); - __raw_writel(period, timer_base + PWM_LRC); -} - -static inline void ls1x_pwmtimer_restart(void) -{ - __raw_writel(0x0, timer_base + PWM_CNT); - __raw_writel(INT_EN | CNT_EN, timer_base + PWM_CTRL); -} - -void __init ls1x_pwmtimer_init(void) -{ - timer_base = ioremap(LS1X_TIMER_BASE, 0xf); - if (!timer_base) - panic("Failed to remap timer registers"); - - ls1x_jiffies_per_tick = DIV_ROUND_CLOSEST(mips_hpt_frequency, HZ); - - ls1x_pwmtimer_set_period(ls1x_jiffies_per_tick); - ls1x_pwmtimer_restart(); -} - -static cycle_t ls1x_clocksource_read(struct clocksource *cs) -{ - unsigned long flags; - int count; - u32 jifs; - static int old_count; - static u32 old_jifs; - - raw_spin_lock_irqsave(&ls1x_timer_lock, flags); - /* - * Although our caller may have the read side of xtime_lock, - * this is now a seqlock, and we are cheating in this routine - * by having side effects on state that we cannot undo if - * there is a collision on the seqlock and our caller has to - * retry. (Namely, old_jifs and old_count.) So we must treat - * jiffies as volatile despite the lock. We read jiffies - * before latching the timer count to guarantee that although - * the jiffies value might be older than the count (that is, - * the counter may underflow between the last point where - * jiffies was incremented and the point where we latch the - * count), it cannot be newer. - */ - jifs = jiffies; - /* read the count */ - count = __raw_readl(timer_base + PWM_CNT); - - /* - * It's possible for count to appear to go the wrong way for this - * reason: - * - * The timer counter underflows, but we haven't handled the resulting - * interrupt and incremented jiffies yet. - * - * Previous attempts to handle these cases intelligently were buggy, so - * we just do the simple thing now. - */ - if (count < old_count && jifs == old_jifs) - count = old_count; - - old_count = count; - old_jifs = jifs; - - raw_spin_unlock_irqrestore(&ls1x_timer_lock, flags); - - return (cycle_t) (jifs * ls1x_jiffies_per_tick) + count; -} - -static struct clocksource ls1x_clocksource = { - .name = "ls1x-pwmtimer", - .read = ls1x_clocksource_read, - .mask = CLOCKSOURCE_MASK(24), - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -static irqreturn_t ls1x_clockevent_isr(int irq, void *devid) -{ - struct clock_event_device *cd = devid; - - ls1x_pwmtimer_restart(); - cd->event_handler(cd); - - return IRQ_HANDLED; -} - -static void ls1x_clockevent_set_mode(enum clock_event_mode mode, - struct clock_event_device *cd) -{ - raw_spin_lock(&ls1x_timer_lock); - switch (mode) { - case CLOCK_EVT_MODE_PERIODIC: - ls1x_pwmtimer_set_period(ls1x_jiffies_per_tick); - ls1x_pwmtimer_restart(); - case CLOCK_EVT_MODE_RESUME: - __raw_writel(INT_EN | CNT_EN, timer_base + PWM_CTRL); - break; - case CLOCK_EVT_MODE_ONESHOT: - case CLOCK_EVT_MODE_SHUTDOWN: - __raw_writel(__raw_readl(timer_base + PWM_CTRL) & ~CNT_EN, - timer_base + PWM_CTRL); - break; - default: - break; - } - raw_spin_unlock(&ls1x_timer_lock); -} - -static int ls1x_clockevent_set_next(unsigned long evt, - struct clock_event_device *cd) -{ - raw_spin_lock(&ls1x_timer_lock); - ls1x_pwmtimer_set_period(evt); - ls1x_pwmtimer_restart(); - raw_spin_unlock(&ls1x_timer_lock); - - return 0; -} - -static struct clock_event_device ls1x_clockevent = { - .name = "ls1x-pwmtimer", - .features = CLOCK_EVT_FEAT_PERIODIC, - .rating = 300, - .irq = LS1X_TIMER_IRQ, - .set_next_event = ls1x_clockevent_set_next, - .set_mode = ls1x_clockevent_set_mode, -}; - -static struct irqaction ls1x_pwmtimer_irqaction = { - .name = "ls1x-pwmtimer", - .handler = ls1x_clockevent_isr, - .dev_id = &ls1x_clockevent, - .flags = IRQF_PERCPU | IRQF_TIMER, -}; - -static void __init ls1x_time_init(void) -{ - struct clock_event_device *cd = &ls1x_clockevent; - int ret; - - if (!mips_hpt_frequency) - panic("Invalid timer clock rate"); - - ls1x_pwmtimer_init(); - - clockevent_set_clock(cd, mips_hpt_frequency); - cd->max_delta_ns = clockevent_delta2ns(0xffffff, cd); - cd->min_delta_ns = clockevent_delta2ns(0x000300, cd); - cd->cpumask = cpumask_of(smp_processor_id()); - clockevents_register_device(cd); - - ls1x_clocksource.rating = 200 + mips_hpt_frequency / 10000000; - ret = clocksource_register_hz(&ls1x_clocksource, mips_hpt_frequency); - if (ret) - panic(KERN_ERR "Failed to register clocksource: %d\n", ret); - - setup_irq(LS1X_TIMER_IRQ, &ls1x_pwmtimer_irqaction); -} -#endif /* CONFIG_CEVT_CSRC_LS1X */ - -void __init plat_time_init(void) -{ - struct clk *clk = NULL; - - /* initialize LS1X clocks */ - ls1x_clk_init(); - -#ifdef CONFIG_CEVT_CSRC_LS1X - /* setup LS1X PWM timer */ - clk = clk_get(NULL, "ls1x_pwmtimer"); - if (IS_ERR(clk)) - panic("unable to get timer clock, err=%ld", PTR_ERR(clk)); - - mips_hpt_frequency = clk_get_rate(clk); - ls1x_time_init(); -#else - /* setup mips r4k timer */ - clk = clk_get(NULL, "cpu_clk"); - if (IS_ERR(clk)) - panic("unable to get cpu clock, err=%ld", PTR_ERR(clk)); - - mips_hpt_frequency = clk_get_rate(clk) / 2; -#endif /* CONFIG_CEVT_CSRC_LS1X */ -} diff --git a/arch/mips/loongson1/ls1b/Makefile b/arch/mips/loongson1/ls1b/Makefile deleted file mode 100644 index 891eac482b82..000000000000 --- a/arch/mips/loongson1/ls1b/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for loongson1B based machines. -# - -obj-y += board.o diff --git a/arch/mips/loongson1/ls1b/board.c b/arch/mips/loongson1/ls1b/board.c deleted file mode 100644 index 58daeea25739..000000000000 --- a/arch/mips/loongson1/ls1b/board.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2011 Zhang, Keguang - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include - -static struct platform_device *ls1b_platform_devices[] __initdata = { - &ls1x_uart_pdev, - &ls1x_cpufreq_pdev, - &ls1x_eth0_pdev, - &ls1x_eth1_pdev, - &ls1x_ehci_pdev, - &ls1x_rtc_pdev, -}; - -static int __init ls1b_platform_init(void) -{ - int err; - - ls1x_serial_setup(&ls1x_uart_pdev); - - err = platform_add_devices(ls1b_platform_devices, - ARRAY_SIZE(ls1b_platform_devices)); - return err; -} - -arch_initcall(ls1b_platform_init); diff --git a/arch/mips/loongson32/Kconfig b/arch/mips/loongson32/Kconfig new file mode 100644 index 000000000000..7704f20529d6 --- /dev/null +++ b/arch/mips/loongson32/Kconfig @@ -0,0 +1,61 @@ +if MACH_LOONGSON32 + +choice + prompt "Machine Type" + +config LOONGSON1_LS1B + bool "Loongson LS1B board" + select CEVT_R4K if !MIPS_EXTERNAL_TIMER + select CSRC_R4K if !MIPS_EXTERNAL_TIMER + select SYS_HAS_CPU_LOONGSON1B + select DMA_NONCOHERENT + select BOOT_ELF32 + select IRQ_MIPS_CPU + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SYS_SUPPORTS_HIGHMEM + select SYS_SUPPORTS_MIPS16 + select SYS_HAS_EARLY_PRINTK + select USE_GENERIC_EARLY_PRINTK_8250 + select COMMON_CLK + +endchoice + +menuconfig CEVT_CSRC_LS1X + bool "Use PWM Timer for clockevent/clocksource" + select MIPS_EXTERNAL_TIMER + depends on CPU_LOONGSON1 + help + This option changes the default clockevent/clocksource to PWM Timer, + and is required by Loongson1 CPUFreq support. + + If unsure, say N. + +choice + prompt "Select clockevent/clocksource" + depends on CEVT_CSRC_LS1X + default TIMER_USE_PWM0 + +config TIMER_USE_PWM0 + bool "Use PWM Timer 0" + help + Use PWM Timer 0 as the default clockevent/clocksourcer. + +config TIMER_USE_PWM1 + bool "Use PWM Timer 1" + help + Use PWM Timer 1 as the default clockevent/clocksourcer. + +config TIMER_USE_PWM2 + bool "Use PWM Timer 2" + help + Use PWM Timer 2 as the default clockevent/clocksourcer. + +config TIMER_USE_PWM3 + bool "Use PWM Timer 3" + help + Use PWM Timer 3 as the default clockevent/clocksourcer. + +endchoice + +endif # MACH_LOONGSON32 diff --git a/arch/mips/loongson32/Makefile b/arch/mips/loongson32/Makefile new file mode 100644 index 000000000000..5f4bd6e071ca --- /dev/null +++ b/arch/mips/loongson32/Makefile @@ -0,0 +1,11 @@ +# +# Common code for all Loongson 1 based systems +# + +obj-$(CONFIG_MACH_LOONGSON32) += common/ + +# +# Loongson LS1B board +# + +obj-$(CONFIG_LOONGSON1_LS1B) += ls1b/ diff --git a/arch/mips/loongson32/Platform b/arch/mips/loongson32/Platform new file mode 100644 index 000000000000..ebb6dc290f0a --- /dev/null +++ b/arch/mips/loongson32/Platform @@ -0,0 +1,7 @@ +cflags-$(CONFIG_CPU_LOONGSON1) += \ + $(call cc-option,-march=mips32r2,-mips32r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \ + -Wa,-mips32r2 -Wa,--trap + +platform-$(CONFIG_MACH_LOONGSON32) += loongson32/ +cflags-$(CONFIG_MACH_LOONGSON32) += -I$(srctree)/arch/mips/include/asm/mach-loongson32 +load-$(CONFIG_LOONGSON1_LS1B) += 0xffffffff80100000 diff --git a/arch/mips/loongson32/common/Makefile b/arch/mips/loongson32/common/Makefile new file mode 100644 index 000000000000..723b4ce3b8f0 --- /dev/null +++ b/arch/mips/loongson32/common/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for common code of loongson1 based machines. +# + +obj-y += time.o irq.o platform.o prom.o reset.o setup.o diff --git a/arch/mips/loongson32/common/irq.c b/arch/mips/loongson32/common/irq.c new file mode 100644 index 000000000000..455a7704a90f --- /dev/null +++ b/arch/mips/loongson32/common/irq.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2011 Zhang, Keguang + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include + +#include +#include + +#define LS1X_INTC_REG(n, x) \ + ((void __iomem *)KSEG1ADDR(LS1X_INTC_BASE + (n * 0x18) + (x))) + +#define LS1X_INTC_INTISR(n) LS1X_INTC_REG(n, 0x0) +#define LS1X_INTC_INTIEN(n) LS1X_INTC_REG(n, 0x4) +#define LS1X_INTC_INTSET(n) LS1X_INTC_REG(n, 0x8) +#define LS1X_INTC_INTCLR(n) LS1X_INTC_REG(n, 0xc) +#define LS1X_INTC_INTPOL(n) LS1X_INTC_REG(n, 0x10) +#define LS1X_INTC_INTEDGE(n) LS1X_INTC_REG(n, 0x14) + +static void ls1x_irq_ack(struct irq_data *d) +{ + unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f; + unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5; + + __raw_writel(__raw_readl(LS1X_INTC_INTCLR(n)) + | (1 << bit), LS1X_INTC_INTCLR(n)); +} + +static void ls1x_irq_mask(struct irq_data *d) +{ + unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f; + unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5; + + __raw_writel(__raw_readl(LS1X_INTC_INTIEN(n)) + & ~(1 << bit), LS1X_INTC_INTIEN(n)); +} + +static void ls1x_irq_mask_ack(struct irq_data *d) +{ + unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f; + unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5; + + __raw_writel(__raw_readl(LS1X_INTC_INTIEN(n)) + & ~(1 << bit), LS1X_INTC_INTIEN(n)); + __raw_writel(__raw_readl(LS1X_INTC_INTCLR(n)) + | (1 << bit), LS1X_INTC_INTCLR(n)); +} + +static void ls1x_irq_unmask(struct irq_data *d) +{ + unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f; + unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5; + + __raw_writel(__raw_readl(LS1X_INTC_INTIEN(n)) + | (1 << bit), LS1X_INTC_INTIEN(n)); +} + +static struct irq_chip ls1x_irq_chip = { + .name = "LS1X-INTC", + .irq_ack = ls1x_irq_ack, + .irq_mask = ls1x_irq_mask, + .irq_mask_ack = ls1x_irq_mask_ack, + .irq_unmask = ls1x_irq_unmask, +}; + +static void ls1x_irq_dispatch(int n) +{ + u32 int_status, irq; + + /* Get pending sources, masked by current enables */ + int_status = __raw_readl(LS1X_INTC_INTISR(n)) & + __raw_readl(LS1X_INTC_INTIEN(n)); + + if (int_status) { + irq = LS1X_IRQ(n, __ffs(int_status)); + do_IRQ(irq); + } +} + +asmlinkage void plat_irq_dispatch(void) +{ + unsigned int pending; + + pending = read_c0_cause() & read_c0_status() & ST0_IM; + + if (pending & CAUSEF_IP7) + do_IRQ(TIMER_IRQ); + else if (pending & CAUSEF_IP2) + ls1x_irq_dispatch(0); /* INT0 */ + else if (pending & CAUSEF_IP3) + ls1x_irq_dispatch(1); /* INT1 */ + else if (pending & CAUSEF_IP4) + ls1x_irq_dispatch(2); /* INT2 */ + else if (pending & CAUSEF_IP5) + ls1x_irq_dispatch(3); /* INT3 */ + else if (pending & CAUSEF_IP6) + ls1x_irq_dispatch(4); /* INT4 */ + else + spurious_interrupt(); + +} + +struct irqaction cascade_irqaction = { + .handler = no_action, + .name = "cascade", + .flags = IRQF_NO_THREAD, +}; + +static void __init ls1x_irq_init(int base) +{ + int n; + + /* Disable interrupts and clear pending, + * setup all IRQs as high level triggered + */ + for (n = 0; n < 4; n++) { + __raw_writel(0x0, LS1X_INTC_INTIEN(n)); + __raw_writel(0xffffffff, LS1X_INTC_INTCLR(n)); + __raw_writel(0xffffffff, LS1X_INTC_INTPOL(n)); + /* set DMA0, DMA1 and DMA2 to edge trigger */ + __raw_writel(n ? 0x0 : 0xe000, LS1X_INTC_INTEDGE(n)); + } + + + for (n = base; n < LS1X_IRQS; n++) { + irq_set_chip_and_handler(n, &ls1x_irq_chip, + handle_level_irq); + } + + setup_irq(INT0_IRQ, &cascade_irqaction); + setup_irq(INT1_IRQ, &cascade_irqaction); + setup_irq(INT2_IRQ, &cascade_irqaction); + setup_irq(INT3_IRQ, &cascade_irqaction); +} + +void __init arch_init_irq(void) +{ + mips_cpu_irq_init(); + ls1x_irq_init(LS1X_IRQ_BASE); +} diff --git a/arch/mips/loongson32/common/platform.c b/arch/mips/loongson32/common/platform.c new file mode 100644 index 000000000000..ddf1d4cbf31e --- /dev/null +++ b/arch/mips/loongson32/common/platform.c @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2011 Zhang, Keguang + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/* 8250/16550 compatible UART */ +#define LS1X_UART(_id) \ + { \ + .mapbase = LS1X_UART ## _id ## _BASE, \ + .irq = LS1X_UART ## _id ## _IRQ, \ + .iotype = UPIO_MEM, \ + .flags = UPF_IOREMAP | UPF_FIXED_TYPE, \ + .type = PORT_16550A, \ + } + +static struct plat_serial8250_port ls1x_serial8250_pdata[] = { + LS1X_UART(0), + LS1X_UART(1), + LS1X_UART(2), + LS1X_UART(3), + {}, +}; + +struct platform_device ls1x_uart_pdev = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = ls1x_serial8250_pdata, + }, +}; + +void __init ls1x_serial_setup(struct platform_device *pdev) +{ + struct clk *clk; + struct plat_serial8250_port *p; + + clk = clk_get(&pdev->dev, pdev->name); + if (IS_ERR(clk)) { + pr_err("unable to get %s clock, err=%ld", + pdev->name, PTR_ERR(clk)); + return; + } + clk_prepare_enable(clk); + + for (p = pdev->dev.platform_data; p->flags != 0; ++p) + p->uartclk = clk_get_rate(clk); +} + +/* CPUFreq */ +static struct plat_ls1x_cpufreq ls1x_cpufreq_pdata = { + .clk_name = "cpu_clk", + .osc_clk_name = "osc_33m_clk", + .max_freq = 266 * 1000, + .min_freq = 33 * 1000, +}; + +struct platform_device ls1x_cpufreq_pdev = { + .name = "ls1x-cpufreq", + .dev = { + .platform_data = &ls1x_cpufreq_pdata, + }, +}; + +/* Synopsys Ethernet GMAC */ +static struct stmmac_mdio_bus_data ls1x_mdio_bus_data = { + .phy_mask = 0, +}; + +static struct stmmac_dma_cfg ls1x_eth_dma_cfg = { + .pbl = 1, +}; + +int ls1x_eth_mux_init(struct platform_device *pdev, void *priv) +{ + struct plat_stmmacenet_data *plat_dat = NULL; + u32 val; + + val = __raw_readl(LS1X_MUX_CTRL1); + + plat_dat = dev_get_platdata(&pdev->dev); + if (plat_dat->bus_id) { + __raw_writel(__raw_readl(LS1X_MUX_CTRL0) | GMAC1_USE_UART1 | + GMAC1_USE_UART0, LS1X_MUX_CTRL0); + switch (plat_dat->interface) { + case PHY_INTERFACE_MODE_RGMII: + val &= ~(GMAC1_USE_TXCLK | GMAC1_USE_PWM23); + break; + case PHY_INTERFACE_MODE_MII: + val |= (GMAC1_USE_TXCLK | GMAC1_USE_PWM23); + break; + default: + pr_err("unsupported mii mode %d\n", + plat_dat->interface); + return -ENOTSUPP; + } + val &= ~GMAC1_SHUT; + } else { + switch (plat_dat->interface) { + case PHY_INTERFACE_MODE_RGMII: + val &= ~(GMAC0_USE_TXCLK | GMAC0_USE_PWM01); + break; + case PHY_INTERFACE_MODE_MII: + val |= (GMAC0_USE_TXCLK | GMAC0_USE_PWM01); + break; + default: + pr_err("unsupported mii mode %d\n", + plat_dat->interface); + return -ENOTSUPP; + } + val &= ~GMAC0_SHUT; + } + __raw_writel(val, LS1X_MUX_CTRL1); + + return 0; +} + +static struct plat_stmmacenet_data ls1x_eth0_pdata = { + .bus_id = 0, + .phy_addr = -1, + .interface = PHY_INTERFACE_MODE_MII, + .mdio_bus_data = &ls1x_mdio_bus_data, + .dma_cfg = &ls1x_eth_dma_cfg, + .has_gmac = 1, + .tx_coe = 1, + .init = ls1x_eth_mux_init, +}; + +static struct resource ls1x_eth0_resources[] = { + [0] = { + .start = LS1X_GMAC0_BASE, + .end = LS1X_GMAC0_BASE + SZ_64K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = "macirq", + .start = LS1X_GMAC0_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device ls1x_eth0_pdev = { + .name = "stmmaceth", + .id = 0, + .num_resources = ARRAY_SIZE(ls1x_eth0_resources), + .resource = ls1x_eth0_resources, + .dev = { + .platform_data = &ls1x_eth0_pdata, + }, +}; + +static struct plat_stmmacenet_data ls1x_eth1_pdata = { + .bus_id = 1, + .phy_addr = -1, + .interface = PHY_INTERFACE_MODE_MII, + .mdio_bus_data = &ls1x_mdio_bus_data, + .dma_cfg = &ls1x_eth_dma_cfg, + .has_gmac = 1, + .tx_coe = 1, + .init = ls1x_eth_mux_init, +}; + +static struct resource ls1x_eth1_resources[] = { + [0] = { + .start = LS1X_GMAC1_BASE, + .end = LS1X_GMAC1_BASE + SZ_64K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = "macirq", + .start = LS1X_GMAC1_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device ls1x_eth1_pdev = { + .name = "stmmaceth", + .id = 1, + .num_resources = ARRAY_SIZE(ls1x_eth1_resources), + .resource = ls1x_eth1_resources, + .dev = { + .platform_data = &ls1x_eth1_pdata, + }, +}; + +/* USB EHCI */ +static u64 ls1x_ehci_dmamask = DMA_BIT_MASK(32); + +static struct resource ls1x_ehci_resources[] = { + [0] = { + .start = LS1X_EHCI_BASE, + .end = LS1X_EHCI_BASE + SZ_32K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = LS1X_EHCI_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct usb_ehci_pdata ls1x_ehci_pdata = { +}; + +struct platform_device ls1x_ehci_pdev = { + .name = "ehci-platform", + .id = -1, + .num_resources = ARRAY_SIZE(ls1x_ehci_resources), + .resource = ls1x_ehci_resources, + .dev = { + .dma_mask = &ls1x_ehci_dmamask, + .platform_data = &ls1x_ehci_pdata, + }, +}; + +/* Real Time Clock */ +struct platform_device ls1x_rtc_pdev = { + .name = "ls1x-rtc", + .id = -1, +}; diff --git a/arch/mips/loongson32/common/prom.c b/arch/mips/loongson32/common/prom.c new file mode 100644 index 000000000000..68600980ea49 --- /dev/null +++ b/arch/mips/loongson32/common/prom.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2011 Zhang, Keguang + * + * Modified from arch/mips/pnx833x/common/prom.c. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include + +#include +#include + +int prom_argc; +char **prom_argv, **prom_envp; +unsigned long memsize, highmemsize; + +char *prom_getenv(char *envname) +{ + char **env = prom_envp; + int i; + + i = strlen(envname); + + while (*env) { + if (strncmp(envname, *env, i) == 0 && *(*env + i) == '=') + return *env + i + 1; + env++; + } + + return 0; +} + +static inline unsigned long env_or_default(char *env, unsigned long dfl) +{ + char *str = prom_getenv(env); + return str ? simple_strtol(str, 0, 0) : dfl; +} + +void __init prom_init_cmdline(void) +{ + char *c = &(arcs_cmdline[0]); + int i; + + for (i = 1; i < prom_argc; i++) { + strcpy(c, prom_argv[i]); + c += strlen(prom_argv[i]); + if (i < prom_argc - 1) + *c++ = ' '; + } + *c = 0; +} + +void __init prom_init(void) +{ + void __iomem *uart_base; + prom_argc = fw_arg0; + prom_argv = (char **)fw_arg1; + prom_envp = (char **)fw_arg2; + + prom_init_cmdline(); + + memsize = env_or_default("memsize", DEFAULT_MEMSIZE); + highmemsize = env_or_default("highmemsize", 0x0); + + if (strstr(arcs_cmdline, "console=ttyS3")) + uart_base = ioremap_nocache(LS1X_UART3_BASE, 0x0f); + else if (strstr(arcs_cmdline, "console=ttyS2")) + uart_base = ioremap_nocache(LS1X_UART2_BASE, 0x0f); + else if (strstr(arcs_cmdline, "console=ttyS1")) + uart_base = ioremap_nocache(LS1X_UART1_BASE, 0x0f); + else + uart_base = ioremap_nocache(LS1X_UART0_BASE, 0x0f); + setup_8250_early_printk_port((unsigned long)uart_base, 0, 0); +} + +void __init prom_free_prom_memory(void) +{ +} diff --git a/arch/mips/loongson32/common/reset.c b/arch/mips/loongson32/common/reset.c new file mode 100644 index 000000000000..c41e4ca56ab4 --- /dev/null +++ b/arch/mips/loongson32/common/reset.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2011 Zhang, Keguang + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include + +#include + +static void __iomem *wdt_base; + +static void ls1x_halt(void) +{ + while (1) { + if (cpu_wait) + cpu_wait(); + } +} + +static void ls1x_restart(char *command) +{ + __raw_writel(0x1, wdt_base + WDT_EN); + __raw_writel(0x1, wdt_base + WDT_TIMER); + __raw_writel(0x1, wdt_base + WDT_SET); + + ls1x_halt(); +} + +static void ls1x_power_off(void) +{ + ls1x_halt(); +} + +static int __init ls1x_reboot_setup(void) +{ + wdt_base = ioremap_nocache(LS1X_WDT_BASE, 0x0f); + if (!wdt_base) + panic("Failed to remap watchdog registers"); + + _machine_restart = ls1x_restart; + _machine_halt = ls1x_halt; + pm_power_off = ls1x_power_off; + + return 0; +} + +arch_initcall(ls1x_reboot_setup); diff --git a/arch/mips/loongson32/common/setup.c b/arch/mips/loongson32/common/setup.c new file mode 100644 index 000000000000..62f41afee241 --- /dev/null +++ b/arch/mips/loongson32/common/setup.c @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2011 Zhang, Keguang + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include + +#include + +void __init plat_mem_setup(void) +{ + add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM); +} + +const char *get_system_type(void) +{ + unsigned int processor_id = (¤t_cpu_data)->processor_id; + + switch (processor_id & PRID_REV_MASK) { + case PRID_REV_LOONGSON1B: + return "LOONGSON LS1B"; + default: + return "LOONGSON (unknown)"; + } +} diff --git a/arch/mips/loongson32/common/time.c b/arch/mips/loongson32/common/time.c new file mode 100644 index 000000000000..df0f850d6a5f --- /dev/null +++ b/arch/mips/loongson32/common/time.c @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2014 Zhang, Keguang + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include + +#include +#include + +#ifdef CONFIG_CEVT_CSRC_LS1X + +#if defined(CONFIG_TIMER_USE_PWM1) +#define LS1X_TIMER_BASE LS1X_PWM1_BASE +#define LS1X_TIMER_IRQ LS1X_PWM1_IRQ + +#elif defined(CONFIG_TIMER_USE_PWM2) +#define LS1X_TIMER_BASE LS1X_PWM2_BASE +#define LS1X_TIMER_IRQ LS1X_PWM2_IRQ + +#elif defined(CONFIG_TIMER_USE_PWM3) +#define LS1X_TIMER_BASE LS1X_PWM3_BASE +#define LS1X_TIMER_IRQ LS1X_PWM3_IRQ + +#else +#define LS1X_TIMER_BASE LS1X_PWM0_BASE +#define LS1X_TIMER_IRQ LS1X_PWM0_IRQ +#endif + +DEFINE_RAW_SPINLOCK(ls1x_timer_lock); + +static void __iomem *timer_base; +static uint32_t ls1x_jiffies_per_tick; + +static inline void ls1x_pwmtimer_set_period(uint32_t period) +{ + __raw_writel(period, timer_base + PWM_HRC); + __raw_writel(period, timer_base + PWM_LRC); +} + +static inline void ls1x_pwmtimer_restart(void) +{ + __raw_writel(0x0, timer_base + PWM_CNT); + __raw_writel(INT_EN | CNT_EN, timer_base + PWM_CTRL); +} + +void __init ls1x_pwmtimer_init(void) +{ + timer_base = ioremap(LS1X_TIMER_BASE, 0xf); + if (!timer_base) + panic("Failed to remap timer registers"); + + ls1x_jiffies_per_tick = DIV_ROUND_CLOSEST(mips_hpt_frequency, HZ); + + ls1x_pwmtimer_set_period(ls1x_jiffies_per_tick); + ls1x_pwmtimer_restart(); +} + +static cycle_t ls1x_clocksource_read(struct clocksource *cs) +{ + unsigned long flags; + int count; + u32 jifs; + static int old_count; + static u32 old_jifs; + + raw_spin_lock_irqsave(&ls1x_timer_lock, flags); + /* + * Although our caller may have the read side of xtime_lock, + * this is now a seqlock, and we are cheating in this routine + * by having side effects on state that we cannot undo if + * there is a collision on the seqlock and our caller has to + * retry. (Namely, old_jifs and old_count.) So we must treat + * jiffies as volatile despite the lock. We read jiffies + * before latching the timer count to guarantee that although + * the jiffies value might be older than the count (that is, + * the counter may underflow between the last point where + * jiffies was incremented and the point where we latch the + * count), it cannot be newer. + */ + jifs = jiffies; + /* read the count */ + count = __raw_readl(timer_base + PWM_CNT); + + /* + * It's possible for count to appear to go the wrong way for this + * reason: + * + * The timer counter underflows, but we haven't handled the resulting + * interrupt and incremented jiffies yet. + * + * Previous attempts to handle these cases intelligently were buggy, so + * we just do the simple thing now. + */ + if (count < old_count && jifs == old_jifs) + count = old_count; + + old_count = count; + old_jifs = jifs; + + raw_spin_unlock_irqrestore(&ls1x_timer_lock, flags); + + return (cycle_t) (jifs * ls1x_jiffies_per_tick) + count; +} + +static struct clocksource ls1x_clocksource = { + .name = "ls1x-pwmtimer", + .read = ls1x_clocksource_read, + .mask = CLOCKSOURCE_MASK(24), + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +static irqreturn_t ls1x_clockevent_isr(int irq, void *devid) +{ + struct clock_event_device *cd = devid; + + ls1x_pwmtimer_restart(); + cd->event_handler(cd); + + return IRQ_HANDLED; +} + +static void ls1x_clockevent_set_mode(enum clock_event_mode mode, + struct clock_event_device *cd) +{ + raw_spin_lock(&ls1x_timer_lock); + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + ls1x_pwmtimer_set_period(ls1x_jiffies_per_tick); + ls1x_pwmtimer_restart(); + case CLOCK_EVT_MODE_RESUME: + __raw_writel(INT_EN | CNT_EN, timer_base + PWM_CTRL); + break; + case CLOCK_EVT_MODE_ONESHOT: + case CLOCK_EVT_MODE_SHUTDOWN: + __raw_writel(__raw_readl(timer_base + PWM_CTRL) & ~CNT_EN, + timer_base + PWM_CTRL); + break; + default: + break; + } + raw_spin_unlock(&ls1x_timer_lock); +} + +static int ls1x_clockevent_set_next(unsigned long evt, + struct clock_event_device *cd) +{ + raw_spin_lock(&ls1x_timer_lock); + ls1x_pwmtimer_set_period(evt); + ls1x_pwmtimer_restart(); + raw_spin_unlock(&ls1x_timer_lock); + + return 0; +} + +static struct clock_event_device ls1x_clockevent = { + .name = "ls1x-pwmtimer", + .features = CLOCK_EVT_FEAT_PERIODIC, + .rating = 300, + .irq = LS1X_TIMER_IRQ, + .set_next_event = ls1x_clockevent_set_next, + .set_mode = ls1x_clockevent_set_mode, +}; + +static struct irqaction ls1x_pwmtimer_irqaction = { + .name = "ls1x-pwmtimer", + .handler = ls1x_clockevent_isr, + .dev_id = &ls1x_clockevent, + .flags = IRQF_PERCPU | IRQF_TIMER, +}; + +static void __init ls1x_time_init(void) +{ + struct clock_event_device *cd = &ls1x_clockevent; + int ret; + + if (!mips_hpt_frequency) + panic("Invalid timer clock rate"); + + ls1x_pwmtimer_init(); + + clockevent_set_clock(cd, mips_hpt_frequency); + cd->max_delta_ns = clockevent_delta2ns(0xffffff, cd); + cd->min_delta_ns = clockevent_delta2ns(0x000300, cd); + cd->cpumask = cpumask_of(smp_processor_id()); + clockevents_register_device(cd); + + ls1x_clocksource.rating = 200 + mips_hpt_frequency / 10000000; + ret = clocksource_register_hz(&ls1x_clocksource, mips_hpt_frequency); + if (ret) + panic(KERN_ERR "Failed to register clocksource: %d\n", ret); + + setup_irq(LS1X_TIMER_IRQ, &ls1x_pwmtimer_irqaction); +} +#endif /* CONFIG_CEVT_CSRC_LS1X */ + +void __init plat_time_init(void) +{ + struct clk *clk = NULL; + + /* initialize LS1X clocks */ + ls1x_clk_init(); + +#ifdef CONFIG_CEVT_CSRC_LS1X + /* setup LS1X PWM timer */ + clk = clk_get(NULL, "ls1x_pwmtimer"); + if (IS_ERR(clk)) + panic("unable to get timer clock, err=%ld", PTR_ERR(clk)); + + mips_hpt_frequency = clk_get_rate(clk); + ls1x_time_init(); +#else + /* setup mips r4k timer */ + clk = clk_get(NULL, "cpu_clk"); + if (IS_ERR(clk)) + panic("unable to get cpu clock, err=%ld", PTR_ERR(clk)); + + mips_hpt_frequency = clk_get_rate(clk) / 2; +#endif /* CONFIG_CEVT_CSRC_LS1X */ +} diff --git a/arch/mips/loongson32/ls1b/Makefile b/arch/mips/loongson32/ls1b/Makefile new file mode 100644 index 000000000000..891eac482b82 --- /dev/null +++ b/arch/mips/loongson32/ls1b/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for loongson1B based machines. +# + +obj-y += board.o diff --git a/arch/mips/loongson32/ls1b/board.c b/arch/mips/loongson32/ls1b/board.c new file mode 100644 index 000000000000..58daeea25739 --- /dev/null +++ b/arch/mips/loongson32/ls1b/board.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2011 Zhang, Keguang + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include + +static struct platform_device *ls1b_platform_devices[] __initdata = { + &ls1x_uart_pdev, + &ls1x_cpufreq_pdev, + &ls1x_eth0_pdev, + &ls1x_eth1_pdev, + &ls1x_ehci_pdev, + &ls1x_rtc_pdev, +}; + +static int __init ls1b_platform_init(void) +{ + int err; + + ls1x_serial_setup(&ls1x_uart_pdev); + + err = platform_add_devices(ls1b_platform_devices, + ARRAY_SIZE(ls1b_platform_devices)); + return err; +} + +arch_initcall(ls1b_platform_init); diff --git a/arch/mips/loongson64/Kconfig b/arch/mips/loongson64/Kconfig new file mode 100644 index 000000000000..497912b38d8e --- /dev/null +++ b/arch/mips/loongson64/Kconfig @@ -0,0 +1,158 @@ +if MACH_LOONGSON64 + +choice + prompt "Machine Type" + +config LEMOTE_FULOONG2E + bool "Lemote Fuloong(2e) mini-PC" + select ARCH_SPARSEMEM_ENABLE + select CEVT_R4K + select CSRC_R4K + select SYS_HAS_CPU_LOONGSON2E + select DMA_NONCOHERENT + select BOOT_ELF32 + select BOARD_SCACHE + select HW_HAS_PCI + select I8259 + select ISA + select IRQ_MIPS_CPU + select SYS_SUPPORTS_32BIT_KERNEL + 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 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 HW_HAS_PCI + select I8259 + select IRQ_MIPS_CPU + select ISA + select SYS_HAS_CPU_LOONGSON2F + select SYS_HAS_EARLY_PRINTK + select SYS_SUPPORTS_32BIT_KERNEL + 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 + select GENERIC_ISA_DMA_SUPPORT_BROKEN + select BOOT_ELF32 + select BOARD_SCACHE + select CSRC_R4K + select CEVT_R4K + select CPU_HAS_WB + select HW_HAS_PCI + select ISA + select HT_PCI + select I8259 + select IRQ_MIPS_CPU + select NR_CPUS_DEFAULT_4 + select SYS_HAS_CPU_LOONGSON3 + select SYS_HAS_EARLY_PRINTK + select SYS_SUPPORTS_SMP + select SYS_SUPPORTS_HOTPLUG_CPU + select SYS_SUPPORTS_NUMA + select SYS_SUPPORTS_64BIT_KERNEL + select SYS_SUPPORTS_HIGHMEM + select SYS_SUPPORTS_LITTLE_ENDIAN + select LOONGSON_MC146818 + select ZONE_DMA32 + select LEFI_FIRMWARE_INTERFACE + select PHYS48_TO_HT40 + help + Generic Loongson 3 family machines utilize the 3A/3B revision + 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 + select MIPS_EXTERNAL_TIMER + help + This option enables the hpet timer of AMD RS780/SBX00. + + If you want to enable the Loongson3 CPUFreq Driver, Please enable + this option at first, otherwise, You will get wrong system time. + + If unsure, say Yes. + +config LOONGSON_SUSPEND + bool + default y + depends on CPU_SUPPORTS_CPUFREQ && SUSPEND + +config LOONGSON_UART_BASE + bool + default y + depends on EARLY_PRINTK || SERIAL_8250 + +config IOMMU_HELPER + bool + +config NEED_SG_DMA_LENGTH + bool + +config SWIOTLB + bool "Soft IOMMU Support for All-Memory DMA" + default y + depends on CPU_LOONGSON3 + select IOMMU_HELPER + select NEED_SG_DMA_LENGTH + select NEED_DMA_MAP_STATE + +config PHYS48_TO_HT40 + bool + default y if CPU_LOONGSON3 + +config LOONGSON_MC146818 + bool + default n + +config LEFI_FIRMWARE_INTERFACE + bool + +endif # MACH_LOONGSON64 diff --git a/arch/mips/loongson64/Makefile b/arch/mips/loongson64/Makefile new file mode 100644 index 000000000000..4fe3d88fc361 --- /dev/null +++ b/arch/mips/loongson64/Makefile @@ -0,0 +1,23 @@ +# +# Common code for all Loongson based systems +# + +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 +# + +obj-$(CONFIG_CPU_LOONGSON3) += loongson-3/ diff --git a/arch/mips/loongson64/Platform b/arch/mips/loongson64/Platform new file mode 100644 index 000000000000..2e48e83d5524 --- /dev/null +++ b/arch/mips/loongson64/Platform @@ -0,0 +1,33 @@ +# +# Loongson Processors' Support +# + +# Only gcc >= 4.4 have Loongson specific support +cflags-$(CONFIG_CPU_LOONGSON2) += -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_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 diff --git a/arch/mips/loongson64/common/Makefile b/arch/mips/loongson64/common/Makefile new file mode 100644 index 000000000000..f2e8153e44f5 --- /dev/null +++ b/arch/mips/loongson64/common/Makefile @@ -0,0 +1,31 @@ +# +# 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_LOONGSON_SUSPEND) += pm.o + +# +# Big Memory (SWIOTLB) Support +# +obj-$(CONFIG_SWIOTLB) += dma-swiotlb.o diff --git a/arch/mips/loongson64/common/bonito-irq.c b/arch/mips/loongson64/common/bonito-irq.c new file mode 100644 index 000000000000..cc0e4fd548e6 --- /dev/null +++ b/arch/mips/loongson64/common/bonito-irq.c @@ -0,0 +1,53 @@ +/* + * 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. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include + +#include + +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 +} diff --git a/arch/mips/loongson64/common/cmdline.c b/arch/mips/loongson64/common/cmdline.c new file mode 100644 index 000000000000..72fed003a536 --- /dev/null +++ b/arch/mips/loongson64/common/cmdline.c @@ -0,0 +1,48 @@ +/* + * 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 + * + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include + +#include + +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(); +} diff --git a/arch/mips/loongson64/common/cs5536/Makefile b/arch/mips/loongson64/common/cs5536/Makefile new file mode 100644 index 000000000000..f12e64007347 --- /dev/null +++ b/arch/mips/loongson64/common/cs5536/Makefile @@ -0,0 +1,11 @@ +# +# Makefile for CS5536 support. +# + +obj-$(CONFIG_CS5536) += cs5536_pci.o cs5536_ide.o cs5536_acc.o cs5536_ohci.o \ + cs5536_isa.o cs5536_ehci.o + +# +# Enable cs5536 mfgpt Timer +# +obj-$(CONFIG_CS5536_MFGPT) += cs5536_mfgpt.o diff --git a/arch/mips/loongson64/common/cs5536/cs5536_acc.c b/arch/mips/loongson64/common/cs5536/cs5536_acc.c new file mode 100644 index 000000000000..ab4d6cc57384 --- /dev/null +++ b/arch/mips/loongson64/common/cs5536/cs5536_acc.c @@ -0,0 +1,140 @@ +/* + * the ACC Virtual Support Module of AMD CS5536 + * + * Copyright (C) 2007 Lemote, Inc. + * Author : jlliu, liujl@lemote.com + * + * Copyright (C) 2009 Lemote, Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include + +void pci_acc_write_reg(int reg, u32 value) +{ + u32 hi = 0, lo = value; + + switch (reg) { + case PCI_COMMAND: + _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); + if (value & PCI_COMMAND_MASTER) + lo |= (0x03 << 8); + else + lo &= ~(0x03 << 8); + _wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo); + break; + case PCI_STATUS: + if (value & PCI_STATUS_PARITY) { + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) { + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_BAR0_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_ACC_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if (value & 0x01) { + value &= 0xfffffffc; + hi = 0xA0000000 | ((value & 0x000ff000) >> 12); + lo = 0x000fff80 | ((value & 0x00000fff) << 20); + _wrmsr(GLIU_MSR_REG(GLIU_IOD_BM1), hi, lo); + } + break; + case PCI_ACC_INT_REG: + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); + /* disable all the usb interrupt in PIC */ + lo &= ~(0xf << PIC_YSEL_LOW_ACC_SHIFT); + if (value) /* enable all the acc interrupt in PIC */ + lo |= (CS5536_ACC_INTR << PIC_YSEL_LOW_ACC_SHIFT); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo); + break; + default: + break; + } +} + +u32 pci_acc_read_reg(int reg) +{ + u32 hi, lo; + u32 conf_data = 0; + + switch (reg) { + case PCI_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_ACC_DEVICE_ID, CS5536_VENDOR_ID); + break; + case PCI_COMMAND: + _rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo); + if (((lo & 0xfff00000) || (hi & 0x000000ff)) + && ((hi & 0xf0000000) == 0xa0000000)) + conf_data |= PCI_COMMAND_IO; + _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); + if ((lo & 0x300) == 0x300) + conf_data |= PCI_COMMAND_MASTER; + break; + case PCI_STATUS: + conf_data |= PCI_STATUS_66MHZ; + conf_data |= PCI_STATUS_FAST_BACK; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REVISION: + _rdmsr(ACC_MSR_REG(ACC_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_ACC_CLASS_CODE << 8); + break; + case PCI_CACHE_LINE_SIZE: + conf_data = + CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, + PCI_NORMAL_LATENCY_TIMER); + break; + case PCI_BAR0_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_ACC_FLAG) { + conf_data = CS5536_ACC_RANGE | + PCI_BASE_ADDRESS_SPACE_IO; + lo &= ~SOFT_BAR_ACC_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo); + conf_data = (hi & 0x000000ff) << 12; + conf_data |= (lo & 0xfff00000) >> 20; + conf_data |= 0x01; + conf_data &= ~0x02; + } + break; + case PCI_CARDBUS_CIS: + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYSTEM_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_ACC_SUB_ID, CS5536_SUB_VENDOR_ID); + break; + case PCI_ROM_ADDRESS: + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPABILITY_LIST: + conf_data = PCI_CAPLIST_USB_POINTER; + break; + case PCI_INTERRUPT_LINE: + conf_data = + CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_ACC_INTR); + break; + default: + break; + } + + return conf_data; +} diff --git a/arch/mips/loongson64/common/cs5536/cs5536_ehci.c b/arch/mips/loongson64/common/cs5536/cs5536_ehci.c new file mode 100644 index 000000000000..ec2e360267a8 --- /dev/null +++ b/arch/mips/loongson64/common/cs5536/cs5536_ehci.c @@ -0,0 +1,160 @@ +/* + * the EHCI Virtual Support Module of AMD CS5536 + * + * Copyright (C) 2007 Lemote, Inc. + * Author : jlliu, liujl@lemote.com + * + * Copyright (C) 2009 Lemote, Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include + +void pci_ehci_write_reg(int reg, u32 value) +{ + u32 hi = 0, lo = value; + + switch (reg) { + case PCI_COMMAND: + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + if (value & PCI_COMMAND_MASTER) + hi |= PCI_COMMAND_MASTER; + else + hi &= ~PCI_COMMAND_MASTER; + + if (value & PCI_COMMAND_MEMORY) + hi |= PCI_COMMAND_MEMORY; + else + hi &= ~PCI_COMMAND_MEMORY; + _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); + break; + case PCI_STATUS: + if (value & PCI_STATUS_PARITY) { + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) { + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_BAR0_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_EHCI_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if ((value & 0x01) == 0x00) { + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + lo = value; + _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); + + value &= 0xfffffff0; + hi = 0x40000000 | ((value & 0xff000000) >> 24); + lo = 0x000fffff | ((value & 0x00fff000) << 8); + _wrmsr(GLIU_MSR_REG(GLIU_P2D_BM4), hi, lo); + } + break; + case PCI_EHCI_LEGSMIEN_REG: + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + hi &= 0x003f0000; + hi |= (value & 0x3f) << 16; + _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); + break; + case PCI_EHCI_FLADJ_REG: + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + hi &= ~0x00003f00; + hi |= value & 0x00003f00; + _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); + break; + default: + break; + } +} + +u32 pci_ehci_read_reg(int reg) +{ + u32 conf_data = 0; + u32 hi, lo; + + switch (reg) { + case PCI_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_EHCI_DEVICE_ID, CS5536_VENDOR_ID); + break; + case PCI_COMMAND: + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + if (hi & PCI_COMMAND_MASTER) + conf_data |= PCI_COMMAND_MASTER; + if (hi & PCI_COMMAND_MEMORY) + conf_data |= PCI_COMMAND_MEMORY; + break; + case PCI_STATUS: + conf_data |= PCI_STATUS_66MHZ; + conf_data |= PCI_STATUS_FAST_BACK; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REVISION: + _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_EHCI_CLASS_CODE << 8); + break; + case PCI_CACHE_LINE_SIZE: + conf_data = + CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, + PCI_NORMAL_LATENCY_TIMER); + break; + case PCI_BAR0_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_EHCI_FLAG) { + conf_data = CS5536_EHCI_RANGE | + PCI_BASE_ADDRESS_SPACE_MEMORY; + lo &= ~SOFT_BAR_EHCI_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + conf_data = lo & 0xfffff000; + } + break; + case PCI_CARDBUS_CIS: + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYSTEM_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_EHCI_SUB_ID, CS5536_SUB_VENDOR_ID); + break; + case PCI_ROM_ADDRESS: + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPABILITY_LIST: + conf_data = PCI_CAPLIST_USB_POINTER; + break; + case PCI_INTERRUPT_LINE: + conf_data = + CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR); + break; + case PCI_EHCI_LEGSMIEN_REG: + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + conf_data = (hi & 0x003f0000) >> 16; + break; + case PCI_EHCI_LEGSMISTS_REG: + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + conf_data = (hi & 0x3f000000) >> 24; + break; + case PCI_EHCI_FLADJ_REG: + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + conf_data = hi & 0x00003f00; + break; + default: + break; + } + + return conf_data; +} diff --git a/arch/mips/loongson64/common/cs5536/cs5536_ide.c b/arch/mips/loongson64/common/cs5536/cs5536_ide.c new file mode 100644 index 000000000000..a73414d9ee51 --- /dev/null +++ b/arch/mips/loongson64/common/cs5536/cs5536_ide.c @@ -0,0 +1,192 @@ +/* + * the IDE Virtual Support Module of AMD CS5536 + * + * Copyright (C) 2007 Lemote, Inc. + * Author : jlliu, liujl@lemote.com + * + * Copyright (C) 2009 Lemote, Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include + +void pci_ide_write_reg(int reg, u32 value) +{ + u32 hi = 0, lo = value; + + switch (reg) { + case PCI_COMMAND: + _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); + if (value & PCI_COMMAND_MASTER) + lo |= (0x03 << 4); + else + lo &= ~(0x03 << 4); + _wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo); + break; + case PCI_STATUS: + if (value & PCI_STATUS_PARITY) { + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) { + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_CACHE_LINE_SIZE: + value &= 0x0000ff00; + _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); + hi &= 0xffffff00; + hi |= (value >> 8); + _wrmsr(SB_MSR_REG(SB_CTRL), hi, lo); + break; + case PCI_BAR4_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_IDE_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if (value & 0x01) { + _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo); + lo = (value & 0xfffffff0) | 0x1; + _wrmsr(IDE_MSR_REG(IDE_IO_BAR), hi, lo); + + value &= 0xfffffffc; + hi = 0x60000000 | ((value & 0x000ff000) >> 12); + lo = 0x000ffff0 | ((value & 0x00000fff) << 20); + _wrmsr(GLIU_MSR_REG(GLIU_IOD_BM2), hi, lo); + } + break; + case PCI_IDE_CFG_REG: + if (value == CS5536_IDE_FLASH_SIGNATURE) { + _rdmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), &hi, &lo); + lo |= 0x01; + _wrmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), hi, lo); + } else { + _rdmsr(IDE_MSR_REG(IDE_CFG), &hi, &lo); + lo = value; + _wrmsr(IDE_MSR_REG(IDE_CFG), hi, lo); + } + break; + case PCI_IDE_DTC_REG: + _rdmsr(IDE_MSR_REG(IDE_DTC), &hi, &lo); + lo = value; + _wrmsr(IDE_MSR_REG(IDE_DTC), hi, lo); + break; + case PCI_IDE_CAST_REG: + _rdmsr(IDE_MSR_REG(IDE_CAST), &hi, &lo); + lo = value; + _wrmsr(IDE_MSR_REG(IDE_CAST), hi, lo); + break; + case PCI_IDE_ETC_REG: + _rdmsr(IDE_MSR_REG(IDE_ETC), &hi, &lo); + lo = value; + _wrmsr(IDE_MSR_REG(IDE_ETC), hi, lo); + break; + case PCI_IDE_PM_REG: + _rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo); + lo = value; + _wrmsr(IDE_MSR_REG(IDE_INTERNAL_PM), hi, lo); + break; + default: + break; + } +} + +u32 pci_ide_read_reg(int reg) +{ + u32 conf_data = 0; + u32 hi, lo; + + switch (reg) { + case PCI_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_IDE_DEVICE_ID, CS5536_VENDOR_ID); + break; + case PCI_COMMAND: + _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo); + if (lo & 0xfffffff0) + conf_data |= PCI_COMMAND_IO; + _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); + if ((lo & 0x30) == 0x30) + conf_data |= PCI_COMMAND_MASTER; + break; + case PCI_STATUS: + conf_data |= PCI_STATUS_66MHZ; + conf_data |= PCI_STATUS_FAST_BACK; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REVISION: + _rdmsr(IDE_MSR_REG(IDE_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_IDE_CLASS_CODE << 8); + break; + case PCI_CACHE_LINE_SIZE: + _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); + hi &= 0x000000f8; + conf_data = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, hi); + break; + case PCI_BAR4_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_IDE_FLAG) { + conf_data = CS5536_IDE_RANGE | + PCI_BASE_ADDRESS_SPACE_IO; + lo &= ~SOFT_BAR_IDE_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo); + conf_data = lo & 0xfffffff0; + conf_data |= 0x01; + conf_data &= ~0x02; + } + break; + case PCI_CARDBUS_CIS: + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYSTEM_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_IDE_SUB_ID, CS5536_SUB_VENDOR_ID); + break; + case PCI_ROM_ADDRESS: + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPABILITY_LIST: + conf_data = PCI_CAPLIST_POINTER; + break; + case PCI_INTERRUPT_LINE: + conf_data = + CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_IDE_INTR); + break; + case PCI_IDE_CFG_REG: + _rdmsr(IDE_MSR_REG(IDE_CFG), &hi, &lo); + conf_data = lo; + break; + case PCI_IDE_DTC_REG: + _rdmsr(IDE_MSR_REG(IDE_DTC), &hi, &lo); + conf_data = lo; + break; + case PCI_IDE_CAST_REG: + _rdmsr(IDE_MSR_REG(IDE_CAST), &hi, &lo); + conf_data = lo; + break; + case PCI_IDE_ETC_REG: + _rdmsr(IDE_MSR_REG(IDE_ETC), &hi, &lo); + conf_data = lo; + break; + case PCI_IDE_PM_REG: + _rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo); + conf_data = lo; + break; + default: + break; + } + + return conf_data; +} diff --git a/arch/mips/loongson64/common/cs5536/cs5536_isa.c b/arch/mips/loongson64/common/cs5536/cs5536_isa.c new file mode 100644 index 000000000000..924be39e7733 --- /dev/null +++ b/arch/mips/loongson64/common/cs5536/cs5536_isa.c @@ -0,0 +1,330 @@ +/* + * the ISA Virtual Support Module of AMD CS5536 + * + * Copyright (C) 2007 Lemote, Inc. + * Author : jlliu, liujl@lemote.com + * + * Copyright (C) 2009 Lemote, Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include + +/* common variables for PCI_ISA_READ/WRITE_BAR */ +static const u32 divil_msr_reg[6] = { + DIVIL_MSR_REG(DIVIL_LBAR_SMB), DIVIL_MSR_REG(DIVIL_LBAR_GPIO), + DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), DIVIL_MSR_REG(DIVIL_LBAR_IRQ), + DIVIL_MSR_REG(DIVIL_LBAR_PMS), DIVIL_MSR_REG(DIVIL_LBAR_ACPI), +}; + +static const u32 soft_bar_flag[6] = { + SOFT_BAR_SMB_FLAG, SOFT_BAR_GPIO_FLAG, SOFT_BAR_MFGPT_FLAG, + SOFT_BAR_IRQ_FLAG, SOFT_BAR_PMS_FLAG, SOFT_BAR_ACPI_FLAG, +}; + +static const u32 sb_msr_reg[6] = { + SB_MSR_REG(SB_R0), SB_MSR_REG(SB_R1), SB_MSR_REG(SB_R2), + SB_MSR_REG(SB_R3), SB_MSR_REG(SB_R4), SB_MSR_REG(SB_R5), +}; + +static const u32 bar_space_range[6] = { + CS5536_SMB_RANGE, CS5536_GPIO_RANGE, CS5536_MFGPT_RANGE, + CS5536_IRQ_RANGE, CS5536_PMS_RANGE, CS5536_ACPI_RANGE, +}; + +static const int bar_space_len[6] = { + CS5536_SMB_LENGTH, CS5536_GPIO_LENGTH, CS5536_MFGPT_LENGTH, + CS5536_IRQ_LENGTH, CS5536_PMS_LENGTH, CS5536_ACPI_LENGTH, +}; + +/* + * enable the divil module bar space. + * + * For all the DIVIL module LBAR, you should control the DIVIL LBAR reg + * and the RCONFx(0~5) reg to use the modules. + */ +static void divil_lbar_enable(void) +{ + u32 hi, lo; + int offset; + + /* + * The DIVIL IRQ is not used yet. and make the RCONF0 reserved. + */ + + for (offset = DIVIL_LBAR_SMB; offset <= DIVIL_LBAR_PMS; offset++) { + _rdmsr(DIVIL_MSR_REG(offset), &hi, &lo); + hi |= 0x01; + _wrmsr(DIVIL_MSR_REG(offset), hi, lo); + } +} + +/* + * disable the divil module bar space. + */ +static void divil_lbar_disable(void) +{ + u32 hi, lo; + int offset; + + for (offset = DIVIL_LBAR_SMB; offset <= DIVIL_LBAR_PMS; offset++) { + _rdmsr(DIVIL_MSR_REG(offset), &hi, &lo); + hi &= ~0x01; + _wrmsr(DIVIL_MSR_REG(offset), hi, lo); + } +} + +/* + * BAR write: write value to the n BAR + */ + +void pci_isa_write_bar(int n, u32 value) +{ + u32 hi = 0, lo = value; + + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= soft_bar_flag[n]; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if (value & 0x01) { + /* NATIVE reg */ + hi = 0x0000f001; + lo &= bar_space_range[n]; + _wrmsr(divil_msr_reg[n], hi, lo); + + /* RCONFx is 4bytes in units for I/O space */ + hi = ((value & 0x000ffffc) << 12) | + ((bar_space_len[n] - 4) << 12) | 0x01; + lo = ((value & 0x000ffffc) << 12) | 0x01; + _wrmsr(sb_msr_reg[n], hi, lo); + } +} + +/* + * BAR read: read the n BAR + */ + +u32 pci_isa_read_bar(int n) +{ + u32 conf_data = 0; + u32 hi, lo; + + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & soft_bar_flag[n]) { + conf_data = bar_space_range[n] | PCI_BASE_ADDRESS_SPACE_IO; + lo &= ~soft_bar_flag[n]; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(divil_msr_reg[n], &hi, &lo); + conf_data = lo & bar_space_range[n]; + conf_data |= 0x01; + conf_data &= ~0x02; + } + return conf_data; +} + +/* + * isa_write: ISA write transfer + * + * We assume that this is not a bus master transfer. + */ +void pci_isa_write_reg(int reg, u32 value) +{ + u32 hi = 0, lo = value; + u32 temp; + + switch (reg) { + case PCI_COMMAND: + if (value & PCI_COMMAND_IO) + divil_lbar_enable(); + else + divil_lbar_disable(); + break; + case PCI_STATUS: + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + temp = lo & 0x0000ffff; + if ((value & PCI_STATUS_SIG_TARGET_ABORT) && + (lo & SB_TAS_ERR_EN)) + temp |= SB_TAS_ERR_FLAG; + + if ((value & PCI_STATUS_REC_TARGET_ABORT) && + (lo & SB_TAR_ERR_EN)) + temp |= SB_TAR_ERR_FLAG; + + if ((value & PCI_STATUS_REC_MASTER_ABORT) + && (lo & SB_MAR_ERR_EN)) + temp |= SB_MAR_ERR_FLAG; + + if ((value & PCI_STATUS_DETECTED_PARITY) + && (lo & SB_PARE_ERR_EN)) + temp |= SB_PARE_ERR_FLAG; + + lo = temp; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + break; + case PCI_CACHE_LINE_SIZE: + value &= 0x0000ff00; + _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); + hi &= 0xffffff00; + hi |= (value >> 8); + _wrmsr(SB_MSR_REG(SB_CTRL), hi, lo); + break; + case PCI_BAR0_REG: + pci_isa_write_bar(0, value); + break; + case PCI_BAR1_REG: + pci_isa_write_bar(1, value); + break; + case PCI_BAR2_REG: + pci_isa_write_bar(2, value); + break; + case PCI_BAR3_REG: + pci_isa_write_bar(3, value); + break; + case PCI_BAR4_REG: + pci_isa_write_bar(4, value); + break; + case PCI_BAR5_REG: + pci_isa_write_bar(5, value); + break; + case PCI_UART1_INT_REG: + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo); + /* disable uart1 interrupt in PIC */ + lo &= ~(0xf << 24); + if (value) /* enable uart1 interrupt in PIC */ + lo |= (CS5536_UART1_INTR << 24); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo); + break; + case PCI_UART2_INT_REG: + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo); + /* disable uart2 interrupt in PIC */ + lo &= ~(0xf << 28); + if (value) /* enable uart2 interrupt in PIC */ + lo |= (CS5536_UART2_INTR << 28); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo); + break; + case PCI_ISA_FIXUP_REG: + if (value) { + /* enable the TARGET ABORT/MASTER ABORT etc. */ + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + lo |= 0x00000063; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + + default: + /* ALL OTHER PCI CONFIG SPACE HEADER IS NOT IMPLEMENTED. */ + break; + } +} + +/* + * isa_read: ISA read transfers + * + * We assume that this is not a bus master transfer. + */ +u32 pci_isa_read_reg(int reg) +{ + u32 conf_data = 0; + u32 hi, lo; + + switch (reg) { + case PCI_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_ISA_DEVICE_ID, CS5536_VENDOR_ID); + break; + case PCI_COMMAND: + /* we just check the first LBAR for the IO enable bit, */ + /* maybe we should changed later. */ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), &hi, &lo); + if (hi & 0x01) + conf_data |= PCI_COMMAND_IO; + break; + case PCI_STATUS: + conf_data |= PCI_STATUS_66MHZ; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + conf_data |= PCI_STATUS_FAST_BACK; + + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_TAS_ERR_FLAG) + conf_data |= PCI_STATUS_SIG_TARGET_ABORT; + if (lo & SB_TAR_ERR_FLAG) + conf_data |= PCI_STATUS_REC_TARGET_ABORT; + if (lo & SB_MAR_ERR_FLAG) + conf_data |= PCI_STATUS_REC_MASTER_ABORT; + if (lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_DETECTED_PARITY; + break; + case PCI_CLASS_REVISION: + _rdmsr(GLCP_MSR_REG(GLCP_CHIP_REV_ID), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_ISA_CLASS_CODE << 8); + break; + case PCI_CACHE_LINE_SIZE: + _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); + hi &= 0x000000f8; + conf_data = CFG_PCI_CACHE_LINE_SIZE(PCI_BRIDGE_HEADER_TYPE, hi); + break; + /* + * we only use the LBAR of DIVIL, no RCONF used. + * all of them are IO space. + */ + case PCI_BAR0_REG: + return pci_isa_read_bar(0); + break; + case PCI_BAR1_REG: + return pci_isa_read_bar(1); + break; + case PCI_BAR2_REG: + return pci_isa_read_bar(2); + break; + case PCI_BAR3_REG: + break; + case PCI_BAR4_REG: + return pci_isa_read_bar(4); + break; + case PCI_BAR5_REG: + return pci_isa_read_bar(5); + break; + case PCI_CARDBUS_CIS: + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYSTEM_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_ISA_SUB_ID, CS5536_SUB_VENDOR_ID); + break; + case PCI_ROM_ADDRESS: + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPABILITY_LIST: + conf_data = PCI_CAPLIST_POINTER; + break; + case PCI_INTERRUPT_LINE: + /* no interrupt used here */ + conf_data = CFG_PCI_INTERRUPT_LINE(0x00, 0x00); + break; + default: + break; + } + + return conf_data; +} + +/* + * The mfgpt timer interrupt is running early, so we must keep the south bridge + * mmio always enabled. Otherwise we may race with the PCI configuration which + * may temporarily disable it. When that happens and the timer interrupt fires, + * we are not able to clear it and the system will hang. + */ +static void cs5536_isa_mmio_always_on(struct pci_dev *dev) +{ + dev->mmio_always_on = 1; +} +DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, + PCI_CLASS_BRIDGE_ISA, 8, cs5536_isa_mmio_always_on); diff --git a/arch/mips/loongson64/common/cs5536/cs5536_mfgpt.c b/arch/mips/loongson64/common/cs5536/cs5536_mfgpt.c new file mode 100644 index 000000000000..12c75db23420 --- /dev/null +++ b/arch/mips/loongson64/common/cs5536/cs5536_mfgpt.c @@ -0,0 +1,213 @@ +/* + * CS5536 General timer functions + * + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Yanhua, yanh@lemote.com + * + * Copyright (C) 2009 Lemote Inc. + * Author: Wu zhangjin, wuzhangjin@gmail.com + * + * Reference: AMD Geode(TM) CS5536 Companion Device Data Book + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +static DEFINE_RAW_SPINLOCK(mfgpt_lock); + +static u32 mfgpt_base; + +/* + * Initialize the MFGPT timer. + * + * This is also called after resume to bring the MFGPT into operation again. + */ + +/* disable counter */ +void disable_mfgpt0_counter(void) +{ + outw(inw(MFGPT0_SETUP) & 0x7fff, MFGPT0_SETUP); +} +EXPORT_SYMBOL(disable_mfgpt0_counter); + +/* enable counter, comparator2 to event mode, 14.318MHz clock */ +void enable_mfgpt0_counter(void) +{ + outw(0xe310, MFGPT0_SETUP); +} +EXPORT_SYMBOL(enable_mfgpt0_counter); + +static void init_mfgpt_timer(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + raw_spin_lock(&mfgpt_lock); + + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + outw(COMPARE, MFGPT0_CMP2); /* set comparator2 */ + outw(0, MFGPT0_CNT); /* set counter to 0 */ + enable_mfgpt0_counter(); + break; + + case CLOCK_EVT_MODE_SHUTDOWN: + case CLOCK_EVT_MODE_UNUSED: + if (evt->mode == CLOCK_EVT_MODE_PERIODIC || + evt->mode == CLOCK_EVT_MODE_ONESHOT) + disable_mfgpt0_counter(); + break; + + case CLOCK_EVT_MODE_ONESHOT: + /* The oneshot mode have very high deviation, Not use it! */ + break; + + case CLOCK_EVT_MODE_RESUME: + /* Nothing to do here */ + break; + } + raw_spin_unlock(&mfgpt_lock); +} + +static struct clock_event_device mfgpt_clockevent = { + .name = "mfgpt", + .features = CLOCK_EVT_FEAT_PERIODIC, + .set_mode = init_mfgpt_timer, + .irq = CS5536_MFGPT_INTR, +}; + +static irqreturn_t timer_interrupt(int irq, void *dev_id) +{ + u32 basehi; + + /* + * get MFGPT base address + * + * NOTE: do not remove me, it's need for the value of mfgpt_base is + * variable + */ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), &basehi, &mfgpt_base); + + /* ack */ + outw(inw(MFGPT0_SETUP) | 0x4000, MFGPT0_SETUP); + + mfgpt_clockevent.event_handler(&mfgpt_clockevent); + + return IRQ_HANDLED; +} + +static struct irqaction irq5 = { + .handler = timer_interrupt, + .flags = IRQF_NOBALANCING | IRQF_TIMER, + .name = "timer" +}; + +/* + * Initialize the conversion factor and the min/max deltas of the clock event + * structure and register the clock event source with the framework. + */ +void __init setup_mfgpt0_timer(void) +{ + u32 basehi; + struct clock_event_device *cd = &mfgpt_clockevent; + unsigned int cpu = smp_processor_id(); + + cd->cpumask = cpumask_of(cpu); + clockevent_set_clock(cd, MFGPT_TICK_RATE); + cd->max_delta_ns = clockevent_delta2ns(0xffff, cd); + cd->min_delta_ns = clockevent_delta2ns(0xf, cd); + + /* Enable MFGPT0 Comparator 2 Output to the Interrupt Mapper */ + _wrmsr(DIVIL_MSR_REG(MFGPT_IRQ), 0, 0x100); + + /* Enable Interrupt Gate 5 */ + _wrmsr(DIVIL_MSR_REG(PIC_ZSEL_LOW), 0, 0x50000); + + /* get MFGPT base address */ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), &basehi, &mfgpt_base); + + clockevents_register_device(cd); + + setup_irq(CS5536_MFGPT_INTR, &irq5); +} + +/* + * Since the MFGPT overflows every tick, its not very useful + * to just read by itself. So use jiffies to emulate a free + * running counter: + */ +static cycle_t mfgpt_read(struct clocksource *cs) +{ + unsigned long flags; + int count; + u32 jifs; + static int old_count; + static u32 old_jifs; + + raw_spin_lock_irqsave(&mfgpt_lock, flags); + /* + * Although our caller may have the read side of xtime_lock, + * this is now a seqlock, and we are cheating in this routine + * by having side effects on state that we cannot undo if + * there is a collision on the seqlock and our caller has to + * retry. (Namely, old_jifs and old_count.) So we must treat + * jiffies as volatile despite the lock. We read jiffies + * before latching the timer count to guarantee that although + * the jiffies value might be older than the count (that is, + * the counter may underflow between the last point where + * jiffies was incremented and the point where we latch the + * count), it cannot be newer. + */ + jifs = jiffies; + /* read the count */ + count = inw(MFGPT0_CNT); + + /* + * It's possible for count to appear to go the wrong way for this + * reason: + * + * The timer counter underflows, but we haven't handled the resulting + * interrupt and incremented jiffies yet. + * + * Previous attempts to handle these cases intelligently were buggy, so + * we just do the simple thing now. + */ + if (count < old_count && jifs == old_jifs) + count = old_count; + + old_count = count; + old_jifs = jifs; + + raw_spin_unlock_irqrestore(&mfgpt_lock, flags); + + return (cycle_t) (jifs * COMPARE) + count; +} + +static struct clocksource clocksource_mfgpt = { + .name = "mfgpt", + .rating = 120, /* Functional for real use, but not desired */ + .read = mfgpt_read, + .mask = CLOCKSOURCE_MASK(32), +}; + +int __init init_mfgpt_clocksource(void) +{ + if (num_possible_cpus() > 1) /* MFGPT does not scale! */ + return 0; + + return clocksource_register_hz(&clocksource_mfgpt, MFGPT_TICK_RATE); +} + +arch_initcall(init_mfgpt_clocksource); diff --git a/arch/mips/loongson64/common/cs5536/cs5536_ohci.c b/arch/mips/loongson64/common/cs5536/cs5536_ohci.c new file mode 100644 index 000000000000..f7c905e50dc4 --- /dev/null +++ b/arch/mips/loongson64/common/cs5536/cs5536_ohci.c @@ -0,0 +1,149 @@ +/* + * the OHCI Virtual Support Module of AMD CS5536 + * + * Copyright (C) 2007 Lemote, Inc. + * Author : jlliu, liujl@lemote.com + * + * Copyright (C) 2009 Lemote, Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include + +void pci_ohci_write_reg(int reg, u32 value) +{ + u32 hi = 0, lo = value; + + switch (reg) { + case PCI_COMMAND: + _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); + if (value & PCI_COMMAND_MASTER) + hi |= PCI_COMMAND_MASTER; + else + hi &= ~PCI_COMMAND_MASTER; + + if (value & PCI_COMMAND_MEMORY) + hi |= PCI_COMMAND_MEMORY; + else + hi &= ~PCI_COMMAND_MEMORY; + _wrmsr(USB_MSR_REG(USB_OHCI), hi, lo); + break; + case PCI_STATUS: + if (value & PCI_STATUS_PARITY) { + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) { + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_BAR0_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_OHCI_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if ((value & 0x01) == 0x00) { + _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); + lo = value; + _wrmsr(USB_MSR_REG(USB_OHCI), hi, lo); + + value &= 0xfffffff0; + hi = 0x40000000 | ((value & 0xff000000) >> 24); + lo = 0x000fffff | ((value & 0x00fff000) << 8); + _wrmsr(GLIU_MSR_REG(GLIU_P2D_BM3), hi, lo); + } + break; + case PCI_OHCI_INT_REG: + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); + lo &= ~(0xf << PIC_YSEL_LOW_USB_SHIFT); + if (value) /* enable all the usb interrupt in PIC */ + lo |= (CS5536_USB_INTR << PIC_YSEL_LOW_USB_SHIFT); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo); + break; + default: + break; + } +} + +u32 pci_ohci_read_reg(int reg) +{ + u32 conf_data = 0; + u32 hi, lo; + + switch (reg) { + case PCI_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_OHCI_DEVICE_ID, CS5536_VENDOR_ID); + break; + case PCI_COMMAND: + _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); + if (hi & PCI_COMMAND_MASTER) + conf_data |= PCI_COMMAND_MASTER; + if (hi & PCI_COMMAND_MEMORY) + conf_data |= PCI_COMMAND_MEMORY; + break; + case PCI_STATUS: + conf_data |= PCI_STATUS_66MHZ; + conf_data |= PCI_STATUS_FAST_BACK; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REVISION: + _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_OHCI_CLASS_CODE << 8); + break; + case PCI_CACHE_LINE_SIZE: + conf_data = + CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, + PCI_NORMAL_LATENCY_TIMER); + break; + case PCI_BAR0_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_OHCI_FLAG) { + conf_data = CS5536_OHCI_RANGE | + PCI_BASE_ADDRESS_SPACE_MEMORY; + lo &= ~SOFT_BAR_OHCI_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); + conf_data = lo & 0xffffff00; + conf_data &= ~0x0000000f; /* 32bit mem */ + } + break; + case PCI_CARDBUS_CIS: + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYSTEM_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_OHCI_SUB_ID, CS5536_SUB_VENDOR_ID); + break; + case PCI_ROM_ADDRESS: + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPABILITY_LIST: + conf_data = PCI_CAPLIST_USB_POINTER; + break; + case PCI_INTERRUPT_LINE: + conf_data = + CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR); + break; + case PCI_OHCI_INT_REG: + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); + if ((lo & 0x00000f00) == CS5536_USB_INTR) + conf_data = 1; + break; + default: + break; + } + + return conf_data; +} diff --git a/arch/mips/loongson64/common/cs5536/cs5536_pci.c b/arch/mips/loongson64/common/cs5536/cs5536_pci.c new file mode 100644 index 000000000000..b739723205f8 --- /dev/null +++ b/arch/mips/loongson64/common/cs5536/cs5536_pci.c @@ -0,0 +1,88 @@ +/* + * read/write operation to the PCI config space of CS5536 + * + * Copyright (C) 2007 Lemote, Inc. + * Author : jlliu, liujl@lemote.com + * + * Copyright (C) 2009 Lemote, Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * the Virtual Support Module(VSM) for virtulizing the PCI + * configure space are defined in cs5536_modulename.c respectively, + * + * after this virtulizing, user can access the PCI configure space + * directly as a normal multi-function PCI device which follows + * the PCI-2.2 spec. + */ + +#include +#include +#include + +enum { + CS5536_FUNC_START = -1, + CS5536_ISA_FUNC, + reserved_func, + CS5536_IDE_FUNC, + CS5536_ACC_FUNC, + CS5536_OHCI_FUNC, + CS5536_EHCI_FUNC, + CS5536_FUNC_END, +}; + +static const cs5536_pci_vsm_write vsm_conf_write[] = { + [CS5536_ISA_FUNC] = pci_isa_write_reg, + [reserved_func] = NULL, + [CS5536_IDE_FUNC] = pci_ide_write_reg, + [CS5536_ACC_FUNC] = pci_acc_write_reg, + [CS5536_OHCI_FUNC] = pci_ohci_write_reg, + [CS5536_EHCI_FUNC] = pci_ehci_write_reg, +}; + +static const cs5536_pci_vsm_read vsm_conf_read[] = { + [CS5536_ISA_FUNC] = pci_isa_read_reg, + [reserved_func] = NULL, + [CS5536_IDE_FUNC] = pci_ide_read_reg, + [CS5536_ACC_FUNC] = pci_acc_read_reg, + [CS5536_OHCI_FUNC] = pci_ohci_read_reg, + [CS5536_EHCI_FUNC] = pci_ehci_read_reg, +}; + +/* + * write to PCI config space and transfer it to MSR write. + */ +void cs5536_pci_conf_write4(int function, int reg, u32 value) +{ + if ((function <= CS5536_FUNC_START) || (function >= CS5536_FUNC_END)) + return; + if ((reg < 0) || (reg > 0x100) || ((reg & 0x03) != 0)) + return; + + if (vsm_conf_write[function] != NULL) + vsm_conf_write[function](reg, value); +} + +/* + * read PCI config space and transfer it to MSR access. + */ +u32 cs5536_pci_conf_read4(int function, int reg) +{ + u32 data = 0; + + if ((function <= CS5536_FUNC_START) || (function >= CS5536_FUNC_END)) + return 0; + if ((reg < 0) || ((reg & 0x03) != 0)) + return 0; + if (reg > 0x100) + return 0xffffffff; + + if (vsm_conf_read[function] != NULL) + data = vsm_conf_read[function](reg); + + return data; +} diff --git a/arch/mips/loongson64/common/dma-swiotlb.c b/arch/mips/loongson64/common/dma-swiotlb.c new file mode 100644 index 000000000000..2c6b989c1bc4 --- /dev/null +++ b/arch/mips/loongson64/common/dma-swiotlb.c @@ -0,0 +1,150 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static void *loongson_dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t gfp, struct dma_attrs *attrs) +{ + void *ret; + + if (dma_alloc_from_coherent(dev, size, dma_handle, &ret)) + return ret; + + /* ignore region specifiers */ + gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM); + +#ifdef CONFIG_ISA + if (dev == NULL) + gfp |= __GFP_DMA; + else +#endif +#ifdef CONFIG_ZONE_DMA + if (dev->coherent_dma_mask < DMA_BIT_MASK(32)) + gfp |= __GFP_DMA; + else +#endif +#ifdef CONFIG_ZONE_DMA32 + if (dev->coherent_dma_mask < DMA_BIT_MASK(40)) + gfp |= __GFP_DMA32; + else +#endif + ; + gfp |= __GFP_NORETRY; + + ret = swiotlb_alloc_coherent(dev, size, dma_handle, gfp); + mb(); + return ret; +} + +static void loongson_dma_free_coherent(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle, struct dma_attrs *attrs) +{ + int order = get_order(size); + + if (dma_release_from_coherent(dev, order, vaddr)) + return; + + swiotlb_free_coherent(dev, size, vaddr, dma_handle); +} + +static dma_addr_t loongson_dma_map_page(struct device *dev, struct page *page, + unsigned long offset, size_t size, + enum dma_data_direction dir, + struct dma_attrs *attrs) +{ + dma_addr_t daddr = swiotlb_map_page(dev, page, offset, size, + dir, attrs); + mb(); + return daddr; +} + +static int loongson_dma_map_sg(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir, + struct dma_attrs *attrs) +{ + int r = swiotlb_map_sg_attrs(dev, sg, nents, dir, NULL); + mb(); + + return r; +} + +static void loongson_dma_sync_single_for_device(struct device *dev, + dma_addr_t dma_handle, size_t size, + enum dma_data_direction dir) +{ + swiotlb_sync_single_for_device(dev, dma_handle, size, dir); + mb(); +} + +static void loongson_dma_sync_sg_for_device(struct device *dev, + struct scatterlist *sg, int nents, + enum dma_data_direction dir) +{ + swiotlb_sync_sg_for_device(dev, sg, nents, dir); + mb(); +} + +static int loongson_dma_set_mask(struct device *dev, u64 mask) +{ + if (mask > DMA_BIT_MASK(loongson_sysconf.dma_mask_bits)) { + *dev->dma_mask = DMA_BIT_MASK(loongson_sysconf.dma_mask_bits); + return -EIO; + } + + *dev->dma_mask = mask; + + return 0; +} + +dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) +{ + long nid; +#ifdef CONFIG_PHYS48_TO_HT40 + /* We extract 2bit node id (bit 44~47, only bit 44~45 used now) from + * Loongson-3's 48bit address space and embed it into 40bit */ + nid = (paddr >> 44) & 0x3; + paddr = ((nid << 44) ^ paddr) | (nid << 37); +#endif + return paddr; +} + +phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) +{ + long nid; +#ifdef CONFIG_PHYS48_TO_HT40 + /* We extract 2bit node id (bit 44~47, only bit 44~45 used now) from + * Loongson-3's 48bit address space and embed it into 40bit */ + nid = (daddr >> 37) & 0x3; + daddr = ((nid << 37) ^ daddr) | (nid << 44); +#endif + return daddr; +} + +static struct dma_map_ops loongson_dma_map_ops = { + .alloc = loongson_dma_alloc_coherent, + .free = loongson_dma_free_coherent, + .map_page = loongson_dma_map_page, + .unmap_page = swiotlb_unmap_page, + .map_sg = loongson_dma_map_sg, + .unmap_sg = swiotlb_unmap_sg_attrs, + .sync_single_for_cpu = swiotlb_sync_single_for_cpu, + .sync_single_for_device = loongson_dma_sync_single_for_device, + .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu, + .sync_sg_for_device = loongson_dma_sync_sg_for_device, + .mapping_error = swiotlb_dma_mapping_error, + .dma_supported = swiotlb_dma_supported, + .set_dma_mask = loongson_dma_set_mask +}; + +void __init plat_swiotlb_setup(void) +{ + swiotlb_init(1); + mips_dma_map_ops = &loongson_dma_map_ops; +} diff --git a/arch/mips/loongson64/common/early_printk.c b/arch/mips/loongson64/common/early_printk.c new file mode 100644 index 000000000000..6ca632e529dc --- /dev/null +++ b/arch/mips/loongson64/common/early_printk.c @@ -0,0 +1,41 @@ +/* early printk support + * + * Copyright (c) 2009 Philippe Vachon + * Copyright (c) 2009 Lemote Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include + +#include + +#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); +} diff --git a/arch/mips/loongson64/common/env.c b/arch/mips/loongson64/common/env.c new file mode 100644 index 000000000000..22f04ca2ff3e --- /dev/null +++ b/arch/mips/loongson64/common/env.c @@ -0,0 +1,200 @@ +/* + * 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 + * + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include +#include + +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; + 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; + if (ecpu->cputype == 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_sysconf.ht_control_base = 0x90000EFDFB000000; + loongson_sysconf.workarounds = WORKAROUND_CPUFREQ; + } else if (ecpu->cputype == 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; + } else { + 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 = (¤t_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: + 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); +} diff --git a/arch/mips/loongson64/common/init.c b/arch/mips/loongson64/common/init.c new file mode 100644 index 000000000000..9b987fe98b5b --- /dev/null +++ b/arch/mips/loongson64/common/init.c @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include + +#include + +/* Loongson CPU address windows config space base address */ +unsigned long __maybe_unused _loongson_addrwincfg_base; + +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); +} + +void __init prom_free_prom_memory(void) +{ +} diff --git a/arch/mips/loongson64/common/irq.c b/arch/mips/loongson64/common/irq.c new file mode 100644 index 000000000000..687003b19b45 --- /dev/null +++ b/arch/mips/loongson64/common/irq.c @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include + +#include +/* + * 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(); +} diff --git a/arch/mips/loongson64/common/machtype.c b/arch/mips/loongson64/common/machtype.c new file mode 100644 index 000000000000..f2807bc662a3 --- /dev/null +++ b/arch/mips/loongson64/common/machtype.c @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * + * Copyright (c) 2009 Zhang Le + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include + +#include +#include + +/* 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; + } +} diff --git a/arch/mips/loongson64/common/mem.c b/arch/mips/loongson64/common/mem.c new file mode 100644 index 000000000000..b01d52473da8 --- /dev/null +++ b/arch/mips/loongson64/common/mem.c @@ -0,0 +1,161 @@ +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include + +#include + +#include +#include +#include +#include + +#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) { + switch (mem_type) { + case SYSTEM_RAM_LOW: + add_memory_region(loongson_memmap->map[i].mem_start, + (u64)loongson_memmap->map[i].mem_size << 20, + BOOT_MEM_RAM); + break; + case SYSTEM_RAM_HIGH: + add_memory_region(loongson_memmap->map[i].mem_start, + (u64)loongson_memmap->map[i].mem_size << 20, + BOOT_MEM_RAM); + break; + case MEM_RESERVED: + add_memory_region(loongson_memmap->map[i].mem_start, + (u64)loongson_memmap->map[i].mem_size << 20, + BOOT_MEM_RESERVED); + 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 +#include +#include + +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 */ diff --git a/arch/mips/loongson64/common/pci.c b/arch/mips/loongson64/common/pci.c new file mode 100644 index 000000000000..4e2575643781 --- /dev/null +++ b/arch/mips/loongson64/common/pci.c @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include + +#include +#include +#include + +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_LOONGSON3 + sbx00_acpi_init(); +#endif + + return 0; +} + +arch_initcall(pcibios_init); diff --git a/arch/mips/loongson64/common/platform.c b/arch/mips/loongson64/common/platform.c new file mode 100644 index 000000000000..0ed38321a9a2 --- /dev/null +++ b/arch/mips/loongson64/common/platform.c @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include + +static struct platform_device loongson2_cpufreq_device = { + .name = "loongson2_cpufreq", + .id = -1, +}; + +static int __init loongson2_cpufreq_init(void) +{ + struct cpuinfo_mips *c = ¤t_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); diff --git a/arch/mips/loongson64/common/pm.c b/arch/mips/loongson64/common/pm.c new file mode 100644 index 000000000000..a6b67ccfc811 --- /dev/null +++ b/arch/mips/loongson64/common/pm.c @@ -0,0 +1,161 @@ +/* + * loongson-specific suspend support + * + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include +#include +#include + +#include +#include + +#include + +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); diff --git a/arch/mips/loongson64/common/reset.c b/arch/mips/loongson64/common/reset.c new file mode 100644 index 000000000000..a60715e11306 --- /dev/null +++ b/arch/mips/loongson64/common/reset.c @@ -0,0 +1,92 @@ +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * 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 +#include + +#include +#include + +#include +#include + +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(); + unreachable(); +#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); diff --git a/arch/mips/loongson64/common/rtc.c b/arch/mips/loongson64/common/rtc.c new file mode 100644 index 000000000000..b5709af09f7f --- /dev/null +++ b/arch/mips/loongson64/common/rtc.c @@ -0,0 +1,43 @@ +/* + * Lemote Fuloong platform support + * + * Copyright(c) 2010 Arnaud Patard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include + +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); diff --git a/arch/mips/loongson64/common/serial.c b/arch/mips/loongson64/common/serial.c new file mode 100644 index 000000000000..c23fa1373729 --- /dev/null +++ b/arch/mips/loongson64/common/serial.c @@ -0,0 +1,112 @@ +/* + * 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 +#include +#include + +#include + +#include +#include + +#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); +} + +device_initcall(serial_init); diff --git a/arch/mips/loongson64/common/setup.c b/arch/mips/loongson64/common/setup.c new file mode 100644 index 000000000000..d477dd6bb326 --- /dev/null +++ b/arch/mips/loongson64/common/setup.c @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include + +#include +#include + +#include + +#ifdef CONFIG_VT +#include +#include +#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 +} diff --git a/arch/mips/loongson64/common/time.c b/arch/mips/loongson64/common/time.c new file mode 100644 index 000000000000..e1a5382ad47e --- /dev/null +++ b/arch/mips/loongson64/common/time.c @@ -0,0 +1,36 @@ +/* + * 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 + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include + +#include +#include + +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_clock(struct timespec *ts) +{ + ts->tv_sec = mc146818_get_cmos_time(); + ts->tv_nsec = 0; +} diff --git a/arch/mips/loongson64/common/uart_base.c b/arch/mips/loongson64/common/uart_base.c new file mode 100644 index 000000000000..9de559d58e1f --- /dev/null +++ b/arch/mips/loongson64/common/uart_base.c @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include + +#include + +/* 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); +} diff --git a/arch/mips/loongson64/fuloong-2e/Makefile b/arch/mips/loongson64/fuloong-2e/Makefile new file mode 100644 index 000000000000..b7622720c1ad --- /dev/null +++ b/arch/mips/loongson64/fuloong-2e/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for Lemote Fuloong2e mini-PC board. +# + +obj-y += irq.o reset.o diff --git a/arch/mips/loongson64/fuloong-2e/irq.c b/arch/mips/loongson64/fuloong-2e/irq.c new file mode 100644 index 000000000000..ef5ec8f3de5f --- /dev/null +++ b/arch/mips/loongson64/fuloong-2e/irq.c @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include + +#include +#include + +#include + +static void i8259_irqdispatch(void) +{ + int irq; + + irq = i8259_irq(); + if (irq >= 0) + do_IRQ(irq); + else + spurious_interrupt(); +} + +asmlinkage void mach_irq_dispatch(unsigned int pending) +{ + if (pending & CAUSEF_IP7) + do_IRQ(MIPS_CPU_IRQ_BASE + 7); + else if (pending & CAUSEF_IP6) /* perf counter loverflow */ + do_perfcnt_IRQ(); + else if (pending & CAUSEF_IP5) + i8259_irqdispatch(); + else if (pending & CAUSEF_IP2) + bonito_irqdispatch(); + else + spurious_interrupt(); +} + +static struct irqaction cascade_irqaction = { + .handler = no_action, + .name = "cascade", + .flags = IRQF_NO_THREAD, +}; + +void __init mach_init_irq(void) +{ + /* init all controller + * 0-15 ------> i8259 interrupt + * 16-23 ------> mips cpu interrupt + * 32-63 ------> bonito irq + */ + + /* most bonito irq should be level triggered */ + LOONGSON_INTEDGE = LOONGSON_ICU_SYSTEMERR | LOONGSON_ICU_MASTERERR | + LOONGSON_ICU_RETRYERR | LOONGSON_ICU_MBOXES; + + /* Sets the first-level interrupt dispatcher. */ + mips_cpu_irq_init(); + init_i8259_irqs(); + bonito_irq_init(); + + /* bonito irq at IP2 */ + setup_irq(MIPS_CPU_IRQ_BASE + 2, &cascade_irqaction); + /* 8259 irq at IP5 */ + setup_irq(MIPS_CPU_IRQ_BASE + 5, &cascade_irqaction); +} diff --git a/arch/mips/loongson64/fuloong-2e/reset.c b/arch/mips/loongson64/fuloong-2e/reset.c new file mode 100644 index 000000000000..da4d2ae2a1f8 --- /dev/null +++ b/arch/mips/loongson64/fuloong-2e/reset.c @@ -0,0 +1,23 @@ +/* Board-specific reboot/shutdown routines + * Copyright (c) 2009 Philippe Vachon + * + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include + +void mach_prepare_reboot(void) +{ + LOONGSON_GENCFG &= ~(1 << 2); + LOONGSON_GENCFG |= (1 << 2); +} + +void mach_prepare_shutdown(void) +{ +} diff --git a/arch/mips/loongson64/lemote-2f/Makefile b/arch/mips/loongson64/lemote-2f/Makefile new file mode 100644 index 000000000000..4f9eaa328a16 --- /dev/null +++ b/arch/mips/loongson64/lemote-2f/Makefile @@ -0,0 +1,11 @@ +# +# Makefile for lemote loongson2f family machines +# + +obj-y += clock.o machtype.o irq.o reset.o ec_kb3310b.o + +# +# Suspend Support +# + +obj-$(CONFIG_LOONGSON_SUSPEND) += pm.o diff --git a/arch/mips/loongson64/lemote-2f/clock.c b/arch/mips/loongson64/lemote-2f/clock.c new file mode 100644 index 000000000000..462e34d46b4a --- /dev/null +++ b/arch/mips/loongson64/lemote-2f/clock.c @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2006 - 2008 Lemote Inc. & Insititute of Computing Technology + * Author: Yanhua, yanh@lemote.com + * + * 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. + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static LIST_HEAD(clock_list); +static DEFINE_SPINLOCK(clock_lock); +static DEFINE_MUTEX(clock_list_sem); + +/* Minimum CLK support */ +enum { + DC_ZERO, DC_25PT = 2, DC_37PT, DC_50PT, DC_62PT, DC_75PT, + DC_87PT, DC_DISABLE, DC_RESV +}; + +struct cpufreq_frequency_table loongson2_clockmod_table[] = { + {0, DC_RESV, CPUFREQ_ENTRY_INVALID}, + {0, DC_ZERO, CPUFREQ_ENTRY_INVALID}, + {0, DC_25PT, 0}, + {0, DC_37PT, 0}, + {0, DC_50PT, 0}, + {0, DC_62PT, 0}, + {0, DC_75PT, 0}, + {0, DC_87PT, 0}, + {0, DC_DISABLE, 0}, + {0, DC_RESV, CPUFREQ_TABLE_END}, +}; +EXPORT_SYMBOL_GPL(loongson2_clockmod_table); + +static struct clk cpu_clk = { + .name = "cpu_clk", + .flags = CLK_ALWAYS_ENABLED | CLK_RATE_PROPAGATES, + .rate = 800000000, +}; + +struct clk *clk_get(struct device *dev, const char *id) +{ + return &cpu_clk; +} +EXPORT_SYMBOL(clk_get); + +static void propagate_rate(struct clk *clk) +{ + struct clk *clkp; + + list_for_each_entry(clkp, &clock_list, node) { + if (likely(clkp->parent != clk)) + continue; + if (likely(clkp->ops && clkp->ops->recalc)) + clkp->ops->recalc(clkp); + if (unlikely(clkp->flags & CLK_RATE_PROPAGATES)) + propagate_rate(clkp); + } +} + +int clk_enable(struct clk *clk) +{ + return 0; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_disable); + +unsigned long clk_get_rate(struct clk *clk) +{ + return (unsigned long)clk->rate; +} +EXPORT_SYMBOL(clk_get_rate); + +void clk_put(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_put); + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + unsigned int rate_khz = rate / 1000; + struct cpufreq_frequency_table *pos; + int ret = 0; + int regval; + + if (likely(clk->ops && clk->ops->set_rate)) { + unsigned long flags; + + spin_lock_irqsave(&clock_lock, flags); + ret = clk->ops->set_rate(clk, rate, 0); + spin_unlock_irqrestore(&clock_lock, flags); + } + + if (unlikely(clk->flags & CLK_RATE_PROPAGATES)) + propagate_rate(clk); + + cpufreq_for_each_valid_entry(pos, loongson2_clockmod_table) + if (rate_khz == pos->frequency) + break; + if (rate_khz != pos->frequency) + return -ENOTSUPP; + + clk->rate = rate; + + regval = LOONGSON_CHIPCFG(0); + regval = (regval & ~0x7) | (pos->driver_data - 1); + LOONGSON_CHIPCFG(0) = regval; + + return ret; +} +EXPORT_SYMBOL_GPL(clk_set_rate); + +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + if (likely(clk->ops && clk->ops->round_rate)) { + unsigned long flags, rounded; + + spin_lock_irqsave(&clock_lock, flags); + rounded = clk->ops->round_rate(clk, rate); + spin_unlock_irqrestore(&clock_lock, flags); + + return rounded; + } + + return rate; +} +EXPORT_SYMBOL_GPL(clk_round_rate); diff --git a/arch/mips/loongson64/lemote-2f/ec_kb3310b.c b/arch/mips/loongson64/lemote-2f/ec_kb3310b.c new file mode 100644 index 000000000000..2b666d3a3947 --- /dev/null +++ b/arch/mips/loongson64/lemote-2f/ec_kb3310b.c @@ -0,0 +1,128 @@ +/* + * Basic KB3310B Embedded Controller support for the YeeLoong 2F netbook + * + * Copyright (C) 2008 Lemote Inc. + * Author: liujl , 2008-04-20 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include + +#include "ec_kb3310b.h" + +static DEFINE_SPINLOCK(index_access_lock); +static DEFINE_SPINLOCK(port_access_lock); + +unsigned char ec_read(unsigned short addr) +{ + unsigned char value; + unsigned long flags; + + spin_lock_irqsave(&index_access_lock, flags); + outb((addr & 0xff00) >> 8, EC_IO_PORT_HIGH); + outb((addr & 0x00ff), EC_IO_PORT_LOW); + value = inb(EC_IO_PORT_DATA); + spin_unlock_irqrestore(&index_access_lock, flags); + + return value; +} +EXPORT_SYMBOL_GPL(ec_read); + +void ec_write(unsigned short addr, unsigned char val) +{ + unsigned long flags; + + spin_lock_irqsave(&index_access_lock, flags); + outb((addr & 0xff00) >> 8, EC_IO_PORT_HIGH); + outb((addr & 0x00ff), EC_IO_PORT_LOW); + outb(val, EC_IO_PORT_DATA); + /* flush the write action */ + inb(EC_IO_PORT_DATA); + spin_unlock_irqrestore(&index_access_lock, flags); +} +EXPORT_SYMBOL_GPL(ec_write); + +/* + * This function is used for EC command writes and corresponding status queries. + */ +int ec_query_seq(unsigned char cmd) +{ + int timeout; + unsigned char status; + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&port_access_lock, flags); + + /* make chip goto reset mode */ + udelay(EC_REG_DELAY); + outb(cmd, EC_CMD_PORT); + udelay(EC_REG_DELAY); + + /* check if the command is received by ec */ + timeout = EC_CMD_TIMEOUT; + status = inb(EC_STS_PORT); + while (timeout-- && (status & (1 << 1))) { + status = inb(EC_STS_PORT); + udelay(EC_REG_DELAY); + } + + spin_unlock_irqrestore(&port_access_lock, flags); + + if (timeout <= 0) { + printk(KERN_ERR "%s: deadable error : timeout...\n", __func__); + ret = -EINVAL; + } else + printk(KERN_INFO + "(%x/%d)ec issued command %d status : 0x%x\n", + timeout, EC_CMD_TIMEOUT - timeout, cmd, status); + + return ret; +} +EXPORT_SYMBOL_GPL(ec_query_seq); + +/* + * Send query command to EC to get the proper event number + */ +int ec_query_event_num(void) +{ + return ec_query_seq(CMD_GET_EVENT_NUM); +} +EXPORT_SYMBOL(ec_query_event_num); + +/* + * Get event number from EC + * + * NOTE: This routine must follow the query_event_num function in the + * interrupt. + */ +int ec_get_event_num(void) +{ + int timeout = 100; + unsigned char value; + unsigned char status; + + udelay(EC_REG_DELAY); + status = inb(EC_STS_PORT); + udelay(EC_REG_DELAY); + while (timeout-- && !(status & (1 << 0))) { + status = inb(EC_STS_PORT); + udelay(EC_REG_DELAY); + } + if (timeout <= 0) { + pr_info("%s: get event number timeout.\n", __func__); + + return -EINVAL; + } + value = inb(EC_DAT_PORT); + udelay(EC_REG_DELAY); + + return value; +} +EXPORT_SYMBOL(ec_get_event_num); diff --git a/arch/mips/loongson64/lemote-2f/ec_kb3310b.h b/arch/mips/loongson64/lemote-2f/ec_kb3310b.h new file mode 100644 index 000000000000..5a3f1860d4d2 --- /dev/null +++ b/arch/mips/loongson64/lemote-2f/ec_kb3310b.h @@ -0,0 +1,188 @@ +/* + * KB3310B Embedded Controller + * + * Copyright (C) 2008 Lemote Inc. + * Author: liujl , 2008-03-14 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef _EC_KB3310B_H +#define _EC_KB3310B_H + +extern unsigned char ec_read(unsigned short addr); +extern void ec_write(unsigned short addr, unsigned char val); +extern int ec_query_seq(unsigned char cmd); +extern int ec_query_event_num(void); +extern int ec_get_event_num(void); + +typedef int (*sci_handler) (int status); +extern sci_handler yeeloong_report_lid_status; + +#define SCI_IRQ_NUM 0x0A + +/* + * The following registers are determined by the EC index configuration. + * 1, fill the PORT_HIGH as EC register high part. + * 2, fill the PORT_LOW as EC register low part. + * 3, fill the PORT_DATA as EC register write data or get the data from it. + */ +#define EC_IO_PORT_HIGH 0x0381 +#define EC_IO_PORT_LOW 0x0382 +#define EC_IO_PORT_DATA 0x0383 + +/* + * EC delay time is 500us for register and status access + */ +#define EC_REG_DELAY 500 /* unit : us */ +#define EC_CMD_TIMEOUT 0x1000 + +/* + * EC access port for SCI communication + */ +#define EC_CMD_PORT 0x66 +#define EC_STS_PORT 0x66 +#define EC_DAT_PORT 0x62 +#define CMD_INIT_IDLE_MODE 0xdd +#define CMD_EXIT_IDLE_MODE 0xdf +#define CMD_INIT_RESET_MODE 0xd8 +#define CMD_REBOOT_SYSTEM 0x8c +#define CMD_GET_EVENT_NUM 0x84 +#define CMD_PROGRAM_PIECE 0xda + +/* temperature & fan registers */ +#define REG_TEMPERATURE_VALUE 0xF458 +#define REG_FAN_AUTO_MAN_SWITCH 0xF459 +#define BIT_FAN_AUTO 0 +#define BIT_FAN_MANUAL 1 +#define REG_FAN_CONTROL 0xF4D2 +#define BIT_FAN_CONTROL_ON (1 << 0) +#define BIT_FAN_CONTROL_OFF (0 << 0) +#define REG_FAN_STATUS 0xF4DA +#define BIT_FAN_STATUS_ON (1 << 0) +#define BIT_FAN_STATUS_OFF (0 << 0) +#define REG_FAN_SPEED_HIGH 0xFE22 +#define REG_FAN_SPEED_LOW 0xFE23 +#define REG_FAN_SPEED_LEVEL 0xF4CC +/* fan speed divider */ +#define FAN_SPEED_DIVIDER 480000 /* (60*1000*1000/62.5/2)*/ + +/* battery registers */ +#define REG_BAT_DESIGN_CAP_HIGH 0xF77D +#define REG_BAT_DESIGN_CAP_LOW 0xF77E +#define REG_BAT_FULLCHG_CAP_HIGH 0xF780 +#define REG_BAT_FULLCHG_CAP_LOW 0xF781 +#define REG_BAT_DESIGN_VOL_HIGH 0xF782 +#define REG_BAT_DESIGN_VOL_LOW 0xF783 +#define REG_BAT_CURRENT_HIGH 0xF784 +#define REG_BAT_CURRENT_LOW 0xF785 +#define REG_BAT_VOLTAGE_HIGH 0xF786 +#define REG_BAT_VOLTAGE_LOW 0xF787 +#define REG_BAT_TEMPERATURE_HIGH 0xF788 +#define REG_BAT_TEMPERATURE_LOW 0xF789 +#define REG_BAT_RELATIVE_CAP_HIGH 0xF492 +#define REG_BAT_RELATIVE_CAP_LOW 0xF493 +#define REG_BAT_VENDOR 0xF4C4 +#define FLAG_BAT_VENDOR_SANYO 0x01 +#define FLAG_BAT_VENDOR_SIMPLO 0x02 +#define REG_BAT_CELL_COUNT 0xF4C6 +#define FLAG_BAT_CELL_3S1P 0x03 +#define FLAG_BAT_CELL_3S2P 0x06 +#define REG_BAT_CHARGE 0xF4A2 +#define FLAG_BAT_CHARGE_DISCHARGE 0x01 +#define FLAG_BAT_CHARGE_CHARGE 0x02 +#define FLAG_BAT_CHARGE_ACPOWER 0x00 +#define REG_BAT_STATUS 0xF4B0 +#define BIT_BAT_STATUS_LOW (1 << 5) +#define BIT_BAT_STATUS_DESTROY (1 << 2) +#define BIT_BAT_STATUS_FULL (1 << 1) +#define BIT_BAT_STATUS_IN (1 << 0) +#define REG_BAT_CHARGE_STATUS 0xF4B1 +#define BIT_BAT_CHARGE_STATUS_OVERTEMP (1 << 2) +#define BIT_BAT_CHARGE_STATUS_PRECHG (1 << 1) +#define REG_BAT_STATE 0xF482 +#define BIT_BAT_STATE_CHARGING (1 << 1) +#define BIT_BAT_STATE_DISCHARGING (1 << 0) +#define REG_BAT_POWER 0xF440 +#define BIT_BAT_POWER_S3 (1 << 2) +#define BIT_BAT_POWER_ON (1 << 1) +#define BIT_BAT_POWER_ACIN (1 << 0) + +/* other registers */ +/* Audio: rd/wr */ +#define REG_AUDIO_VOLUME 0xF46C +#define REG_AUDIO_MUTE 0xF4E7 +#define REG_AUDIO_BEEP 0xF4D0 +/* USB port power or not: rd/wr */ +#define REG_USB0_FLAG 0xF461 +#define REG_USB1_FLAG 0xF462 +#define REG_USB2_FLAG 0xF463 +#define BIT_USB_FLAG_ON 1 +#define BIT_USB_FLAG_OFF 0 +/* LID */ +#define REG_LID_DETECT 0xF4BD +#define BIT_LID_DETECT_ON 1 +#define BIT_LID_DETECT_OFF 0 +/* CRT */ +#define REG_CRT_DETECT 0xF4AD +#define BIT_CRT_DETECT_PLUG 1 +#define BIT_CRT_DETECT_UNPLUG 0 +/* LCD backlight brightness adjust: 9 levels */ +#define REG_DISPLAY_BRIGHTNESS 0xF4F5 +/* Black screen Status */ +#define BIT_DISPLAY_LCD_ON 1 +#define BIT_DISPLAY_LCD_OFF 0 +/* LCD backlight control: off/restore */ +#define REG_BACKLIGHT_CTRL 0xF7BD +#define BIT_BACKLIGHT_ON 1 +#define BIT_BACKLIGHT_OFF 0 +/* Reset the machine auto-clear: rd/wr */ +#define REG_RESET 0xF4EC +#define BIT_RESET_ON 1 +/* Light the led: rd/wr */ +#define REG_LED 0xF4C8 +#define BIT_LED_RED_POWER (1 << 0) +#define BIT_LED_ORANGE_POWER (1 << 1) +#define BIT_LED_GREEN_CHARGE (1 << 2) +#define BIT_LED_RED_CHARGE (1 << 3) +#define BIT_LED_NUMLOCK (1 << 4) +/* Test led mode, all led on/off */ +#define REG_LED_TEST 0xF4C2 +#define BIT_LED_TEST_IN 1 +#define BIT_LED_TEST_OUT 0 +/* Camera on/off */ +#define REG_CAMERA_STATUS 0xF46A +#define BIT_CAMERA_STATUS_ON 1 +#define BIT_CAMERA_STATUS_OFF 0 +#define REG_CAMERA_CONTROL 0xF7B7 +#define BIT_CAMERA_CONTROL_OFF 0 +#define BIT_CAMERA_CONTROL_ON 1 +/* Wlan Status */ +#define REG_WLAN 0xF4FA +#define BIT_WLAN_ON 1 +#define BIT_WLAN_OFF 0 +#define REG_DISPLAY_LCD 0xF79F + +/* SCI Event Number from EC */ +enum { + EVENT_LID = 0x23, /* LID open/close */ + EVENT_DISPLAY_TOGGLE, /* Fn+F3 for display switch */ + EVENT_SLEEP, /* Fn+F1 for entering sleep mode */ + EVENT_OVERTEMP, /* Over-temperature happened */ + EVENT_CRT_DETECT, /* CRT is connected */ + EVENT_CAMERA, /* Camera on/off */ + EVENT_USB_OC2, /* USB2 Over Current occurred */ + EVENT_USB_OC0, /* USB0 Over Current occurred */ + EVENT_BLACK_SCREEN, /* Turn on/off backlight */ + EVENT_AUDIO_MUTE, /* Mute on/off */ + EVENT_DISPLAY_BRIGHTNESS,/* LCD backlight brightness adjust */ + EVENT_AC_BAT, /* AC & Battery relative issue */ + EVENT_AUDIO_VOLUME, /* Volume adjust */ + EVENT_WLAN, /* Wlan on/off */ + EVENT_END +}; + +#endif /* !_EC_KB3310B_H */ diff --git a/arch/mips/loongson64/lemote-2f/irq.c b/arch/mips/loongson64/lemote-2f/irq.c new file mode 100644 index 000000000000..cab5f43e0e29 --- /dev/null +++ b/arch/mips/loongson64/lemote-2f/irq.c @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2007 Lemote Inc. + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include + +#include +#include +#include + +#include +#include + +#define LOONGSON_TIMER_IRQ (MIPS_CPU_IRQ_BASE + 7) /* cpu timer */ +#define LOONGSON_NORTH_BRIDGE_IRQ (MIPS_CPU_IRQ_BASE + 6) /* bonito */ +#define LOONGSON_UART_IRQ (MIPS_CPU_IRQ_BASE + 3) /* cpu serial port */ +#define LOONGSON_SOUTH_BRIDGE_IRQ (MIPS_CPU_IRQ_BASE + 2) /* i8259 */ + +#define LOONGSON_INT_BIT_INT0 (1 << 11) +#define LOONGSON_INT_BIT_INT1 (1 << 12) + +/* + * The generic i8259_irq() make the kernel hang on booting. Since we cannot + * get the irq via the IRR directly, we access the ISR instead. + */ +int mach_i8259_irq(void) +{ + int irq, isr; + + irq = -1; + + if ((LOONGSON_INTISR & LOONGSON_INTEN) & LOONGSON_INT_BIT_INT0) { + raw_spin_lock(&i8259A_lock); + isr = inb(PIC_MASTER_CMD) & + ~inb(PIC_MASTER_IMR) & ~(1 << PIC_CASCADE_IR); + if (!isr) + isr = (inb(PIC_SLAVE_CMD) & ~inb(PIC_SLAVE_IMR)) << 8; + irq = ffs(isr) - 1; + if (unlikely(irq == 7)) { + /* + * This may be a spurious interrupt. + * + * Read the interrupt status register (ISR). If the most + * significant bit is not set then there is no valid + * interrupt. + */ + outb(0x0B, PIC_MASTER_ISR); /* ISR register */ + if (~inb(PIC_MASTER_ISR) & 0x80) + irq = -1; + } + raw_spin_unlock(&i8259A_lock); + } + + return irq; +} +EXPORT_SYMBOL(mach_i8259_irq); + +static void i8259_irqdispatch(void) +{ + int irq; + + irq = mach_i8259_irq(); + if (irq >= 0) + do_IRQ(irq); + else + spurious_interrupt(); +} + +void mach_irq_dispatch(unsigned int pending) +{ + if (pending & CAUSEF_IP7) + do_IRQ(LOONGSON_TIMER_IRQ); + else if (pending & CAUSEF_IP6) { /* North Bridge, Perf counter */ + do_perfcnt_IRQ(); + bonito_irqdispatch(); + } else if (pending & CAUSEF_IP3) /* CPU UART */ + do_IRQ(LOONGSON_UART_IRQ); + else if (pending & CAUSEF_IP2) /* South Bridge */ + i8259_irqdispatch(); + else + spurious_interrupt(); +} + +static irqreturn_t ip6_action(int cpl, void *dev_id) +{ + return IRQ_HANDLED; +} + +static struct irqaction ip6_irqaction = { + .handler = ip6_action, + .name = "cascade", + .flags = IRQF_SHARED | IRQF_NO_THREAD, +}; + +static struct irqaction cascade_irqaction = { + .handler = no_action, + .name = "cascade", + .flags = IRQF_NO_THREAD, +}; + +void __init mach_init_irq(void) +{ + /* init all controller + * 0-15 ------> i8259 interrupt + * 16-23 ------> mips cpu interrupt + * 32-63 ------> bonito irq + */ + + /* setup cs5536 as high level trigger */ + LOONGSON_INTPOL = LOONGSON_INT_BIT_INT0 | LOONGSON_INT_BIT_INT1; + LOONGSON_INTEDGE &= ~(LOONGSON_INT_BIT_INT0 | LOONGSON_INT_BIT_INT1); + + /* Sets the first-level interrupt dispatcher. */ + mips_cpu_irq_init(); + init_i8259_irqs(); + bonito_irq_init(); + + /* setup north bridge irq (bonito) */ + setup_irq(LOONGSON_NORTH_BRIDGE_IRQ, &ip6_irqaction); + /* setup source bridge irq (i8259) */ + setup_irq(LOONGSON_SOUTH_BRIDGE_IRQ, &cascade_irqaction); +} diff --git a/arch/mips/loongson64/lemote-2f/machtype.c b/arch/mips/loongson64/lemote-2f/machtype.c new file mode 100644 index 000000000000..b55e6eece5e0 --- /dev/null +++ b/arch/mips/loongson64/lemote-2f/machtype.c @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include + +#include + +void __init mach_prom_init_machtype(void) +{ + /* We share the same kernel image file among Lemote 2F family + * of machines, and provide the machtype= kernel command line + * to users to indicate their machine, this command line will + * be passed by the latest PMON automatically. and fortunately, + * up to now, we can get the machine type from the PMON_VER= + * commandline directly except the NAS machine, In the old + * machines, this will help the users a lot. + * + * If no "machtype=" passed, get machine type from "PMON_VER=". + * PMON_VER=LM8089 Lemote 8.9'' netbook + * LM8101 Lemote 10.1'' netbook + * (The above two netbooks have the same kernel support) + * LM6XXX Lemote FuLoong(2F) box series + * LM9XXX Lemote LynLoong PC series + */ + if (strstr(arcs_cmdline, "PMON_VER=LM")) { + if (strstr(arcs_cmdline, "PMON_VER=LM8")) + mips_machtype = MACH_LEMOTE_YL2F89; + else if (strstr(arcs_cmdline, "PMON_VER=LM6")) + mips_machtype = MACH_LEMOTE_FL2F; + else if (strstr(arcs_cmdline, "PMON_VER=LM9")) + mips_machtype = MACH_LEMOTE_LL2F; + else + mips_machtype = MACH_LEMOTE_NAS; + + strcat(arcs_cmdline, " machtype="); + strcat(arcs_cmdline, get_system_type()); + strcat(arcs_cmdline, " "); + } +} diff --git a/arch/mips/loongson64/lemote-2f/pm.c b/arch/mips/loongson64/lemote-2f/pm.c new file mode 100644 index 000000000000..cac4d382ea73 --- /dev/null +++ b/arch/mips/loongson64/lemote-2f/pm.c @@ -0,0 +1,149 @@ +/* + * Lemote loongson2f family machines' specific suspend support + * + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include "ec_kb3310b.h" + +#define I8042_KBD_IRQ 1 +#define I8042_CTR_KBDINT 0x01 +#define I8042_CTR_KBDDIS 0x10 + +static unsigned char i8042_ctr; + +static int i8042_enable_kbd_port(void) +{ + if (i8042_command(&i8042_ctr, I8042_CMD_CTL_RCTR)) { + pr_err("i8042.c: Can't read CTR while enabling i8042 kbd port." + "\n"); + return -EIO; + } + + i8042_ctr &= ~I8042_CTR_KBDDIS; + i8042_ctr |= I8042_CTR_KBDINT; + + if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { + i8042_ctr &= ~I8042_CTR_KBDINT; + i8042_ctr |= I8042_CTR_KBDDIS; + pr_err("i8042.c: Failed to enable KBD port.\n"); + + return -EIO; + } + + return 0; +} + +void setup_wakeup_events(void) +{ + int irq_mask; + + switch (mips_machtype) { + case MACH_LEMOTE_ML2F7: + case MACH_LEMOTE_YL2F89: + /* open the keyboard irq in i8259A */ + outb((0xff & ~(1 << I8042_KBD_IRQ)), PIC_MASTER_IMR); + irq_mask = inb(PIC_MASTER_IMR); + + /* enable keyboard port */ + i8042_enable_kbd_port(); + + /* Wakeup CPU via SCI lid open event */ + outb(irq_mask & ~(1 << PIC_CASCADE_IR), PIC_MASTER_IMR); + inb(PIC_MASTER_IMR); + outb(0xff & ~(1 << (SCI_IRQ_NUM - 8)), PIC_SLAVE_IMR); + inb(PIC_SLAVE_IMR); + + break; + + default: + break; + } +} + +static struct delayed_work lid_task; +static int initialized; +/* yeeloong_report_lid_status will be implemented in yeeloong_laptop.c */ +sci_handler yeeloong_report_lid_status; +EXPORT_SYMBOL(yeeloong_report_lid_status); +static void yeeloong_lid_update_task(struct work_struct *work) +{ + if (yeeloong_report_lid_status) + yeeloong_report_lid_status(BIT_LID_DETECT_ON); +} + +int wakeup_loongson(void) +{ + int irq; + + /* query the interrupt number */ + irq = mach_i8259_irq(); + if (irq < 0) + return 0; + + printk(KERN_INFO "%s: irq = %d\n", __func__, irq); + + if (irq == I8042_KBD_IRQ) + return 1; + else if (irq == SCI_IRQ_NUM) { + int ret, sci_event; + /* query the event number */ + ret = ec_query_seq(CMD_GET_EVENT_NUM); + if (ret < 0) + return 0; + sci_event = ec_get_event_num(); + if (sci_event < 0) + return 0; + if (sci_event == EVENT_LID) { + int lid_status; + /* check the LID status */ + lid_status = ec_read(REG_LID_DETECT); + /* wakeup cpu when people open the LID */ + if (lid_status == BIT_LID_DETECT_ON) { + /* If we call it directly here, the WARNING + * will be sent out by getnstimeofday + * via "WARN_ON(timekeeping_suspended);" + * because we can not schedule in suspend mode. + */ + if (initialized == 0) { + INIT_DELAYED_WORK(&lid_task, + yeeloong_lid_update_task); + initialized = 1; + } + schedule_delayed_work(&lid_task, 1); + return 1; + } + } + } + + return 0; +} + +void __weak mach_suspend(void) +{ + disable_mfgpt0_counter(); +} + +void __weak mach_resume(void) +{ + enable_mfgpt0_counter(); +} diff --git a/arch/mips/loongson64/lemote-2f/reset.c b/arch/mips/loongson64/lemote-2f/reset.c new file mode 100644 index 000000000000..a26ca7fcd7e0 --- /dev/null +++ b/arch/mips/loongson64/lemote-2f/reset.c @@ -0,0 +1,159 @@ +/* Board-specific reboot/shutdown routines + * + * Copyright (c) 2009 Philippe Vachon + * + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include + +#include + +#include + +#include +#include "ec_kb3310b.h" + +static void reset_cpu(void) +{ + /* + * reset cpu to full speed, this is needed when enabling cpu frequency + * scalling + */ + LOONGSON_CHIPCFG(0) |= 0x7; +} + +/* reset support for fuloong2f */ + +static void fl2f_reboot(void) +{ + reset_cpu(); + + /* send a reset signal to south bridge. + * + * NOTE: if enable "Power Management" in kernel, rtl8169 will not reset + * normally with this reset operation and it will not work in PMON, but + * you can type halt command and then reboot, seems the hardware reset + * logic not work normally. + */ + { + u32 hi, lo; + _rdmsr(DIVIL_MSR_REG(DIVIL_SOFT_RESET), &hi, &lo); + lo |= 0x00000001; + _wrmsr(DIVIL_MSR_REG(DIVIL_SOFT_RESET), hi, lo); + } +} + +static void fl2f_shutdown(void) +{ + u32 hi, lo, val; + int gpio_base; + + /* get gpio base */ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &lo); + gpio_base = lo & 0xff00; + + /* make cs5536 gpio13 output enable */ + val = inl(gpio_base + GPIOL_OUT_EN); + val &= ~(1 << (16 + 13)); + val |= (1 << 13); + outl(val, gpio_base + GPIOL_OUT_EN); + mmiowb(); + /* make cs5536 gpio13 output low level voltage. */ + val = inl(gpio_base + GPIOL_OUT_VAL) & ~(1 << (13)); + val |= (1 << (16 + 13)); + outl(val, gpio_base + GPIOL_OUT_VAL); + mmiowb(); +} + +/* reset support for yeeloong2f and mengloong2f notebook */ + +static void ml2f_reboot(void) +{ + reset_cpu(); + + /* sending an reset signal to EC(embedded controller) */ + ec_write(REG_RESET, BIT_RESET_ON); +} + +#define yl2f89_reboot ml2f_reboot + +/* menglong(7inches) laptop has different shutdown logic from 8.9inches */ +#define EC_SHUTDOWN_IO_PORT_HIGH 0xff2d +#define EC_SHUTDOWN_IO_PORT_LOW 0xff2e +#define EC_SHUTDOWN_IO_PORT_DATA 0xff2f +#define REG_SHUTDOWN_HIGH 0xFC +#define REG_SHUTDOWN_LOW 0x29 +#define BIT_SHUTDOWN_ON (1 << 1) + +static void ml2f_shutdown(void) +{ + u8 val; + u64 i; + + outb(REG_SHUTDOWN_HIGH, EC_SHUTDOWN_IO_PORT_HIGH); + outb(REG_SHUTDOWN_LOW, EC_SHUTDOWN_IO_PORT_LOW); + mmiowb(); + val = inb(EC_SHUTDOWN_IO_PORT_DATA); + outb(val & (~BIT_SHUTDOWN_ON), EC_SHUTDOWN_IO_PORT_DATA); + mmiowb(); + /* need enough wait here... how many microseconds needs? */ + for (i = 0; i < 0x10000; i++) + delay(); + outb(val | BIT_SHUTDOWN_ON, EC_SHUTDOWN_IO_PORT_DATA); + mmiowb(); +} + +static void yl2f89_shutdown(void) +{ + /* cpu-gpio0 output low */ + LOONGSON_GPIODATA &= ~0x00000001; + /* cpu-gpio0 as output */ + LOONGSON_GPIOIE &= ~0x00000001; +} + +void mach_prepare_reboot(void) +{ + switch (mips_machtype) { + case MACH_LEMOTE_FL2F: + case MACH_LEMOTE_NAS: + case MACH_LEMOTE_LL2F: + fl2f_reboot(); + break; + case MACH_LEMOTE_ML2F7: + ml2f_reboot(); + break; + case MACH_LEMOTE_YL2F89: + yl2f89_reboot(); + break; + default: + break; + } +} + +void mach_prepare_shutdown(void) +{ + switch (mips_machtype) { + case MACH_LEMOTE_FL2F: + case MACH_LEMOTE_NAS: + case MACH_LEMOTE_LL2F: + fl2f_shutdown(); + break; + case MACH_LEMOTE_ML2F7: + ml2f_shutdown(); + break; + case MACH_LEMOTE_YL2F89: + yl2f89_shutdown(); + break; + default: + break; + } +} diff --git a/arch/mips/loongson64/loongson-3/Makefile b/arch/mips/loongson64/loongson-3/Makefile new file mode 100644 index 000000000000..622fead5ebc9 --- /dev/null +++ b/arch/mips/loongson64/loongson-3/Makefile @@ -0,0 +1,10 @@ +# +# Makefile for Loongson-3 family machines +# +obj-y += irq.o cop2-ex.o platform.o + +obj-$(CONFIG_SMP) += smp.o + +obj-$(CONFIG_NUMA) += numa.o + +obj-$(CONFIG_RS780_HPET) += hpet.o diff --git a/arch/mips/loongson64/loongson-3/cop2-ex.c b/arch/mips/loongson64/loongson-3/cop2-ex.c new file mode 100644 index 000000000000..ea13764d0a03 --- /dev/null +++ b/arch/mips/loongson64/loongson-3/cop2-ex.c @@ -0,0 +1,63 @@ +/* + * 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) 2014 Lemote Corporation. + * written by Huacai Chen + * + * based on arch/mips/cavium-octeon/cpu.c + * Copyright (C) 2009 Wind River Systems, + * written by Ralf Baechle + */ +#include +#include +#include + +#include +#include +#include +#include + +static int loongson_cu2_call(struct notifier_block *nfb, unsigned long action, + void *data) +{ + int fpu_owned; + int fr = !test_thread_flag(TIF_32BIT_FPREGS); + + switch (action) { + case CU2_EXCEPTION: + preempt_disable(); + fpu_owned = __is_fpu_owner(); + if (!fr) + set_c0_status(ST0_CU1 | ST0_CU2); + else + set_c0_status(ST0_CU1 | ST0_CU2 | ST0_FR); + enable_fpu_hazard(); + KSTK_STATUS(current) |= (ST0_CU1 | ST0_CU2); + if (fr) + KSTK_STATUS(current) |= ST0_FR; + else + KSTK_STATUS(current) &= ~ST0_FR; + /* If FPU is owned, we needn't init or restore fp */ + if (!fpu_owned) { + set_thread_flag(TIF_USEDFPU); + if (!used_math()) { + _init_fpu(current->thread.fpu.fcr31); + set_used_math(); + } else + _restore_fp(current); + } + preempt_enable(); + + return NOTIFY_STOP; /* Don't call default notifier */ + } + + return NOTIFY_OK; /* Let default notifier send signals */ +} + +static int __init loongson_cu2_setup(void) +{ + return cu2_notifier(loongson_cu2_call, 0); +} +early_initcall(loongson_cu2_setup); diff --git a/arch/mips/loongson64/loongson-3/hpet.c b/arch/mips/loongson64/loongson-3/hpet.c new file mode 100644 index 000000000000..5c21cd3bd339 --- /dev/null +++ b/arch/mips/loongson64/loongson-3/hpet.c @@ -0,0 +1,257 @@ +#include +#include +#include +#include +#include +#include + +#include +#include + +#define SMBUS_CFG_BASE (loongson_sysconf.ht_control_base + 0x0300a000) +#define SMBUS_PCI_REG40 0x40 +#define SMBUS_PCI_REG64 0x64 +#define SMBUS_PCI_REGB4 0xb4 + +static DEFINE_SPINLOCK(hpet_lock); +DEFINE_PER_CPU(struct clock_event_device, hpet_clockevent_device); + +static unsigned int smbus_read(int offset) +{ + return *(volatile unsigned int *)(SMBUS_CFG_BASE + offset); +} + +static void smbus_write(int offset, int data) +{ + *(volatile unsigned int *)(SMBUS_CFG_BASE + offset) = data; +} + +static void smbus_enable(int offset, int bit) +{ + unsigned int cfg = smbus_read(offset); + + cfg |= bit; + smbus_write(offset, cfg); +} + +static int hpet_read(int offset) +{ + return *(volatile unsigned int *)(HPET_MMIO_ADDR + offset); +} + +static void hpet_write(int offset, int data) +{ + *(volatile unsigned int *)(HPET_MMIO_ADDR + offset) = data; +} + +static void hpet_start_counter(void) +{ + unsigned int cfg = hpet_read(HPET_CFG); + + cfg |= HPET_CFG_ENABLE; + hpet_write(HPET_CFG, cfg); +} + +static void hpet_stop_counter(void) +{ + unsigned int cfg = hpet_read(HPET_CFG); + + cfg &= ~HPET_CFG_ENABLE; + hpet_write(HPET_CFG, cfg); +} + +static void hpet_reset_counter(void) +{ + hpet_write(HPET_COUNTER, 0); + hpet_write(HPET_COUNTER + 4, 0); +} + +static void hpet_restart_counter(void) +{ + hpet_stop_counter(); + hpet_reset_counter(); + hpet_start_counter(); +} + +static void hpet_enable_legacy_int(void) +{ + /* Do nothing on Loongson-3 */ +} + +static void hpet_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + int cfg = 0; + + spin_lock(&hpet_lock); + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + pr_info("set clock event to periodic mode!\n"); + /* stop counter */ + hpet_stop_counter(); + + /* enables the timer0 to generate a periodic interrupt */ + cfg = hpet_read(HPET_T0_CFG); + cfg &= ~HPET_TN_LEVEL; + cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC | + HPET_TN_SETVAL | HPET_TN_32BIT; + hpet_write(HPET_T0_CFG, cfg); + + /* set the comparator */ + hpet_write(HPET_T0_CMP, HPET_COMPARE_VAL); + udelay(1); + hpet_write(HPET_T0_CMP, HPET_COMPARE_VAL); + + /* start counter */ + hpet_start_counter(); + break; + case CLOCK_EVT_MODE_SHUTDOWN: + case CLOCK_EVT_MODE_UNUSED: + cfg = hpet_read(HPET_T0_CFG); + cfg &= ~HPET_TN_ENABLE; + hpet_write(HPET_T0_CFG, cfg); + break; + case CLOCK_EVT_MODE_ONESHOT: + pr_info("set clock event to one shot mode!\n"); + cfg = hpet_read(HPET_T0_CFG); + /* set timer0 type + * 1 : periodic interrupt + * 0 : non-periodic(oneshot) interrupt + */ + cfg &= ~HPET_TN_PERIODIC; + cfg |= HPET_TN_ENABLE | HPET_TN_32BIT; + hpet_write(HPET_T0_CFG, cfg); + break; + case CLOCK_EVT_MODE_RESUME: + hpet_enable_legacy_int(); + break; + } + spin_unlock(&hpet_lock); +} + +static int hpet_next_event(unsigned long delta, + struct clock_event_device *evt) +{ + unsigned int cnt; + int res; + + cnt = hpet_read(HPET_COUNTER); + cnt += delta; + hpet_write(HPET_T0_CMP, cnt); + + res = ((int)(hpet_read(HPET_COUNTER) - cnt) > 0) ? -ETIME : 0; + return res; +} + +static irqreturn_t hpet_irq_handler(int irq, void *data) +{ + int is_irq; + struct clock_event_device *cd; + unsigned int cpu = smp_processor_id(); + + is_irq = hpet_read(HPET_STATUS); + if (is_irq & HPET_T0_IRS) { + /* clear the TIMER0 irq status register */ + hpet_write(HPET_STATUS, HPET_T0_IRS); + cd = &per_cpu(hpet_clockevent_device, cpu); + cd->event_handler(cd); + return IRQ_HANDLED; + } + return IRQ_NONE; +} + +static struct irqaction hpet_irq = { + .handler = hpet_irq_handler, + .flags = IRQF_NOBALANCING | IRQF_TIMER, + .name = "hpet", +}; + +/* + * hpet address assignation and irq setting should be done in bios. + * but pmon don't do this, we just setup here directly. + * The operation under is normal. unfortunately, hpet_setup process + * is before pci initialize. + * + * { + * struct pci_dev *pdev; + * + * pdev = pci_get_device(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS, NULL); + * pci_write_config_word(pdev, SMBUS_PCI_REGB4, HPET_ADDR); + * + * ... + * } + */ +static void hpet_setup(void) +{ + /* set hpet base address */ + smbus_write(SMBUS_PCI_REGB4, HPET_ADDR); + + /* enable decodeing of access to HPET MMIO*/ + smbus_enable(SMBUS_PCI_REG40, (1 << 28)); + + /* HPET irq enable */ + smbus_enable(SMBUS_PCI_REG64, (1 << 10)); + + hpet_enable_legacy_int(); +} + +void __init setup_hpet_timer(void) +{ + unsigned int cpu = smp_processor_id(); + struct clock_event_device *cd; + + hpet_setup(); + + cd = &per_cpu(hpet_clockevent_device, cpu); + cd->name = "hpet"; + cd->rating = 320; + cd->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; + cd->set_mode = hpet_set_mode; + cd->set_next_event = hpet_next_event; + cd->irq = HPET_T0_IRQ; + cd->cpumask = cpumask_of(cpu); + clockevent_set_clock(cd, HPET_FREQ); + cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); + cd->min_delta_ns = 5000; + + clockevents_register_device(cd); + setup_irq(HPET_T0_IRQ, &hpet_irq); + pr_info("hpet clock event device register\n"); +} + +static cycle_t hpet_read_counter(struct clocksource *cs) +{ + return (cycle_t)hpet_read(HPET_COUNTER); +} + +static void hpet_suspend(struct clocksource *cs) +{ +} + +static void hpet_resume(struct clocksource *cs) +{ + hpet_setup(); + hpet_restart_counter(); +} + +static struct clocksource csrc_hpet = { + .name = "hpet", + /* mips clocksource rating is less than 300, so hpet is better. */ + .rating = 300, + .read = hpet_read_counter, + .mask = CLOCKSOURCE_MASK(32), + /* oneshot mode work normal with this flag */ + .flags = CLOCK_SOURCE_IS_CONTINUOUS, + .suspend = hpet_suspend, + .resume = hpet_resume, + .mult = 0, + .shift = 10, +}; + +int __init init_hpet_clocksource(void) +{ + csrc_hpet.mult = clocksource_hz2mult(HPET_FREQ, csrc_hpet.shift); + return clocksource_register_hz(&csrc_hpet, HPET_FREQ); +} + +arch_initcall(init_hpet_clocksource); diff --git a/arch/mips/loongson64/loongson-3/irq.c b/arch/mips/loongson64/loongson-3/irq.c new file mode 100644 index 000000000000..0f75b6b3d218 --- /dev/null +++ b/arch/mips/loongson64/loongson-3/irq.c @@ -0,0 +1,143 @@ +#include +#include +#include +#include + +#include +#include +#include + +#include "smp.h" + +unsigned int ht_irq[] = {0, 1, 3, 4, 5, 6, 7, 8, 12, 14, 15}; + +static void ht_irqdispatch(void) +{ + unsigned int i, irq; + + irq = LOONGSON_HT1_INT_VECTOR(0); + LOONGSON_HT1_INT_VECTOR(0) = irq; /* Acknowledge the IRQs */ + + for (i = 0; i < ARRAY_SIZE(ht_irq); i++) { + if (irq & (0x1 << ht_irq[i])) + do_IRQ(ht_irq[i]); + } +} + +void mach_irq_dispatch(unsigned int pending) +{ + if (pending & CAUSEF_IP7) + do_IRQ(LOONGSON_TIMER_IRQ); +#if defined(CONFIG_SMP) + else if (pending & CAUSEF_IP6) + loongson3_ipi_interrupt(NULL); +#endif + else if (pending & CAUSEF_IP3) + ht_irqdispatch(); + else if (pending & CAUSEF_IP2) + do_IRQ(LOONGSON_UART_IRQ); + else { + pr_err("%s : spurious interrupt\n", __func__); + spurious_interrupt(); + } +} + +static struct irqaction cascade_irqaction = { + .handler = no_action, + .flags = IRQF_NO_SUSPEND, + .name = "cascade", +}; + +static inline void mask_loongson_irq(struct irq_data *d) +{ + clear_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE)); + irq_disable_hazard(); + + /* Workaround: UART IRQ may deliver to any core */ + if (d->irq == LOONGSON_UART_IRQ) { + int cpu = smp_processor_id(); + int node_id = cpu_logical_map(cpu) / loongson_sysconf.cores_per_node; + int core_id = cpu_logical_map(cpu) % loongson_sysconf.cores_per_node; + u64 intenclr_addr = smp_group[node_id] | + (u64)(&LOONGSON_INT_ROUTER_INTENCLR); + u64 introuter_lpc_addr = smp_group[node_id] | + (u64)(&LOONGSON_INT_ROUTER_LPC); + + *(volatile u32 *)intenclr_addr = 1 << 10; + *(volatile u8 *)introuter_lpc_addr = 0x10 + (1<irq == LOONGSON_UART_IRQ) { + int cpu = smp_processor_id(); + int node_id = cpu_logical_map(cpu) / loongson_sysconf.cores_per_node; + int core_id = cpu_logical_map(cpu) % loongson_sysconf.cores_per_node; + u64 intenset_addr = smp_group[node_id] | + (u64)(&LOONGSON_INT_ROUTER_INTENSET); + u64 introuter_lpc_addr = smp_group[node_id] | + (u64)(&LOONGSON_INT_ROUTER_LPC); + + *(volatile u32 *)intenset_addr = 1 << 10; + *(volatile u8 *)introuter_lpc_addr = 0x10 + (1<irq - MIPS_CPU_IRQ_BASE)); + irq_enable_hazard(); +} + + /* For MIPS IRQs which shared by all cores */ +static struct irq_chip loongson_irq_chip = { + .name = "Loongson", + .irq_ack = mask_loongson_irq, + .irq_mask = mask_loongson_irq, + .irq_mask_ack = mask_loongson_irq, + .irq_unmask = unmask_loongson_irq, + .irq_eoi = unmask_loongson_irq, +}; + +void irq_router_init(void) +{ + int i; + + /* route LPC int to cpu core0 int 0 */ + LOONGSON_INT_ROUTER_LPC = + LOONGSON_INT_COREx_INTy(loongson_sysconf.boot_cpu_id, 0); + /* route HT1 int0 ~ int7 to cpu core0 INT1*/ + for (i = 0; i < 8; i++) + LOONGSON_INT_ROUTER_HT1(i) = + LOONGSON_INT_COREx_INTy(loongson_sysconf.boot_cpu_id, 1); + /* enable HT1 interrupt */ + LOONGSON_HT1_INTN_EN(0) = 0xffffffff; + /* enable router interrupt intenset */ + LOONGSON_INT_ROUTER_INTENSET = + LOONGSON_INT_ROUTER_INTEN | (0xffff << 16) | 0x1 << 10; +} + +void __init mach_init_irq(void) +{ + clear_c0_status(ST0_IM | ST0_BEV); + + irq_router_init(); + mips_cpu_irq_init(); + init_i8259_irqs(); + irq_set_chip_and_handler(LOONGSON_UART_IRQ, + &loongson_irq_chip, handle_level_irq); + + /* setup HT1 irq */ + setup_irq(LOONGSON_HT1_IRQ, &cascade_irqaction); + + set_c0_status(STATUSF_IP2 | STATUSF_IP6); +} + +#ifdef CONFIG_HOTPLUG_CPU + +void fixup_irqs(void) +{ + irq_cpu_offline(); + clear_c0_status(ST0_IM); +} + +#endif diff --git a/arch/mips/loongson64/loongson-3/numa.c b/arch/mips/loongson64/loongson-3/numa.c new file mode 100644 index 000000000000..12d14ed48778 --- /dev/null +++ b/arch/mips/loongson64/loongson-3/numa.c @@ -0,0 +1,296 @@ +/* + * Copyright (C) 2010 Loongson Inc. & Lemote Inc. & + * Insititute of Computing Technology + * Author: Xiang Gao, gaoxiang@ict.ac.cn + * Huacai Chen, chenhc@lemote.com + * Xiaofu Meng, Shuangshuang Zhang + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct node_data prealloc__node_data[MAX_NUMNODES]; +unsigned char __node_distances[MAX_NUMNODES][MAX_NUMNODES]; +EXPORT_SYMBOL(__node_distances); +struct node_data *__node_data[MAX_NUMNODES]; +EXPORT_SYMBOL(__node_data); + +static void enable_lpa(void) +{ + unsigned long value; + + value = __read_32bit_c0_register($16, 3); + value |= 0x00000080; + __write_32bit_c0_register($16, 3, value); + value = __read_32bit_c0_register($16, 3); + pr_info("CP0_Config3: CP0 16.3 (0x%lx)\n", value); + + value = __read_32bit_c0_register($5, 1); + value |= 0x20000000; + __write_32bit_c0_register($5, 1, value); + value = __read_32bit_c0_register($5, 1); + pr_info("CP0_PageGrain: CP0 5.1 (0x%lx)\n", value); +} + +static void cpu_node_probe(void) +{ + int i; + + nodes_clear(node_possible_map); + nodes_clear(node_online_map); + for (i = 0; i < loongson_sysconf.nr_nodes; i++) { + node_set_state(num_online_nodes(), N_POSSIBLE); + node_set_online(num_online_nodes()); + } + + pr_info("NUMA: Discovered %d cpus on %d nodes\n", + loongson_sysconf.nr_cpus, num_online_nodes()); +} + +static int __init compute_node_distance(int row, int col) +{ + int package_row = row * loongson_sysconf.cores_per_node / + loongson_sysconf.cores_per_package; + int package_col = col * loongson_sysconf.cores_per_node / + loongson_sysconf.cores_per_package; + + if (col == row) + return 0; + else if (package_row == package_col) + return 40; + else + return 100; +} + +static void __init init_topology_matrix(void) +{ + int row, col; + + for (row = 0; row < MAX_NUMNODES; row++) + for (col = 0; col < MAX_NUMNODES; col++) + __node_distances[row][col] = -1; + + for_each_online_node(row) { + for_each_online_node(col) { + __node_distances[row][col] = + compute_node_distance(row, col); + } + } +} + +static unsigned long nid_to_addroffset(unsigned int nid) +{ + unsigned long result; + switch (nid) { + case 0: + default: + result = NODE0_ADDRSPACE_OFFSET; + break; + case 1: + result = NODE1_ADDRSPACE_OFFSET; + break; + case 2: + result = NODE2_ADDRSPACE_OFFSET; + break; + case 3: + result = NODE3_ADDRSPACE_OFFSET; + break; + } + return result; +} + +static void __init szmem(unsigned int node) +{ + u32 i, mem_type; + static unsigned long num_physpages = 0; + u64 node_id, node_psize, start_pfn, end_pfn, mem_start, mem_size; + + /* Parse memory information and activate */ + for (i = 0; i < loongson_memmap->nr_map; i++) { + node_id = loongson_memmap->map[i].node_id; + if (node_id != node) + continue; + + mem_type = loongson_memmap->map[i].mem_type; + mem_size = loongson_memmap->map[i].mem_size; + mem_start = loongson_memmap->map[i].mem_start; + + switch (mem_type) { + case SYSTEM_RAM_LOW: + start_pfn = ((node_id << 44) + mem_start) >> PAGE_SHIFT; + node_psize = (mem_size << 20) >> PAGE_SHIFT; + end_pfn = start_pfn + node_psize; + num_physpages += node_psize; + pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx MB\n", + (u32)node_id, mem_type, mem_start, mem_size); + pr_info(" start_pfn:0x%llx, end_pfn:0x%llx, num_physpages:0x%lx\n", + start_pfn, end_pfn, num_physpages); + add_memory_region((node_id << 44) + mem_start, + (u64)mem_size << 20, BOOT_MEM_RAM); + memblock_add_node(PFN_PHYS(start_pfn), + PFN_PHYS(end_pfn - start_pfn), node); + break; + case SYSTEM_RAM_HIGH: + start_pfn = ((node_id << 44) + mem_start) >> PAGE_SHIFT; + node_psize = (mem_size << 20) >> PAGE_SHIFT; + end_pfn = start_pfn + node_psize; + num_physpages += node_psize; + pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx MB\n", + (u32)node_id, mem_type, mem_start, mem_size); + pr_info(" start_pfn:0x%llx, end_pfn:0x%llx, num_physpages:0x%lx\n", + start_pfn, end_pfn, num_physpages); + add_memory_region((node_id << 44) + mem_start, + (u64)mem_size << 20, BOOT_MEM_RAM); + memblock_add_node(PFN_PHYS(start_pfn), + PFN_PHYS(end_pfn - start_pfn), node); + break; + case MEM_RESERVED: + pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx MB\n", + (u32)node_id, mem_type, mem_start, mem_size); + add_memory_region((node_id << 44) + mem_start, + (u64)mem_size << 20, BOOT_MEM_RESERVED); + memblock_reserve(((node_id << 44) + mem_start), + mem_size << 20); + break; + } + } +} + +static void __init node_mem_init(unsigned int node) +{ + unsigned long bootmap_size; + unsigned long node_addrspace_offset; + unsigned long start_pfn, end_pfn, freepfn; + + node_addrspace_offset = nid_to_addroffset(node); + pr_info("Node%d's addrspace_offset is 0x%lx\n", + node, node_addrspace_offset); + + get_pfn_range_for_nid(node, &start_pfn, &end_pfn); + freepfn = start_pfn; + if (node == 0) + freepfn = PFN_UP(__pa_symbol(&_end)); /* kernel end address */ + pr_info("Node%d: start_pfn=0x%lx, end_pfn=0x%lx, freepfn=0x%lx\n", + node, start_pfn, end_pfn, freepfn); + + __node_data[node] = prealloc__node_data + node; + + NODE_DATA(node)->bdata = &bootmem_node_data[node]; + NODE_DATA(node)->node_start_pfn = start_pfn; + NODE_DATA(node)->node_spanned_pages = end_pfn - start_pfn; + + bootmap_size = init_bootmem_node(NODE_DATA(node), freepfn, + start_pfn, end_pfn); + free_bootmem_with_active_regions(node, end_pfn); + if (node == 0) /* used by finalize_initrd() */ + max_low_pfn = end_pfn; + + /* This is reserved for the kernel and bdata->node_bootmem_map */ + reserve_bootmem_node(NODE_DATA(node), start_pfn << PAGE_SHIFT, + ((freepfn - start_pfn) << PAGE_SHIFT) + bootmap_size, + BOOTMEM_DEFAULT); + + if (node == 0 && node_end_pfn(0) >= (0xffffffff >> PAGE_SHIFT)) { + /* Reserve 0xff800000~0xffffffff for RS780E integrated GPU */ + reserve_bootmem_node(NODE_DATA(node), + (node_addrspace_offset | 0xff800000), + 8 << 20, BOOTMEM_DEFAULT); + } + + sparse_memory_present_with_active_regions(node); +} + +static __init void prom_meminit(void) +{ + unsigned int node, cpu, active_cpu = 0; + + cpu_node_probe(); + init_topology_matrix(); + + for (node = 0; node < loongson_sysconf.nr_nodes; node++) { + if (node_online(node)) { + szmem(node); + node_mem_init(node); + cpumask_clear(&__node_data[(node)]->cpumask); + } + } + for (cpu = 0; cpu < loongson_sysconf.nr_cpus; cpu++) { + node = cpu / loongson_sysconf.cores_per_node; + if (node >= num_online_nodes()) + node = 0; + + if (loongson_sysconf.reserved_cpus_mask & (1<cpumask); + pr_info("NUMA: set cpumask cpu %d on node %d\n", active_cpu, node); + + active_cpu++; + } +} + +void __init paging_init(void) +{ + unsigned node; + unsigned long zones_size[MAX_NR_ZONES] = {0, }; + + pagetable_init(); + + for_each_online_node(node) { + unsigned long start_pfn, end_pfn; + + get_pfn_range_for_nid(node, &start_pfn, &end_pfn); + + if (end_pfn > max_low_pfn) + max_low_pfn = end_pfn; + } +#ifdef CONFIG_ZONE_DMA32 + zones_size[ZONE_DMA32] = MAX_DMA32_PFN; +#endif + zones_size[ZONE_NORMAL] = max_low_pfn; + free_area_init_nodes(zones_size); +} + +void __init mem_init(void) +{ + high_memory = (void *) __va(get_num_physpages() << PAGE_SHIFT); + free_all_bootmem(); + setup_zero_pages(); /* This comes from node 0 */ + mem_init_print_info(NULL); +} + +/* All PCI device belongs to logical Node-0 */ +int pcibus_to_node(struct pci_bus *bus) +{ + return 0; +} +EXPORT_SYMBOL(pcibus_to_node); + +void __init prom_init_numa_memory(void) +{ + enable_lpa(); + prom_meminit(); +} +EXPORT_SYMBOL(prom_init_numa_memory); diff --git a/arch/mips/loongson64/loongson-3/platform.c b/arch/mips/loongson64/loongson-3/platform.c new file mode 100644 index 000000000000..25a97cc0ee33 --- /dev/null +++ b/arch/mips/loongson64/loongson-3/platform.c @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * Xiang Yu, xiangy@lemote.com + * Chen Huacai, chenhc@lemote.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include + +static int __init loongson3_platform_init(void) +{ + int i; + struct platform_device *pdev; + + if (loongson_sysconf.ecname[0] != '\0') + platform_device_register_simple(loongson_sysconf.ecname, -1, NULL, 0); + + for (i = 0; i < loongson_sysconf.nr_sensors; i++) { + if (loongson_sysconf.sensors[i].type > SENSOR_FAN) + continue; + + pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL); + pdev->name = loongson_sysconf.sensors[i].name; + pdev->id = loongson_sysconf.sensors[i].id; + pdev->dev.platform_data = &loongson_sysconf.sensors[i]; + platform_device_register(pdev); + } + + return 0; +} + +arch_initcall(loongson3_platform_init); diff --git a/arch/mips/loongson64/loongson-3/smp.c b/arch/mips/loongson64/loongson-3/smp.c new file mode 100644 index 000000000000..509877c6e9d9 --- /dev/null +++ b/arch/mips/loongson64/loongson-3/smp.c @@ -0,0 +1,652 @@ +/* + * Copyright (C) 2010, 2011, 2012, Lemote, Inc. + * Author: Chen Huacai, chenhc@lemote.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "smp.h" + +DEFINE_PER_CPU(int, cpu_state); +DEFINE_PER_CPU(uint32_t, core0_c0count); + +static void *ipi_set0_regs[16]; +static void *ipi_clear0_regs[16]; +static void *ipi_status0_regs[16]; +static void *ipi_en0_regs[16]; +static void *ipi_mailbox_buf[16]; + +/* read a 32bit value from ipi register */ +#define loongson3_ipi_read32(addr) readl(addr) +/* read a 64bit value from ipi register */ +#define loongson3_ipi_read64(addr) readq(addr) +/* write a 32bit value to ipi register */ +#define loongson3_ipi_write32(action, addr) \ + do { \ + writel(action, addr); \ + __wbflush(); \ + } while (0) +/* write a 64bit value to ipi register */ +#define loongson3_ipi_write64(action, addr) \ + do { \ + writeq(action, addr); \ + __wbflush(); \ + } while (0) + +static void ipi_set0_regs_init(void) +{ + ipi_set0_regs[0] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + SET0); + ipi_set0_regs[1] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + SET0); + ipi_set0_regs[2] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + SET0); + ipi_set0_regs[3] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + SET0); + ipi_set0_regs[4] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + SET0); + ipi_set0_regs[5] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + SET0); + ipi_set0_regs[6] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + SET0); + ipi_set0_regs[7] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + SET0); + ipi_set0_regs[8] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + SET0); + ipi_set0_regs[9] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + SET0); + ipi_set0_regs[10] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + SET0); + ipi_set0_regs[11] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + SET0); + ipi_set0_regs[12] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + SET0); + ipi_set0_regs[13] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + SET0); + ipi_set0_regs[14] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + SET0); + ipi_set0_regs[15] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + SET0); +} + +static void ipi_clear0_regs_init(void) +{ + ipi_clear0_regs[0] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + CLEAR0); + ipi_clear0_regs[1] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + CLEAR0); + ipi_clear0_regs[2] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + CLEAR0); + ipi_clear0_regs[3] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + CLEAR0); + ipi_clear0_regs[4] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + CLEAR0); + ipi_clear0_regs[5] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + CLEAR0); + ipi_clear0_regs[6] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + CLEAR0); + ipi_clear0_regs[7] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + CLEAR0); + ipi_clear0_regs[8] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + CLEAR0); + ipi_clear0_regs[9] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + CLEAR0); + ipi_clear0_regs[10] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + CLEAR0); + ipi_clear0_regs[11] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + CLEAR0); + ipi_clear0_regs[12] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + CLEAR0); + ipi_clear0_regs[13] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + CLEAR0); + ipi_clear0_regs[14] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + CLEAR0); + ipi_clear0_regs[15] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + CLEAR0); +} + +static void ipi_status0_regs_init(void) +{ + ipi_status0_regs[0] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + STATUS0); + ipi_status0_regs[1] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + STATUS0); + ipi_status0_regs[2] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + STATUS0); + ipi_status0_regs[3] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + STATUS0); + ipi_status0_regs[4] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + STATUS0); + ipi_status0_regs[5] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + STATUS0); + ipi_status0_regs[6] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + STATUS0); + ipi_status0_regs[7] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + STATUS0); + ipi_status0_regs[8] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + STATUS0); + ipi_status0_regs[9] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + STATUS0); + ipi_status0_regs[10] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + STATUS0); + ipi_status0_regs[11] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + STATUS0); + ipi_status0_regs[12] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + STATUS0); + ipi_status0_regs[13] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + STATUS0); + ipi_status0_regs[14] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + STATUS0); + ipi_status0_regs[15] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + STATUS0); +} + +static void ipi_en0_regs_init(void) +{ + ipi_en0_regs[0] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + EN0); + ipi_en0_regs[1] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + EN0); + ipi_en0_regs[2] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + EN0); + ipi_en0_regs[3] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + EN0); + ipi_en0_regs[4] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + EN0); + ipi_en0_regs[5] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + EN0); + ipi_en0_regs[6] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + EN0); + ipi_en0_regs[7] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + EN0); + ipi_en0_regs[8] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + EN0); + ipi_en0_regs[9] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + EN0); + ipi_en0_regs[10] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + EN0); + ipi_en0_regs[11] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + EN0); + ipi_en0_regs[12] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + EN0); + ipi_en0_regs[13] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + EN0); + ipi_en0_regs[14] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + EN0); + ipi_en0_regs[15] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + EN0); +} + +static void ipi_mailbox_buf_init(void) +{ + ipi_mailbox_buf[0] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + BUF); + ipi_mailbox_buf[1] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + BUF); + ipi_mailbox_buf[2] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + BUF); + ipi_mailbox_buf[3] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + BUF); + ipi_mailbox_buf[4] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + BUF); + ipi_mailbox_buf[5] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + BUF); + ipi_mailbox_buf[6] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + BUF); + ipi_mailbox_buf[7] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + BUF); + ipi_mailbox_buf[8] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + BUF); + ipi_mailbox_buf[9] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + BUF); + ipi_mailbox_buf[10] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + BUF); + ipi_mailbox_buf[11] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + BUF); + ipi_mailbox_buf[12] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + BUF); + ipi_mailbox_buf[13] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + BUF); + ipi_mailbox_buf[14] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + BUF); + ipi_mailbox_buf[15] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + BUF); +} + +/* + * Simple enough, just poke the appropriate ipi register + */ +static void loongson3_send_ipi_single(int cpu, unsigned int action) +{ + loongson3_ipi_write32((u32)action, ipi_set0_regs[cpu_logical_map(cpu)]); +} + +static void +loongson3_send_ipi_mask(const struct cpumask *mask, unsigned int action) +{ + unsigned int i; + + for_each_cpu(i, mask) + loongson3_ipi_write32((u32)action, ipi_set0_regs[cpu_logical_map(i)]); +} + +void loongson3_ipi_interrupt(struct pt_regs *regs) +{ + int i, cpu = smp_processor_id(); + unsigned int action, c0count; + + /* Load the ipi register to figure out what we're supposed to do */ + action = loongson3_ipi_read32(ipi_status0_regs[cpu_logical_map(cpu)]); + + /* Clear the ipi register to clear the interrupt */ + loongson3_ipi_write32((u32)action, ipi_clear0_regs[cpu_logical_map(cpu)]); + + if (action & SMP_RESCHEDULE_YOURSELF) + scheduler_ipi(); + + if (action & SMP_CALL_FUNCTION) + smp_call_function_interrupt(); + + if (action & SMP_ASK_C0COUNT) { + BUG_ON(cpu != 0); + c0count = read_c0_count(); + for (i = 1; i < num_possible_cpus(); i++) + per_cpu(core0_c0count, i) = c0count; + } +} + +#define MAX_LOOPS 1111 +/* + * SMP init and finish on secondary CPUs + */ +static void loongson3_init_secondary(void) +{ + int i; + uint32_t initcount; + unsigned int cpu = smp_processor_id(); + unsigned int imask = STATUSF_IP7 | STATUSF_IP6 | + STATUSF_IP3 | STATUSF_IP2; + + /* Set interrupt mask, but don't enable */ + change_c0_status(ST0_IM, imask); + + for (i = 0; i < num_possible_cpus(); i++) + loongson3_ipi_write32(0xffffffff, ipi_en0_regs[cpu_logical_map(i)]); + + per_cpu(cpu_state, cpu) = CPU_ONLINE; + cpu_data[cpu].core = + cpu_logical_map(cpu) % loongson_sysconf.cores_per_package; + cpu_data[cpu].package = + cpu_logical_map(cpu) / loongson_sysconf.cores_per_package; + + i = 0; + __this_cpu_write(core0_c0count, 0); + loongson3_send_ipi_single(0, SMP_ASK_C0COUNT); + while (!__this_cpu_read(core0_c0count)) { + i++; + cpu_relax(); + } + + if (i > MAX_LOOPS) + i = MAX_LOOPS; + initcount = __this_cpu_read(core0_c0count) + i; + write_c0_count(initcount); +} + +static void loongson3_smp_finish(void) +{ + int cpu = smp_processor_id(); + + write_c0_compare(read_c0_count() + mips_hpt_frequency/HZ); + local_irq_enable(); + loongson3_ipi_write64(0, + (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x0)); + pr_info("CPU#%d finished, CP0_ST=%x\n", + smp_processor_id(), read_c0_status()); +} + +static void __init loongson3_smp_setup(void) +{ + int i = 0, num = 0; /* i: physical id, num: logical id */ + + init_cpu_possible(cpu_none_mask); + + /* For unified kernel, NR_CPUS is the maximum possible value, + * loongson_sysconf.nr_cpus is the really present value */ + while (i < loongson_sysconf.nr_cpus) { + if (loongson_sysconf.reserved_cpus_mask & (1< #include -#include -#include +#include +#include static struct { struct device *dev; diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 0fe4ad8826b2..354b908a03d8 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1484,7 +1484,7 @@ config RTC_DRV_PUV3 config RTC_DRV_LOONGSON1 tristate "loongson1 RTC support" - depends on MACH_LOONGSON1 + depends on MACH_LOONGSON32 help This is a driver for the loongson1 on-chip Counter0 (Time-Of-Year counter) to be used as a RTC. diff --git a/drivers/rtc/rtc-ls1x.c b/drivers/rtc/rtc-ls1x.c index 8445e564094a..22a9ec4f2b83 100644 --- a/drivers/rtc/rtc-ls1x.c +++ b/drivers/rtc/rtc-ls1x.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #define LS1X_RTC_REG_OFFSET (LS1X_RTC_BASE + 0x20) #define LS1X_RTC_REGS(x) \