149f2ec91SRalf Baechle /* 249f2ec91SRalf Baechle * MIPS idle loop and WAIT instruction support. 349f2ec91SRalf Baechle * 449f2ec91SRalf Baechle * Copyright (C) xxxx the Anonymous 549f2ec91SRalf Baechle * Copyright (C) 1994 - 2006 Ralf Baechle 649f2ec91SRalf Baechle * Copyright (C) 2003, 2004 Maciej W. Rozycki 749f2ec91SRalf Baechle * Copyright (C) 2001, 2004, 2011, 2012 MIPS Technologies, Inc. 849f2ec91SRalf Baechle * 949f2ec91SRalf Baechle * This program is free software; you can redistribute it and/or 1049f2ec91SRalf Baechle * modify it under the terms of the GNU General Public License 1149f2ec91SRalf Baechle * as published by the Free Software Foundation; either version 1249f2ec91SRalf Baechle * 2 of the License, or (at your option) any later version. 1349f2ec91SRalf Baechle */ 1449f2ec91SRalf Baechle #include <linux/export.h> 1549f2ec91SRalf Baechle #include <linux/init.h> 1649f2ec91SRalf Baechle #include <linux/irqflags.h> 1749f2ec91SRalf Baechle #include <linux/printk.h> 1849f2ec91SRalf Baechle #include <linux/sched.h> 1949f2ec91SRalf Baechle #include <asm/cpu.h> 2049f2ec91SRalf Baechle #include <asm/cpu-info.h> 2149f2ec91SRalf Baechle #include <asm/mipsregs.h> 2249f2ec91SRalf Baechle 2349f2ec91SRalf Baechle /* 2449f2ec91SRalf Baechle * Not all of the MIPS CPUs have the "wait" instruction available. Moreover, 2549f2ec91SRalf Baechle * the implementation of the "wait" feature differs between CPU families. This 2649f2ec91SRalf Baechle * points to the function that implements CPU specific wait. 2749f2ec91SRalf Baechle * The wait instruction stops the pipeline and reduces the power consumption of 2849f2ec91SRalf Baechle * the CPU very much. 2949f2ec91SRalf Baechle */ 3049f2ec91SRalf Baechle void (*cpu_wait)(void); 3149f2ec91SRalf Baechle EXPORT_SYMBOL(cpu_wait); 3249f2ec91SRalf Baechle 3349f2ec91SRalf Baechle static void r3081_wait(void) 3449f2ec91SRalf Baechle { 3549f2ec91SRalf Baechle unsigned long cfg = read_c0_conf(); 3649f2ec91SRalf Baechle write_c0_conf(cfg | R30XX_CONF_HALT); 37fb40bc3eSRalf Baechle local_irq_enable(); 3849f2ec91SRalf Baechle } 3949f2ec91SRalf Baechle 4049f2ec91SRalf Baechle static void r39xx_wait(void) 4149f2ec91SRalf Baechle { 4249f2ec91SRalf Baechle local_irq_disable(); 4349f2ec91SRalf Baechle if (!need_resched()) 4449f2ec91SRalf Baechle write_c0_conf(read_c0_conf() | TX39_CONF_HALT); 4549f2ec91SRalf Baechle local_irq_enable(); 4649f2ec91SRalf Baechle } 4749f2ec91SRalf Baechle 4849f2ec91SRalf Baechle extern void r4k_wait(void); 4949f2ec91SRalf Baechle 5049f2ec91SRalf Baechle /* 5149f2ec91SRalf Baechle * This variant is preferable as it allows testing need_resched and going to 5249f2ec91SRalf Baechle * sleep depending on the outcome atomically. Unfortunately the "It is 5349f2ec91SRalf Baechle * implementation-dependent whether the pipeline restarts when a non-enabled 5449f2ec91SRalf Baechle * interrupt is requested" restriction in the MIPS32/MIPS64 architecture makes 5549f2ec91SRalf Baechle * using this version a gamble. 5649f2ec91SRalf Baechle */ 5749f2ec91SRalf Baechle void r4k_wait_irqoff(void) 5849f2ec91SRalf Baechle { 5949f2ec91SRalf Baechle local_irq_disable(); 6049f2ec91SRalf Baechle if (!need_resched()) 61f91a148aSRalf Baechle __asm__( 62f91a148aSRalf Baechle " .set push \n" 6349f2ec91SRalf Baechle " .set mips3 \n" 6449f2ec91SRalf Baechle " wait \n" 6549f2ec91SRalf Baechle " .set pop \n"); 6649f2ec91SRalf Baechle local_irq_enable(); 67f91a148aSRalf Baechle __asm__( 68f91a148aSRalf Baechle " .globl __pastwait \n" 6949f2ec91SRalf Baechle "__pastwait: \n"); 7049f2ec91SRalf Baechle } 7149f2ec91SRalf Baechle 7249f2ec91SRalf Baechle /* 7349f2ec91SRalf Baechle * The RM7000 variant has to handle erratum 38. The workaround is to not 7449f2ec91SRalf Baechle * have any pending stores when the WAIT instruction is executed. 7549f2ec91SRalf Baechle */ 7649f2ec91SRalf Baechle static void rm7k_wait_irqoff(void) 7749f2ec91SRalf Baechle { 7849f2ec91SRalf Baechle local_irq_disable(); 7949f2ec91SRalf Baechle if (!need_resched()) 8049f2ec91SRalf Baechle __asm__( 8149f2ec91SRalf Baechle " .set push \n" 8249f2ec91SRalf Baechle " .set mips3 \n" 8349f2ec91SRalf Baechle " .set noat \n" 8449f2ec91SRalf Baechle " mfc0 $1, $12 \n" 8549f2ec91SRalf Baechle " sync \n" 8649f2ec91SRalf Baechle " mtc0 $1, $12 # stalls until W stage \n" 8749f2ec91SRalf Baechle " wait \n" 8849f2ec91SRalf Baechle " mtc0 $1, $12 # stalls until W stage \n" 8949f2ec91SRalf Baechle " .set pop \n"); 9049f2ec91SRalf Baechle local_irq_enable(); 9149f2ec91SRalf Baechle } 9249f2ec91SRalf Baechle 9349f2ec91SRalf Baechle /* 9449f2ec91SRalf Baechle * The Au1xxx wait is available only if using 32khz counter or 9549f2ec91SRalf Baechle * external timer source, but specifically not CP0 Counter. 9649f2ec91SRalf Baechle * alchemy/common/time.c may override cpu_wait! 9749f2ec91SRalf Baechle */ 9849f2ec91SRalf Baechle static void au1k_wait(void) 9949f2ec91SRalf Baechle { 100f91a148aSRalf Baechle __asm__( 101f91a148aSRalf Baechle " .set mips3 \n" 10249f2ec91SRalf Baechle " cache 0x14, 0(%0) \n" 10349f2ec91SRalf Baechle " cache 0x14, 32(%0) \n" 10449f2ec91SRalf Baechle " sync \n" 10549f2ec91SRalf Baechle " nop \n" 10649f2ec91SRalf Baechle " wait \n" 10749f2ec91SRalf Baechle " nop \n" 10849f2ec91SRalf Baechle " nop \n" 10949f2ec91SRalf Baechle " nop \n" 11049f2ec91SRalf Baechle " nop \n" 11149f2ec91SRalf Baechle " .set mips0 \n" 11249f2ec91SRalf Baechle : : "r" (au1k_wait)); 113fb40bc3eSRalf Baechle local_irq_enable(); 11449f2ec91SRalf Baechle } 11549f2ec91SRalf Baechle 11649f2ec91SRalf Baechle static int __initdata nowait; 11749f2ec91SRalf Baechle 11849f2ec91SRalf Baechle static int __init wait_disable(char *s) 11949f2ec91SRalf Baechle { 12049f2ec91SRalf Baechle nowait = 1; 12149f2ec91SRalf Baechle 12249f2ec91SRalf Baechle return 1; 12349f2ec91SRalf Baechle } 12449f2ec91SRalf Baechle 12549f2ec91SRalf Baechle __setup("nowait", wait_disable); 12649f2ec91SRalf Baechle 12749f2ec91SRalf Baechle void __init check_wait(void) 12849f2ec91SRalf Baechle { 12949f2ec91SRalf Baechle struct cpuinfo_mips *c = ¤t_cpu_data; 13049f2ec91SRalf Baechle 13149f2ec91SRalf Baechle if (nowait) { 13249f2ec91SRalf Baechle printk("Wait instruction disabled.\n"); 13349f2ec91SRalf Baechle return; 13449f2ec91SRalf Baechle } 13549f2ec91SRalf Baechle 13649f2ec91SRalf Baechle switch (c->cputype) { 13749f2ec91SRalf Baechle case CPU_R3081: 13849f2ec91SRalf Baechle case CPU_R3081E: 13949f2ec91SRalf Baechle cpu_wait = r3081_wait; 14049f2ec91SRalf Baechle break; 14149f2ec91SRalf Baechle case CPU_TX3927: 14249f2ec91SRalf Baechle cpu_wait = r39xx_wait; 14349f2ec91SRalf Baechle break; 14449f2ec91SRalf Baechle case CPU_R4200: 14549f2ec91SRalf Baechle /* case CPU_R4300: */ 14649f2ec91SRalf Baechle case CPU_R4600: 14749f2ec91SRalf Baechle case CPU_R4640: 14849f2ec91SRalf Baechle case CPU_R4650: 14949f2ec91SRalf Baechle case CPU_R4700: 15049f2ec91SRalf Baechle case CPU_R5000: 15149f2ec91SRalf Baechle case CPU_R5500: 15249f2ec91SRalf Baechle case CPU_NEVADA: 15349f2ec91SRalf Baechle case CPU_4KC: 15449f2ec91SRalf Baechle case CPU_4KEC: 15549f2ec91SRalf Baechle case CPU_4KSC: 15649f2ec91SRalf Baechle case CPU_5KC: 15749f2ec91SRalf Baechle case CPU_25KF: 15849f2ec91SRalf Baechle case CPU_PR4450: 15949f2ec91SRalf Baechle case CPU_BMIPS3300: 16049f2ec91SRalf Baechle case CPU_BMIPS4350: 16149f2ec91SRalf Baechle case CPU_BMIPS4380: 16249f2ec91SRalf Baechle case CPU_BMIPS5000: 16349f2ec91SRalf Baechle case CPU_CAVIUM_OCTEON: 16449f2ec91SRalf Baechle case CPU_CAVIUM_OCTEON_PLUS: 16549f2ec91SRalf Baechle case CPU_CAVIUM_OCTEON2: 16649f2ec91SRalf Baechle case CPU_JZRISC: 16749f2ec91SRalf Baechle case CPU_LOONGSON1: 16849f2ec91SRalf Baechle case CPU_XLR: 16949f2ec91SRalf Baechle case CPU_XLP: 17049f2ec91SRalf Baechle cpu_wait = r4k_wait; 17149f2ec91SRalf Baechle break; 17249f2ec91SRalf Baechle 17349f2ec91SRalf Baechle case CPU_RM7000: 17449f2ec91SRalf Baechle cpu_wait = rm7k_wait_irqoff; 17549f2ec91SRalf Baechle break; 17649f2ec91SRalf Baechle 17749f2ec91SRalf Baechle case CPU_M14KC: 17849f2ec91SRalf Baechle case CPU_M14KEC: 17949f2ec91SRalf Baechle case CPU_24K: 18049f2ec91SRalf Baechle case CPU_34K: 18149f2ec91SRalf Baechle case CPU_1004K: 18249f2ec91SRalf Baechle cpu_wait = r4k_wait; 18349f2ec91SRalf Baechle if (read_c0_config7() & MIPS_CONF7_WII) 18449f2ec91SRalf Baechle cpu_wait = r4k_wait_irqoff; 18549f2ec91SRalf Baechle break; 18649f2ec91SRalf Baechle 18749f2ec91SRalf Baechle case CPU_74K: 18849f2ec91SRalf Baechle cpu_wait = r4k_wait; 18949f2ec91SRalf Baechle if ((c->processor_id & 0xff) >= PRID_REV_ENCODE_332(2, 1, 0)) 19049f2ec91SRalf Baechle cpu_wait = r4k_wait_irqoff; 19149f2ec91SRalf Baechle break; 19249f2ec91SRalf Baechle 19349f2ec91SRalf Baechle case CPU_TX49XX: 19449f2ec91SRalf Baechle cpu_wait = r4k_wait_irqoff; 19549f2ec91SRalf Baechle break; 19649f2ec91SRalf Baechle case CPU_ALCHEMY: 19749f2ec91SRalf Baechle cpu_wait = au1k_wait; 19849f2ec91SRalf Baechle break; 19949f2ec91SRalf Baechle case CPU_20KC: 20049f2ec91SRalf Baechle /* 20149f2ec91SRalf Baechle * WAIT on Rev1.0 has E1, E2, E3 and E16. 20249f2ec91SRalf Baechle * WAIT on Rev2.0 and Rev3.0 has E16. 20349f2ec91SRalf Baechle * Rev3.1 WAIT is nop, why bother 20449f2ec91SRalf Baechle */ 20549f2ec91SRalf Baechle if ((c->processor_id & 0xff) <= 0x64) 20649f2ec91SRalf Baechle break; 20749f2ec91SRalf Baechle 20849f2ec91SRalf Baechle /* 20949f2ec91SRalf Baechle * Another rev is incremeting c0_count at a reduced clock 21049f2ec91SRalf Baechle * rate while in WAIT mode. So we basically have the choice 21149f2ec91SRalf Baechle * between using the cp0 timer as clocksource or avoiding 21249f2ec91SRalf Baechle * the WAIT instruction. Until more details are known, 21349f2ec91SRalf Baechle * disable the use of WAIT for 20Kc entirely. 21449f2ec91SRalf Baechle cpu_wait = r4k_wait; 21549f2ec91SRalf Baechle */ 21649f2ec91SRalf Baechle break; 21749f2ec91SRalf Baechle case CPU_RM9000: 21849f2ec91SRalf Baechle if ((c->processor_id & 0x00ff) >= 0x40) 21949f2ec91SRalf Baechle cpu_wait = r4k_wait; 22049f2ec91SRalf Baechle break; 22149f2ec91SRalf Baechle default: 22249f2ec91SRalf Baechle break; 22349f2ec91SRalf Baechle } 22449f2ec91SRalf Baechle } 22549f2ec91SRalf Baechle 22600baf857SRalf Baechle static void smtc_idle_hook(void) 22749f2ec91SRalf Baechle { 22849f2ec91SRalf Baechle #ifdef CONFIG_MIPS_MT_SMTC 22900baf857SRalf Baechle void smtc_idle_loop_hook(void); 23049f2ec91SRalf Baechle 23149f2ec91SRalf Baechle smtc_idle_loop_hook(); 23249f2ec91SRalf Baechle #endif 23300baf857SRalf Baechle } 23400baf857SRalf Baechle 23500baf857SRalf Baechle void arch_cpu_idle(void) 23600baf857SRalf Baechle { 23700baf857SRalf Baechle smtc_idle_hook(); 23849f2ec91SRalf Baechle if (cpu_wait) 239c9b6869dSRalf Baechle cpu_wait(); 24049f2ec91SRalf Baechle else 24149f2ec91SRalf Baechle local_irq_enable(); 24249f2ec91SRalf Baechle } 243