From d0514728247b91476a525a064f8b3c2f0c47bec4 Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Wed, 7 Oct 2015 14:08:00 +0800 Subject: MIPS: Loongson-3: Move chipset ACPI code from drivers to arch SB700/SB710/SB800 chipset ACPI code is mostly Loongson-3 specific routines rather than a "platform driver". Signed-off-by: Huacai Chen Cc: John Crispin Cc: Steven J. Hill Cc: Fuxin Zhang Cc: Zhangjin Wu Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/11273/ Signed-off-by: Ralf Baechle --- drivers/platform/mips/Kconfig | 4 - drivers/platform/mips/Makefile | 1 - drivers/platform/mips/acpi_init.c | 150 -------------------------------------- 3 files changed, 155 deletions(-) delete mode 100644 drivers/platform/mips/acpi_init.c (limited to 'drivers/platform') diff --git a/drivers/platform/mips/Kconfig b/drivers/platform/mips/Kconfig index 125e569017be..b3ae30a4c67b 100644 --- a/drivers/platform/mips/Kconfig +++ b/drivers/platform/mips/Kconfig @@ -15,10 +15,6 @@ menuconfig MIPS_PLATFORM_DEVICES if MIPS_PLATFORM_DEVICES -config MIPS_ACPI - bool - default y if LOONGSON_MACH3X - config CPU_HWMON tristate "Loongson CPU HWMon Driver" depends on LOONGSON_MACH3X diff --git a/drivers/platform/mips/Makefile b/drivers/platform/mips/Makefile index 43412849b195..8dfd03924c37 100644 --- a/drivers/platform/mips/Makefile +++ b/drivers/platform/mips/Makefile @@ -1,2 +1 @@ -obj-$(CONFIG_MIPS_ACPI) += acpi_init.o obj-$(CONFIG_CPU_HWMON) += cpu_hwmon.o diff --git a/drivers/platform/mips/acpi_init.c b/drivers/platform/mips/acpi_init.c deleted file mode 100644 index dbdad79ead8f..000000000000 --- a/drivers/platform/mips/acpi_init.c +++ /dev/null @@ -1,150 +0,0 @@ -#include -#include -#include -#include - -#define SBX00_ACPI_IO_BASE 0x800 -#define SBX00_ACPI_IO_SIZE 0x100 - -#define ACPI_PM_EVT_BLK (SBX00_ACPI_IO_BASE + 0x00) /* 4 bytes */ -#define ACPI_PM_CNT_BLK (SBX00_ACPI_IO_BASE + 0x04) /* 2 bytes */ -#define ACPI_PMA_CNT_BLK (SBX00_ACPI_IO_BASE + 0x0F) /* 1 byte */ -#define ACPI_PM_TMR_BLK (SBX00_ACPI_IO_BASE + 0x18) /* 4 bytes */ -#define ACPI_GPE0_BLK (SBX00_ACPI_IO_BASE + 0x10) /* 8 bytes */ -#define ACPI_END (SBX00_ACPI_IO_BASE + 0x80) - -#define PM_INDEX 0xCD6 -#define PM_DATA 0xCD7 -#define PM2_INDEX 0xCD0 -#define PM2_DATA 0xCD1 - -/* - * SCI interrupt need acpi space, allocate here - */ - -static int __init register_acpi_resource(void) -{ - request_region(SBX00_ACPI_IO_BASE, SBX00_ACPI_IO_SIZE, "acpi"); - return 0; -} - -static void pmio_write_index(u16 index, u8 reg, u8 value) -{ - outb(reg, index); - outb(value, index + 1); -} - -static u8 pmio_read_index(u16 index, u8 reg) -{ - outb(reg, index); - return inb(index + 1); -} - -void pm_iowrite(u8 reg, u8 value) -{ - pmio_write_index(PM_INDEX, reg, value); -} -EXPORT_SYMBOL(pm_iowrite); - -u8 pm_ioread(u8 reg) -{ - return pmio_read_index(PM_INDEX, reg); -} -EXPORT_SYMBOL(pm_ioread); - -void pm2_iowrite(u8 reg, u8 value) -{ - pmio_write_index(PM2_INDEX, reg, value); -} -EXPORT_SYMBOL(pm2_iowrite); - -u8 pm2_ioread(u8 reg) -{ - return pmio_read_index(PM2_INDEX, reg); -} -EXPORT_SYMBOL(pm2_ioread); - -static void acpi_hw_clear_status(void) -{ - u16 value; - - /* PMStatus: Clear WakeStatus/PwrBtnStatus */ - value = inw(ACPI_PM_EVT_BLK); - value |= (1 << 8 | 1 << 15); - outw(value, ACPI_PM_EVT_BLK); - - /* GPEStatus: Clear all generated events */ - outl(inl(ACPI_GPE0_BLK), ACPI_GPE0_BLK); -} - -void acpi_registers_setup(void) -{ - u32 value; - - /* PM Status Base */ - pm_iowrite(0x20, ACPI_PM_EVT_BLK & 0xff); - pm_iowrite(0x21, ACPI_PM_EVT_BLK >> 8); - - /* PM Control Base */ - pm_iowrite(0x22, ACPI_PM_CNT_BLK & 0xff); - pm_iowrite(0x23, ACPI_PM_CNT_BLK >> 8); - - /* GPM Base */ - pm_iowrite(0x28, ACPI_GPE0_BLK & 0xff); - pm_iowrite(0x29, ACPI_GPE0_BLK >> 8); - - /* ACPI End */ - pm_iowrite(0x2e, ACPI_END & 0xff); - pm_iowrite(0x2f, ACPI_END >> 8); - - /* IO Decode: When AcpiDecodeEnable set, South-Bridge uses the contents - * of the PM registers at index 0x20~0x2B to decode ACPI I/O address. */ - pm_iowrite(0x0e, 1 << 3); - - /* SCI_EN set */ - outw(1, ACPI_PM_CNT_BLK); - - /* Enable to generate SCI */ - pm_iowrite(0x10, pm_ioread(0x10) | 1); - - /* GPM3/GPM9 enable */ - value = inl(ACPI_GPE0_BLK + 4); - outl(value | (1 << 14) | (1 << 22), ACPI_GPE0_BLK + 4); - - /* Set GPM9 as input */ - pm_iowrite(0x8d, pm_ioread(0x8d) & (~(1 << 1))); - - /* Set GPM9 as non-output */ - pm_iowrite(0x94, pm_ioread(0x94) | (1 << 3)); - - /* GPM3 config ACPI trigger SCIOUT */ - pm_iowrite(0x33, pm_ioread(0x33) & (~(3 << 4))); - - /* GPM9 config ACPI trigger SCIOUT */ - pm_iowrite(0x3d, pm_ioread(0x3d) & (~(3 << 2))); - - /* GPM3 config falling edge trigger */ - pm_iowrite(0x37, pm_ioread(0x37) & (~(1 << 6))); - - /* No wait for STPGNT# in ACPI Sx state */ - pm_iowrite(0x7c, pm_ioread(0x7c) | (1 << 6)); - - /* Set GPM3 pull-down enable */ - value = pm2_ioread(0xf6); - value |= ((1 << 7) | (1 << 3)); - pm2_iowrite(0xf6, value); - - /* Set GPM9 pull-down enable */ - value = pm2_ioread(0xf8); - value |= ((1 << 5) | (1 << 1)); - pm2_iowrite(0xf8, value); -} - -int __init sbx00_acpi_init(void) -{ - register_acpi_resource(); - acpi_registers_setup(); - acpi_hw_clear_status(); - - return 0; -} -- cgit v1.2.3 From b2edcfc814017eb278e29bfdc72844f0434dd8b1 Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Thu, 3 Mar 2016 09:45:09 +0800 Subject: MIPS: Loongson: Add Loongson-3A R2 basic support Loongson-3 CPU family: Code-name Brand-name PRId Loongson-3A R1 Loongson-3A1000 0x6305 Loongson-3A R2 Loongson-3A2000 0x6308 Loongson-3B R1 Loongson-3B1000 0x6306 Loongson-3B R2 Loongson-3B1500 0x6307 Features of R2 revision of Loongson-3A: - Primary cache includes I-Cache, D-Cache and V-Cache (Victim Cache). - I-Cache, D-Cache and V-Cache are 16-way set-associative, linesize is 64 bytes. - 64 entries of VTLB (classic TLB), 1024 entries of FTLB (8-way set-associative). - Supports DSP/DSPv2 instructions, UserLocal register and Read-Inhibit/ Execute-Inhibit. [ralf@linux-mips.org: Resolved merge conflicts.] Signed-off-by: Huacai Chen Cc: Aurelien Jarno Cc: Steven J . Hill Cc: Fuxin Zhang Cc: Zhangjin Wu Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/12751/ Patchwork: https://patchwork.linux-mips.org/patch/13136/ Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 2 + arch/mips/include/asm/cacheops.h | 6 ++ arch/mips/include/asm/cpu-info.h | 1 + arch/mips/include/asm/cpu.h | 4 +- .../asm/mach-loongson64/cpu-feature-overrides.h | 18 +--- .../asm/mach-loongson64/kernel-entry-init.h | 6 +- arch/mips/include/asm/mipsregs.h | 2 + arch/mips/include/asm/pgtable.h | 4 +- arch/mips/kernel/cpu-probe.c | 38 +++++++- arch/mips/kernel/idle.c | 5 + arch/mips/kernel/traps.c | 3 +- arch/mips/loongson64/common/env.c | 7 +- arch/mips/loongson64/loongson-3/smp.c | 106 +++++++++++++++++++-- arch/mips/mm/c-r4k.c | 27 ++++++ drivers/platform/mips/cpu_hwmon.c | 4 +- 15 files changed, 201 insertions(+), 32 deletions(-) (limited to 'drivers/platform') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index fbd63ff8eba4..adcc97ea4392 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1354,6 +1354,7 @@ config CPU_LOONGSON3 select CPU_SUPPORTS_HUGEPAGES select WEAK_ORDERING select WEAK_REORDERING_BEYOND_LLSC + select MIPS_PGD_C0_CONTEXT select ARCH_REQUIRE_GPIOLIB help The Loongson 3 processor implements the MIPS64R2 instruction @@ -1823,6 +1824,7 @@ config CPU_BMIPS5000 config SYS_HAS_CPU_LOONGSON3 bool select CPU_SUPPORTS_CPUFREQ + select CPU_HAS_RIXI config SYS_HAS_CPU_LOONGSON2E bool diff --git a/arch/mips/include/asm/cacheops.h b/arch/mips/include/asm/cacheops.h index c3212ff26723..8031fbc6b69a 100644 --- a/arch/mips/include/asm/cacheops.h +++ b/arch/mips/include/asm/cacheops.h @@ -21,6 +21,7 @@ #define Cache_I 0x00 #define Cache_D 0x01 #define Cache_T 0x02 +#define Cache_V 0x02 /* Loongson-3 */ #define Cache_S 0x03 #define Index_Writeback_Inv 0x00 @@ -107,4 +108,9 @@ */ #define Hit_Invalidate_I_Loongson2 (Cache_I | 0x00) +/* + * Loongson3-specific cacheops + */ +#define Index_Writeback_Inv_V (Cache_V | Index_Writeback_Inv) + #endif /* __ASM_CACHEOPS_H */ diff --git a/arch/mips/include/asm/cpu-info.h b/arch/mips/include/asm/cpu-info.h index 9ec81684b1b8..b090aa51d644 100644 --- a/arch/mips/include/asm/cpu-info.h +++ b/arch/mips/include/asm/cpu-info.h @@ -60,6 +60,7 @@ struct cpuinfo_mips { int tlbsizeftlbways; struct cache_desc icache; /* Primary I-cache */ struct cache_desc dcache; /* Primary D or combined I/D cache */ + struct cache_desc vcache; /* Victim cache, between pcache and scache */ struct cache_desc scache; /* Secondary cache */ struct cache_desc tcache; /* Tertiary/split secondary cache */ int srsets; /* Shadow register sets */ diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index 9127a583d1f1..810536b6900c 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h @@ -42,6 +42,7 @@ #define PRID_COMP_LEXRA 0x0b0000 #define PRID_COMP_NETLOGIC 0x0c0000 #define PRID_COMP_CAVIUM 0x0d0000 +#define PRID_COMP_LOONGSON 0x140000 #define PRID_COMP_INGENIC_D0 0xd00000 /* JZ4740, JZ4750 */ #define PRID_COMP_INGENIC_D1 0xd10000 /* JZ4770, JZ4775 */ #define PRID_COMP_INGENIC_E1 0xe10000 /* JZ4780 */ @@ -241,9 +242,10 @@ #define PRID_REV_LOONGSON1B 0x0020 #define PRID_REV_LOONGSON2E 0x0002 #define PRID_REV_LOONGSON2F 0x0003 -#define PRID_REV_LOONGSON3A 0x0005 +#define PRID_REV_LOONGSON3A_R1 0x0005 #define PRID_REV_LOONGSON3B_R1 0x0006 #define PRID_REV_LOONGSON3B_R2 0x0007 +#define PRID_REV_LOONGSON3A_R2 0x0008 /* * Older processors used to encode processor version and revision in two diff --git a/arch/mips/include/asm/mach-loongson64/cpu-feature-overrides.h b/arch/mips/include/asm/mach-loongson64/cpu-feature-overrides.h index 98963c2c7be4..89328a3d44d8 100644 --- a/arch/mips/include/asm/mach-loongson64/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-loongson64/cpu-feature-overrides.h @@ -16,11 +16,6 @@ #ifndef __ASM_MACH_LOONGSON64_CPU_FEATURE_OVERRIDES_H #define __ASM_MACH_LOONGSON64_CPU_FEATURE_OVERRIDES_H -#define cpu_dcache_line_size() 32 -#define cpu_icache_line_size() 32 -#define cpu_scache_line_size() 32 - - #define cpu_has_32fpr 1 #define cpu_has_3k_cache 0 #define cpu_has_4k_cache 1 @@ -31,24 +26,17 @@ #define cpu_has_counter 1 #define cpu_has_dc_aliases (PAGE_SIZE < 0x4000) #define cpu_has_divec 0 -#define cpu_has_dsp 0 -#define cpu_has_dsp2 0 #define cpu_has_ejtag 0 -#define cpu_has_ic_fills_f_dc 0 #define cpu_has_inclusive_pcaches 1 #define cpu_has_llsc 1 #define cpu_has_mcheck 0 #define cpu_has_mdmx 0 #define cpu_has_mips16 0 -#define cpu_has_mips32r2 0 #define cpu_has_mips3d 0 -#define cpu_has_mips64r2 0 #define cpu_has_mipsmt 0 -#define cpu_has_prefetch 0 #define cpu_has_smartmips 0 #define cpu_has_tlb 1 #define cpu_has_tx39_cache 0 -#define cpu_has_userlocal 0 #define cpu_has_vce 0 #define cpu_has_veic 0 #define cpu_has_vint 0 @@ -56,6 +44,10 @@ #define cpu_has_watch 1 #define cpu_has_local_ebase 0 -#define cpu_has_wsbh IS_ENABLED(CONFIG_CPU_LOONGSON3) +#ifdef CONFIG_CPU_LOONGSON3 +#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-loongson64/kernel-entry-init.h b/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h index 3f2f84f6c401..da83482ff0b9 100644 --- a/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h +++ b/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h @@ -23,7 +23,8 @@ or t0, (0x1 << 7) mtc0 t0, $16, 3 /* Set ELPA on LOONGSON3 pagegrain */ - li t0, (0x1 << 29) + mfc0 t0, $5, 1 + or t0, (0x1 << 29) mtc0 t0, $5, 1 _ehb .set pop @@ -42,7 +43,8 @@ or t0, (0x1 << 7) mtc0 t0, $16, 3 /* Set ELPA on LOONGSON3 pagegrain */ - li t0, (0x1 << 29) + mfc0 t0, $5, 1 + or t0, (0x1 << 29) mtc0 t0, $5, 1 _ehb .set pop diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index aea90631a301..28ded49d25c6 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -636,6 +636,8 @@ #define MIPS_CONF6_SYND (_ULCAST_(1) << 13) /* proAptiv FTLB on/off bit */ #define MIPS_CONF6_FTLBEN (_ULCAST_(1) << 15) +/* Loongson-3 FTLB on/off bit */ +#define MIPS_CONF6_FTLBDIS (_ULCAST_(1) << 22) /* FTLB probability bits */ #define MIPS_CONF6_FTLBP_SHIFT (16) diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h index 45de57651619..7f422500b65d 100644 --- a/arch/mips/include/asm/pgtable.h +++ b/arch/mips/include/asm/pgtable.h @@ -384,7 +384,7 @@ static inline pte_t pte_mkdirty(pte_t pte) static inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; -#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) +#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) || defined(CONFIG_CPU_LOONGSON3) if (!(pte_val(pte) & _PAGE_NO_READ)) pte_val(pte) |= _PAGE_SILENT_READ; else @@ -570,7 +570,7 @@ static inline pmd_t pmd_mkyoung(pmd_t pmd) { pmd_val(pmd) |= _PAGE_ACCESSED; -#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) +#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) || defined(CONFIG_CPU_LOONGSON3) if (!(pmd_val(pmd) & _PAGE_NO_READ)) pmd_val(pmd) |= _PAGE_SILENT_READ; else diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index d72bd7eb8bce..2bfd48375b46 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -562,6 +562,16 @@ static int set_ftlb_enable(struct cpuinfo_mips *c, int enable) write_c0_config7(config | (calculate_ftlb_probability(c) << MIPS_CONF7_FTLBP_SHIFT)); break; + case CPU_LOONGSON3: + /* Loongson-3 cores use Config6 to enable the FTLB */ + config = read_c0_config6(); + if (enable) + /* Enable FTLB */ + write_c0_config6(config & ~MIPS_CONF6_FTLBDIS); + else + /* Disable FTLB */ + write_c0_config6(config | MIPS_CONF6_FTLBDIS); + break; default: return 1; } @@ -1178,7 +1188,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) set_isa(c, MIPS_CPU_ISA_III); c->fpu_msk31 |= FPU_CSR_CONDX; break; - case PRID_REV_LOONGSON3A: + case PRID_REV_LOONGSON3A_R1: c->cputype = CPU_LOONGSON3; __cpu_name[cpu] = "ICT Loongson-3"; set_elf_platform(cpu, "loongson3a"); @@ -1512,6 +1522,29 @@ platform: } } +static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu) +{ + switch (c->processor_id & PRID_IMP_MASK) { + case PRID_IMP_LOONGSON_64: /* Loongson-2/3 */ + switch (c->processor_id & PRID_REV_MASK) { + case PRID_REV_LOONGSON3A_R2: + c->cputype = CPU_LOONGSON3; + __cpu_name[cpu] = "ICT Loongson-3"; + set_elf_platform(cpu, "loongson3a"); + set_isa(c, MIPS_CPU_ISA_M64R2); + break; + } + + decode_configs(c); + c->options |= MIPS_CPU_TLBINV; + c->writecombine = _CACHE_UNCACHED_ACCELERATED; + break; + default: + panic("Unknown Loongson Processor ID!"); + break; + } +} + static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu) { decode_configs(c); @@ -1659,6 +1692,9 @@ void cpu_probe(void) case PRID_COMP_CAVIUM: cpu_probe_cavium(c, cpu); break; + case PRID_COMP_LOONGSON: + cpu_probe_loongson(c, cpu); + break; case PRID_COMP_INGENIC_D0: case PRID_COMP_INGENIC_D1: case PRID_COMP_INGENIC_E1: diff --git a/arch/mips/kernel/idle.c b/arch/mips/kernel/idle.c index 46794d64c0bf..60ab4c44d305 100644 --- a/arch/mips/kernel/idle.c +++ b/arch/mips/kernel/idle.c @@ -181,6 +181,11 @@ void __init check_wait(void) case CPU_XLP: cpu_wait = r4k_wait; break; + case CPU_LOONGSON3: + if ((c->processor_id & PRID_REV_MASK) >= PRID_REV_LOONGSON3A_R2) + cpu_wait = r4k_wait; + break; + case CPU_BMIPS5000: cpu_wait = r4k_wait_irqoff; break; diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index dcda63e65854..38864dc179ff 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -1772,7 +1772,8 @@ asmlinkage void do_ftlb(void) /* For the moment, report the problem and hang. */ if ((cpu_has_mips_r2_r6) && - ((current_cpu_data.processor_id & 0xff0000) == PRID_COMP_MIPS)) { + (((current_cpu_data.processor_id & 0xff0000) == PRID_COMP_MIPS) || + ((current_cpu_data.processor_id & 0xff0000) == PRID_COMP_LOONGSON))) { pr_err("FTLB error exception, cp0_ecc=0x%08x:\n", read_c0_ecc()); pr_err("cp0_errorepc == %0*lx\n", field, read_c0_errorepc()); diff --git a/arch/mips/loongson64/common/env.c b/arch/mips/loongson64/common/env.c index d6d07ad56180..57d590ac8004 100644 --- a/arch/mips/loongson64/common/env.c +++ b/arch/mips/loongson64/common/env.c @@ -105,6 +105,10 @@ void __init prom_init_env(void) 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; } else if (ecpu->cputype == Loongson_3B) { @@ -187,7 +191,8 @@ void __init prom_init_env(void) case PRID_REV_LOONGSON2F: cpu_clock_freq = 797000000; break; - case PRID_REV_LOONGSON3A: + case PRID_REV_LOONGSON3A_R1: + case PRID_REV_LOONGSON3A_R2: cpu_clock_freq = 900000000; break; case PRID_REV_LOONGSON3B_R1: diff --git a/arch/mips/loongson64/loongson-3/smp.c b/arch/mips/loongson64/loongson-3/smp.c index b913cd240d77..e59759af63d9 100644 --- a/arch/mips/loongson64/loongson-3/smp.c +++ b/arch/mips/loongson64/loongson-3/smp.c @@ -439,7 +439,7 @@ static void loongson3_cpu_die(unsigned int cpu) * flush all L1 entries at first. Then, another core (usually Core 0) can * safely disable the clock of the target core. loongson3_play_dead() is * called via CKSEG1 (uncached and unmmaped) */ -static void loongson3a_play_dead(int *state_addr) +static void loongson3a_r1_play_dead(int *state_addr) { register int val; register long cpuid, core, node, count; @@ -501,6 +501,89 @@ static void loongson3a_play_dead(int *state_addr) : "a1"); } +static void loongson3a_r2_play_dead(int *state_addr) +{ + register int val; + register long cpuid, core, node, count; + register void *addr, *base, *initfunc; + + __asm__ __volatile__( + " .set push \n" + " .set noreorder \n" + " li %[addr], 0x80000000 \n" /* KSEG0 */ + "1: cache 0, 0(%[addr]) \n" /* flush L1 ICache */ + " cache 0, 1(%[addr]) \n" + " cache 0, 2(%[addr]) \n" + " cache 0, 3(%[addr]) \n" + " cache 1, 0(%[addr]) \n" /* flush L1 DCache */ + " cache 1, 1(%[addr]) \n" + " cache 1, 2(%[addr]) \n" + " cache 1, 3(%[addr]) \n" + " addiu %[sets], %[sets], -1 \n" + " bnez %[sets], 1b \n" + " addiu %[addr], %[addr], 0x40 \n" + " li %[addr], 0x80000000 \n" /* KSEG0 */ + "2: cache 2, 0(%[addr]) \n" /* flush L1 VCache */ + " cache 2, 1(%[addr]) \n" + " cache 2, 2(%[addr]) \n" + " cache 2, 3(%[addr]) \n" + " cache 2, 4(%[addr]) \n" + " cache 2, 5(%[addr]) \n" + " cache 2, 6(%[addr]) \n" + " cache 2, 7(%[addr]) \n" + " cache 2, 8(%[addr]) \n" + " cache 2, 9(%[addr]) \n" + " cache 2, 10(%[addr]) \n" + " cache 2, 11(%[addr]) \n" + " cache 2, 12(%[addr]) \n" + " cache 2, 13(%[addr]) \n" + " cache 2, 14(%[addr]) \n" + " cache 2, 15(%[addr]) \n" + " addiu %[vsets], %[vsets], -1 \n" + " bnez %[vsets], 2b \n" + " addiu %[addr], %[addr], 0x40 \n" + " li %[val], 0x7 \n" /* *state_addr = CPU_DEAD; */ + " sw %[val], (%[state_addr]) \n" + " sync \n" + " cache 21, (%[state_addr]) \n" /* flush entry of *state_addr */ + " .set pop \n" + : [addr] "=&r" (addr), [val] "=&r" (val) + : [state_addr] "r" (state_addr), + [sets] "r" (cpu_data[smp_processor_id()].dcache.sets), + [vsets] "r" (cpu_data[smp_processor_id()].vcache.sets)); + + __asm__ __volatile__( + " .set push \n" + " .set noreorder \n" + " .set mips64 \n" + " mfc0 %[cpuid], $15, 1 \n" + " andi %[cpuid], 0x3ff \n" + " dli %[base], 0x900000003ff01000 \n" + " andi %[core], %[cpuid], 0x3 \n" + " sll %[core], 8 \n" /* get core id */ + " or %[base], %[base], %[core] \n" + " andi %[node], %[cpuid], 0xc \n" + " dsll %[node], 42 \n" /* get node id */ + " or %[base], %[base], %[node] \n" + "1: li %[count], 0x100 \n" /* wait for init loop */ + "2: bnez %[count], 2b \n" /* limit mailbox access */ + " addiu %[count], -1 \n" + " ld %[initfunc], 0x20(%[base]) \n" /* get PC via mailbox */ + " beqz %[initfunc], 1b \n" + " nop \n" + " ld $sp, 0x28(%[base]) \n" /* get SP via mailbox */ + " ld $gp, 0x30(%[base]) \n" /* get GP via mailbox */ + " ld $a1, 0x38(%[base]) \n" + " jr %[initfunc] \n" /* jump to initial PC */ + " nop \n" + " .set pop \n" + : [core] "=&r" (core), [node] "=&r" (node), + [base] "=&r" (base), [cpuid] "=&r" (cpuid), + [count] "=&r" (count), [initfunc] "=&r" (initfunc) + : /* No Input */ + : "a1"); +} + static void loongson3b_play_dead(int *state_addr) { register int val; @@ -572,13 +655,18 @@ void play_dead(void) void (*play_dead_at_ckseg1)(int *); idle_task_exit(); - switch (loongson_sysconf.cputype) { - case Loongson_3A: + switch (read_c0_prid() & PRID_REV_MASK) { + case PRID_REV_LOONGSON3A_R1: default: play_dead_at_ckseg1 = - (void *)CKSEG1ADDR((unsigned long)loongson3a_play_dead); + (void *)CKSEG1ADDR((unsigned long)loongson3a_r1_play_dead); + break; + case PRID_REV_LOONGSON3A_R2: + play_dead_at_ckseg1 = + (void *)CKSEG1ADDR((unsigned long)loongson3a_r2_play_dead); break; - case Loongson_3B: + case PRID_REV_LOONGSON3B_R1: + case PRID_REV_LOONGSON3B_R2: play_dead_at_ckseg1 = (void *)CKSEG1ADDR((unsigned long)loongson3b_play_dead); break; @@ -593,9 +681,9 @@ void loongson3_disable_clock(int cpu) uint64_t core_id = cpu_data[cpu].core; uint64_t package_id = cpu_data[cpu].package; - if (loongson_sysconf.cputype == Loongson_3A) { + if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) { LOONGSON_CHIPCFG(package_id) &= ~(1 << (12 + core_id)); - } else if (loongson_sysconf.cputype == Loongson_3B) { + } else { if (!(loongson_sysconf.workarounds & WORKAROUND_CPUHOTPLUG)) LOONGSON_FREQCTRL(package_id) &= ~(1 << (core_id * 4 + 3)); } @@ -606,9 +694,9 @@ void loongson3_enable_clock(int cpu) uint64_t core_id = cpu_data[cpu].core; uint64_t package_id = cpu_data[cpu].package; - if (loongson_sysconf.cputype == Loongson_3A) { + if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) { LOONGSON_CHIPCFG(package_id) |= 1 << (12 + core_id); - } else if (loongson_sysconf.cputype == Loongson_3B) { + } else { if (!(loongson_sysconf.workarounds & WORKAROUND_CPUHOTPLUG)) LOONGSON_FREQCTRL(package_id) |= 1 << (core_id * 4 + 3); } diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 6f43bdf9a679..77fbaf1cdfd6 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -77,6 +77,7 @@ static inline void r4k_on_each_cpu(void (*func) (void *info), void *info) */ static unsigned long icache_size __read_mostly; static unsigned long dcache_size __read_mostly; +static unsigned long vcache_size __read_mostly; static unsigned long scache_size __read_mostly; /* @@ -1349,6 +1350,31 @@ static void probe_pcache(void) c->dcache.linesz); } +static void probe_vcache(void) +{ + struct cpuinfo_mips *c = ¤t_cpu_data; + unsigned int config2, lsize; + + if (current_cpu_type() != CPU_LOONGSON3) + return; + + config2 = read_c0_config2(); + if ((lsize = ((config2 >> 20) & 15))) + c->vcache.linesz = 2 << lsize; + else + c->vcache.linesz = lsize; + + c->vcache.sets = 64 << ((config2 >> 24) & 15); + c->vcache.ways = 1 + ((config2 >> 16) & 15); + + vcache_size = c->vcache.sets * c->vcache.ways * c->vcache.linesz; + + c->vcache.waybit = 0; + + pr_info("Unified victim cache %ldkB %s, linesize %d bytes.\n", + vcache_size >> 10, way_string[c->vcache.ways], c->vcache.linesz); +} + /* * If you even _breathe_ on this function, look at the gcc output and make sure * it does not pop things on and off the stack for the cache sizing loop that @@ -1671,6 +1697,7 @@ void r4k_cache_init(void) struct cpuinfo_mips *c = ¤t_cpu_data; probe_pcache(); + probe_vcache(); setup_scache(); r4k_blast_dcache_page_setup(); diff --git a/drivers/platform/mips/cpu_hwmon.c b/drivers/platform/mips/cpu_hwmon.c index 0f6c63e17049..8c5072b7ad4f 100644 --- a/drivers/platform/mips/cpu_hwmon.c +++ b/drivers/platform/mips/cpu_hwmon.c @@ -20,9 +20,9 @@ int loongson3_cpu_temp(int cpu) u32 reg; reg = LOONGSON_CHIPTEMP(cpu); - if (loongson_sysconf.cputype == Loongson_3A) + if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) reg = (reg >> 8) & 0xff; - else if (loongson_sysconf.cputype == Loongson_3B) + else reg = ((reg >> 8) & 0xff) - 100; return (int)reg * 1000; -- cgit v1.2.3