MIPS: Fork loongson2ef from loongson64
authorJiaxun Yang <jiaxun.yang@flygoat.com>
Sun, 20 Oct 2019 14:43:14 +0000 (22:43 +0800)
committerPaul Burton <paulburton@kernel.org>
Fri, 1 Nov 2019 21:30:52 +0000 (14:30 -0700)
As later model of GSx64 family processors including 2-series-soc have
similar design with initial loongson3a while loongson2e/f seems less
identical, we separate loongson2e/f support code out of mach-loongson64
to make our life easier.

This patch contains mostly file moving works.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
[paulburton@kernel.org: Squash in the MAINTAINERS updates]
Signed-off-by: Paul Burton <paulburton@kernel.org>
Cc: linux-mips@vger.kernel.org
Cc: paul.burton@mips.com
92 files changed:
MAINTAINERS
arch/mips/Kbuild.platforms
arch/mips/Kconfig
arch/mips/configs/fuloong2e_defconfig
arch/mips/configs/lemote2f_defconfig
arch/mips/include/asm/mach-loongson2ef/boot_param.h [new file with mode: 0644]
arch/mips/include/asm/mach-loongson2ef/cpu-feature-overrides.h [new file with mode: 0644]
arch/mips/include/asm/mach-loongson2ef/cs5536/cs5536.h [new file with mode: 0644]
arch/mips/include/asm/mach-loongson2ef/cs5536/cs5536_mfgpt.h [new file with mode: 0644]
arch/mips/include/asm/mach-loongson2ef/cs5536/cs5536_pci.h [new file with mode: 0644]
arch/mips/include/asm/mach-loongson2ef/cs5536/cs5536_vsm.h [new file with mode: 0644]
arch/mips/include/asm/mach-loongson2ef/irq.h [new file with mode: 0644]
arch/mips/include/asm/mach-loongson2ef/kernel-entry-init.h [new file with mode: 0644]
arch/mips/include/asm/mach-loongson2ef/loongson.h [new file with mode: 0644]
arch/mips/include/asm/mach-loongson2ef/loongson_hwmon.h [new file with mode: 0644]
arch/mips/include/asm/mach-loongson2ef/loongson_regs.h [new file with mode: 0644]
arch/mips/include/asm/mach-loongson2ef/machine.h [new file with mode: 0644]
arch/mips/include/asm/mach-loongson2ef/mc146818rtc.h [new file with mode: 0644]
arch/mips/include/asm/mach-loongson2ef/mem.h [new file with mode: 0644]
arch/mips/include/asm/mach-loongson2ef/mmzone.h [new file with mode: 0644]
arch/mips/include/asm/mach-loongson2ef/pci.h [new file with mode: 0644]
arch/mips/include/asm/mach-loongson2ef/spaces.h [new file with mode: 0644]
arch/mips/include/asm/mach-loongson2ef/topology.h [new file with mode: 0644]
arch/mips/include/asm/mach-loongson2ef/workarounds.h [new file with mode: 0644]
arch/mips/loongson2ef/Kconfig [new file with mode: 0644]
arch/mips/loongson2ef/Makefile [new file with mode: 0644]
arch/mips/loongson2ef/Platform [new file with mode: 0644]
arch/mips/loongson2ef/common/Makefile [new file with mode: 0644]
arch/mips/loongson2ef/common/bonito-irq.c [new file with mode: 0644]
arch/mips/loongson2ef/common/cmdline.c [new file with mode: 0644]
arch/mips/loongson2ef/common/cs5536/Makefile [new file with mode: 0644]
arch/mips/loongson2ef/common/cs5536/cs5536_acc.c [new file with mode: 0644]
arch/mips/loongson2ef/common/cs5536/cs5536_ehci.c [new file with mode: 0644]
arch/mips/loongson2ef/common/cs5536/cs5536_ide.c [new file with mode: 0644]
arch/mips/loongson2ef/common/cs5536/cs5536_isa.c [new file with mode: 0644]
arch/mips/loongson2ef/common/cs5536/cs5536_mfgpt.c [new file with mode: 0644]
arch/mips/loongson2ef/common/cs5536/cs5536_ohci.c [new file with mode: 0644]
arch/mips/loongson2ef/common/cs5536/cs5536_pci.c [new file with mode: 0644]
arch/mips/loongson2ef/common/early_printk.c [new file with mode: 0644]
arch/mips/loongson2ef/common/env.c [new file with mode: 0644]
arch/mips/loongson2ef/common/init.c [new file with mode: 0644]
arch/mips/loongson2ef/common/irq.c [new file with mode: 0644]
arch/mips/loongson2ef/common/machtype.c [new file with mode: 0644]
arch/mips/loongson2ef/common/mem.c [new file with mode: 0644]
arch/mips/loongson2ef/common/pci.c [new file with mode: 0644]
arch/mips/loongson2ef/common/platform.c [new file with mode: 0644]
arch/mips/loongson2ef/common/pm.c [new file with mode: 0644]
arch/mips/loongson2ef/common/reset.c [new file with mode: 0644]
arch/mips/loongson2ef/common/rtc.c [new file with mode: 0644]
arch/mips/loongson2ef/common/serial.c [new file with mode: 0644]
arch/mips/loongson2ef/common/setup.c [new file with mode: 0644]
arch/mips/loongson2ef/common/time.c [new file with mode: 0644]
arch/mips/loongson2ef/common/uart_base.c [new file with mode: 0644]
arch/mips/loongson2ef/fuloong-2e/Makefile [new file with mode: 0644]
arch/mips/loongson2ef/fuloong-2e/dma.c [new file with mode: 0644]
arch/mips/loongson2ef/fuloong-2e/irq.c [new file with mode: 0644]
arch/mips/loongson2ef/fuloong-2e/reset.c [new file with mode: 0644]
arch/mips/loongson2ef/lemote-2f/Makefile [new file with mode: 0644]
arch/mips/loongson2ef/lemote-2f/clock.c [new file with mode: 0644]
arch/mips/loongson2ef/lemote-2f/dma.c [new file with mode: 0644]
arch/mips/loongson2ef/lemote-2f/ec_kb3310b.c [new file with mode: 0644]
arch/mips/loongson2ef/lemote-2f/ec_kb3310b.h [new file with mode: 0644]
arch/mips/loongson2ef/lemote-2f/irq.c [new file with mode: 0644]
arch/mips/loongson2ef/lemote-2f/machtype.c [new file with mode: 0644]
arch/mips/loongson2ef/lemote-2f/pm.c [new file with mode: 0644]
arch/mips/loongson2ef/lemote-2f/reset.c [new file with mode: 0644]
arch/mips/loongson64/Kconfig
arch/mips/loongson64/Makefile
arch/mips/loongson64/Platform
arch/mips/loongson64/common/Makefile
arch/mips/loongson64/common/cs5536/Makefile [deleted file]
arch/mips/loongson64/common/cs5536/cs5536_acc.c [deleted file]
arch/mips/loongson64/common/cs5536/cs5536_ehci.c [deleted file]
arch/mips/loongson64/common/cs5536/cs5536_ide.c [deleted file]
arch/mips/loongson64/common/cs5536/cs5536_isa.c [deleted file]
arch/mips/loongson64/common/cs5536/cs5536_mfgpt.c [deleted file]
arch/mips/loongson64/common/cs5536/cs5536_ohci.c [deleted file]
arch/mips/loongson64/common/cs5536/cs5536_pci.c [deleted file]
arch/mips/loongson64/fuloong-2e/Makefile [deleted file]
arch/mips/loongson64/fuloong-2e/dma.c [deleted file]
arch/mips/loongson64/fuloong-2e/irq.c [deleted file]
arch/mips/loongson64/fuloong-2e/reset.c [deleted file]
arch/mips/loongson64/lemote-2f/Makefile [deleted file]
arch/mips/loongson64/lemote-2f/clock.c [deleted file]
arch/mips/loongson64/lemote-2f/dma.c [deleted file]
arch/mips/loongson64/lemote-2f/ec_kb3310b.c [deleted file]
arch/mips/loongson64/lemote-2f/ec_kb3310b.h [deleted file]
arch/mips/loongson64/lemote-2f/irq.c [deleted file]
arch/mips/loongson64/lemote-2f/machtype.c [deleted file]
arch/mips/loongson64/lemote-2f/pm.c [deleted file]
arch/mips/loongson64/lemote-2f/reset.c [deleted file]
drivers/cpufreq/loongson2_cpufreq.c

index 55199ef7fa744cd7f8bd3cef1bb88c76880542b0..6bd0df79d8323798d02c514d9af8c2b2ebff984a 100644 (file)
@@ -10871,18 +10871,18 @@ F:    arch/mips/include/asm/mach-loongson32/
 F:     drivers/*/*loongson1*
 F:     drivers/*/*/*loongson1*
 
-MIPS/LOONGSON2 ARCHITECTURE
+MIPS/LOONGSON2EF ARCHITECTURE
 M:     Jiaxun Yang <jiaxun.yang@flygoat.com>
 L:     linux-mips@vger.kernel.org
 S:     Maintained
-F:     arch/mips/loongson64/fuloong-2e/
-F:     arch/mips/loongson64/lemote-2f/
-F:     arch/mips/include/asm/mach-loongson64/
+F:     arch/mips/loongson2ef/
+F:     arch/mips/include/asm/mach-loongson2ef/
 F:     drivers/*/*loongson2*
 F:     drivers/*/*/*loongson2*
 
-MIPS/LOONGSON3 ARCHITECTURE
+MIPS/LOONGSON64 ARCHITECTURE
 M:     Huacai Chen <chenhc@lemote.com>
+M:     Jiaxun Yang <jiaxun.yang@flygoat.com>
 L:     linux-mips@vger.kernel.org
 S:     Maintained
 F:     arch/mips/loongson64/
index 0de8398821066868ad01b2f2a5497852c287fdfb..7c0d461483efc519295121db288ea1fe41850e12 100644 (file)
@@ -17,6 +17,7 @@ platforms += jazz
 platforms += jz4740
 platforms += lantiq
 platforms += lasat
+platforms += loongson2ef
 platforms += loongson32
 platforms += loongson64
 platforms += mti-malta
index a4e8c75bc086014cbb569f6046a677fbff7b3b76..aa6f8497ddd9c035dca5c016290dbf2e7c8feae5 100644 (file)
@@ -453,18 +453,18 @@ config MACH_LOONGSON32
          the Institute of Computing Technology (ICT), Chinese Academy of
          Sciences (CAS).
 
-config MACH_LOONGSON64
-       bool "Loongson-2/3 family of machines"
+config MACH_LOONGSON2EF
+       bool "Loongson-2E/F family of machines"
        select SYS_SUPPORTS_ZBOOT
        help
-         This enables the support of Loongson-2/3 family of machines.
+         This enables the support of early Loongson-2E/F family of machines.
 
-         Loongson-2 is a family of single-core CPUs and Loongson-3 is a
-         family of multi-core CPUs. They are both 64-bit general-purpose
-         MIPS-compatible CPUs. Loongson-2/3 are developed by the Institute
-         of Computing Technology (ICT), Chinese Academy of Sciences (CAS)
-         in the People's Republic of China. The chief architect is Professor
-         Weiwu Hu.
+config MACH_LOONGSON64
+       bool "Loongson-2/3 GSx64 family of machines"
+       select SYS_SUPPORTS_ZBOOT
+       help
+         This enables the support of Loongson-2/3 family of processors with
+         GSx64 microarchitecture.
 
 config MACH_PISTACHIO
        bool "IMG Pistachio SoC based boards"
@@ -1037,6 +1037,7 @@ source "arch/mips/sibyte/Kconfig"
 source "arch/mips/txx9/Kconfig"
 source "arch/mips/vr41xx/Kconfig"
 source "arch/mips/cavium-octeon/Kconfig"
+source "arch/mips/loongson2ef/Kconfig"
 source "arch/mips/loongson32/Kconfig"
 source "arch/mips/loongson64/Kconfig"
 source "arch/mips/netlogic/Kconfig"
index 7a7af706e89816cfb95e1747fc65f75eaae8457f..1788ae23bff92fb297930a65a938d9bd150a468d 100644 (file)
@@ -15,7 +15,7 @@ CONFIG_EXPERT=y
 # CONFIG_COMPAT_BRK is not set
 CONFIG_SLAB=y
 CONFIG_PROFILING=y
-CONFIG_MACH_LOONGSON64=y
+CONFIG_MACH_LOONGSON2EF=y
 CONFIG_PCI=y
 CONFIG_MIPS32_O32=y
 CONFIG_MIPS32_N32=y
index d44f1469cf64c553c36d5c8615c91c948b794527..f9f93427c9bd21a5e52a0c77fad5e3ea51a488fd 100644 (file)
@@ -12,7 +12,7 @@ CONFIG_LOG_BUF_SHIFT=15
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_EXPERT=y
 CONFIG_PROFILING=y
-CONFIG_MACH_LOONGSON64=y
+CONFIG_MACH_LOONGSON2EF=y
 CONFIG_LEMOTE_MACH2F=y
 CONFIG_KEXEC=y
 # CONFIG_SECCOMP is not set
diff --git a/arch/mips/include/asm/mach-loongson2ef/boot_param.h b/arch/mips/include/asm/mach-loongson2ef/boot_param.h
new file mode 100644 (file)
index 0000000..8c286be
--- /dev/null
@@ -0,0 +1,221 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_MACH_LOONGSON64_BOOT_PARAM_H_
+#define __ASM_MACH_LOONGSON64_BOOT_PARAM_H_
+
+#define SYSTEM_RAM_LOW         1
+#define SYSTEM_RAM_HIGH                2
+#define SYSTEM_RAM_RESERVED    3
+#define PCI_IO                 4
+#define PCI_MEM                        5
+#define LOONGSON_CFG_REG       6
+#define VIDEO_ROM              7
+#define ADAPTER_ROM            8
+#define ACPI_TABLE             9
+#define SMBIOS_TABLE           10
+#define MAX_MEMORY_TYPE                11
+
+#define LOONGSON3_BOOT_MEM_MAP_MAX 128
+struct efi_memory_map_loongson {
+       u16 vers;       /* version of efi_memory_map */
+       u32 nr_map;     /* number of memory_maps */
+       u32 mem_freq;   /* memory frequence */
+       struct mem_map {
+               u32 node_id;    /* node_id which memory attached to */
+               u32 mem_type;   /* system memory, pci memory, pci io, etc. */
+               u64 mem_start;  /* memory map start address */
+               u32 mem_size;   /* each memory_map size, not the total size */
+       } map[LOONGSON3_BOOT_MEM_MAP_MAX];
+} __packed;
+
+enum loongson_cpu_type {
+       Legacy_2E = 0x0,
+       Legacy_2F = 0x1,
+       Legacy_3A = 0x2,
+       Legacy_3B = 0x3,
+       Legacy_1A = 0x4,
+       Legacy_1B = 0x5,
+       Legacy_2G = 0x6,
+       Legacy_2H = 0x7,
+       Loongson_1A = 0x100,
+       Loongson_1B = 0x101,
+       Loongson_2E = 0x200,
+       Loongson_2F = 0x201,
+       Loongson_2G = 0x202,
+       Loongson_2H = 0x203,
+       Loongson_3A = 0x300,
+       Loongson_3B = 0x301
+};
+
+/*
+ * Capability and feature descriptor structure for MIPS CPU
+ */
+struct efi_cpuinfo_loongson {
+       u16 vers;     /* version of efi_cpuinfo_loongson */
+       u32 processor_id; /* PRID, e.g. 6305, 6306 */
+       u32 cputype;  /* Loongson_3A/3B, etc. */
+       u32 total_node;   /* num of total numa nodes */
+       u16 cpu_startup_core_id; /* Boot core id */
+       u16 reserved_cores_mask;
+       u32 cpu_clock_freq; /* cpu_clock */
+       u32 nr_cpus;
+} __packed;
+
+#define MAX_UARTS 64
+struct uart_device {
+       u32 iotype; /* see include/linux/serial_core.h */
+       u32 uartclk;
+       u32 int_offset;
+       u64 uart_base;
+} __packed;
+
+#define MAX_SENSORS 64
+#define SENSOR_TEMPER  0x00000001
+#define SENSOR_VOLTAGE 0x00000002
+#define SENSOR_FAN     0x00000004
+struct sensor_device {
+       char name[32];  /* a formal name */
+       char label[64]; /* a flexible description */
+       u32 type;       /* SENSOR_* */
+       u32 id;         /* instance id of a sensor-class */
+       u32 fan_policy; /* see loongson_hwmon.h */
+       u32 fan_percent;/* only for constant speed policy */
+       u64 base_addr;  /* base address of device registers */
+} __packed;
+
+struct system_loongson {
+       u16 vers;     /* version of system_loongson */
+       u32 ccnuma_smp; /* 0: no numa; 1: has numa */
+       u32 sing_double_channel; /* 1:single; 2:double */
+       u32 nr_uarts;
+       struct uart_device uarts[MAX_UARTS];
+       u32 nr_sensors;
+       struct sensor_device sensors[MAX_SENSORS];
+       char has_ec;
+       char ec_name[32];
+       u64 ec_base_addr;
+       char has_tcm;
+       char tcm_name[32];
+       u64 tcm_base_addr;
+       u64 workarounds; /* see workarounds.h */
+} __packed;
+
+struct irq_source_routing_table {
+       u16 vers;
+       u16 size;
+       u16 rtr_bus;
+       u16 rtr_devfn;
+       u32 vendor;
+       u32 device;
+       u32 PIC_type;   /* conform use HT or PCI to route to CPU-PIC */
+       u64 ht_int_bit; /* 3A: 1<<24; 3B: 1<<16 */
+       u64 ht_enable;  /* irqs used in this PIC */
+       u32 node_id;    /* node id: 0x0-0; 0x1-1; 0x10-2; 0x11-3 */
+       u64 pci_mem_start_addr;
+       u64 pci_mem_end_addr;
+       u64 pci_io_start_addr;
+       u64 pci_io_end_addr;
+       u64 pci_config_addr;
+       u32 dma_mask_bits;
+} __packed;
+
+struct interface_info {
+       u16 vers; /* version of the specificition */
+       u16 size;
+       u8  flag;
+       char description[64];
+} __packed;
+
+#define MAX_RESOURCE_NUMBER 128
+struct resource_loongson {
+       u64 start; /* resource start address */
+       u64 end;   /* resource end address */
+       char name[64];
+       u32 flags;
+};
+
+struct archdev_data {};  /* arch specific additions */
+
+struct board_devices {
+       char name[64];    /* hold the device name */
+       u32 num_resources; /* number of device_resource */
+       /* for each device's resource */
+       struct resource_loongson resource[MAX_RESOURCE_NUMBER];
+       /* arch specific additions */
+       struct archdev_data archdata;
+};
+
+struct loongson_special_attribute {
+       u16 vers;     /* version of this special */
+       char special_name[64]; /* special_atribute_name */
+       u32 loongson_special_type; /* type of special device */
+       /* for each device's resource */
+       struct resource_loongson resource[MAX_RESOURCE_NUMBER];
+};
+
+struct loongson_params {
+       u64 memory_offset;      /* efi_memory_map_loongson struct offset */
+       u64 cpu_offset;         /* efi_cpuinfo_loongson struct offset */
+       u64 system_offset;      /* system_loongson struct offset */
+       u64 irq_offset;         /* irq_source_routing_table struct offset */
+       u64 interface_offset;   /* interface_info struct offset */
+       u64 special_offset;     /* loongson_special_attribute struct offset */
+       u64 boarddev_table_offset;  /* board_devices offset */
+};
+
+struct smbios_tables {
+       u16 vers;     /* version of smbios */
+       u64 vga_bios; /* vga_bios address */
+       struct loongson_params lp;
+};
+
+struct efi_reset_system_t {
+       u64 ResetCold;
+       u64 ResetWarm;
+       u64 ResetType;
+       u64 Shutdown;
+       u64 DoSuspend; /* NULL if not support */
+};
+
+struct efi_loongson {
+       u64 mps;        /* MPS table */
+       u64 acpi;       /* ACPI table (IA64 ext 0.71) */
+       u64 acpi20;     /* ACPI table (ACPI 2.0) */
+       struct smbios_tables smbios;    /* SM BIOS table */
+       u64 sal_systab; /* SAL system table */
+       u64 boot_info;  /* boot info table */
+};
+
+struct boot_params {
+       struct efi_loongson efi;
+       struct efi_reset_system_t reset_system;
+};
+
+struct loongson_system_configuration {
+       u32 nr_cpus;
+       u32 nr_nodes;
+       int cores_per_node;
+       int cores_per_package;
+       u16 boot_cpu_id;
+       u16 reserved_cpus_mask;
+       enum loongson_cpu_type cputype;
+       u64 ht_control_base;
+       u64 pci_mem_start_addr;
+       u64 pci_mem_end_addr;
+       u64 pci_io_base;
+       u64 restart_addr;
+       u64 poweroff_addr;
+       u64 suspend_addr;
+       u64 vgabios_addr;
+       u32 dma_mask_bits;
+       char ecname[32];
+       u32 nr_uarts;
+       struct uart_device uarts[MAX_UARTS];
+       u32 nr_sensors;
+       struct sensor_device sensors[MAX_SENSORS];
+       u64 workarounds;
+};
+
+extern struct efi_memory_map_loongson *loongson_memmap;
+extern struct loongson_system_configuration loongson_sysconf;
+
+#endif
diff --git a/arch/mips/include/asm/mach-loongson2ef/cpu-feature-overrides.h b/arch/mips/include/asm/mach-loongson2ef/cpu-feature-overrides.h
new file mode 100644 (file)
index 0000000..83ad90d
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2009 Wu Zhangjin <wuzhangjin@gmail.com>
+ * Copyright (C) 2009 Philippe Vachon <philippe@cowpig.ca>
+ * Copyright (C) 2009 Zhang Le <r0bertz@gentoo.org>
+ *
+ * reference: /proc/cpuinfo,
+ *     arch/mips/kernel/cpu-probe.c(cpu_probe_legacy),
+ *     arch/mips/kernel/proc.c(show_cpuinfo),
+ *     loongson2f user manual.
+ */
+
+#ifndef __ASM_MACH_LOONGSON64_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_LOONGSON64_CPU_FEATURE_OVERRIDES_H
+
+#define cpu_has_32fpr          1
+#define cpu_has_3k_cache       0
+#define cpu_has_4k_cache       1
+#define cpu_has_4kex           1
+#define cpu_has_64bits         1
+#define cpu_has_cache_cdex_p   0
+#define cpu_has_cache_cdex_s   0
+#define cpu_has_counter                1
+#define cpu_has_dc_aliases     (PAGE_SIZE < 0x4000)
+#define cpu_has_divec          0
+#define cpu_has_ejtag          0
+#define cpu_has_inclusive_pcaches      1
+#define cpu_has_llsc           1
+#define cpu_has_mcheck         0
+#define cpu_has_mdmx           0
+#define cpu_has_mips16         0
+#define cpu_has_mips16e2       0
+#define cpu_has_mips3d         0
+#define cpu_has_mipsmt         0
+#define cpu_has_smartmips      0
+#define cpu_has_tlb            1
+#define cpu_has_tx39_cache     0
+#define cpu_has_vce            0
+#define cpu_has_veic           0
+#define cpu_has_vint           0
+#define cpu_has_vtag_icache    0
+#define cpu_has_watch          1
+
+#ifdef CONFIG_CPU_LOONGSON64
+#define cpu_has_wsbh           1
+#define cpu_has_ic_fills_f_dc  1
+#define cpu_hwrena_impl_bits   0xc0000000
+#endif
+
+#endif /* __ASM_MACH_LOONGSON64_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-loongson2ef/cs5536/cs5536.h b/arch/mips/include/asm/mach-loongson2ef/cs5536/cs5536.h
new file mode 100644 (file)
index 0000000..9795b33
--- /dev/null
@@ -0,0 +1,306 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * The header file of cs5536 south bridge.
+ *
+ * Copyright (C) 2007 Lemote, Inc.
+ * Author : jlliu <liujl@lemote.com>
+ */
+
+#ifndef _CS5536_H
+#define _CS5536_H
+
+#include <linux/types.h>
+
+extern void _rdmsr(u32 msr, u32 *hi, u32 *lo);
+extern void _wrmsr(u32 msr, u32 hi, u32 lo);
+
+/*
+ * MSR module base
+ */
+#define CS5536_SB_MSR_BASE     (0x00000000)
+#define CS5536_GLIU_MSR_BASE   (0x10000000)
+#define CS5536_ILLEGAL_MSR_BASE (0x20000000)
+#define CS5536_USB_MSR_BASE    (0x40000000)
+#define CS5536_IDE_MSR_BASE    (0x60000000)
+#define CS5536_DIVIL_MSR_BASE  (0x80000000)
+#define CS5536_ACC_MSR_BASE    (0xa0000000)
+#define CS5536_UNUSED_MSR_BASE (0xc0000000)
+#define CS5536_GLCP_MSR_BASE   (0xe0000000)
+
+#define SB_MSR_REG(offset)     (CS5536_SB_MSR_BASE     | (offset))
+#define GLIU_MSR_REG(offset)   (CS5536_GLIU_MSR_BASE   | (offset))
+#define ILLEGAL_MSR_REG(offset) (CS5536_ILLEGAL_MSR_BASE | (offset))
+#define USB_MSR_REG(offset)    (CS5536_USB_MSR_BASE    | (offset))
+#define IDE_MSR_REG(offset)    (CS5536_IDE_MSR_BASE    | (offset))
+#define DIVIL_MSR_REG(offset)  (CS5536_DIVIL_MSR_BASE  | (offset))
+#define ACC_MSR_REG(offset)    (CS5536_ACC_MSR_BASE    | (offset))
+#define UNUSED_MSR_REG(offset) (CS5536_UNUSED_MSR_BASE | (offset))
+#define GLCP_MSR_REG(offset)   (CS5536_GLCP_MSR_BASE   | (offset))
+
+/*
+ * BAR SPACE OF VIRTUAL PCI :
+ * range for pci probe use, length is the actual size.
+ */
+/* IO space for all DIVIL modules */
+#define CS5536_IRQ_RANGE       0xffffffe0 /* USERD FOR PCI PROBE */
+#define CS5536_IRQ_LENGTH      0x20    /* THE REGS ACTUAL LENGTH */
+#define CS5536_SMB_RANGE       0xfffffff8
+#define CS5536_SMB_LENGTH      0x08
+#define CS5536_GPIO_RANGE      0xffffff00
+#define CS5536_GPIO_LENGTH     0x100
+#define CS5536_MFGPT_RANGE     0xffffffc0
+#define CS5536_MFGPT_LENGTH    0x40
+#define CS5536_ACPI_RANGE      0xffffffe0
+#define CS5536_ACPI_LENGTH     0x20
+#define CS5536_PMS_RANGE       0xffffff80
+#define CS5536_PMS_LENGTH      0x80
+/* IO space for IDE */
+#define CS5536_IDE_RANGE       0xfffffff0
+#define CS5536_IDE_LENGTH      0x10
+/* IO space for ACC */
+#define CS5536_ACC_RANGE       0xffffff80
+#define CS5536_ACC_LENGTH      0x80
+/* MEM space for ALL USB modules */
+#define CS5536_OHCI_RANGE      0xfffff000
+#define CS5536_OHCI_LENGTH     0x1000
+#define CS5536_EHCI_RANGE      0xfffff000
+#define CS5536_EHCI_LENGTH     0x1000
+
+/*
+ * PCI MSR ACCESS
+ */
+#define PCI_MSR_CTRL           0xF0
+#define PCI_MSR_ADDR           0xF4
+#define PCI_MSR_DATA_LO                0xF8
+#define PCI_MSR_DATA_HI                0xFC
+
+/**************** MSR *****************************/
+
+/*
+ * GLIU STANDARD MSR
+ */
+#define GLIU_CAP               0x00
+#define GLIU_CONFIG            0x01
+#define GLIU_SMI               0x02
+#define GLIU_ERROR             0x03
+#define GLIU_PM                        0x04
+#define GLIU_DIAG              0x05
+
+/*
+ * GLIU SPEC. MSR
+ */
+#define GLIU_P2D_BM0           0x20
+#define GLIU_P2D_BM1           0x21
+#define GLIU_P2D_BM2           0x22
+#define GLIU_P2D_BMK0          0x23
+#define GLIU_P2D_BMK1          0x24
+#define GLIU_P2D_BM3           0x25
+#define GLIU_P2D_BM4           0x26
+#define GLIU_COH               0x80
+#define GLIU_PAE               0x81
+#define GLIU_ARB               0x82
+#define GLIU_ASMI              0x83
+#define GLIU_AERR              0x84
+#define GLIU_DEBUG             0x85
+#define GLIU_PHY_CAP           0x86
+#define GLIU_NOUT_RESP         0x87
+#define GLIU_NOUT_WDATA                0x88
+#define GLIU_WHOAMI            0x8B
+#define GLIU_SLV_DIS           0x8C
+#define GLIU_IOD_BM0           0xE0
+#define GLIU_IOD_BM1           0xE1
+#define GLIU_IOD_BM2           0xE2
+#define GLIU_IOD_BM3           0xE3
+#define GLIU_IOD_BM4           0xE4
+#define GLIU_IOD_BM5           0xE5
+#define GLIU_IOD_BM6           0xE6
+#define GLIU_IOD_BM7           0xE7
+#define GLIU_IOD_BM8           0xE8
+#define GLIU_IOD_BM9           0xE9
+#define GLIU_IOD_SC0           0xEA
+#define GLIU_IOD_SC1           0xEB
+#define GLIU_IOD_SC2           0xEC
+#define GLIU_IOD_SC3           0xED
+#define GLIU_IOD_SC4           0xEE
+#define GLIU_IOD_SC5           0xEF
+#define GLIU_IOD_SC6           0xF0
+#define GLIU_IOD_SC7           0xF1
+
+/*
+ * SB STANDARD
+ */
+#define SB_CAP         0x00
+#define SB_CONFIG      0x01
+#define SB_SMI         0x02
+#define SB_ERROR       0x03
+#define SB_MAR_ERR_EN          0x00000001
+#define SB_TAR_ERR_EN          0x00000002
+#define SB_RSVD_BIT1           0x00000004
+#define SB_EXCEP_ERR_EN                0x00000008
+#define SB_SYSE_ERR_EN         0x00000010
+#define SB_PARE_ERR_EN         0x00000020
+#define SB_TAS_ERR_EN          0x00000040
+#define SB_MAR_ERR_FLAG                0x00010000
+#define SB_TAR_ERR_FLAG                0x00020000
+#define SB_RSVD_BIT2           0x00040000
+#define SB_EXCEP_ERR_FLAG      0x00080000
+#define SB_SYSE_ERR_FLAG       0x00100000
+#define SB_PARE_ERR_FLAG       0x00200000
+#define SB_TAS_ERR_FLAG                0x00400000
+#define SB_PM          0x04
+#define SB_DIAG                0x05
+
+/*
+ * SB SPEC.
+ */
+#define SB_CTRL                0x10
+#define SB_R0          0x20
+#define SB_R1          0x21
+#define SB_R2          0x22
+#define SB_R3          0x23
+#define SB_R4          0x24
+#define SB_R5          0x25
+#define SB_R6          0x26
+#define SB_R7          0x27
+#define SB_R8          0x28
+#define SB_R9          0x29
+#define SB_R10         0x2A
+#define SB_R11         0x2B
+#define SB_R12         0x2C
+#define SB_R13         0x2D
+#define SB_R14         0x2E
+#define SB_R15         0x2F
+
+/*
+ * GLCP STANDARD
+ */
+#define GLCP_CAP               0x00
+#define GLCP_CONFIG            0x01
+#define GLCP_SMI               0x02
+#define GLCP_ERROR             0x03
+#define GLCP_PM                        0x04
+#define GLCP_DIAG              0x05
+
+/*
+ * GLCP SPEC.
+ */
+#define GLCP_CLK_DIS_DELAY     0x08
+#define GLCP_PM_CLK_DISABLE    0x09
+#define GLCP_GLB_PM            0x0B
+#define GLCP_DBG_OUT           0x0C
+#define GLCP_RSVD1             0x0D
+#define GLCP_SOFT_COM          0x0E
+#define SOFT_BAR_SMB_FLAG      0x00000001
+#define SOFT_BAR_GPIO_FLAG     0x00000002
+#define SOFT_BAR_MFGPT_FLAG    0x00000004
+#define SOFT_BAR_IRQ_FLAG      0x00000008
+#define SOFT_BAR_PMS_FLAG      0x00000010
+#define SOFT_BAR_ACPI_FLAG     0x00000020
+#define SOFT_BAR_IDE_FLAG      0x00000400
+#define SOFT_BAR_ACC_FLAG      0x00000800
+#define SOFT_BAR_OHCI_FLAG     0x00001000
+#define SOFT_BAR_EHCI_FLAG     0x00002000
+#define GLCP_RSVD2             0x0F
+#define GLCP_CLK_OFF           0x10
+#define GLCP_CLK_ACTIVE                0x11
+#define GLCP_CLK_DISABLE       0x12
+#define GLCP_CLK4ACK           0x13
+#define GLCP_SYS_RST           0x14
+#define GLCP_RSVD3             0x15
+#define GLCP_DBG_CLK_CTRL      0x16
+#define GLCP_CHIP_REV_ID       0x17
+
+/* PIC */
+#define PIC_YSEL_LOW           0x20
+#define PIC_YSEL_LOW_USB_SHIFT         8
+#define PIC_YSEL_LOW_ACC_SHIFT         16
+#define PIC_YSEL_LOW_FLASH_SHIFT       24
+#define PIC_YSEL_HIGH          0x21
+#define PIC_ZSEL_LOW           0x22
+#define PIC_ZSEL_HIGH          0x23
+#define PIC_IRQM_PRIM          0x24
+#define PIC_IRQM_LPC           0x25
+#define PIC_XIRR_STS_LOW       0x26
+#define PIC_XIRR_STS_HIGH      0x27
+#define PCI_SHDW               0x34
+
+/*
+ * DIVIL STANDARD
+ */
+#define DIVIL_CAP              0x00
+#define DIVIL_CONFIG           0x01
+#define DIVIL_SMI              0x02
+#define DIVIL_ERROR            0x03
+#define DIVIL_PM               0x04
+#define DIVIL_DIAG             0x05
+
+/*
+ * DIVIL SPEC.
+ */
+#define DIVIL_LBAR_IRQ         0x08
+#define DIVIL_LBAR_KEL         0x09
+#define DIVIL_LBAR_SMB         0x0B
+#define DIVIL_LBAR_GPIO                0x0C
+#define DIVIL_LBAR_MFGPT       0x0D
+#define DIVIL_LBAR_ACPI                0x0E
+#define DIVIL_LBAR_PMS         0x0F
+#define DIVIL_LEG_IO           0x14
+#define DIVIL_BALL_OPTS                0x15
+#define DIVIL_SOFT_IRQ         0x16
+#define DIVIL_SOFT_RESET       0x17
+
+/* MFGPT */
+#define MFGPT_IRQ      0x28
+
+/*
+ * IDE STANDARD
+ */
+#define IDE_CAP                0x00
+#define IDE_CONFIG     0x01
+#define IDE_SMI                0x02
+#define IDE_ERROR      0x03
+#define IDE_PM         0x04
+#define IDE_DIAG       0x05
+
+/*
+ * IDE SPEC.
+ */
+#define IDE_IO_BAR     0x08
+#define IDE_CFG                0x10
+#define IDE_DTC                0x12
+#define IDE_CAST       0x13
+#define IDE_ETC                0x14
+#define IDE_INTERNAL_PM 0x15
+
+/*
+ * ACC STANDARD
+ */
+#define ACC_CAP                0x00
+#define ACC_CONFIG     0x01
+#define ACC_SMI                0x02
+#define ACC_ERROR      0x03
+#define ACC_PM         0x04
+#define ACC_DIAG       0x05
+
+/*
+ * USB STANDARD
+ */
+#define USB_CAP                0x00
+#define USB_CONFIG     0x01
+#define USB_SMI                0x02
+#define USB_ERROR      0x03
+#define USB_PM         0x04
+#define USB_DIAG       0x05
+
+/*
+ * USB SPEC.
+ */
+#define USB_OHCI       0x08
+#define USB_EHCI       0x09
+
+/****************** NATIVE ***************************/
+/* GPIO : I/O SPACE; REG : 32BITS */
+#define GPIOL_OUT_VAL          0x00
+#define GPIOL_OUT_EN           0x04
+
+#endif                         /* _CS5536_H */
diff --git a/arch/mips/include/asm/mach-loongson2ef/cs5536/cs5536_mfgpt.h b/arch/mips/include/asm/mach-loongson2ef/cs5536/cs5536_mfgpt.h
new file mode 100644 (file)
index 0000000..52e8bb0
--- /dev/null
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * cs5536 mfgpt header file
+ */
+
+#ifndef _CS5536_MFGPT_H
+#define _CS5536_MFGPT_H
+
+#include <cs5536/cs5536.h>
+#include <cs5536/cs5536_pci.h>
+
+#ifdef CONFIG_CS5536_MFGPT
+extern void setup_mfgpt0_timer(void);
+extern void disable_mfgpt0_counter(void);
+extern void enable_mfgpt0_counter(void);
+#else
+static inline void __maybe_unused setup_mfgpt0_timer(void)
+{
+}
+static inline void __maybe_unused disable_mfgpt0_counter(void)
+{
+}
+static inline void __maybe_unused enable_mfgpt0_counter(void)
+{
+}
+#endif
+
+#define MFGPT_TICK_RATE 14318000
+#define COMPARE         ((MFGPT_TICK_RATE + HZ/2) / HZ)
+
+#define MFGPT_BASE     mfgpt_base
+#define MFGPT0_CMP2    (MFGPT_BASE + 2)
+#define MFGPT0_CNT     (MFGPT_BASE + 4)
+#define MFGPT0_SETUP   (MFGPT_BASE + 6)
+
+#endif /*!_CS5536_MFGPT_H */
diff --git a/arch/mips/include/asm/mach-loongson2ef/cs5536/cs5536_pci.h b/arch/mips/include/asm/mach-loongson2ef/cs5536/cs5536_pci.h
new file mode 100644 (file)
index 0000000..a0d4b75
--- /dev/null
@@ -0,0 +1,153 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * the definition file of cs5536 Virtual Support Module(VSM).
+ * pci configuration space can be accessed through the VSM, so
+ * there is no need of the MSR read/write now, except the spec.
+ * MSR registers which are not implemented yet.
+ *
+ * Copyright (C) 2007 Lemote Inc.
+ * Author : jlliu, liujl@lemote.com
+ */
+
+#ifndef _CS5536_PCI_H
+#define _CS5536_PCI_H
+
+#include <linux/types.h>
+#include <linux/pci_regs.h>
+
+extern void cs5536_pci_conf_write4(int function, int reg, u32 value);
+extern u32 cs5536_pci_conf_read4(int function, int reg);
+
+#define CS5536_ACC_INTR                9
+#define CS5536_IDE_INTR                14
+#define CS5536_USB_INTR                11
+#define CS5536_MFGPT_INTR      5
+#define CS5536_UART1_INTR      4
+#define CS5536_UART2_INTR      3
+
+/************** PCI BUS DEVICE FUNCTION ***************/
+
+/*
+ * PCI bus device function
+ */
+#define PCI_BUS_CS5536         0
+#define PCI_IDSEL_CS5536       14
+
+/********** STANDARD PCI-2.2 EXPANSION ****************/
+
+/*
+ * PCI configuration space
+ * we have to virtualize the PCI configure space head, so we should
+ * define the necessary IDs and some others.
+ */
+
+/* CONFIG of PCI VENDOR ID*/
+#define CFG_PCI_VENDOR_ID(mod_dev_id, sys_vendor_id) \
+       (((mod_dev_id) << 16) | (sys_vendor_id))
+
+/* VENDOR ID */
+#define CS5536_VENDOR_ID       0x1022
+
+/* DEVICE ID */
+#define CS5536_ISA_DEVICE_ID           0x2090
+#define CS5536_IDE_DEVICE_ID           0x209a
+#define CS5536_ACC_DEVICE_ID           0x2093
+#define CS5536_OHCI_DEVICE_ID          0x2094
+#define CS5536_EHCI_DEVICE_ID          0x2095
+
+/* CLASS CODE : CLASS SUB-CLASS INTERFACE */
+#define CS5536_ISA_CLASS_CODE          0x060100
+#define CS5536_IDE_CLASS_CODE          0x010180
+#define CS5536_ACC_CLASS_CODE          0x040100
+#define CS5536_OHCI_CLASS_CODE         0x0C0310
+#define CS5536_EHCI_CLASS_CODE         0x0C0320
+
+/* BHLC : BIST HEADER-TYPE LATENCY-TIMER CACHE-LINE-SIZE */
+
+#define CFG_PCI_CACHE_LINE_SIZE(header_type, latency_timer)    \
+       ((PCI_NONE_BIST << 24) | ((header_type) << 16) \
+               | ((latency_timer) << 8) | PCI_NORMAL_CACHE_LINE_SIZE);
+
+#define PCI_NONE_BIST                  0x00    /* RO not implemented yet. */
+#define PCI_BRIDGE_HEADER_TYPE         0x80    /* RO */
+#define PCI_NORMAL_HEADER_TYPE         0x00
+#define PCI_NORMAL_LATENCY_TIMER       0x00
+#define PCI_NORMAL_CACHE_LINE_SIZE     0x08    /* RW */
+
+/* BAR */
+#define PCI_BAR0_REG                   0x10
+#define PCI_BAR1_REG                   0x14
+#define PCI_BAR2_REG                   0x18
+#define PCI_BAR3_REG                   0x1c
+#define PCI_BAR4_REG                   0x20
+#define PCI_BAR5_REG                   0x24
+#define PCI_BAR_RANGE_MASK             0xFFFFFFFF
+
+/* CARDBUS CIS POINTER */
+#define PCI_CARDBUS_CIS_POINTER                0x00000000
+
+/* SUBSYSTEM VENDOR ID */
+#define CS5536_SUB_VENDOR_ID           CS5536_VENDOR_ID
+
+/* SUBSYSTEM ID */
+#define CS5536_ISA_SUB_ID              CS5536_ISA_DEVICE_ID
+#define CS5536_IDE_SUB_ID              CS5536_IDE_DEVICE_ID
+#define CS5536_ACC_SUB_ID              CS5536_ACC_DEVICE_ID
+#define CS5536_OHCI_SUB_ID             CS5536_OHCI_DEVICE_ID
+#define CS5536_EHCI_SUB_ID             CS5536_EHCI_DEVICE_ID
+
+/* EXPANSION ROM BAR */
+#define PCI_EXPANSION_ROM_BAR          0x00000000
+
+/* CAPABILITIES POINTER */
+#define PCI_CAPLIST_POINTER            0x00000000
+#define PCI_CAPLIST_USB_POINTER                0x40
+/* INTERRUPT */
+
+#define CFG_PCI_INTERRUPT_LINE(pin, mod_intr) \
+       ((PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | \
+               ((pin) << 8) | (mod_intr))
+
+#define PCI_MAX_LATENCY                        0x40
+#define PCI_MIN_GRANT                  0x00
+#define PCI_DEFAULT_PIN                        0x01
+
+/*********** EXPANSION PCI REG ************************/
+
+/*
+ * ISA EXPANSION
+ */
+#define PCI_UART1_INT_REG      0x50
+#define PCI_UART2_INT_REG      0x54
+#define PCI_ISA_FIXUP_REG      0x58
+
+/*
+ * IDE EXPANSION
+ */
+#define PCI_IDE_CFG_REG                0x40
+#define CS5536_IDE_FLASH_SIGNATURE     0xDEADBEEF
+#define PCI_IDE_DTC_REG                0x48
+#define PCI_IDE_CAST_REG       0x4C
+#define PCI_IDE_ETC_REG                0x50
+#define PCI_IDE_PM_REG         0x54
+#define PCI_IDE_INT_REG                0x60
+
+/*
+ * ACC EXPANSION
+ */
+#define PCI_ACC_INT_REG                0x50
+
+/*
+ * OHCI EXPANSION : INTTERUPT IS IMPLEMENTED BY THE OHCI
+ */
+#define PCI_OHCI_PM_REG                0x40
+#define PCI_OHCI_INT_REG       0x50
+
+/*
+ * EHCI EXPANSION
+ */
+#define PCI_EHCI_LEGSMIEN_REG  0x50
+#define PCI_EHCI_LEGSMISTS_REG 0x54
+#define PCI_EHCI_FLADJ_REG     0x60
+
+#endif                         /* _CS5536_PCI_H_ */
diff --git a/arch/mips/include/asm/mach-loongson2ef/cs5536/cs5536_vsm.h b/arch/mips/include/asm/mach-loongson2ef/cs5536/cs5536_vsm.h
new file mode 100644 (file)
index 0000000..70d0153
--- /dev/null
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * the read/write interfaces for Virtual Support Module(VSM)
+ *
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Wu Zhangjin <wuzhangjin@gmail.com>
+ */
+
+#ifndef _CS5536_VSM_H
+#define _CS5536_VSM_H
+
+#include <linux/types.h>
+
+typedef void (*cs5536_pci_vsm_write)(int reg, u32 value);
+typedef u32 (*cs5536_pci_vsm_read)(int reg);
+
+#define DECLARE_CS5536_MODULE(name) \
+extern void pci_##name##_write_reg(int reg, u32 value); \
+extern u32 pci_##name##_read_reg(int reg);
+
+/* ide module */
+DECLARE_CS5536_MODULE(ide)
+/* acc module */
+DECLARE_CS5536_MODULE(acc)
+/* ohci module */
+DECLARE_CS5536_MODULE(ohci)
+/* isa module */
+DECLARE_CS5536_MODULE(isa)
+/* ehci module */
+DECLARE_CS5536_MODULE(ehci)
+
+#endif                         /* _CS5536_VSM_H */
diff --git a/arch/mips/include/asm/mach-loongson2ef/irq.h b/arch/mips/include/asm/mach-loongson2ef/irq.h
new file mode 100644 (file)
index 0000000..557e069
--- /dev/null
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_MACH_LOONGSON64_IRQ_H_
+#define __ASM_MACH_LOONGSON64_IRQ_H_
+
+#include <boot_param.h>
+
+#ifdef CONFIG_CPU_LOONGSON64
+
+/* cpu core interrupt numbers */
+#define MIPS_CPU_IRQ_BASE 56
+
+#define LOONGSON_UART_IRQ   (MIPS_CPU_IRQ_BASE + 2) /* UART */
+#define LOONGSON_BRIDGE_IRQ (MIPS_CPU_IRQ_BASE + 3) /* CASCADE */
+#define LOONGSON_TIMER_IRQ  (MIPS_CPU_IRQ_BASE + 7) /* CPU Timer */
+
+#define LOONGSON_HT1_CFG_BASE          loongson_sysconf.ht_control_base
+#define LOONGSON_HT1_INT_VECTOR_BASE   (LOONGSON_HT1_CFG_BASE + 0x80)
+#define LOONGSON_HT1_INT_EN_BASE       (LOONGSON_HT1_CFG_BASE + 0xa0)
+#define LOONGSON_HT1_INT_VECTOR(n)     \
+               LOONGSON3_REG32(LOONGSON_HT1_INT_VECTOR_BASE, 4 * (n))
+#define LOONGSON_HT1_INTN_EN(n)                \
+               LOONGSON3_REG32(LOONGSON_HT1_INT_EN_BASE, 4 * (n))
+
+#define LOONGSON_INT_ROUTER_OFFSET     0x1400
+#define LOONGSON_INT_ROUTER_INTEN      \
+         LOONGSON3_REG32(LOONGSON3_REG_BASE, LOONGSON_INT_ROUTER_OFFSET + 0x24)
+#define LOONGSON_INT_ROUTER_INTENSET   \
+         LOONGSON3_REG32(LOONGSON3_REG_BASE, LOONGSON_INT_ROUTER_OFFSET + 0x28)
+#define LOONGSON_INT_ROUTER_INTENCLR   \
+         LOONGSON3_REG32(LOONGSON3_REG_BASE, LOONGSON_INT_ROUTER_OFFSET + 0x2c)
+#define LOONGSON_INT_ROUTER_ENTRY(n)   \
+         LOONGSON3_REG8(LOONGSON3_REG_BASE, LOONGSON_INT_ROUTER_OFFSET + n)
+#define LOONGSON_INT_ROUTER_LPC                LOONGSON_INT_ROUTER_ENTRY(0x0a)
+#define LOONGSON_INT_ROUTER_HT1(n)     LOONGSON_INT_ROUTER_ENTRY(n + 0x18)
+
+#define LOONGSON_INT_COREx_INTy(x, y)  (1<<(x) | 1<<(y+4))     /* route to int y of core x */
+
+#endif
+
+extern void fixup_irqs(void);
+extern void loongson3_ipi_interrupt(struct pt_regs *regs);
+
+#include_next <irq.h>
+#endif /* __ASM_MACH_LOONGSON64_IRQ_H_ */
diff --git a/arch/mips/include/asm/mach-loongson2ef/kernel-entry-init.h b/arch/mips/include/asm/mach-loongson2ef/kernel-entry-init.h
new file mode 100644 (file)
index 0000000..28ccb06
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005 Embedded Alley Solutions, Inc
+ * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2009 Jiajie Chen (chenjiajie@cse.buaa.edu.cn)
+ * Copyright (C) 2012 Huacai Chen (chenhc@lemote.com)
+ */
+#ifndef __ASM_MACH_LOONGSON64_KERNEL_ENTRY_H
+#define __ASM_MACH_LOONGSON64_KERNEL_ENTRY_H
+
+#include <asm/cpu.h>
+
+/*
+ * Override macros used in arch/mips/kernel/head.S.
+ */
+       .macro  kernel_entry_setup
+#ifdef CONFIG_CPU_LOONGSON64
+       .set    push
+       .set    mips64
+       /* Set LPA on LOONGSON3 config3 */
+       mfc0    t0, CP0_CONFIG3
+       or      t0, (0x1 << 7)
+       mtc0    t0, CP0_CONFIG3
+       /* Set ELPA on LOONGSON3 pagegrain */
+       mfc0    t0, CP0_PAGEGRAIN
+       or      t0, (0x1 << 29)
+       mtc0    t0, CP0_PAGEGRAIN
+       /* Enable STFill Buffer */
+       mfc0    t0, CP0_PRID
+       /* Loongson-3A R4+ */
+       andi    t1, t0, PRID_IMP_MASK
+       li      t2, PRID_IMP_LOONGSON_64G
+       beq     t1, t2, 1f
+       nop
+       /* Loongson-3A R2/R3 */
+       andi    t0, (PRID_IMP_MASK | PRID_REV_MASK)
+       slti    t0, (PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R2_0)
+       bnez    t0, 2f
+       nop
+1:
+       mfc0    t0, CP0_CONFIG6
+       or      t0, 0x100
+       mtc0    t0, CP0_CONFIG6
+2:
+       _ehb
+       .set    pop
+#endif
+       .endm
+
+/*
+ * Do SMP slave processor setup.
+ */
+       .macro  smp_slave_setup
+#ifdef CONFIG_CPU_LOONGSON64
+       .set    push
+       .set    mips64
+       /* Set LPA on LOONGSON3 config3 */
+       mfc0    t0, CP0_CONFIG3
+       or      t0, (0x1 << 7)
+       mtc0    t0, CP0_CONFIG3
+       /* Set ELPA on LOONGSON3 pagegrain */
+       mfc0    t0, CP0_PAGEGRAIN
+       or      t0, (0x1 << 29)
+       mtc0    t0, CP0_PAGEGRAIN
+       /* Enable STFill Buffer */
+       mfc0    t0, CP0_PRID
+       /* Loongson-3A R4+ */
+       andi    t1, t0, PRID_IMP_MASK
+       li      t2, PRID_IMP_LOONGSON_64G
+       beq     t1, t2, 1f
+       nop
+       /* Loongson-3A R2/R3 */
+       andi    t0, (PRID_IMP_MASK | PRID_REV_MASK)
+       slti    t0, (PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R2_0)
+       bnez    t0, 2f
+       nop
+1:
+       mfc0    t0, CP0_CONFIG6
+       or      t0, 0x100
+       mtc0    t0, CP0_CONFIG6
+2:
+       _ehb
+       .set    pop
+#endif
+       .endm
+
+#endif /* __ASM_MACH_LOONGSON64_KERNEL_ENTRY_H */
diff --git a/arch/mips/include/asm/mach-loongson2ef/loongson.h b/arch/mips/include/asm/mach-loongson2ef/loongson.h
new file mode 100644 (file)
index 0000000..40a24b7
--- /dev/null
@@ -0,0 +1,355 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Wu Zhangjin <wuzhangjin@gmail.com>
+ */
+
+#ifndef __ASM_MACH_LOONGSON64_LOONGSON_H
+#define __ASM_MACH_LOONGSON64_LOONGSON_H
+
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <boot_param.h>
+
+/* loongson internal northbridge initialization */
+extern void bonito_irq_init(void);
+
+/* machine-specific reboot/halt operation */
+extern void mach_prepare_reboot(void);
+extern void mach_prepare_shutdown(void);
+
+/* environment arguments from bootloader */
+extern u32 cpu_clock_freq;
+extern u32 memsize, highmemsize;
+extern const struct plat_smp_ops loongson3_smp_ops;
+
+/* loongson-specific command line, env and memory initialization */
+extern void __init prom_init_memory(void);
+extern void __init prom_init_cmdline(void);
+extern void __init prom_init_machtype(void);
+extern void __init prom_init_env(void);
+#ifdef CONFIG_LOONGSON_UART_BASE
+extern unsigned long _loongson_uart_base[], loongson_uart_base[];
+extern void prom_init_loongson_uart_base(void);
+#endif
+
+static inline void prom_init_uart_base(void)
+{
+#ifdef CONFIG_LOONGSON_UART_BASE
+       prom_init_loongson_uart_base();
+#endif
+}
+
+/* irq operation functions */
+extern void bonito_irqdispatch(void);
+extern void __init bonito_irq_init(void);
+extern void __init mach_init_irq(void);
+extern void mach_irq_dispatch(unsigned int pending);
+extern int mach_i8259_irq(void);
+
+/* We need this in some places... */
+#define delay() ({             \
+       int x;                          \
+       for (x = 0; x < 100000; x++)    \
+               __asm__ __volatile__(""); \
+})
+
+#define LOONGSON_REG(x) \
+       (*(volatile u32 *)((char *)CKSEG1ADDR(LOONGSON_REG_BASE) + (x)))
+
+#define LOONGSON3_REG8(base, x) \
+       (*(volatile u8 *)((char *)TO_UNCAC(base) + (x)))
+
+#define LOONGSON3_REG32(base, x) \
+       (*(volatile u32 *)((char *)TO_UNCAC(base) + (x)))
+
+#define LOONGSON_IRQ_BASE      32
+#define LOONGSON2_PERFCNT_IRQ  (MIPS_CPU_IRQ_BASE + 6) /* cpu perf counter */
+
+#include <linux/interrupt.h>
+static inline void do_perfcnt_IRQ(void)
+{
+#if IS_ENABLED(CONFIG_OPROFILE)
+       do_IRQ(LOONGSON2_PERFCNT_IRQ);
+#endif
+}
+
+#define LOONGSON_FLASH_BASE    0x1c000000
+#define LOONGSON_FLASH_SIZE    0x02000000      /* 32M */
+#define LOONGSON_FLASH_TOP     (LOONGSON_FLASH_BASE+LOONGSON_FLASH_SIZE-1)
+
+#define LOONGSON_LIO0_BASE     0x1e000000
+#define LOONGSON_LIO0_SIZE     0x01C00000      /* 28M */
+#define LOONGSON_LIO0_TOP      (LOONGSON_LIO0_BASE+LOONGSON_LIO0_SIZE-1)
+
+#define LOONGSON_BOOT_BASE     0x1fc00000
+#define LOONGSON_BOOT_SIZE     0x00100000      /* 1M */
+#define LOONGSON_BOOT_TOP      (LOONGSON_BOOT_BASE+LOONGSON_BOOT_SIZE-1)
+#define LOONGSON_REG_BASE      0x1fe00000
+#define LOONGSON_REG_SIZE      0x00100000      /* 256Bytes + 256Bytes + ??? */
+#define LOONGSON_REG_TOP       (LOONGSON_REG_BASE+LOONGSON_REG_SIZE-1)
+/* Loongson-3 specific registers */
+#define LOONGSON3_REG_BASE     0x3ff00000
+#define LOONGSON3_REG_SIZE     0x00100000      /* 256Bytes + 256Bytes + ??? */
+#define LOONGSON3_REG_TOP      (LOONGSON3_REG_BASE+LOONGSON3_REG_SIZE-1)
+
+#define LOONGSON_LIO1_BASE     0x1ff00000
+#define LOONGSON_LIO1_SIZE     0x00100000      /* 1M */
+#define LOONGSON_LIO1_TOP      (LOONGSON_LIO1_BASE+LOONGSON_LIO1_SIZE-1)
+
+#define LOONGSON_PCILO0_BASE   0x10000000
+#define LOONGSON_PCILO1_BASE   0x14000000
+#define LOONGSON_PCILO2_BASE   0x18000000
+#define LOONGSON_PCILO_BASE    LOONGSON_PCILO0_BASE
+#define LOONGSON_PCILO_SIZE    0x0c000000      /* 64M * 3 */
+#define LOONGSON_PCILO_TOP     (LOONGSON_PCILO0_BASE+LOONGSON_PCILO_SIZE-1)
+
+#define LOONGSON_PCICFG_BASE   0x1fe80000
+#define LOONGSON_PCICFG_SIZE   0x00000800      /* 2K */
+#define LOONGSON_PCICFG_TOP    (LOONGSON_PCICFG_BASE+LOONGSON_PCICFG_SIZE-1)
+
+#ifdef CONFIG_CPU_LOONGSON64
+#define LOONGSON_PCIIO_BASE    loongson_sysconf.pci_io_base
+#else
+#define LOONGSON_PCIIO_BASE    0x1fd00000
+#endif
+
+#define LOONGSON_PCIIO_SIZE    0x00100000      /* 1M */
+#define LOONGSON_PCIIO_TOP     (LOONGSON_PCIIO_BASE+LOONGSON_PCIIO_SIZE-1)
+
+/* Loongson Register Bases */
+
+#define LOONGSON_PCICONFIGBASE 0x00
+#define LOONGSON_REGBASE       0x100
+
+/* PCI Configuration Registers */
+
+#define LOONGSON_PCI_REG(x)    LOONGSON_REG(LOONGSON_PCICONFIGBASE + (x))
+#define LOONGSON_PCIDID                LOONGSON_PCI_REG(0x00)
+#define LOONGSON_PCICMD                LOONGSON_PCI_REG(0x04)
+#define LOONGSON_PCICLASS      LOONGSON_PCI_REG(0x08)
+#define LOONGSON_PCILTIMER     LOONGSON_PCI_REG(0x0c)
+#define LOONGSON_PCIBASE0      LOONGSON_PCI_REG(0x10)
+#define LOONGSON_PCIBASE1      LOONGSON_PCI_REG(0x14)
+#define LOONGSON_PCIBASE2      LOONGSON_PCI_REG(0x18)
+#define LOONGSON_PCIBASE3      LOONGSON_PCI_REG(0x1c)
+#define LOONGSON_PCIBASE4      LOONGSON_PCI_REG(0x20)
+#define LOONGSON_PCIEXPRBASE   LOONGSON_PCI_REG(0x30)
+#define LOONGSON_PCIINT                LOONGSON_PCI_REG(0x3c)
+
+#define LOONGSON_PCI_ISR4C     LOONGSON_PCI_REG(0x4c)
+
+#define LOONGSON_PCICMD_PERR_CLR       0x80000000
+#define LOONGSON_PCICMD_SERR_CLR       0x40000000
+#define LOONGSON_PCICMD_MABORT_CLR     0x20000000
+#define LOONGSON_PCICMD_MTABORT_CLR    0x10000000
+#define LOONGSON_PCICMD_TABORT_CLR     0x08000000
+#define LOONGSON_PCICMD_MPERR_CLR      0x01000000
+#define LOONGSON_PCICMD_PERRRESPEN     0x00000040
+#define LOONGSON_PCICMD_ASTEPEN                0x00000080
+#define LOONGSON_PCICMD_SERREN         0x00000100
+#define LOONGSON_PCILTIMER_BUSLATENCY  0x0000ff00
+#define LOONGSON_PCILTIMER_BUSLATENCY_SHIFT    8
+
+/* Loongson h/w Configuration */
+
+#define LOONGSON_GENCFG_OFFSET         0x4
+#define LOONGSON_GENCFG LOONGSON_REG(LOONGSON_REGBASE + LOONGSON_GENCFG_OFFSET)
+
+#define LOONGSON_GENCFG_DEBUGMODE      0x00000001
+#define LOONGSON_GENCFG_SNOOPEN                0x00000002
+#define LOONGSON_GENCFG_CPUSELFRESET   0x00000004
+
+#define LOONGSON_GENCFG_FORCE_IRQA     0x00000008
+#define LOONGSON_GENCFG_IRQA_ISOUT     0x00000010
+#define LOONGSON_GENCFG_IRQA_FROM_INT1 0x00000020
+#define LOONGSON_GENCFG_BYTESWAP       0x00000040
+
+#define LOONGSON_GENCFG_UNCACHED       0x00000080
+#define LOONGSON_GENCFG_PREFETCHEN     0x00000100
+#define LOONGSON_GENCFG_WBEHINDEN      0x00000200
+#define LOONGSON_GENCFG_CACHEALG       0x00000c00
+#define LOONGSON_GENCFG_CACHEALG_SHIFT 10
+#define LOONGSON_GENCFG_PCIQUEUE       0x00001000
+#define LOONGSON_GENCFG_CACHESTOP      0x00002000
+#define LOONGSON_GENCFG_MSTRBYTESWAP   0x00004000
+#define LOONGSON_GENCFG_BUSERREN       0x00008000
+#define LOONGSON_GENCFG_NORETRYTIMEOUT 0x00010000
+#define LOONGSON_GENCFG_SHORTCOPYTIMEOUT       0x00020000
+
+/* PCI address map control */
+
+#define LOONGSON_PCIMAP                        LOONGSON_REG(LOONGSON_REGBASE + 0x10)
+#define LOONGSON_PCIMEMBASECFG         LOONGSON_REG(LOONGSON_REGBASE + 0x14)
+#define LOONGSON_PCIMAP_CFG            LOONGSON_REG(LOONGSON_REGBASE + 0x18)
+
+/* GPIO Regs - r/w */
+
+#define LOONGSON_GPIODATA              LOONGSON_REG(LOONGSON_REGBASE + 0x1c)
+#define LOONGSON_GPIOIE                        LOONGSON_REG(LOONGSON_REGBASE + 0x20)
+
+/* ICU Configuration Regs - r/w */
+
+#define LOONGSON_INTEDGE               LOONGSON_REG(LOONGSON_REGBASE + 0x24)
+#define LOONGSON_INTSTEER              LOONGSON_REG(LOONGSON_REGBASE + 0x28)
+#define LOONGSON_INTPOL                        LOONGSON_REG(LOONGSON_REGBASE + 0x2c)
+
+/* ICU Enable Regs - IntEn & IntISR are r/o. */
+
+#define LOONGSON_INTENSET              LOONGSON_REG(LOONGSON_REGBASE + 0x30)
+#define LOONGSON_INTENCLR              LOONGSON_REG(LOONGSON_REGBASE + 0x34)
+#define LOONGSON_INTEN                 LOONGSON_REG(LOONGSON_REGBASE + 0x38)
+#define LOONGSON_INTISR                        LOONGSON_REG(LOONGSON_REGBASE + 0x3c)
+
+/* ICU */
+#define LOONGSON_ICU_MBOXES            0x0000000f
+#define LOONGSON_ICU_MBOXES_SHIFT      0
+#define LOONGSON_ICU_DMARDY            0x00000010
+#define LOONGSON_ICU_DMAEMPTY          0x00000020
+#define LOONGSON_ICU_COPYRDY           0x00000040
+#define LOONGSON_ICU_COPYEMPTY         0x00000080
+#define LOONGSON_ICU_COPYERR           0x00000100
+#define LOONGSON_ICU_PCIIRQ            0x00000200
+#define LOONGSON_ICU_MASTERERR         0x00000400
+#define LOONGSON_ICU_SYSTEMERR         0x00000800
+#define LOONGSON_ICU_DRAMPERR          0x00001000
+#define LOONGSON_ICU_RETRYERR          0x00002000
+#define LOONGSON_ICU_GPIOS             0x01ff0000
+#define LOONGSON_ICU_GPIOS_SHIFT               16
+#define LOONGSON_ICU_GPINS             0x7e000000
+#define LOONGSON_ICU_GPINS_SHIFT               25
+#define LOONGSON_ICU_MBOX(N)           (1<<(LOONGSON_ICU_MBOXES_SHIFT+(N)))
+#define LOONGSON_ICU_GPIO(N)           (1<<(LOONGSON_ICU_GPIOS_SHIFT+(N)))
+#define LOONGSON_ICU_GPIN(N)           (1<<(LOONGSON_ICU_GPINS_SHIFT+(N)))
+
+/* PCI prefetch window base & mask */
+
+#define LOONGSON_MEM_WIN_BASE_L                LOONGSON_REG(LOONGSON_REGBASE + 0x40)
+#define LOONGSON_MEM_WIN_BASE_H                LOONGSON_REG(LOONGSON_REGBASE + 0x44)
+#define LOONGSON_MEM_WIN_MASK_L                LOONGSON_REG(LOONGSON_REGBASE + 0x48)
+#define LOONGSON_MEM_WIN_MASK_H                LOONGSON_REG(LOONGSON_REGBASE + 0x4c)
+
+/* PCI_Hit*_Sel_* */
+
+#define LOONGSON_PCI_HIT0_SEL_L                LOONGSON_REG(LOONGSON_REGBASE + 0x50)
+#define LOONGSON_PCI_HIT0_SEL_H                LOONGSON_REG(LOONGSON_REGBASE + 0x54)
+#define LOONGSON_PCI_HIT1_SEL_L                LOONGSON_REG(LOONGSON_REGBASE + 0x58)
+#define LOONGSON_PCI_HIT1_SEL_H                LOONGSON_REG(LOONGSON_REGBASE + 0x5c)
+#define LOONGSON_PCI_HIT2_SEL_L                LOONGSON_REG(LOONGSON_REGBASE + 0x60)
+#define LOONGSON_PCI_HIT2_SEL_H                LOONGSON_REG(LOONGSON_REGBASE + 0x64)
+
+/* PXArb Config & Status */
+
+#define LOONGSON_PXARB_CFG             LOONGSON_REG(LOONGSON_REGBASE + 0x68)
+#define LOONGSON_PXARB_STATUS          LOONGSON_REG(LOONGSON_REGBASE + 0x6c)
+
+#define MAX_PACKAGES 4
+
+/* Chip Config registor of each physical cpu package, PRid >= Loongson-2F */
+extern u64 loongson_chipcfg[MAX_PACKAGES];
+#define LOONGSON_CHIPCFG(id) (*(volatile u32 *)(loongson_chipcfg[id]))
+
+/* Chip Temperature registor of each physical cpu package, PRid >= Loongson-3A */
+extern u64 loongson_chiptemp[MAX_PACKAGES];
+#define LOONGSON_CHIPTEMP(id) (*(volatile u32 *)(loongson_chiptemp[id]))
+
+/* Freq Control register of each physical cpu package, PRid >= Loongson-3B */
+extern u64 loongson_freqctrl[MAX_PACKAGES];
+#define LOONGSON_FREQCTRL(id) (*(volatile u32 *)(loongson_freqctrl[id]))
+
+/* pcimap */
+
+#define LOONGSON_PCIMAP_PCIMAP_LO0     0x0000003f
+#define LOONGSON_PCIMAP_PCIMAP_LO0_SHIFT       0
+#define LOONGSON_PCIMAP_PCIMAP_LO1     0x00000fc0
+#define LOONGSON_PCIMAP_PCIMAP_LO1_SHIFT       6
+#define LOONGSON_PCIMAP_PCIMAP_LO2     0x0003f000
+#define LOONGSON_PCIMAP_PCIMAP_LO2_SHIFT       12
+#define LOONGSON_PCIMAP_PCIMAP_2       0x00040000
+#define LOONGSON_PCIMAP_WIN(WIN, ADDR) \
+       ((((ADDR)>>26) & LOONGSON_PCIMAP_PCIMAP_LO0) << ((WIN)*6))
+
+#ifdef CONFIG_CPU_SUPPORTS_CPUFREQ
+#include <linux/cpufreq.h>
+extern struct cpufreq_frequency_table loongson2_clockmod_table[];
+#endif
+
+/*
+ * address windows configuration module
+ *
+ * loongson2e do not have this module
+ */
+#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
+
+/* address window config module base address */
+#define LOONGSON_ADDRWINCFG_BASE               0x3ff00000ul
+#define LOONGSON_ADDRWINCFG_SIZE               0x180
+
+extern unsigned long _loongson_addrwincfg_base;
+#define LOONGSON_ADDRWINCFG(offset) \
+       (*(volatile u64 *)(_loongson_addrwincfg_base + (offset)))
+
+#define CPU_WIN0_BASE  LOONGSON_ADDRWINCFG(0x00)
+#define CPU_WIN1_BASE  LOONGSON_ADDRWINCFG(0x08)
+#define CPU_WIN2_BASE  LOONGSON_ADDRWINCFG(0x10)
+#define CPU_WIN3_BASE  LOONGSON_ADDRWINCFG(0x18)
+
+#define CPU_WIN0_MASK  LOONGSON_ADDRWINCFG(0x20)
+#define CPU_WIN1_MASK  LOONGSON_ADDRWINCFG(0x28)
+#define CPU_WIN2_MASK  LOONGSON_ADDRWINCFG(0x30)
+#define CPU_WIN3_MASK  LOONGSON_ADDRWINCFG(0x38)
+
+#define CPU_WIN0_MMAP  LOONGSON_ADDRWINCFG(0x40)
+#define CPU_WIN1_MMAP  LOONGSON_ADDRWINCFG(0x48)
+#define CPU_WIN2_MMAP  LOONGSON_ADDRWINCFG(0x50)
+#define CPU_WIN3_MMAP  LOONGSON_ADDRWINCFG(0x58)
+
+#define PCIDMA_WIN0_BASE       LOONGSON_ADDRWINCFG(0x60)
+#define PCIDMA_WIN1_BASE       LOONGSON_ADDRWINCFG(0x68)
+#define PCIDMA_WIN2_BASE       LOONGSON_ADDRWINCFG(0x70)
+#define PCIDMA_WIN3_BASE       LOONGSON_ADDRWINCFG(0x78)
+
+#define PCIDMA_WIN0_MASK       LOONGSON_ADDRWINCFG(0x80)
+#define PCIDMA_WIN1_MASK       LOONGSON_ADDRWINCFG(0x88)
+#define PCIDMA_WIN2_MASK       LOONGSON_ADDRWINCFG(0x90)
+#define PCIDMA_WIN3_MASK       LOONGSON_ADDRWINCFG(0x98)
+
+#define PCIDMA_WIN0_MMAP       LOONGSON_ADDRWINCFG(0xa0)
+#define PCIDMA_WIN1_MMAP       LOONGSON_ADDRWINCFG(0xa8)
+#define PCIDMA_WIN2_MMAP       LOONGSON_ADDRWINCFG(0xb0)
+#define PCIDMA_WIN3_MMAP       LOONGSON_ADDRWINCFG(0xb8)
+
+#define ADDRWIN_WIN0   0
+#define ADDRWIN_WIN1   1
+#define ADDRWIN_WIN2   2
+#define ADDRWIN_WIN3   3
+
+#define ADDRWIN_MAP_DST_DDR    0
+#define ADDRWIN_MAP_DST_PCI    1
+#define ADDRWIN_MAP_DST_LIO    1
+
+/*
+ * s: CPU, PCIDMA
+ * d: DDR, PCI, LIO
+ * win: 0, 1, 2, 3
+ * src: map source
+ * dst: map destination
+ * size: ~mask + 1
+ */
+#define LOONGSON_ADDRWIN_CFG(s, d, w, src, dst, size) do {\
+       s##_WIN##w##_BASE = (src); \
+       s##_WIN##w##_MMAP = (dst) | ADDRWIN_MAP_DST_##d; \
+       s##_WIN##w##_MASK = ~(size-1); \
+} while (0)
+
+#define LOONGSON_ADDRWIN_CPUTOPCI(win, src, dst, size) \
+       LOONGSON_ADDRWIN_CFG(CPU, PCI, win, src, dst, size)
+#define LOONGSON_ADDRWIN_CPUTODDR(win, src, dst, size) \
+       LOONGSON_ADDRWIN_CFG(CPU, DDR, win, src, dst, size)
+#define LOONGSON_ADDRWIN_PCITODDR(win, src, dst, size) \
+       LOONGSON_ADDRWIN_CFG(PCIDMA, DDR, win, src, dst, size)
+
+#endif /* ! CONFIG_CPU_SUPPORTS_ADDRWINCFG */
+
+#endif /* __ASM_MACH_LOONGSON64_LOONGSON_H */
diff --git a/arch/mips/include/asm/mach-loongson2ef/loongson_hwmon.h b/arch/mips/include/asm/mach-loongson2ef/loongson_hwmon.h
new file mode 100644 (file)
index 0000000..545f91f
--- /dev/null
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __LOONGSON_HWMON_H_
+#define __LOONGSON_HWMON_H_
+
+#include <linux/types.h>
+
+#define MIN_TEMP       0
+#define MAX_TEMP       255
+#define NOT_VALID_TEMP 999
+
+typedef int (*get_temp_fun)(int);
+extern int loongson3_cpu_temp(int);
+
+/* 0:Max speed, 1:Manual, 2:Auto */
+enum fan_control_mode {
+       FAN_FULL_MODE = 0,
+       FAN_MANUAL_MODE = 1,
+       FAN_AUTO_MODE = 2,
+       FAN_MODE_END
+};
+
+struct temp_range {
+       u8 low;
+       u8 high;
+       u8 level;
+};
+
+#define CONSTANT_SPEED_POLICY  0  /* at constant speed */
+#define STEP_SPEED_POLICY      1  /* use up/down arrays to describe policy */
+#define KERNEL_HELPER_POLICY   2  /* kernel as a helper to fan control */
+
+#define MAX_STEP_NUM   16
+#define MAX_FAN_LEVEL  255
+
+/* loongson_fan_policy works when fan work at FAN_AUTO_MODE */
+struct loongson_fan_policy {
+       u8      type;
+
+       /* percent only used when type is CONSTANT_SPEED_POLICY */
+       u8      percent;
+
+       /* period between two check. (Unit: S) */
+       u8      adjust_period;
+
+       /* fan adjust usually depend on a temprature input */
+       get_temp_fun    depend_temp;
+
+       /* up_step/down_step used when type is STEP_SPEED_POLICY */
+       u8      up_step_num;
+       u8      down_step_num;
+       struct temp_range up_step[MAX_STEP_NUM];
+       struct temp_range down_step[MAX_STEP_NUM];
+       struct delayed_work work;
+};
+
+#endif /* __LOONGSON_HWMON_H_*/
diff --git a/arch/mips/include/asm/mach-loongson2ef/loongson_regs.h b/arch/mips/include/asm/mach-loongson2ef/loongson_regs.h
new file mode 100644 (file)
index 0000000..363a47a
--- /dev/null
@@ -0,0 +1,227 @@
+/*
+ * Read/Write Loongson Extension Registers
+ */
+
+#ifndef _LOONGSON_REGS_H_
+#define _LOONGSON_REGS_H_
+
+#include <linux/types.h>
+#include <linux/bits.h>
+
+#include <asm/mipsregs.h>
+#include <asm/cpu.h>
+
+static inline bool cpu_has_cfg(void)
+{
+       return ((read_c0_prid() & PRID_IMP_MASK) == PRID_IMP_LOONGSON_64G);
+}
+
+static inline u32 read_cpucfg(u32 reg)
+{
+       u32 __res;
+
+       __asm__ __volatile__(
+               "parse_r __res,%0\n\t"
+               "parse_r reg,%1\n\t"
+               ".insn \n\t"
+               ".word (0xc8080118 | (reg << 21) | (__res << 11))\n\t"
+               :"=r"(__res)
+               :"r"(reg)
+               :
+               );
+       return __res;
+}
+
+/* Bit Domains for CFG registers */
+#define LOONGSON_CFG0  0x0
+#define LOONGSON_CFG0_PRID GENMASK(31, 0)
+
+#define LOONGSON_CFG1 0x1
+#define LOONGSON_CFG1_FP       BIT(0)
+#define LOONGSON_CFG1_FPREV    GENMASK(3, 1)
+#define LOONGSON_CFG1_MMI      BIT(4)
+#define LOONGSON_CFG1_MSA1     BIT(5)
+#define LOONGSON_CFG1_MSA2     BIT(6)
+#define LOONGSON_CFG1_CGP      BIT(7)
+#define LOONGSON_CFG1_WRP      BIT(8)
+#define LOONGSON_CFG1_LSX1     BIT(9)
+#define LOONGSON_CFG1_LSX2     BIT(10)
+#define LOONGSON_CFG1_LASX     BIT(11)
+#define LOONGSON_CFG1_R6FXP    BIT(12)
+#define LOONGSON_CFG1_R6CRCP   BIT(13)
+#define LOONGSON_CFG1_R6FPP    BIT(14)
+#define LOONGSON_CFG1_CNT64    BIT(15)
+#define LOONGSON_CFG1_LSLDR0   BIT(16)
+#define LOONGSON_CFG1_LSPREF   BIT(17)
+#define LOONGSON_CFG1_LSPREFX  BIT(18)
+#define LOONGSON_CFG1_LSSYNCI  BIT(19)
+#define LOONGSON_CFG1_LSUCA    BIT(20)
+#define LOONGSON_CFG1_LLSYNC   BIT(21)
+#define LOONGSON_CFG1_TGTSYNC  BIT(22)
+#define LOONGSON_CFG1_LLEXC    BIT(23)
+#define LOONGSON_CFG1_SCRAND   BIT(24)
+#define LOONGSON_CFG1_MUALP    BIT(25)
+#define LOONGSON_CFG1_KMUALEN  BIT(26)
+#define LOONGSON_CFG1_ITLBT    BIT(27)
+#define LOONGSON_CFG1_LSUPERF  BIT(28)
+#define LOONGSON_CFG1_SFBP     BIT(29)
+#define LOONGSON_CFG1_CDMAP    BIT(30)
+
+#define LOONGSON_CFG2 0x2
+#define LOONGSON_CFG2_LEXT1    BIT(0)
+#define LOONGSON_CFG2_LEXT2    BIT(1)
+#define LOONGSON_CFG2_LEXT3    BIT(2)
+#define LOONGSON_CFG2_LSPW     BIT(3)
+#define LOONGSON_CFG2_LBT1     BIT(4)
+#define LOONGSON_CFG2_LBT2     BIT(5)
+#define LOONGSON_CFG2_LBT3     BIT(6)
+#define LOONGSON_CFG2_LBTMMU   BIT(7)
+#define LOONGSON_CFG2_LPMP     BIT(8)
+#define LOONGSON_CFG2_LPMPREV  GENMASK(11, 9)
+#define LOONGSON_CFG2_LAMO     BIT(12)
+#define LOONGSON_CFG2_LPIXU    BIT(13)
+#define LOONGSON_CFG2_LPIXUN   BIT(14)
+#define LOONGSON_CFG2_LZVP     BIT(15)
+#define LOONGSON_CFG2_LZVREV   GENMASK(18, 16)
+#define LOONGSON_CFG2_LGFTP    BIT(19)
+#define LOONGSON_CFG2_LGFTPREV GENMASK(22, 20)
+#define LOONGSON_CFG2_LLFTP    BIT(23)
+#define LOONGSON_CFG2_LLFTPREV GENMASK(26, 24)
+#define LOONGSON_CFG2_LCSRP    BIT(27)
+#define LOONGSON_CFG2_LDISBLIKELY      BIT(28)
+
+#define LOONGSON_CFG3 0x3
+#define LOONGSON_CFG3_LCAMP    BIT(0)
+#define LOONGSON_CFG3_LCAMREV  GENMASK(3, 1)
+#define LOONGSON_CFG3_LCAMNUM  GENMASK(11, 4)
+#define LOONGSON_CFG3_LCAMKW   GENMASK(19, 12)
+#define LOONGSON_CFG3_LCAMVW   GENMASK(27, 20)
+
+#define LOONGSON_CFG4 0x4
+#define LOONGSON_CFG4_CCFREQ   GENMASK(31, 0)
+
+#define LOONGSON_CFG5 0x5
+#define LOONGSON_CFG5_CFM      GENMASK(15, 0)
+#define LOONGSON_CFG5_CFD      GENMASK(31, 16)
+
+#define LOONGSON_CFG6 0x6
+
+#define LOONGSON_CFG7 0x7
+#define LOONGSON_CFG7_GCCAEQRP BIT(0)
+#define LOONGSON_CFG7_UCAWINP  BIT(1)
+
+static inline bool cpu_has_csr(void)
+{
+       if (cpu_has_cfg())
+               return (read_cpucfg(LOONGSON_CFG2) & LOONGSON_CFG2_LCSRP);
+
+       return false;
+}
+
+static inline u32 csr_readl(u32 reg)
+{
+       u32 __res;
+
+       /* RDCSR reg, val */
+       __asm__ __volatile__(
+               "parse_r __res,%0\n\t"
+               "parse_r reg,%1\n\t"
+               ".insn \n\t"
+               ".word (0xc8000118 | (reg << 21) | (__res << 11))\n\t"
+               :"=r"(__res)
+               :"r"(reg)
+               :
+               );
+       return __res;
+}
+
+static inline u64 csr_readq(u32 reg)
+{
+       u64 __res;
+
+       /* DWRCSR reg, val */
+       __asm__ __volatile__(
+               "parse_r __res,%0\n\t"
+               "parse_r reg,%1\n\t"
+               ".insn \n\t"
+               ".word (0xc8020118 | (reg << 21) | (__res << 11))\n\t"
+               :"=r"(__res)
+               :"r"(reg)
+               :
+               );
+       return __res;
+}
+
+static inline void csr_writel(u32 val, u32 reg)
+{
+       /* WRCSR reg, val */
+       __asm__ __volatile__(
+               "parse_r reg,%0\n\t"
+               "parse_r val,%1\n\t"
+               ".insn \n\t"
+               ".word (0xc8010118 | (reg << 21) | (val << 11))\n\t"
+               :
+               :"r"(reg),"r"(val)
+               :
+               );
+}
+
+static inline void csr_writeq(u64 val, u32 reg)
+{
+       /* DWRCSR reg, val */
+       __asm__ __volatile__(
+               "parse_r reg,%0\n\t"
+               "parse_r val,%1\n\t"
+               ".insn \n\t"
+               ".word (0xc8030118 | (reg << 21) | (val << 11))\n\t"
+               :
+               :"r"(reg),"r"(val)
+               :
+               );
+}
+
+/* Public CSR Register can also be accessed with regular addresses */
+#define CSR_PUBLIC_MMIO_BASE 0x1fe00000
+
+#define MMIO_CSR(x)            (void *)TO_UNCAC(CSR_PUBLIC_MMIO_BASE + x)
+
+#define LOONGSON_CSR_FEATURES  0x8
+#define LOONGSON_CSRF_TEMP     BIT(0)
+#define LOONGSON_CSRF_NODECNT  BIT(1)
+#define LOONGSON_CSRF_MSI      BIT(2)
+#define LOONGSON_CSRF_EXTIOI   BIT(3)
+#define LOONGSON_CSRF_IPI      BIT(4)
+#define LOONGSON_CSRF_FREQ     BIT(5)
+
+#define LOONGSON_CSR_VENDOR    0x10 /* Vendor name string, should be "Loongson" */
+#define LOONGSON_CSR_CPUNAME   0x20 /* Processor name string */
+#define LOONGSON_CSR_NODECNT   0x408
+#define LOONGSON_CSR_CPUTEMP   0x428
+
+/* PerCore CSR, only accessable by local cores */
+#define LOONGSON_CSR_IPI_STATUS        0x1000
+#define LOONGSON_CSR_IPI_EN    0x1004
+#define LOONGSON_CSR_IPI_SET   0x1008
+#define LOONGSON_CSR_IPI_CLEAR 0x100c
+#define LOONGSON_CSR_IPI_SEND  0x1040
+#define CSR_IPI_SEND_IP_SHIFT  0
+#define CSR_IPI_SEND_CPU_SHIFT 16
+#define CSR_IPI_SEND_BLOCK     BIT(31)
+
+static inline u64 drdtime(void)
+{
+       int rID = 0;
+       u64 val = 0;
+
+       __asm__ __volatile__(
+               "parse_r rID,%0\n\t"
+               "parse_r val,%1\n\t"
+               ".insn \n\t"
+               ".word (0xc8090118 | (rID << 21) | (val << 11))\n\t"
+               :"=r"(rID),"=r"(val)
+               :
+               );
+       return val;
+}
+
+#endif
diff --git a/arch/mips/include/asm/mach-loongson2ef/machine.h b/arch/mips/include/asm/mach-loongson2ef/machine.h
new file mode 100644 (file)
index 0000000..8ef7ea9
--- /dev/null
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Wu Zhangjin <wuzhangjin@gmail.com>
+ */
+
+#ifndef __ASM_MACH_LOONGSON64_MACHINE_H
+#define __ASM_MACH_LOONGSON64_MACHINE_H
+
+#ifdef CONFIG_LEMOTE_FULOONG2E
+
+#define LOONGSON_MACHTYPE MACH_LEMOTE_FL2E
+
+#endif
+
+/* use fuloong2f as the default machine of LEMOTE_MACH2F */
+#ifdef CONFIG_LEMOTE_MACH2F
+
+#define LOONGSON_MACHTYPE MACH_LEMOTE_FL2F
+
+#endif
+
+#ifdef CONFIG_LOONGSON_MACH3X
+
+#define LOONGSON_MACHTYPE MACH_LOONGSON_GENERIC
+
+#endif /* CONFIG_LOONGSON_MACH3X */
+
+#endif /* __ASM_MACH_LOONGSON64_MACHINE_H */
diff --git a/arch/mips/include/asm/mach-loongson2ef/mc146818rtc.h b/arch/mips/include/asm/mach-loongson2ef/mc146818rtc.h
new file mode 100644 (file)
index 0000000..ebdccfe
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1998, 2001, 03, 07 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ * RTC routines for PC style attached Dallas chip.
+ */
+#ifndef __ASM_MACH_LOONGSON64_MC146818RTC_H
+#define __ASM_MACH_LOONGSON64_MC146818RTC_H
+
+#include <linux/io.h>
+
+#define RTC_PORT(x)    (0x70 + (x))
+#define RTC_IRQ                8
+
+static inline unsigned char CMOS_READ(unsigned long addr)
+{
+       outb_p(addr, RTC_PORT(0));
+       return inb_p(RTC_PORT(1));
+}
+
+static inline void CMOS_WRITE(unsigned char data, unsigned long addr)
+{
+       outb_p(addr, RTC_PORT(0));
+       outb_p(data, RTC_PORT(1));
+}
+
+#define RTC_ALWAYS_BCD 0
+
+#ifndef mc146818_decode_year
+#define mc146818_decode_year(year) ((year) < 70 ? (year) + 2000 : (year) + 1970)
+#endif
+
+#endif /* __ASM_MACH_LOONGSON64_MC146818RTC_H */
diff --git a/arch/mips/include/asm/mach-loongson2ef/mem.h b/arch/mips/include/asm/mach-loongson2ef/mem.h
new file mode 100644 (file)
index 0000000..ce33c17
--- /dev/null
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Wu Zhangjin <wuzhangjin@gmail.com>
+ */
+
+#ifndef __ASM_MACH_LOONGSON64_MEM_H
+#define __ASM_MACH_LOONGSON64_MEM_H
+
+/*
+ * high memory space
+ *
+ * in loongson2e, starts from 512M
+ * in loongson2f, starts from 2G 256M
+ */
+#ifdef CONFIG_CPU_LOONGSON2E
+#define LOONGSON_HIGHMEM_START 0x20000000
+#else
+#define LOONGSON_HIGHMEM_START 0x90000000
+#endif
+
+/*
+ * the peripheral registers(MMIO):
+ *
+ * On the Lemote Loongson 2e system, reside between 0x1000:0000 and 0x2000:0000.
+ * On the Lemote Loongson 2f system, reside between 0x1000:0000 and 0x8000:0000.
+ */
+
+#define LOONGSON_MMIO_MEM_START 0x10000000
+
+#ifdef CONFIG_CPU_LOONGSON2E
+#define LOONGSON_MMIO_MEM_END  0x20000000
+#else
+#define LOONGSON_MMIO_MEM_END  0x80000000
+#endif
+
+#endif /* __ASM_MACH_LOONGSON64_MEM_H */
diff --git a/arch/mips/include/asm/mach-loongson2ef/mmzone.h b/arch/mips/include/asm/mach-loongson2ef/mmzone.h
new file mode 100644 (file)
index 0000000..62073d6
--- /dev/null
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2010 Loongson Inc. & Lemote Inc. &
+ *                    Institute of Computing Technology
+ * Author:  Xiang Gao, gaoxiang@ict.ac.cn
+ *          Huacai Chen, chenhc@lemote.com
+ *          Xiaofu Meng, Shuangshuang Zhang
+ */
+#ifndef _ASM_MACH_MMZONE_H
+#define _ASM_MACH_MMZONE_H
+
+#include <boot_param.h>
+#define NODE_ADDRSPACE_SHIFT 44
+#define NODE0_ADDRSPACE_OFFSET 0x000000000000UL
+#define NODE1_ADDRSPACE_OFFSET 0x100000000000UL
+#define NODE2_ADDRSPACE_OFFSET 0x200000000000UL
+#define NODE3_ADDRSPACE_OFFSET 0x300000000000UL
+
+#define pa_to_nid(addr)  (((addr) & 0xf00000000000) >> NODE_ADDRSPACE_SHIFT)
+#define nid_to_addrbase(nid) ((nid) << NODE_ADDRSPACE_SHIFT)
+
+#define LEVELS_PER_SLICE 128
+
+struct slice_data {
+       unsigned long irq_enable_mask[2];
+       int level_to_irq[LEVELS_PER_SLICE];
+};
+
+struct hub_data {
+       cpumask_t       h_cpus;
+       unsigned long slice_map;
+       unsigned long irq_alloc_mask[2];
+       struct slice_data slice[2];
+};
+
+struct node_data {
+       struct pglist_data pglist;
+       struct hub_data hub;
+       cpumask_t cpumask;
+};
+
+extern struct node_data *__node_data[];
+
+#define NODE_DATA(n)           (&__node_data[(n)]->pglist)
+#define hub_data(n)            (&__node_data[(n)]->hub)
+
+extern void setup_zero_pages(void);
+extern void __init prom_init_numa_memory(void);
+
+#endif /* _ASM_MACH_MMZONE_H */
diff --git a/arch/mips/include/asm/mach-loongson2ef/pci.h b/arch/mips/include/asm/mach-loongson2ef/pci.h
new file mode 100644 (file)
index 0000000..05cc905
--- /dev/null
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2008 Zhang Le <r0bertz@gentoo.org>
+ * Copyright (c) 2009 Wu Zhangjin <wuzhangjin@gmail.com>
+ */
+
+#ifndef __ASM_MACH_LOONGSON64_PCI_H_
+#define __ASM_MACH_LOONGSON64_PCI_H_
+
+extern struct pci_ops loongson_pci_ops;
+
+/* this is an offset from mips_io_port_base */
+#define LOONGSON_PCI_IO_START  0x00004000UL
+
+#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
+
+/*
+ * we use address window2 to map cpu address space to pci space
+ * window2: cpu [1G, 2G] -> pci [1G, 2G]
+ * why not use window 0 & 1? because they are used by cpu when booting.
+ * window0: cpu [0, 256M] -> ddr [0, 256M]
+ * window1: cpu [256M, 512M] -> pci [256M, 512M]
+ */
+
+/* the smallest LOONGSON_CPU_MEM_SRC can be 512M */
+#define LOONGSON_CPU_MEM_SRC   0x40000000ul            /* 1G */
+#define LOONGSON_PCI_MEM_DST   LOONGSON_CPU_MEM_SRC
+
+#define LOONGSON_PCI_MEM_START LOONGSON_PCI_MEM_DST
+#define LOONGSON_PCI_MEM_END   (0x80000000ul-1)        /* 2G */
+
+#define MMAP_CPUTOPCI_SIZE     (LOONGSON_PCI_MEM_END - \
+                                       LOONGSON_PCI_MEM_START + 1)
+
+#else  /* loongson2f/32bit & loongson2e */
+
+/* this pci memory space is mapped by pcimap in pci.c */
+#ifdef CONFIG_CPU_LOONGSON64
+#define LOONGSON_PCI_MEM_START 0x40000000UL
+#define LOONGSON_PCI_MEM_END   0x7effffffUL
+#else
+#define LOONGSON_PCI_MEM_START LOONGSON_PCILO1_BASE
+#define LOONGSON_PCI_MEM_END   (LOONGSON_PCILO1_BASE + 0x04000000 * 2)
+#endif
+/* this is an offset from mips_io_port_base */
+#define LOONGSON_PCI_IO_START  0x00004000UL
+
+#endif /* !CONFIG_CPU_SUPPORTS_ADDRWINCFG */
+
+#endif /* !__ASM_MACH_LOONGSON64_PCI_H_ */
diff --git a/arch/mips/include/asm/mach-loongson2ef/spaces.h b/arch/mips/include/asm/mach-loongson2ef/spaces.h
new file mode 100644 (file)
index 0000000..e85bc1d
--- /dev/null
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_MACH_LOONGSON64_SPACES_H_
+#define __ASM_MACH_LOONGSON64_SPACES_H_
+
+#if defined(CONFIG_64BIT)
+#define CAC_BASE        _AC(0x9800000000000000, UL)
+#endif /* CONFIG_64BIT */
+
+#include <asm/mach-generic/spaces.h>
+#endif
diff --git a/arch/mips/include/asm/mach-loongson2ef/topology.h b/arch/mips/include/asm/mach-loongson2ef/topology.h
new file mode 100644 (file)
index 0000000..7ff819a
--- /dev/null
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_MACH_TOPOLOGY_H
+#define _ASM_MACH_TOPOLOGY_H
+
+#ifdef CONFIG_NUMA
+
+#define cpu_to_node(cpu)       (cpu_logical_map(cpu) >> 2)
+#define cpumask_of_node(node)  (&__node_data[(node)]->cpumask)
+
+struct pci_bus;
+extern int pcibus_to_node(struct pci_bus *);
+
+#define cpumask_of_pcibus(bus) (cpu_online_mask)
+
+extern unsigned char __node_distances[MAX_NUMNODES][MAX_NUMNODES];
+
+#define node_distance(from, to)        (__node_distances[(from)][(to)])
+
+#endif
+
+#include <asm-generic/topology.h>
+
+#endif /* _ASM_MACH_TOPOLOGY_H */
diff --git a/arch/mips/include/asm/mach-loongson2ef/workarounds.h b/arch/mips/include/asm/mach-loongson2ef/workarounds.h
new file mode 100644 (file)
index 0000000..17b7117
--- /dev/null
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_MACH_LOONGSON64_WORKAROUNDS_H_
+#define __ASM_MACH_LOONGSON64_WORKAROUNDS_H_
+
+#define WORKAROUND_CPUFREQ     0x00000001
+#define WORKAROUND_CPUHOTPLUG  0x00000002
+
+#endif
diff --git a/arch/mips/loongson2ef/Kconfig b/arch/mips/loongson2ef/Kconfig
new file mode 100644 (file)
index 0000000..007bd02
--- /dev/null
@@ -0,0 +1,96 @@
+# SPDX-License-Identifier: GPL-2.0
+if MACH_LOONGSON2EF
+
+choice
+       prompt "Machine Type"
+
+config LEMOTE_FULOONG2E
+       bool "Lemote Fuloong(2e) mini-PC"
+       select ARCH_SPARSEMEM_ENABLE
+       select ARCH_MIGHT_HAVE_PC_PARPORT
+       select ARCH_MIGHT_HAVE_PC_SERIO
+       select CEVT_R4K
+       select CSRC_R4K
+       select SYS_HAS_CPU_LOONGSON2E
+       select DMA_NONCOHERENT
+       select BOOT_ELF32
+       select BOARD_SCACHE
+       select FORCE_PCI
+       select I8259
+       select ISA
+       select IRQ_MIPS_CPU
+       select SYS_SUPPORTS_64BIT_KERNEL
+       select SYS_SUPPORTS_LITTLE_ENDIAN
+       select SYS_SUPPORTS_HIGHMEM
+       select SYS_HAS_EARLY_PRINTK
+       select GENERIC_ISA_DMA_SUPPORT_BROKEN
+       select CPU_HAS_WB
+       select LOONGSON_MC146818
+       help
+         Lemote Fuloong(2e) mini-PC board based on the Chinese Loongson-2E CPU and
+         an FPGA northbridge
+
+         Lemote Fuloong(2e) mini PC have a VIA686B south bridge.
+
+config LEMOTE_MACH2F
+       bool "Lemote Loongson 2F family machines"
+       select ARCH_SPARSEMEM_ENABLE
+       select ARCH_MIGHT_HAVE_PC_PARPORT
+       select ARCH_MIGHT_HAVE_PC_SERIO
+       select BOARD_SCACHE
+       select BOOT_ELF32
+       select CEVT_R4K if ! MIPS_EXTERNAL_TIMER
+       select CPU_HAS_WB
+       select CS5536
+       select CSRC_R4K if ! MIPS_EXTERNAL_TIMER
+       select DMA_NONCOHERENT
+       select GENERIC_ISA_DMA_SUPPORT_BROKEN
+       select HAVE_CLK
+       select FORCE_PCI
+       select I8259
+       select IRQ_MIPS_CPU
+       select ISA
+       select SYS_HAS_CPU_LOONGSON2F
+       select SYS_HAS_EARLY_PRINTK
+       select SYS_SUPPORTS_64BIT_KERNEL
+       select SYS_SUPPORTS_HIGHMEM
+       select SYS_SUPPORTS_LITTLE_ENDIAN
+       select LOONGSON_MC146818
+       help
+         Lemote Loongson 2F family machines utilize the 2F revision of
+         Loongson processor and the AMD CS5536 south bridge.
+
+         These family machines include fuloong2f mini PC, yeeloong2f notebook,
+         LingLoong allinone PC and so forth.
+
+endchoice
+
+config CS5536
+       bool
+
+config CS5536_MFGPT
+       bool "CS5536 MFGPT Timer"
+       depends on CS5536 && !HIGH_RES_TIMERS
+       select MIPS_EXTERNAL_TIMER
+       help
+         This option enables the mfgpt0 timer of AMD CS5536. With this timer
+         switched on you can not use high resolution timers.
+
+         If you want to enable the Loongson2 CPUFreq Driver, Please enable
+         this option at first, otherwise, You will get wrong system time.
+
+         If unsure, say Yes.
+
+config LOONGSON_UART_BASE
+       bool
+       default y
+       depends on EARLY_PRINTK || SERIAL_8250
+
+config LOONGSON_MC146818
+       bool
+       default n
+
+config LEFI_FIRMWARE_INTERFACE
+       bool
+
+endif # MACH_LOONGSON2EF
diff --git a/arch/mips/loongson2ef/Makefile b/arch/mips/loongson2ef/Makefile
new file mode 100644 (file)
index 0000000..d4af160
--- /dev/null
@@ -0,0 +1,18 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Common code for all Loongson based systems
+#
+
+obj-$(CONFIG_MACH_LOONGSON2EF) += common/
+
+#
+# Lemote Fuloong mini-PC (Loongson 2E-based)
+#
+
+obj-$(CONFIG_LEMOTE_FULOONG2E) += fuloong-2e/
+
+#
+# Lemote loongson2f family machines
+#
+
+obj-$(CONFIG_LEMOTE_MACH2F)  += lemote-2f/
diff --git a/arch/mips/loongson2ef/Platform b/arch/mips/loongson2ef/Platform
new file mode 100644 (file)
index 0000000..3aca429
--- /dev/null
@@ -0,0 +1,32 @@
+#
+# Loongson Processors' Support
+#
+
+# Only gcc >= 4.4 have Loongson specific support
+cflags-$(CONFIG_CPU_LOONGSON2EF)       += -Wa,--trap
+cflags-$(CONFIG_CPU_LOONGSON2E) += \
+       $(call cc-option,-march=loongson2e,-march=r4600)
+cflags-$(CONFIG_CPU_LOONGSON2F) += \
+       $(call cc-option,-march=loongson2f,-march=r4600)
+# Enable the workarounds for Loongson2f
+ifdef CONFIG_CPU_LOONGSON2F_WORKAROUNDS
+  ifeq ($(call as-option,-Wa$(comma)-mfix-loongson2f-nop,),)
+    $(error only binutils >= 2.20.2 have needed option -mfix-loongson2f-nop)
+  else
+    cflags-$(CONFIG_CPU_NOP_WORKAROUNDS) += -Wa$(comma)-mfix-loongson2f-nop
+  endif
+  ifeq ($(call as-option,-Wa$(comma)-mfix-loongson2f-jump,),)
+    $(error only binutils >= 2.20.2 have needed option -mfix-loongson2f-jump)
+  else
+    cflags-$(CONFIG_CPU_JUMP_WORKAROUNDS) += -Wa$(comma)-mfix-loongson2f-jump
+  endif
+endif
+
+#
+# Loongson Machines' Support
+#
+
+platform-$(CONFIG_MACH_LOONGSON2EF) += loongson2ef/
+cflags-$(CONFIG_MACH_LOONGSON2EF) += -I$(srctree)/arch/mips/include/asm/mach-loongson2ef -mno-branch-likely
+load-$(CONFIG_LEMOTE_FULOONG2E) += 0xffffffff80100000
+load-$(CONFIG_LEMOTE_MACH2F) += 0xffffffff80200000
diff --git a/arch/mips/loongson2ef/common/Makefile b/arch/mips/loongson2ef/common/Makefile
new file mode 100644 (file)
index 0000000..684624f
--- /dev/null
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for loongson based machines.
+#
+
+obj-y += setup.o init.o cmdline.o env.o time.o reset.o irq.o \
+    bonito-irq.o mem.o machtype.o platform.o serial.o
+obj-$(CONFIG_PCI) += pci.o
+
+#
+# Serial port support
+#
+obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
+obj-$(CONFIG_LOONGSON_UART_BASE) += uart_base.o
+obj-$(CONFIG_LOONGSON_MC146818) += rtc.o
+
+#
+# Enable CS5536 Virtual Support Module(VSM) to virtulize the PCI configure
+# space
+#
+obj-$(CONFIG_CS5536) += cs5536/
+
+#
+# Suspend Support
+#
+
+obj-$(CONFIG_SUSPEND) += pm.o
diff --git a/arch/mips/loongson2ef/common/bonito-irq.c b/arch/mips/loongson2ef/common/bonito-irq.c
new file mode 100644 (file)
index 0000000..82352cc
--- /dev/null
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org)
+ *
+ * Copyright (C) 2007 Lemote Inc. & Institute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ */
+#include <linux/interrupt.h>
+#include <linux/compiler.h>
+
+#include <loongson.h>
+
+static inline void bonito_irq_enable(struct irq_data *d)
+{
+       LOONGSON_INTENSET = (1 << (d->irq - LOONGSON_IRQ_BASE));
+       mmiowb();
+}
+
+static inline void bonito_irq_disable(struct irq_data *d)
+{
+       LOONGSON_INTENCLR = (1 << (d->irq - LOONGSON_IRQ_BASE));
+       mmiowb();
+}
+
+static struct irq_chip bonito_irq_type = {
+       .name           = "bonito_irq",
+       .irq_mask       = bonito_irq_disable,
+       .irq_unmask     = bonito_irq_enable,
+};
+
+static struct irqaction __maybe_unused dma_timeout_irqaction = {
+       .handler        = no_action,
+       .name           = "dma_timeout",
+};
+
+void bonito_irq_init(void)
+{
+       u32 i;
+
+       for (i = LOONGSON_IRQ_BASE; i < LOONGSON_IRQ_BASE + 32; i++)
+               irq_set_chip_and_handler(i, &bonito_irq_type,
+                                        handle_level_irq);
+
+#ifdef CONFIG_CPU_LOONGSON2E
+       setup_irq(LOONGSON_IRQ_BASE + 10, &dma_timeout_irqaction);
+#endif
+}
diff --git a/arch/mips/loongson2ef/common/cmdline.c b/arch/mips/loongson2ef/common/cmdline.c
new file mode 100644 (file)
index 0000000..a735460
--- /dev/null
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Based on Ocelot Linux port, which is
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * Copyright 2003 ICT CAS
+ * Author: Michael Guo <guoyi@ict.ac.cn>
+ *
+ * Copyright (C) 2007 Lemote Inc. & Institute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ *
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin, wuzhangjin@gmail.com
+ */
+#include <asm/bootinfo.h>
+
+#include <loongson.h>
+
+void __init prom_init_cmdline(void)
+{
+       int prom_argc;
+       /* pmon passes arguments in 32bit pointers */
+       int *_prom_argv;
+       int i;
+       long l;
+
+       /* firmware arguments are initialized in head.S */
+       prom_argc = fw_arg0;
+       _prom_argv = (int *)fw_arg1;
+
+       /* arg[0] is "g", the rest is boot parameters */
+       arcs_cmdline[0] = '\0';
+       for (i = 1; i < prom_argc; i++) {
+               l = (long)_prom_argv[i];
+               if (strlen(arcs_cmdline) + strlen(((char *)l) + 1)
+                   >= sizeof(arcs_cmdline))
+                       break;
+               strcat(arcs_cmdline, ((char *)l));
+               strcat(arcs_cmdline, " ");
+       }
+
+       prom_init_machtype();
+}
diff --git a/arch/mips/loongson2ef/common/cs5536/Makefile b/arch/mips/loongson2ef/common/cs5536/Makefile
new file mode 100644 (file)
index 0000000..b32b296
--- /dev/null
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# 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/loongson2ef/common/cs5536/cs5536_acc.c b/arch/mips/loongson2ef/common/cs5536/cs5536_acc.c
new file mode 100644 (file)
index 0000000..ff50aae
--- /dev/null
@@ -0,0 +1,136 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * 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
+ */
+
+#include <cs5536/cs5536.h>
+#include <cs5536/cs5536_pci.h>
+
+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/loongson2ef/common/cs5536/cs5536_ehci.c b/arch/mips/loongson2ef/common/cs5536/cs5536_ehci.c
new file mode 100644 (file)
index 0000000..bd4c39f
--- /dev/null
@@ -0,0 +1,156 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * 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
+ */
+
+#include <cs5536/cs5536.h>
+#include <cs5536/cs5536_pci.h>
+
+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/loongson2ef/common/cs5536/cs5536_ide.c b/arch/mips/loongson2ef/common/cs5536/cs5536_ide.c
new file mode 100644 (file)
index 0000000..bb93329
--- /dev/null
@@ -0,0 +1,188 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * 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
+ */
+
+#include <cs5536/cs5536.h>
+#include <cs5536/cs5536_pci.h>
+
+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/loongson2ef/common/cs5536/cs5536_isa.c b/arch/mips/loongson2ef/common/cs5536/cs5536_isa.c
new file mode 100644 (file)
index 0000000..5ad38f8
--- /dev/null
@@ -0,0 +1,326 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * 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
+ */
+
+#include <linux/pci.h>
+#include <cs5536/cs5536.h>
+#include <cs5536/cs5536_pci.h>
+
+/* 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/loongson2ef/common/cs5536/cs5536_mfgpt.c b/arch/mips/loongson2ef/common/cs5536/cs5536_mfgpt.c
new file mode 100644 (file)
index 0000000..30af1b7
--- /dev/null
@@ -0,0 +1,207 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * CS5536 General timer functions
+ *
+ * Copyright (C) 2007 Lemote Inc. & Institute 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
+ */
+
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/export.h>
+#include <linux/jiffies.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/clockchips.h>
+
+#include <asm/time.h>
+
+#include <cs5536/cs5536_mfgpt.h>
+
+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 int mfgpt_timer_set_periodic(struct clock_event_device *evt)
+{
+       raw_spin_lock(&mfgpt_lock);
+
+       outw(COMPARE, MFGPT0_CMP2);     /* set comparator2 */
+       outw(0, MFGPT0_CNT);            /* set counter to 0 */
+       enable_mfgpt0_counter();
+
+       raw_spin_unlock(&mfgpt_lock);
+       return 0;
+}
+
+static int mfgpt_timer_shutdown(struct clock_event_device *evt)
+{
+       if (clockevent_state_periodic(evt) || clockevent_state_oneshot(evt)) {
+               raw_spin_lock(&mfgpt_lock);
+               disable_mfgpt0_counter();
+               raw_spin_unlock(&mfgpt_lock);
+       }
+
+       return 0;
+}
+
+static struct clock_event_device mfgpt_clockevent = {
+       .name = "mfgpt",
+       .features = CLOCK_EVT_FEAT_PERIODIC,
+
+       /* The oneshot mode have very high deviation, don't use it! */
+       .set_state_shutdown = mfgpt_timer_shutdown,
+       .set_state_periodic = mfgpt_timer_set_periodic,
+       .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->max_delta_ticks = 0xffff;
+       cd->min_delta_ns = clockevent_delta2ns(0xf, cd);
+       cd->min_delta_ticks = 0xf;
+
+       /* 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 u64 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 (u64) (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/loongson2ef/common/cs5536/cs5536_ohci.c b/arch/mips/loongson2ef/common/cs5536/cs5536_ohci.c
new file mode 100644 (file)
index 0000000..71a52b1
--- /dev/null
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * 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
+ */
+
+#include <cs5536/cs5536.h>
+#include <cs5536/cs5536_pci.h>
+
+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 >> PIC_YSEL_LOW_USB_SHIFT) & 0xf) == CS5536_USB_INTR)
+                       conf_data = 1;
+               break;
+       default:
+               break;
+       }
+
+       return conf_data;
+}
diff --git a/arch/mips/loongson2ef/common/cs5536/cs5536_pci.c b/arch/mips/loongson2ef/common/cs5536/cs5536_pci.c
new file mode 100644 (file)
index 0000000..202c89b
--- /dev/null
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * 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
+ *
+ *     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 <linux/types.h>
+#include <cs5536/cs5536_pci.h>
+#include <cs5536/cs5536_vsm.h>
+
+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/loongson2ef/common/early_printk.c b/arch/mips/loongson2ef/common/early_printk.c
new file mode 100644 (file)
index 0000000..5e2a151
--- /dev/null
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*  early printk support
+ *
+ *  Copyright (c) 2009 Philippe Vachon <philippe@cowpig.ca>
+ *  Copyright (c) 2009 Lemote Inc.
+ *  Author: Wu Zhangjin, wuzhangjin@gmail.com
+ */
+#include <linux/serial_reg.h>
+#include <asm/setup.h>
+
+#include <loongson.h>
+
+#define PORT(base, offset) (u8 *)(base + offset)
+
+static inline unsigned int serial_in(unsigned char *base, int offset)
+{
+       return readb(PORT(base, offset));
+}
+
+static inline void serial_out(unsigned char *base, int offset, int value)
+{
+       writeb(value, PORT(base, offset));
+}
+
+void prom_putchar(char c)
+{
+       int timeout;
+       unsigned char *uart_base;
+
+       uart_base = (unsigned char *)_loongson_uart_base[0];
+       timeout = 1024;
+
+       while (((serial_in(uart_base, UART_LSR) & UART_LSR_THRE) == 0) &&
+                       (timeout-- > 0))
+               ;
+
+       serial_out(uart_base, UART_TX, c);
+}
diff --git a/arch/mips/loongson2ef/common/env.c b/arch/mips/loongson2ef/common/env.c
new file mode 100644 (file)
index 0000000..09d5cf4
--- /dev/null
@@ -0,0 +1,212 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Based on Ocelot Linux port, which is
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * Copyright 2003 ICT CAS
+ * Author: Michael Guo <guoyi@ict.ac.cn>
+ *
+ * Copyright (C) 2007 Lemote Inc. & Institute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ *
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin, wuzhangjin@gmail.com
+ */
+#include <linux/export.h>
+#include <asm/bootinfo.h>
+#include <loongson.h>
+#include <boot_param.h>
+#include <workarounds.h>
+
+u32 cpu_clock_freq;
+EXPORT_SYMBOL(cpu_clock_freq);
+struct efi_memory_map_loongson *loongson_memmap;
+struct loongson_system_configuration loongson_sysconf;
+
+u64 loongson_chipcfg[MAX_PACKAGES] = {0xffffffffbfc00180};
+u64 loongson_chiptemp[MAX_PACKAGES];
+u64 loongson_freqctrl[MAX_PACKAGES];
+
+unsigned long long smp_group[4];
+
+#define parse_even_earlier(res, option, p)                             \
+do {                                                                   \
+       unsigned int tmp __maybe_unused;                                \
+                                                                       \
+       if (strncmp(option, (char *)p, strlen(option)) == 0)            \
+               tmp = kstrtou32((char *)p + strlen(option"="), 10, &res); \
+} while (0)
+
+void __init prom_init_env(void)
+{
+       /* pmon passes arguments in 32bit pointers */
+       unsigned int processor_id;
+
+#ifndef CONFIG_LEFI_FIRMWARE_INTERFACE
+       int *_prom_envp;
+       long l;
+
+       /* firmware arguments are initialized in head.S */
+       _prom_envp = (int *)fw_arg2;
+
+       l = (long)*_prom_envp;
+       while (l != 0) {
+               parse_even_earlier(cpu_clock_freq, "cpuclock", l);
+               parse_even_earlier(memsize, "memsize", l);
+               parse_even_earlier(highmemsize, "highmemsize", l);
+               _prom_envp++;
+               l = (long)*_prom_envp;
+       }
+       if (memsize == 0)
+               memsize = 256;
+
+       loongson_sysconf.nr_uarts = 1;
+
+       pr_info("memsize=%u, highmemsize=%u\n", memsize, highmemsize);
+#else
+       struct boot_params *boot_p;
+       struct loongson_params *loongson_p;
+       struct system_loongson *esys;
+       struct efi_cpuinfo_loongson *ecpu;
+       struct irq_source_routing_table *eirq_source;
+
+       /* firmware arguments are initialized in head.S */
+       boot_p = (struct boot_params *)fw_arg2;
+       loongson_p = &(boot_p->efi.smbios.lp);
+
+       esys = (struct system_loongson *)
+               ((u64)loongson_p + loongson_p->system_offset);
+       ecpu = (struct efi_cpuinfo_loongson *)
+               ((u64)loongson_p + loongson_p->cpu_offset);
+       eirq_source = (struct irq_source_routing_table *)
+               ((u64)loongson_p + loongson_p->irq_offset);
+       loongson_memmap = (struct efi_memory_map_loongson *)
+               ((u64)loongson_p + loongson_p->memory_offset);
+
+       cpu_clock_freq = ecpu->cpu_clock_freq;
+       loongson_sysconf.cputype = ecpu->cputype;
+       switch (ecpu->cputype) {
+       case Legacy_3A:
+       case Loongson_3A:
+               loongson_sysconf.cores_per_node = 4;
+               loongson_sysconf.cores_per_package = 4;
+               smp_group[0] = 0x900000003ff01000;
+               smp_group[1] = 0x900010003ff01000;
+               smp_group[2] = 0x900020003ff01000;
+               smp_group[3] = 0x900030003ff01000;
+               loongson_chipcfg[0] = 0x900000001fe00180;
+               loongson_chipcfg[1] = 0x900010001fe00180;
+               loongson_chipcfg[2] = 0x900020001fe00180;
+               loongson_chipcfg[3] = 0x900030001fe00180;
+               loongson_chiptemp[0] = 0x900000001fe0019c;
+               loongson_chiptemp[1] = 0x900010001fe0019c;
+               loongson_chiptemp[2] = 0x900020001fe0019c;
+               loongson_chiptemp[3] = 0x900030001fe0019c;
+               loongson_freqctrl[0] = 0x900000001fe001d0;
+               loongson_freqctrl[1] = 0x900010001fe001d0;
+               loongson_freqctrl[2] = 0x900020001fe001d0;
+               loongson_freqctrl[3] = 0x900030001fe001d0;
+               loongson_sysconf.ht_control_base = 0x90000EFDFB000000;
+               loongson_sysconf.workarounds = WORKAROUND_CPUFREQ;
+               break;
+       case Legacy_3B:
+       case Loongson_3B:
+               loongson_sysconf.cores_per_node = 4; /* One chip has 2 nodes */
+               loongson_sysconf.cores_per_package = 8;
+               smp_group[0] = 0x900000003ff01000;
+               smp_group[1] = 0x900010003ff05000;
+               smp_group[2] = 0x900020003ff09000;
+               smp_group[3] = 0x900030003ff0d000;
+               loongson_chipcfg[0] = 0x900000001fe00180;
+               loongson_chipcfg[1] = 0x900020001fe00180;
+               loongson_chipcfg[2] = 0x900040001fe00180;
+               loongson_chipcfg[3] = 0x900060001fe00180;
+               loongson_chiptemp[0] = 0x900000001fe0019c;
+               loongson_chiptemp[1] = 0x900020001fe0019c;
+               loongson_chiptemp[2] = 0x900040001fe0019c;
+               loongson_chiptemp[3] = 0x900060001fe0019c;
+               loongson_freqctrl[0] = 0x900000001fe001d0;
+               loongson_freqctrl[1] = 0x900020001fe001d0;
+               loongson_freqctrl[2] = 0x900040001fe001d0;
+               loongson_freqctrl[3] = 0x900060001fe001d0;
+               loongson_sysconf.ht_control_base = 0x90001EFDFB000000;
+               loongson_sysconf.workarounds = WORKAROUND_CPUHOTPLUG;
+               break;
+       default:
+               loongson_sysconf.cores_per_node = 1;
+               loongson_sysconf.cores_per_package = 1;
+               loongson_chipcfg[0] = 0x900000001fe00180;
+       }
+
+       loongson_sysconf.nr_cpus = ecpu->nr_cpus;
+       loongson_sysconf.boot_cpu_id = ecpu->cpu_startup_core_id;
+       loongson_sysconf.reserved_cpus_mask = ecpu->reserved_cores_mask;
+       if (ecpu->nr_cpus > NR_CPUS || ecpu->nr_cpus == 0)
+               loongson_sysconf.nr_cpus = NR_CPUS;
+       loongson_sysconf.nr_nodes = (loongson_sysconf.nr_cpus +
+               loongson_sysconf.cores_per_node - 1) /
+               loongson_sysconf.cores_per_node;
+
+       loongson_sysconf.pci_mem_start_addr = eirq_source->pci_mem_start_addr;
+       loongson_sysconf.pci_mem_end_addr = eirq_source->pci_mem_end_addr;
+       loongson_sysconf.pci_io_base = eirq_source->pci_io_start_addr;
+       loongson_sysconf.dma_mask_bits = eirq_source->dma_mask_bits;
+       if (loongson_sysconf.dma_mask_bits < 32 ||
+               loongson_sysconf.dma_mask_bits > 64)
+               loongson_sysconf.dma_mask_bits = 32;
+
+       loongson_sysconf.restart_addr = boot_p->reset_system.ResetWarm;
+       loongson_sysconf.poweroff_addr = boot_p->reset_system.Shutdown;
+       loongson_sysconf.suspend_addr = boot_p->reset_system.DoSuspend;
+
+       loongson_sysconf.vgabios_addr = boot_p->efi.smbios.vga_bios;
+       pr_debug("Shutdown Addr: %llx, Restart Addr: %llx, VBIOS Addr: %llx\n",
+               loongson_sysconf.poweroff_addr, loongson_sysconf.restart_addr,
+               loongson_sysconf.vgabios_addr);
+
+       memset(loongson_sysconf.ecname, 0, 32);
+       if (esys->has_ec)
+               memcpy(loongson_sysconf.ecname, esys->ec_name, 32);
+       loongson_sysconf.workarounds |= esys->workarounds;
+
+       loongson_sysconf.nr_uarts = esys->nr_uarts;
+       if (esys->nr_uarts < 1 || esys->nr_uarts > MAX_UARTS)
+               loongson_sysconf.nr_uarts = 1;
+       memcpy(loongson_sysconf.uarts, esys->uarts,
+               sizeof(struct uart_device) * loongson_sysconf.nr_uarts);
+
+       loongson_sysconf.nr_sensors = esys->nr_sensors;
+       if (loongson_sysconf.nr_sensors > MAX_SENSORS)
+               loongson_sysconf.nr_sensors = 0;
+       if (loongson_sysconf.nr_sensors)
+               memcpy(loongson_sysconf.sensors, esys->sensors,
+                       sizeof(struct sensor_device) * loongson_sysconf.nr_sensors);
+#endif
+       if (cpu_clock_freq == 0) {
+               processor_id = (&current_cpu_data)->processor_id;
+               switch (processor_id & PRID_REV_MASK) {
+               case PRID_REV_LOONGSON2E:
+                       cpu_clock_freq = 533080000;
+                       break;
+               case PRID_REV_LOONGSON2F:
+                       cpu_clock_freq = 797000000;
+                       break;
+               case PRID_REV_LOONGSON3A_R1:
+               case PRID_REV_LOONGSON3A_R2_0:
+               case PRID_REV_LOONGSON3A_R2_1:
+               case PRID_REV_LOONGSON3A_R3_0:
+               case PRID_REV_LOONGSON3A_R3_1:
+                       cpu_clock_freq = 900000000;
+                       break;
+               case PRID_REV_LOONGSON3B_R1:
+               case PRID_REV_LOONGSON3B_R2:
+                       cpu_clock_freq = 1000000000;
+                       break;
+               default:
+                       cpu_clock_freq = 100000000;
+                       break;
+               }
+       }
+       pr_info("CpuClock = %u\n", cpu_clock_freq);
+}
diff --git a/arch/mips/loongson2ef/common/init.c b/arch/mips/loongson2ef/common/init.c
new file mode 100644 (file)
index 0000000..912fe61
--- /dev/null
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin, wuzhangjin@gmail.com
+ */
+
+#include <linux/memblock.h>
+#include <asm/bootinfo.h>
+#include <asm/traps.h>
+#include <asm/smp-ops.h>
+#include <asm/cacheflush.h>
+
+#include <loongson.h>
+
+/* Loongson CPU address windows config space base address */
+unsigned long __maybe_unused _loongson_addrwincfg_base;
+
+static void __init mips_nmi_setup(void)
+{
+       void *base;
+       extern char except_vec_nmi;
+
+       base = (void *)(CAC_BASE + 0x380);
+       memcpy(base, &except_vec_nmi, 0x80);
+       flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
+}
+
+void __init prom_init(void)
+{
+#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
+       _loongson_addrwincfg_base = (unsigned long)
+               ioremap(LOONGSON_ADDRWINCFG_BASE, LOONGSON_ADDRWINCFG_SIZE);
+#endif
+
+       prom_init_cmdline();
+       prom_init_env();
+
+       /* init base address of io space */
+       set_io_port_base((unsigned long)
+               ioremap(LOONGSON_PCIIO_BASE, LOONGSON_PCIIO_SIZE));
+
+#ifdef CONFIG_NUMA
+       prom_init_numa_memory();
+#else
+       prom_init_memory();
+#endif
+
+       /*init the uart base address */
+       prom_init_uart_base();
+       register_smp_ops(&loongson3_smp_ops);
+       board_nmi_handler_setup = mips_nmi_setup;
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
diff --git a/arch/mips/loongson2ef/common/irq.c b/arch/mips/loongson2ef/common/irq.c
new file mode 100644 (file)
index 0000000..0ea93c1
--- /dev/null
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2007 Lemote Inc. & Institute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ */
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+
+#include <loongson.h>
+/*
+ * the first level int-handler will jump here if it is a bonito irq
+ */
+void bonito_irqdispatch(void)
+{
+       u32 int_status;
+       int i;
+
+       /* workaround the IO dma problem: let cpu looping to allow DMA finish */
+       int_status = LOONGSON_INTISR;
+       while (int_status & (1 << 10)) {
+               udelay(1);
+               int_status = LOONGSON_INTISR;
+       }
+
+       /* Get pending sources, masked by current enables */
+       int_status = LOONGSON_INTISR & LOONGSON_INTEN;
+
+       if (int_status) {
+               i = __ffs(int_status);
+               do_IRQ(LOONGSON_IRQ_BASE + i);
+       }
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+       unsigned int pending;
+
+       pending = read_c0_cause() & read_c0_status() & ST0_IM;
+
+       /* machine-specific plat_irq_dispatch */
+       mach_irq_dispatch(pending);
+}
+
+void __init arch_init_irq(void)
+{
+       /*
+        * Clear all of the interrupts while we change the able around a bit.
+        * int-handler is not on bootstrap
+        */
+       clear_c0_status(ST0_IM | ST0_BEV);
+
+       /* no steer */
+       LOONGSON_INTSTEER = 0;
+
+       /*
+        * Mask out all interrupt by writing "1" to all bit position in
+        * the interrupt reset reg.
+        */
+       LOONGSON_INTENCLR = ~0;
+
+       /* machine specific irq init */
+       mach_init_irq();
+}
diff --git a/arch/mips/loongson2ef/common/machtype.c b/arch/mips/loongson2ef/common/machtype.c
new file mode 100644 (file)
index 0000000..4e42d92
--- /dev/null
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin, wuzhangjin@gmail.com
+ *
+ * Copyright (c) 2009 Zhang Le <r0bertz@gentoo.org>
+ */
+#include <linux/errno.h>
+#include <asm/bootinfo.h>
+
+#include <loongson.h>
+#include <machine.h>
+
+/* please ensure the length of the machtype string is less than 50 */
+#define MACHTYPE_LEN 50
+
+static const char *system_types[] = {
+       [MACH_LOONGSON_UNKNOWN] = "unknown loongson machine",
+       [MACH_LEMOTE_FL2E]      = "lemote-fuloong-2e-box",
+       [MACH_LEMOTE_FL2F]      = "lemote-fuloong-2f-box",
+       [MACH_LEMOTE_ML2F7]     = "lemote-mengloong-2f-7inches",
+       [MACH_LEMOTE_YL2F89]    = "lemote-yeeloong-2f-8.9inches",
+       [MACH_DEXXON_GDIUM2F10] = "dexxon-gdium-2f",
+       [MACH_LEMOTE_NAS]       = "lemote-nas-2f",
+       [MACH_LEMOTE_LL2F]      = "lemote-lynloong-2f",
+       [MACH_LOONGSON_GENERIC] = "generic-loongson-machine",
+       [MACH_LOONGSON_END]     = NULL,
+};
+
+const char *get_system_type(void)
+{
+       return system_types[mips_machtype];
+}
+
+void __weak __init mach_prom_init_machtype(void)
+{
+}
+
+void __init prom_init_machtype(void)
+{
+       char *p, str[MACHTYPE_LEN + 1];
+       int machtype = MACH_LEMOTE_FL2E;
+
+       mips_machtype = LOONGSON_MACHTYPE;
+
+       p = strstr(arcs_cmdline, "machtype=");
+       if (!p) {
+               mach_prom_init_machtype();
+               return;
+       }
+       p += strlen("machtype=");
+       strncpy(str, p, MACHTYPE_LEN);
+       str[MACHTYPE_LEN] = '\0';
+       p = strstr(str, " ");
+       if (p)
+               *p = '\0';
+
+       for (; system_types[machtype]; machtype++)
+               if (strstr(system_types[machtype], str)) {
+                       mips_machtype = machtype;
+                       break;
+               }
+}
diff --git a/arch/mips/loongson2ef/common/mem.c b/arch/mips/loongson2ef/common/mem.c
new file mode 100644 (file)
index 0000000..4254ac4
--- /dev/null
@@ -0,0 +1,157 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ */
+#include <linux/fs.h>
+#include <linux/fcntl.h>
+#include <linux/memblock.h>
+#include <linux/mm.h>
+
+#include <asm/bootinfo.h>
+
+#include <loongson.h>
+#include <boot_param.h>
+#include <mem.h>
+#include <pci.h>
+
+#ifndef CONFIG_LEFI_FIRMWARE_INTERFACE
+
+u32 memsize, highmemsize;
+
+void __init prom_init_memory(void)
+{
+       add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM);
+
+       add_memory_region(memsize << 20, LOONGSON_PCI_MEM_START - (memsize <<
+                               20), BOOT_MEM_RESERVED);
+
+#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
+       {
+               int bit;
+
+               bit = fls(memsize + highmemsize);
+               if (bit != ffs(memsize + highmemsize))
+                       bit += 20;
+               else
+                       bit = bit + 20 - 1;
+
+               /* set cpu window3 to map CPU to DDR: 2G -> 2G */
+               LOONGSON_ADDRWIN_CPUTODDR(ADDRWIN_WIN3, 0x80000000ul,
+                                         0x80000000ul, (1 << bit));
+               mmiowb();
+       }
+#endif /* !CONFIG_CPU_SUPPORTS_ADDRWINCFG */
+
+#ifdef CONFIG_64BIT
+       if (highmemsize > 0)
+               add_memory_region(LOONGSON_HIGHMEM_START,
+                                 highmemsize << 20, BOOT_MEM_RAM);
+
+       add_memory_region(LOONGSON_PCI_MEM_END + 1, LOONGSON_HIGHMEM_START -
+                         LOONGSON_PCI_MEM_END - 1, BOOT_MEM_RESERVED);
+
+#endif /* !CONFIG_64BIT */
+}
+
+#else /* CONFIG_LEFI_FIRMWARE_INTERFACE */
+
+void __init prom_init_memory(void)
+{
+       int i;
+       u32 node_id;
+       u32 mem_type;
+
+       /* parse memory information */
+       for (i = 0; i < loongson_memmap->nr_map; i++) {
+               node_id = loongson_memmap->map[i].node_id;
+               mem_type = loongson_memmap->map[i].mem_type;
+
+               if (node_id != 0)
+                       continue;
+
+               switch (mem_type) {
+               case SYSTEM_RAM_LOW:
+                       memblock_add(loongson_memmap->map[i].mem_start,
+                               (u64)loongson_memmap->map[i].mem_size << 20);
+                       break;
+               case SYSTEM_RAM_HIGH:
+                       memblock_add(loongson_memmap->map[i].mem_start,
+                               (u64)loongson_memmap->map[i].mem_size << 20);
+                       break;
+               case SYSTEM_RAM_RESERVED:
+                       memblock_reserve(loongson_memmap->map[i].mem_start,
+                               (u64)loongson_memmap->map[i].mem_size << 20);
+                       break;
+               }
+       }
+}
+
+#endif /* CONFIG_LEFI_FIRMWARE_INTERFACE */
+
+/* override of arch/mips/mm/cache.c: __uncached_access */
+int __uncached_access(struct file *file, unsigned long addr)
+{
+       if (file->f_flags & O_DSYNC)
+               return 1;
+
+       return addr >= __pa(high_memory) ||
+               ((addr >= LOONGSON_MMIO_MEM_START) &&
+                (addr < LOONGSON_MMIO_MEM_END));
+}
+
+#ifdef CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED
+
+#include <linux/pci.h>
+#include <linux/sched.h>
+#include <asm/current.h>
+
+static unsigned long uca_start, uca_end;
+
+pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
+                             unsigned long size, pgprot_t vma_prot)
+{
+       unsigned long offset = pfn << PAGE_SHIFT;
+       unsigned long end = offset + size;
+
+       if (__uncached_access(file, offset)) {
+               if (uca_start && (offset >= uca_start) &&
+                   (end <= uca_end))
+                       return __pgprot((pgprot_val(vma_prot) &
+                                        ~_CACHE_MASK) |
+                                       _CACHE_UNCACHED_ACCELERATED);
+               else
+                       return pgprot_noncached(vma_prot);
+       }
+       return vma_prot;
+}
+
+static int __init find_vga_mem_init(void)
+{
+       struct pci_dev *dev = 0;
+       struct resource *r;
+       int idx;
+
+       if (uca_start)
+               return 0;
+
+       for_each_pci_dev(dev) {
+               if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
+                       for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) {
+                               r = &dev->resource[idx];
+                               if (!r->start && r->end)
+                                       continue;
+                               if (r->flags & IORESOURCE_IO)
+                                       continue;
+                               if (r->flags & IORESOURCE_MEM) {
+                                       uca_start = r->start;
+                                       uca_end = r->end;
+                                       return 0;
+                               }
+                       }
+               }
+       }
+
+       return 0;
+}
+
+late_initcall(find_vga_mem_init);
+#endif /* !CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED */
diff --git a/arch/mips/loongson2ef/common/pci.c b/arch/mips/loongson2ef/common/pci.c
new file mode 100644 (file)
index 0000000..2d9755c
--- /dev/null
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ */
+#include <linux/pci.h>
+
+#include <pci.h>
+#include <loongson.h>
+#include <boot_param.h>
+
+static struct resource loongson_pci_mem_resource = {
+       .name   = "pci memory space",
+       .start  = LOONGSON_PCI_MEM_START,
+       .end    = LOONGSON_PCI_MEM_END,
+       .flags  = IORESOURCE_MEM,
+};
+
+static struct resource loongson_pci_io_resource = {
+       .name   = "pci io space",
+       .start  = LOONGSON_PCI_IO_START,
+       .end    = IO_SPACE_LIMIT,
+       .flags  = IORESOURCE_IO,
+};
+
+static struct pci_controller  loongson_pci_controller = {
+       .pci_ops        = &loongson_pci_ops,
+       .io_resource    = &loongson_pci_io_resource,
+       .mem_resource   = &loongson_pci_mem_resource,
+       .mem_offset     = 0x00000000UL,
+       .io_offset      = 0x00000000UL,
+};
+
+static void __init setup_pcimap(void)
+{
+       /*
+        * local to PCI mapping for CPU accessing PCI space
+        * CPU address space [256M,448M] is window for accessing pci space
+        * we set pcimap_lo[0,1,2] to map it to pci space[0M,64M], [320M,448M]
+        *
+        * pcimap: PCI_MAP2  PCI_Mem_Lo2 PCI_Mem_Lo1 PCI_Mem_Lo0
+        *           [<2G]   [384M,448M] [320M,384M] [0M,64M]
+        */
+       LOONGSON_PCIMAP = LOONGSON_PCIMAP_PCIMAP_2 |
+               LOONGSON_PCIMAP_WIN(2, LOONGSON_PCILO2_BASE) |
+               LOONGSON_PCIMAP_WIN(1, LOONGSON_PCILO1_BASE) |
+               LOONGSON_PCIMAP_WIN(0, 0);
+
+       /*
+        * PCI-DMA to local mapping: [2G,2G+256M] -> [0M,256M]
+        */
+       LOONGSON_PCIBASE0 = 0x80000000ul;   /* base: 2G -> mmap: 0M */
+       /* size: 256M, burst transmission, pre-fetch enable, 64bit */
+       LOONGSON_PCI_HIT0_SEL_L = 0xc000000cul;
+       LOONGSON_PCI_HIT0_SEL_H = 0xfffffffful;
+       LOONGSON_PCI_HIT1_SEL_L = 0x00000006ul; /* set this BAR as invalid */
+       LOONGSON_PCI_HIT1_SEL_H = 0x00000000ul;
+       LOONGSON_PCI_HIT2_SEL_L = 0x00000006ul; /* set this BAR as invalid */
+       LOONGSON_PCI_HIT2_SEL_H = 0x00000000ul;
+
+       /* avoid deadlock of PCI reading/writing lock operation */
+       LOONGSON_PCI_ISR4C = 0xd2000001ul;
+
+       /* can not change gnt to break pci transfer when device's gnt not
+       deassert for some broken device */
+       LOONGSON_PXARB_CFG = 0x00fe0105ul;
+
+#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
+       /*
+        * set cpu addr window2 to map CPU address space to PCI address space
+        */
+       LOONGSON_ADDRWIN_CPUTOPCI(ADDRWIN_WIN2, LOONGSON_CPU_MEM_SRC,
+               LOONGSON_PCI_MEM_DST, MMAP_CPUTOPCI_SIZE);
+#endif
+}
+
+extern int sbx00_acpi_init(void);
+
+static int __init pcibios_init(void)
+{
+       setup_pcimap();
+
+       loongson_pci_controller.io_map_base = mips_io_port_base;
+#ifdef CONFIG_LEFI_FIRMWARE_INTERFACE
+       loongson_pci_mem_resource.start = loongson_sysconf.pci_mem_start_addr;
+       loongson_pci_mem_resource.end = loongson_sysconf.pci_mem_end_addr;
+#endif
+       register_pci_controller(&loongson_pci_controller);
+
+#ifdef CONFIG_CPU_LOONGSON64
+       sbx00_acpi_init();
+#endif
+
+       return 0;
+}
+
+arch_initcall(pcibios_init);
diff --git a/arch/mips/loongson2ef/common/platform.c b/arch/mips/loongson2ef/common/platform.c
new file mode 100644 (file)
index 0000000..0084820
--- /dev/null
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin, wuzhangjin@gmail.com
+ */
+
+#include <linux/err.h>
+#include <linux/smp.h>
+#include <linux/platform_device.h>
+
+static struct platform_device loongson2_cpufreq_device = {
+       .name = "loongson2_cpufreq",
+       .id = -1,
+};
+
+static int __init loongson2_cpufreq_init(void)
+{
+       struct cpuinfo_mips *c = &current_cpu_data;
+
+       /* Only 2F revision and it's successors support CPUFreq */
+       if ((c->processor_id & PRID_REV_MASK) >= PRID_REV_LOONGSON2F)
+               return platform_device_register(&loongson2_cpufreq_device);
+
+       return -ENODEV;
+}
+
+arch_initcall(loongson2_cpufreq_init);
diff --git a/arch/mips/loongson2ef/common/pm.c b/arch/mips/loongson2ef/common/pm.c
new file mode 100644 (file)
index 0000000..b8aed87
--- /dev/null
@@ -0,0 +1,157 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * loongson-specific suspend support
+ *
+ *  Copyright (C) 2009 Lemote Inc.
+ *  Author: Wu Zhangjin <wuzhangjin@gmail.com>
+ */
+#include <linux/suspend.h>
+#include <linux/interrupt.h>
+#include <linux/pm.h>
+
+#include <asm/i8259.h>
+#include <asm/mipsregs.h>
+
+#include <loongson.h>
+
+static unsigned int __maybe_unused cached_master_mask; /* i8259A */
+static unsigned int __maybe_unused cached_slave_mask;
+static unsigned int __maybe_unused cached_bonito_irq_mask; /* bonito */
+
+void arch_suspend_disable_irqs(void)
+{
+       /* disable all mips events */
+       local_irq_disable();
+
+#ifdef CONFIG_I8259
+       /* disable all events of i8259A */
+       cached_slave_mask = inb(PIC_SLAVE_IMR);
+       cached_master_mask = inb(PIC_MASTER_IMR);
+
+       outb(0xff, PIC_SLAVE_IMR);
+       inb(PIC_SLAVE_IMR);
+       outb(0xff, PIC_MASTER_IMR);
+       inb(PIC_MASTER_IMR);
+#endif
+       /* disable all events of bonito */
+       cached_bonito_irq_mask = LOONGSON_INTEN;
+       LOONGSON_INTENCLR = 0xffff;
+       (void)LOONGSON_INTENCLR;
+}
+
+void arch_suspend_enable_irqs(void)
+{
+       /* enable all mips events */
+       local_irq_enable();
+#ifdef CONFIG_I8259
+       /* only enable the cached events of i8259A */
+       outb(cached_slave_mask, PIC_SLAVE_IMR);
+       outb(cached_master_mask, PIC_MASTER_IMR);
+#endif
+       /* enable all cached events of bonito */
+       LOONGSON_INTENSET = cached_bonito_irq_mask;
+       (void)LOONGSON_INTENSET;
+}
+
+/*
+ * Setup the board-specific events for waking up loongson from wait mode
+ */
+void __weak setup_wakeup_events(void)
+{
+}
+
+/*
+ * Check wakeup events
+ */
+int __weak wakeup_loongson(void)
+{
+       return 1;
+}
+
+/*
+ * If the events are really what we want to wakeup the CPU, wake it up
+ * otherwise put the CPU asleep again.
+ */
+static void wait_for_wakeup_events(void)
+{
+       while (!wakeup_loongson())
+               LOONGSON_CHIPCFG(0) &= ~0x7;
+}
+
+/*
+ * Stop all perf counters
+ *
+ * $24 is the control register of Loongson perf counter
+ */
+static inline void stop_perf_counters(void)
+{
+       __write_64bit_c0_register($24, 0, 0);
+}
+
+
+static void loongson_suspend_enter(void)
+{
+       static unsigned int cached_cpu_freq;
+
+       /* setup wakeup events via enabling the IRQs */
+       setup_wakeup_events();
+
+       stop_perf_counters();
+
+       cached_cpu_freq = LOONGSON_CHIPCFG(0);
+
+       /* Put CPU into wait mode */
+       LOONGSON_CHIPCFG(0) &= ~0x7;
+
+       /* wait for the given events to wakeup cpu from wait mode */
+       wait_for_wakeup_events();
+
+       LOONGSON_CHIPCFG(0) = cached_cpu_freq;
+       mmiowb();
+}
+
+void __weak mach_suspend(void)
+{
+}
+
+void __weak mach_resume(void)
+{
+}
+
+static int loongson_pm_enter(suspend_state_t state)
+{
+       mach_suspend();
+
+       /* processor specific suspend */
+       loongson_suspend_enter();
+
+       mach_resume();
+
+       return 0;
+}
+
+static int loongson_pm_valid_state(suspend_state_t state)
+{
+       switch (state) {
+       case PM_SUSPEND_ON:
+       case PM_SUSPEND_STANDBY:
+       case PM_SUSPEND_MEM:
+               return 1;
+
+       default:
+               return 0;
+       }
+}
+
+static const struct platform_suspend_ops loongson_pm_ops = {
+       .valid  = loongson_pm_valid_state,
+       .enter  = loongson_pm_enter,
+};
+
+static int __init loongson_pm_init(void)
+{
+       suspend_set_ops(&loongson_pm_ops);
+
+       return 0;
+}
+arch_initcall(loongson_pm_init);
diff --git a/arch/mips/loongson2ef/common/reset.c b/arch/mips/loongson2ef/common/reset.c
new file mode 100644 (file)
index 0000000..ce39e91
--- /dev/null
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ *
+ * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Zhangjin Wu, wuzhangjin@gmail.com
+ */
+#include <linux/init.h>
+#include <linux/pm.h>
+
+#include <asm/idle.h>
+#include <asm/reboot.h>
+
+#include <loongson.h>
+#include <boot_param.h>
+
+static inline void loongson_reboot(void)
+{
+#ifndef CONFIG_CPU_JUMP_WORKAROUNDS
+       ((void (*)(void))ioremap_nocache(LOONGSON_BOOT_BASE, 4)) ();
+#else
+       void (*func)(void);
+
+       func = (void *)ioremap_nocache(LOONGSON_BOOT_BASE, 4);
+
+       __asm__ __volatile__(
+       "       .set    noat                                            \n"
+       "       jr      %[func]                                         \n"
+       "       .set    at                                              \n"
+       : /* No outputs */
+       : [func] "r" (func));
+#endif
+}
+
+static void loongson_restart(char *command)
+{
+#ifndef CONFIG_LEFI_FIRMWARE_INTERFACE
+       /* do preparation for reboot */
+       mach_prepare_reboot();
+
+       /* reboot via jumping to boot base address */
+       loongson_reboot();
+#else
+       void (*fw_restart)(void) = (void *)loongson_sysconf.restart_addr;
+
+       fw_restart();
+       while (1) {
+               if (cpu_wait)
+                       cpu_wait();
+       }
+#endif
+}
+
+static void loongson_poweroff(void)
+{
+#ifndef CONFIG_LEFI_FIRMWARE_INTERFACE
+       mach_prepare_shutdown();
+
+       /*
+        * It needs a wait loop here, but mips/kernel/reset.c already calls
+        * a generic delay loop, machine_hang(), so simply return.
+        */
+       return;
+#else
+       void (*fw_poweroff)(void) = (void *)loongson_sysconf.poweroff_addr;
+
+       fw_poweroff();
+       while (1) {
+               if (cpu_wait)
+                       cpu_wait();
+       }
+#endif
+}
+
+static void loongson_halt(void)
+{
+       pr_notice("\n\n** You can safely turn off the power now **\n\n");
+       while (1) {
+               if (cpu_wait)
+                       cpu_wait();
+       }
+}
+
+static int __init mips_reboot_setup(void)
+{
+       _machine_restart = loongson_restart;
+       _machine_halt = loongson_halt;
+       pm_power_off = loongson_poweroff;
+
+       return 0;
+}
+
+arch_initcall(mips_reboot_setup);
diff --git a/arch/mips/loongson2ef/common/rtc.c b/arch/mips/loongson2ef/common/rtc.c
new file mode 100644 (file)
index 0000000..8d7628c
--- /dev/null
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ *  Lemote Fuloong platform support
+ *
+ *  Copyright(c) 2010 Arnaud Patard <apatard@mandriva.com>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/mc146818rtc.h>
+
+static struct resource loongson_rtc_resources[] = {
+       {
+               .start  = RTC_PORT(0),
+               .end    = RTC_PORT(1),
+               .flags  = IORESOURCE_IO,
+       }, {
+               .start  = RTC_IRQ,
+               .end    = RTC_IRQ,
+               .flags  = IORESOURCE_IRQ,
+       }
+};
+
+static struct platform_device loongson_rtc_device = {
+       .name           = "rtc_cmos",
+       .id             = -1,
+       .resource       = loongson_rtc_resources,
+       .num_resources  = ARRAY_SIZE(loongson_rtc_resources),
+};
+
+
+static int __init loongson_rtc_platform_init(void)
+{
+       platform_device_register(&loongson_rtc_device);
+       return 0;
+}
+
+device_initcall(loongson_rtc_platform_init);
diff --git a/arch/mips/loongson2ef/common/serial.c b/arch/mips/loongson2ef/common/serial.c
new file mode 100644 (file)
index 0000000..98c3a7f
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
+ *
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Yan hua (yanhua@lemote.com)
+ * Author: Wu Zhangjin (wuzhangjin@gmail.com)
+ */
+
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/serial_8250.h>
+
+#include <asm/bootinfo.h>
+
+#include <loongson.h>
+#include <machine.h>
+
+#define PORT(int, clk)                 \
+{                                                              \
+       .irq            = int,                                  \
+       .uartclk        = clk,                                  \
+       .iotype         = UPIO_PORT,                            \
+       .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,    \
+       .regshift       = 0,                                    \
+}
+
+#define PORT_M(int, clk)                               \
+{                                                              \
+       .irq            = MIPS_CPU_IRQ_BASE + (int),            \
+       .uartclk        = clk,                                  \
+       .iotype         = UPIO_MEM,                             \
+       .membase        = (void __iomem *)NULL,                 \
+       .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,    \
+       .regshift       = 0,                                    \
+}
+
+static struct plat_serial8250_port uart8250_data[][MAX_UARTS + 1] = {
+       [MACH_LOONGSON_UNKNOWN] = {},
+       [MACH_LEMOTE_FL2E]      = {PORT(4, 1843200), {} },
+       [MACH_LEMOTE_FL2F]      = {PORT(3, 1843200), {} },
+       [MACH_LEMOTE_ML2F7]     = {PORT_M(3, 3686400), {} },
+       [MACH_LEMOTE_YL2F89]    = {PORT_M(3, 3686400), {} },
+       [MACH_DEXXON_GDIUM2F10] = {PORT_M(3, 3686400), {} },
+       [MACH_LEMOTE_NAS]       = {PORT_M(3, 3686400), {} },
+       [MACH_LEMOTE_LL2F]      = {PORT(3, 1843200), {} },
+       [MACH_LOONGSON_GENERIC] = {PORT_M(2, 25000000), {} },
+       [MACH_LOONGSON_END]     = {},
+};
+
+static struct platform_device uart8250_device = {
+       .name = "serial8250",
+       .id = PLAT8250_DEV_PLATFORM,
+};
+
+static int __init serial_init(void)
+{
+       int i;
+       unsigned char iotype;
+
+       iotype = uart8250_data[mips_machtype][0].iotype;
+
+       if (UPIO_MEM == iotype) {
+               uart8250_data[mips_machtype][0].mapbase =
+                       loongson_uart_base[0];
+               uart8250_data[mips_machtype][0].membase =
+                       (void __iomem *)_loongson_uart_base[0];
+       }
+       else if (UPIO_PORT == iotype)
+               uart8250_data[mips_machtype][0].iobase =
+                       loongson_uart_base[0] - LOONGSON_PCIIO_BASE;
+
+       if (loongson_sysconf.uarts[0].uartclk)
+               uart8250_data[mips_machtype][0].uartclk =
+                       loongson_sysconf.uarts[0].uartclk;
+
+       for (i = 1; i < loongson_sysconf.nr_uarts; i++) {
+               iotype = loongson_sysconf.uarts[i].iotype;
+               uart8250_data[mips_machtype][i].iotype = iotype;
+               loongson_uart_base[i] = loongson_sysconf.uarts[i].uart_base;
+
+               if (UPIO_MEM == iotype) {
+                       uart8250_data[mips_machtype][i].irq =
+                               MIPS_CPU_IRQ_BASE + loongson_sysconf.uarts[i].int_offset;
+                       uart8250_data[mips_machtype][i].mapbase =
+                               loongson_uart_base[i];
+                       uart8250_data[mips_machtype][i].membase =
+                               ioremap_nocache(loongson_uart_base[i], 8);
+               } else if (UPIO_PORT == iotype) {
+                       uart8250_data[mips_machtype][i].irq =
+                               loongson_sysconf.uarts[i].int_offset;
+                       uart8250_data[mips_machtype][i].iobase =
+                               loongson_uart_base[i] - LOONGSON_PCIIO_BASE;
+               }
+
+               uart8250_data[mips_machtype][i].uartclk =
+                       loongson_sysconf.uarts[i].uartclk;
+               uart8250_data[mips_machtype][i].flags =
+                       UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
+       }
+
+       memset(&uart8250_data[mips_machtype][loongson_sysconf.nr_uarts],
+                       0, sizeof(struct plat_serial8250_port));
+       uart8250_device.dev.platform_data = uart8250_data[mips_machtype];
+
+       return platform_device_register(&uart8250_device);
+}
+module_init(serial_init);
+
+static void __exit serial_exit(void)
+{
+       platform_device_unregister(&uart8250_device);
+}
+module_exit(serial_exit);
diff --git a/arch/mips/loongson2ef/common/setup.c b/arch/mips/loongson2ef/common/setup.c
new file mode 100644 (file)
index 0000000..bc2da4c
--- /dev/null
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2007 Lemote Inc. & Institute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ */
+#include <linux/export.h>
+#include <linux/init.h>
+
+#include <asm/wbflush.h>
+#include <asm/bootinfo.h>
+
+#include <loongson.h>
+
+#ifdef CONFIG_VT
+#include <linux/console.h>
+#include <linux/screen_info.h>
+#endif
+
+static void wbflush_loongson(void)
+{
+       asm(".set\tpush\n\t"
+           ".set\tnoreorder\n\t"
+           ".set mips3\n\t"
+           "sync\n\t"
+           "nop\n\t"
+           ".set\tpop\n\t"
+           ".set mips0\n\t");
+}
+
+void (*__wbflush)(void) = wbflush_loongson;
+EXPORT_SYMBOL(__wbflush);
+
+void __init plat_mem_setup(void)
+{
+#ifdef CONFIG_VT
+#if defined(CONFIG_VGA_CONSOLE)
+       conswitchp = &vga_con;
+
+       screen_info = (struct screen_info) {
+               .orig_x                 = 0,
+               .orig_y                 = 25,
+               .orig_video_cols        = 80,
+               .orig_video_lines       = 25,
+               .orig_video_isVGA       = VIDEO_TYPE_VGAC,
+               .orig_video_points      = 16,
+       };
+#elif defined(CONFIG_DUMMY_CONSOLE)
+       conswitchp = &dummy_con;
+#endif
+#endif
+}
diff --git a/arch/mips/loongson2ef/common/time.c b/arch/mips/loongson2ef/common/time.c
new file mode 100644 (file)
index 0000000..e78760c
--- /dev/null
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ *
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin, wuzhangjin@gmail.com
+ */
+#include <asm/mc146818-time.h>
+#include <asm/time.h>
+#include <asm/hpet.h>
+
+#include <loongson.h>
+#include <cs5536/cs5536_mfgpt.h>
+
+void __init plat_time_init(void)
+{
+       /* setup mips r4k timer */
+       mips_hpt_frequency = cpu_clock_freq / 2;
+
+#ifdef CONFIG_RS780_HPET
+       setup_hpet_timer();
+#else
+       setup_mfgpt0_timer();
+#endif
+}
+
+void read_persistent_clock64(struct timespec64 *ts)
+{
+       ts->tv_sec = mc146818_get_cmos_time();
+       ts->tv_nsec = 0;
+}
diff --git a/arch/mips/loongson2ef/common/uart_base.c b/arch/mips/loongson2ef/common/uart_base.c
new file mode 100644 (file)
index 0000000..e88d937
--- /dev/null
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin, wuzhangjin@gmail.com
+ */
+
+#include <linux/export.h>
+#include <asm/bootinfo.h>
+
+#include <loongson.h>
+
+/* raw */
+unsigned long loongson_uart_base[MAX_UARTS] = {};
+/* ioremapped */
+unsigned long _loongson_uart_base[MAX_UARTS] = {};
+
+EXPORT_SYMBOL(loongson_uart_base);
+EXPORT_SYMBOL(_loongson_uart_base);
+
+void prom_init_loongson_uart_base(void)
+{
+       switch (mips_machtype) {
+       case MACH_LOONGSON_GENERIC:
+               /* The CPU provided serial port (CPU) */
+               loongson_uart_base[0] = LOONGSON_REG_BASE + 0x1e0;
+               break;
+       case MACH_LEMOTE_FL2E:
+               loongson_uart_base[0] = LOONGSON_PCIIO_BASE + 0x3f8;
+               break;
+       case MACH_LEMOTE_FL2F:
+       case MACH_LEMOTE_LL2F:
+               loongson_uart_base[0] = LOONGSON_PCIIO_BASE + 0x2f8;
+               break;
+       case MACH_LEMOTE_ML2F7:
+       case MACH_LEMOTE_YL2F89:
+       case MACH_DEXXON_GDIUM2F10:
+       case MACH_LEMOTE_NAS:
+       default:
+               /* The CPU provided serial port (LPC) */
+               loongson_uart_base[0] = LOONGSON_LIO1_BASE + 0x3f8;
+               break;
+       }
+
+       _loongson_uart_base[0] =
+               (unsigned long)ioremap_nocache(loongson_uart_base[0], 8);
+}
diff --git a/arch/mips/loongson2ef/fuloong-2e/Makefile b/arch/mips/loongson2ef/fuloong-2e/Makefile
new file mode 100644 (file)
index 0000000..bb58edb
--- /dev/null
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Makefile for Lemote Fuloong2e mini-PC board.
+#
+
+obj-y += irq.o reset.o dma.o
diff --git a/arch/mips/loongson2ef/fuloong-2e/dma.c b/arch/mips/loongson2ef/fuloong-2e/dma.c
new file mode 100644 (file)
index 0000000..e122292
--- /dev/null
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/dma-direct.h>
+
+dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
+{
+       return paddr | 0x80000000;
+}
+
+phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr)
+{
+       return dma_addr & 0x7fffffff;
+}
diff --git a/arch/mips/loongson2ef/fuloong-2e/irq.c b/arch/mips/loongson2ef/fuloong-2e/irq.c
new file mode 100644 (file)
index 0000000..32278e7
--- /dev/null
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2007 Lemote Inc. & Institute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ */
+#include <linux/interrupt.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/i8259.h>
+
+#include <loongson.h>
+
+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/loongson2ef/fuloong-2e/reset.c b/arch/mips/loongson2ef/fuloong-2e/reset.c
new file mode 100644 (file)
index 0000000..8273de1
--- /dev/null
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* Board-specific reboot/shutdown routines
+ * Copyright (c) 2009 Philippe Vachon <philippe@cowpig.ca>
+ *
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin, wuzhangjin@gmail.com
+ */
+
+#include <loongson.h>
+
+void mach_prepare_reboot(void)
+{
+       LOONGSON_GENCFG &= ~(1 << 2);
+       LOONGSON_GENCFG |= (1 << 2);
+}
+
+void mach_prepare_shutdown(void)
+{
+}
diff --git a/arch/mips/loongson2ef/lemote-2f/Makefile b/arch/mips/loongson2ef/lemote-2f/Makefile
new file mode 100644 (file)
index 0000000..881a0ec
--- /dev/null
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Makefile for lemote loongson2f family machines
+#
+
+obj-y += clock.o machtype.o irq.o reset.o dma.o ec_kb3310b.o
+
+#
+# Suspend Support
+#
+
+obj-$(CONFIG_SUSPEND) += pm.o
diff --git a/arch/mips/loongson2ef/lemote-2f/clock.c b/arch/mips/loongson2ef/lemote-2f/clock.c
new file mode 100644 (file)
index 0000000..1ced30e
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2006 - 2008 Lemote Inc. & Institute 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 <linux/clk.h>
+#include <linux/cpufreq.h>
+#include <linux/errno.h>
+#include <linux/export.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+
+#include <asm/clock.h>
+#include <asm/mach-loongson2ef/loongson.h>
+
+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)
+{
+       if (!clk)
+               return 0;
+
+       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/loongson2ef/lemote-2f/dma.c b/arch/mips/loongson2ef/lemote-2f/dma.c
new file mode 100644 (file)
index 0000000..abf0e39
--- /dev/null
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/dma-direct.h>
+
+dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
+{
+       return paddr | 0x80000000;
+}
+
+phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr)
+{
+       if (dma_addr > 0x8fffffff)
+               return dma_addr;
+       return dma_addr & 0x0fffffff;
+}
diff --git a/arch/mips/loongson2ef/lemote-2f/ec_kb3310b.c b/arch/mips/loongson2ef/lemote-2f/ec_kb3310b.c
new file mode 100644 (file)
index 0000000..d138220
--- /dev/null
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Basic KB3310B Embedded Controller support for the YeeLoong 2F netbook
+ *
+ *  Copyright (C) 2008 Lemote Inc.
+ *  Author: liujl <liujl@lemote.com>, 2008-04-20
+ */
+
+#include <linux/io.h>
+#include <linux/export.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+
+#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/loongson2ef/lemote-2f/ec_kb3310b.h b/arch/mips/loongson2ef/lemote-2f/ec_kb3310b.h
new file mode 100644 (file)
index 0000000..aecdbc9
--- /dev/null
@@ -0,0 +1,184 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * KB3310B Embedded Controller
+ *
+ *  Copyright (C) 2008 Lemote Inc.
+ *  Author: liujl <liujl@lemote.com>, 2008-03-14
+ */
+
+#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/loongson2ef/lemote-2f/irq.c b/arch/mips/loongson2ef/lemote-2f/irq.c
new file mode 100644 (file)
index 0000000..c58a044
--- /dev/null
@@ -0,0 +1,126 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2007 Lemote Inc.
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ */
+
+#include <linux/export.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/i8259.h>
+#include <asm/mipsregs.h>
+
+#include <loongson.h>
+#include <machine.h>
+
+#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 | IRQF_NO_SUSPEND,
+};
+
+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/loongson2ef/lemote-2f/machtype.c b/arch/mips/loongson2ef/lemote-2f/machtype.c
new file mode 100644 (file)
index 0000000..9462a3a
--- /dev/null
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin, wuzhangjin@gmail.com
+ */
+#include <asm/bootinfo.h>
+
+#include <loongson.h>
+
+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/loongson2ef/lemote-2f/pm.c b/arch/mips/loongson2ef/lemote-2f/pm.c
new file mode 100644 (file)
index 0000000..3d00272
--- /dev/null
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ *  Lemote loongson2f family machines' specific suspend support
+ *
+ *  Copyright (C) 2009 Lemote Inc.
+ *  Author: Wu Zhangjin <wuzhangjin@gmail.com>
+ */
+
+#include <linux/suspend.h>
+#include <linux/interrupt.h>
+#include <linux/pm.h>
+#include <linux/i8042.h>
+#include <linux/export.h>
+
+#include <asm/i8259.h>
+#include <asm/mipsregs.h>
+#include <asm/bootinfo.h>
+
+#include <loongson.h>
+
+#include <cs5536/cs5536_mfgpt.h>
+#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/loongson2ef/lemote-2f/reset.c b/arch/mips/loongson2ef/lemote-2f/reset.c
new file mode 100644 (file)
index 0000000..0db0934
--- /dev/null
@@ -0,0 +1,155 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* Board-specific reboot/shutdown routines
+ *
+ * Copyright (c) 2009 Philippe Vachon <philippe@cowpig.ca>
+ *
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin, wuzhangjin@gmail.com
+ */
+
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+
+#include <asm/bootinfo.h>
+
+#include <loongson.h>
+
+#include <cs5536/cs5536.h>
+#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;
+       }
+}
index d08b20ff2b27bf98aff61a10000c11696fa6656a..0e99a5af6e909b2a0481596aac30049845f82207 100644 (file)
@@ -4,65 +4,6 @@ if MACH_LOONGSON64
 choice
        prompt "Machine Type"
 
-config LEMOTE_FULOONG2E
-       bool "Lemote Fuloong(2e) mini-PC"
-       select ARCH_SPARSEMEM_ENABLE
-       select ARCH_MIGHT_HAVE_PC_PARPORT
-       select ARCH_MIGHT_HAVE_PC_SERIO
-       select CEVT_R4K
-       select CSRC_R4K
-       select SYS_HAS_CPU_LOONGSON2E
-       select DMA_NONCOHERENT
-       select BOOT_ELF32
-       select BOARD_SCACHE
-       select HAVE_PCI
-       select I8259
-       select ISA
-       select IRQ_MIPS_CPU
-       select SYS_SUPPORTS_64BIT_KERNEL
-       select SYS_SUPPORTS_LITTLE_ENDIAN
-       select SYS_SUPPORTS_HIGHMEM
-       select SYS_HAS_EARLY_PRINTK
-       select GENERIC_ISA_DMA_SUPPORT_BROKEN
-       select CPU_HAS_WB
-       select LOONGSON_MC146818
-       help
-         Lemote Fuloong(2e) mini-PC board based on the Chinese Loongson-2E CPU and
-         an FPGA northbridge
-
-         Lemote Fuloong(2e) mini PC have a VIA686B south bridge.
-
-config LEMOTE_MACH2F
-       bool "Lemote Loongson 2F family machines"
-       select ARCH_SPARSEMEM_ENABLE
-       select ARCH_MIGHT_HAVE_PC_PARPORT
-       select ARCH_MIGHT_HAVE_PC_SERIO
-       select BOARD_SCACHE
-       select BOOT_ELF32
-       select CEVT_R4K if ! MIPS_EXTERNAL_TIMER
-       select CPU_HAS_WB
-       select CS5536
-       select CSRC_R4K if ! MIPS_EXTERNAL_TIMER
-       select DMA_NONCOHERENT
-       select GENERIC_ISA_DMA_SUPPORT_BROKEN
-       select HAVE_CLK
-       select HAVE_PCI
-       select I8259
-       select IRQ_MIPS_CPU
-       select ISA
-       select SYS_HAS_CPU_LOONGSON2F
-       select SYS_HAS_EARLY_PRINTK
-       select SYS_SUPPORTS_64BIT_KERNEL
-       select SYS_SUPPORTS_HIGHMEM
-       select SYS_SUPPORTS_LITTLE_ENDIAN
-       select LOONGSON_MC146818
-       help
-         Lemote Loongson 2F family machines utilize the 2F revision of
-         Loongson processor and the AMD CS5536 south bridge.
-
-         These family machines include fuloong2f mini PC, yeeloong2f notebook,
-         LingLoong allinone PC and so forth.
-
 config LOONGSON_MACH3X
        bool "Generic Loongson 3 family machines"
        select ARCH_SPARSEMEM_ENABLE
@@ -95,22 +36,6 @@ config LOONGSON_MACH3X
                of Loongson processor and RS780/SBX00 chipset.
 endchoice
 
-config CS5536
-       bool
-
-config CS5536_MFGPT
-       bool "CS5536 MFGPT Timer"
-       depends on CS5536 && !HIGH_RES_TIMERS
-       select MIPS_EXTERNAL_TIMER
-       help
-         This option enables the mfgpt0 timer of AMD CS5536. With this timer
-         switched on you can not use high resolution timers.
-
-         If you want to enable the Loongson2 CPUFreq Driver, Please enable
-         this option at first, otherwise, You will get wrong system time.
-
-         If unsure, say Yes.
-
 config RS780_HPET
        bool "RS780/SBX00 HPET Timer"
        depends on LOONGSON_MACH3X
index c74bc0251e9d6e8b165a53b0d1c5a053ba062202..dc16a23c171ffe8a46733fb539208697d084e1aa 100644 (file)
@@ -5,18 +5,6 @@
 
 obj-$(CONFIG_MACH_LOONGSON64) += common/
 
-#
-# Lemote Fuloong mini-PC (Loongson 2E-based)
-#
-
-obj-$(CONFIG_LEMOTE_FULOONG2E) += fuloong-2e/
-
-#
-# Lemote loongson2f family machines
-#
-
-obj-$(CONFIG_LEMOTE_MACH2F)  += lemote-2f/
-
 #
 # All Loongson-3 family machines
 #
index 4da74eea7de885060f35e49253ab255b09f02db3..31167e568e46cf32e63ccd1eaf24777d05f878be 100644 (file)
@@ -2,25 +2,6 @@
 # Loongson Processors' Support
 #
 
-# Only gcc >= 4.4 have Loongson specific support
-cflags-$(CONFIG_CPU_LOONGSON2EF)       += -Wa,--trap
-cflags-$(CONFIG_CPU_LOONGSON2E) += \
-       $(call cc-option,-march=loongson2e,-march=r4600)
-cflags-$(CONFIG_CPU_LOONGSON2F) += \
-       $(call cc-option,-march=loongson2f,-march=r4600)
-# Enable the workarounds for Loongson2f
-ifdef CONFIG_CPU_LOONGSON2F_WORKAROUNDS
-  ifeq ($(call as-option,-Wa$(comma)-mfix-loongson2f-nop,),)
-    $(error only binutils >= 2.20.2 have needed option -mfix-loongson2f-nop)
-  else
-    cflags-$(CONFIG_CPU_NOP_WORKAROUNDS) += -Wa$(comma)-mfix-loongson2f-nop
-  endif
-  ifeq ($(call as-option,-Wa$(comma)-mfix-loongson2f-jump,),)
-    $(error only binutils >= 2.20.2 have needed option -mfix-loongson2f-jump)
-  else
-    cflags-$(CONFIG_CPU_JUMP_WORKAROUNDS) += -Wa$(comma)-mfix-loongson2f-jump
-  endif
-endif
 
 cflags-$(CONFIG_CPU_LOONGSON64)        += -Wa,--trap
 
@@ -72,6 +53,4 @@ endif
 
 platform-$(CONFIG_MACH_LOONGSON64) += loongson64/
 cflags-$(CONFIG_MACH_LOONGSON64) += -I$(srctree)/arch/mips/include/asm/mach-loongson64 -mno-branch-likely
-load-$(CONFIG_LEMOTE_FULOONG2E) += 0xffffffff80100000
-load-$(CONFIG_LEMOTE_MACH2F) += 0xffffffff80200000
 load-$(CONFIG_LOONGSON_MACH3X) += 0xffffffff80200000
index 684624f61f5a5235c032a0dd028da740f1b5a27a..85438df80950140338e704f6d7e233838d90cc45 100644 (file)
@@ -14,12 +14,6 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
 obj-$(CONFIG_LOONGSON_UART_BASE) += uart_base.o
 obj-$(CONFIG_LOONGSON_MC146818) += rtc.o
 
-#
-# Enable CS5536 Virtual Support Module(VSM) to virtulize the PCI configure
-# space
-#
-obj-$(CONFIG_CS5536) += cs5536/
-
 #
 # Suspend Support
 #
diff --git a/arch/mips/loongson64/common/cs5536/Makefile b/arch/mips/loongson64/common/cs5536/Makefile
deleted file mode 100644 (file)
index b32b296..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# 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
deleted file mode 100644 (file)
index ff50aae..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * 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
- */
-
-#include <cs5536/cs5536.h>
-#include <cs5536/cs5536_pci.h>
-
-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
deleted file mode 100644 (file)
index bd4c39f..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * 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
- */
-
-#include <cs5536/cs5536.h>
-#include <cs5536/cs5536_pci.h>
-
-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
deleted file mode 100644 (file)
index bb93329..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * 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
- */
-
-#include <cs5536/cs5536.h>
-#include <cs5536/cs5536_pci.h>
-
-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
deleted file mode 100644 (file)
index 5ad38f8..0000000
+++ /dev/null
@@ -1,326 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * 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
- */
-
-#include <linux/pci.h>
-#include <cs5536/cs5536.h>
-#include <cs5536/cs5536_pci.h>
-
-/* 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
deleted file mode 100644 (file)
index 30af1b7..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * CS5536 General timer functions
- *
- * Copyright (C) 2007 Lemote Inc. & Institute 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
- */
-
-#include <linux/io.h>
-#include <linux/init.h>
-#include <linux/export.h>
-#include <linux/jiffies.h>
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
-#include <linux/clockchips.h>
-
-#include <asm/time.h>
-
-#include <cs5536/cs5536_mfgpt.h>
-
-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 int mfgpt_timer_set_periodic(struct clock_event_device *evt)
-{
-       raw_spin_lock(&mfgpt_lock);
-
-       outw(COMPARE, MFGPT0_CMP2);     /* set comparator2 */
-       outw(0, MFGPT0_CNT);            /* set counter to 0 */
-       enable_mfgpt0_counter();
-
-       raw_spin_unlock(&mfgpt_lock);
-       return 0;
-}
-
-static int mfgpt_timer_shutdown(struct clock_event_device *evt)
-{
-       if (clockevent_state_periodic(evt) || clockevent_state_oneshot(evt)) {
-               raw_spin_lock(&mfgpt_lock);
-               disable_mfgpt0_counter();
-               raw_spin_unlock(&mfgpt_lock);
-       }
-
-       return 0;
-}
-
-static struct clock_event_device mfgpt_clockevent = {
-       .name = "mfgpt",
-       .features = CLOCK_EVT_FEAT_PERIODIC,
-
-       /* The oneshot mode have very high deviation, don't use it! */
-       .set_state_shutdown = mfgpt_timer_shutdown,
-       .set_state_periodic = mfgpt_timer_set_periodic,
-       .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->max_delta_ticks = 0xffff;
-       cd->min_delta_ns = clockevent_delta2ns(0xf, cd);
-       cd->min_delta_ticks = 0xf;
-
-       /* 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 u64 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 (u64) (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
deleted file mode 100644 (file)
index 71a52b1..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * 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
- */
-
-#include <cs5536/cs5536.h>
-#include <cs5536/cs5536_pci.h>
-
-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 >> PIC_YSEL_LOW_USB_SHIFT) & 0xf) == 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
deleted file mode 100644 (file)
index 202c89b..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * 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
- *
- *     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 <linux/types.h>
-#include <cs5536/cs5536_pci.h>
-#include <cs5536/cs5536_vsm.h>
-
-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/fuloong-2e/Makefile b/arch/mips/loongson64/fuloong-2e/Makefile
deleted file mode 100644 (file)
index bb58edb..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Makefile for Lemote Fuloong2e mini-PC board.
-#
-
-obj-y += irq.o reset.o dma.o
diff --git a/arch/mips/loongson64/fuloong-2e/dma.c b/arch/mips/loongson64/fuloong-2e/dma.c
deleted file mode 100644 (file)
index e122292..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <linux/dma-direct.h>
-
-dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
-{
-       return paddr | 0x80000000;
-}
-
-phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr)
-{
-       return dma_addr & 0x7fffffff;
-}
diff --git a/arch/mips/loongson64/fuloong-2e/irq.c b/arch/mips/loongson64/fuloong-2e/irq.c
deleted file mode 100644 (file)
index 32278e7..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright (C) 2007 Lemote Inc. & Institute of Computing Technology
- * Author: Fuxin Zhang, zhangfx@lemote.com
- */
-#include <linux/interrupt.h>
-
-#include <asm/irq_cpu.h>
-#include <asm/i8259.h>
-
-#include <loongson.h>
-
-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
deleted file mode 100644 (file)
index 8273de1..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/* Board-specific reboot/shutdown routines
- * Copyright (c) 2009 Philippe Vachon <philippe@cowpig.ca>
- *
- * Copyright (C) 2009 Lemote Inc.
- * Author: Wu Zhangjin, wuzhangjin@gmail.com
- */
-
-#include <loongson.h>
-
-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
deleted file mode 100644 (file)
index 881a0ec..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Makefile for lemote loongson2f family machines
-#
-
-obj-y += clock.o machtype.o irq.o reset.o dma.o ec_kb3310b.o
-
-#
-# Suspend Support
-#
-
-obj-$(CONFIG_SUSPEND) += pm.o
diff --git a/arch/mips/loongson64/lemote-2f/clock.c b/arch/mips/loongson64/lemote-2f/clock.c
deleted file mode 100644 (file)
index 8281334..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2006 - 2008 Lemote Inc. & Institute 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 <linux/clk.h>
-#include <linux/cpufreq.h>
-#include <linux/errno.h>
-#include <linux/export.h>
-#include <linux/list.h>
-#include <linux/mutex.h>
-#include <linux/spinlock.h>
-
-#include <asm/clock.h>
-#include <asm/mach-loongson64/loongson.h>
-
-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)
-{
-       if (!clk)
-               return 0;
-
-       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/dma.c b/arch/mips/loongson64/lemote-2f/dma.c
deleted file mode 100644 (file)
index abf0e39..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <linux/dma-direct.h>
-
-dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
-{
-       return paddr | 0x80000000;
-}
-
-phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr)
-{
-       if (dma_addr > 0x8fffffff)
-               return dma_addr;
-       return dma_addr & 0x0fffffff;
-}
diff --git a/arch/mips/loongson64/lemote-2f/ec_kb3310b.c b/arch/mips/loongson64/lemote-2f/ec_kb3310b.c
deleted file mode 100644 (file)
index d138220..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Basic KB3310B Embedded Controller support for the YeeLoong 2F netbook
- *
- *  Copyright (C) 2008 Lemote Inc.
- *  Author: liujl <liujl@lemote.com>, 2008-04-20
- */
-
-#include <linux/io.h>
-#include <linux/export.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-
-#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
deleted file mode 100644 (file)
index aecdbc9..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * KB3310B Embedded Controller
- *
- *  Copyright (C) 2008 Lemote Inc.
- *  Author: liujl <liujl@lemote.com>, 2008-03-14
- */
-
-#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
deleted file mode 100644 (file)
index c58a044..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright (C) 2007 Lemote Inc.
- * Author: Fuxin Zhang, zhangfx@lemote.com
- */
-
-#include <linux/export.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-
-#include <asm/irq_cpu.h>
-#include <asm/i8259.h>
-#include <asm/mipsregs.h>
-
-#include <loongson.h>
-#include <machine.h>
-
-#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 | IRQF_NO_SUSPEND,
-};
-
-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
deleted file mode 100644 (file)
index 9462a3a..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright (C) 2009 Lemote Inc.
- * Author: Wu Zhangjin, wuzhangjin@gmail.com
- */
-#include <asm/bootinfo.h>
-
-#include <loongson.h>
-
-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
deleted file mode 100644 (file)
index 3d00272..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *  Lemote loongson2f family machines' specific suspend support
- *
- *  Copyright (C) 2009 Lemote Inc.
- *  Author: Wu Zhangjin <wuzhangjin@gmail.com>
- */
-
-#include <linux/suspend.h>
-#include <linux/interrupt.h>
-#include <linux/pm.h>
-#include <linux/i8042.h>
-#include <linux/export.h>
-
-#include <asm/i8259.h>
-#include <asm/mipsregs.h>
-#include <asm/bootinfo.h>
-
-#include <loongson.h>
-
-#include <cs5536/cs5536_mfgpt.h>
-#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
deleted file mode 100644 (file)
index 0db0934..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/* Board-specific reboot/shutdown routines
- *
- * Copyright (c) 2009 Philippe Vachon <philippe@cowpig.ca>
- *
- * Copyright (C) 2009 Lemote Inc.
- * Author: Wu Zhangjin, wuzhangjin@gmail.com
- */
-
-#include <linux/io.h>
-#include <linux/delay.h>
-#include <linux/types.h>
-
-#include <asm/bootinfo.h>
-
-#include <loongson.h>
-
-#include <cs5536/cs5536.h>
-#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;
-       }
-}
index 890813e0bb768011ea31db35c97317091a25bc0a..e9caa9586982acfd137aa02b083d4b5ff08607f3 100644 (file)
@@ -23,7 +23,7 @@
 #include <asm/clock.h>
 #include <asm/idle.h>
 
-#include <asm/mach-loongson64/loongson.h>
+#include <asm/mach-loongson2ef/loongson.h>
 
 static uint nowait;