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> 21bdc92d74SRalf Baechle #include <asm/idle.h> 2249f2ec91SRalf Baechle #include <asm/mipsregs.h> 2349f2ec91SRalf Baechle 2449f2ec91SRalf Baechle /* 2549f2ec91SRalf Baechle * Not all of the MIPS CPUs have the "wait" instruction available. Moreover, 2649f2ec91SRalf Baechle * the implementation of the "wait" feature differs between CPU families. This 2749f2ec91SRalf Baechle * points to the function that implements CPU specific wait. 2849f2ec91SRalf Baechle * The wait instruction stops the pipeline and reduces the power consumption of 2949f2ec91SRalf Baechle * the CPU very much. 3049f2ec91SRalf Baechle */ 3149f2ec91SRalf Baechle void (*cpu_wait)(void); 3249f2ec91SRalf Baechle EXPORT_SYMBOL(cpu_wait); 3349f2ec91SRalf Baechle 3449f2ec91SRalf Baechle static void r3081_wait(void) 3549f2ec91SRalf Baechle { 3649f2ec91SRalf Baechle unsigned long cfg = read_c0_conf(); 3749f2ec91SRalf Baechle write_c0_conf(cfg | R30XX_CONF_HALT); 38fb40bc3eSRalf Baechle local_irq_enable(); 3949f2ec91SRalf Baechle } 4049f2ec91SRalf Baechle 4149f2ec91SRalf Baechle static void r39xx_wait(void) 4249f2ec91SRalf Baechle { 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 /* 4949f2ec91SRalf Baechle * This variant is preferable as it allows testing need_resched and going to 5049f2ec91SRalf Baechle * sleep depending on the outcome atomically. Unfortunately the "It is 5149f2ec91SRalf Baechle * implementation-dependent whether the pipeline restarts when a non-enabled 5249f2ec91SRalf Baechle * interrupt is requested" restriction in the MIPS32/MIPS64 architecture makes 5349f2ec91SRalf Baechle * using this version a gamble. 5449f2ec91SRalf Baechle */ 5549f2ec91SRalf Baechle void r4k_wait_irqoff(void) 5649f2ec91SRalf Baechle { 5749f2ec91SRalf Baechle if (!need_resched()) 58f91a148aSRalf Baechle __asm__( 59f91a148aSRalf Baechle " .set push \n" 6049f2ec91SRalf Baechle " .set mips3 \n" 6149f2ec91SRalf Baechle " wait \n" 6249f2ec91SRalf Baechle " .set pop \n"); 6349f2ec91SRalf Baechle local_irq_enable(); 64f91a148aSRalf Baechle __asm__( 65f91a148aSRalf Baechle " .globl __pastwait \n" 6649f2ec91SRalf Baechle "__pastwait: \n"); 6749f2ec91SRalf Baechle } 6849f2ec91SRalf Baechle 6949f2ec91SRalf Baechle /* 7049f2ec91SRalf Baechle * The RM7000 variant has to handle erratum 38. The workaround is to not 7149f2ec91SRalf Baechle * have any pending stores when the WAIT instruction is executed. 7249f2ec91SRalf Baechle */ 7349f2ec91SRalf Baechle static void rm7k_wait_irqoff(void) 7449f2ec91SRalf Baechle { 7549f2ec91SRalf Baechle if (!need_resched()) 7649f2ec91SRalf Baechle __asm__( 7749f2ec91SRalf Baechle " .set push \n" 7849f2ec91SRalf Baechle " .set mips3 \n" 7949f2ec91SRalf Baechle " .set noat \n" 8049f2ec91SRalf Baechle " mfc0 $1, $12 \n" 8149f2ec91SRalf Baechle " sync \n" 8249f2ec91SRalf Baechle " mtc0 $1, $12 # stalls until W stage \n" 8349f2ec91SRalf Baechle " wait \n" 8449f2ec91SRalf Baechle " mtc0 $1, $12 # stalls until W stage \n" 8549f2ec91SRalf Baechle " .set pop \n"); 8649f2ec91SRalf Baechle local_irq_enable(); 8749f2ec91SRalf Baechle } 8849f2ec91SRalf Baechle 8949f2ec91SRalf Baechle /* 9049f2ec91SRalf Baechle * The Au1xxx wait is available only if using 32khz counter or 9149f2ec91SRalf Baechle * external timer source, but specifically not CP0 Counter. 9249f2ec91SRalf Baechle * alchemy/common/time.c may override cpu_wait! 9349f2ec91SRalf Baechle */ 9449f2ec91SRalf Baechle static void au1k_wait(void) 9549f2ec91SRalf Baechle { 96f91a148aSRalf Baechle __asm__( 97f91a148aSRalf Baechle " .set mips3 \n" 9849f2ec91SRalf Baechle " cache 0x14, 0(%0) \n" 9949f2ec91SRalf Baechle " cache 0x14, 32(%0) \n" 10049f2ec91SRalf Baechle " sync \n" 10149f2ec91SRalf Baechle " nop \n" 10249f2ec91SRalf Baechle " wait \n" 10349f2ec91SRalf Baechle " nop \n" 10449f2ec91SRalf Baechle " nop \n" 10549f2ec91SRalf Baechle " nop \n" 10649f2ec91SRalf Baechle " nop \n" 10749f2ec91SRalf Baechle " .set mips0 \n" 10849f2ec91SRalf Baechle : : "r" (au1k_wait)); 109fb40bc3eSRalf Baechle local_irq_enable(); 11049f2ec91SRalf Baechle } 11149f2ec91SRalf Baechle 11249f2ec91SRalf Baechle static int __initdata nowait; 11349f2ec91SRalf Baechle 11449f2ec91SRalf Baechle static int __init wait_disable(char *s) 11549f2ec91SRalf Baechle { 11649f2ec91SRalf Baechle nowait = 1; 11749f2ec91SRalf Baechle 11849f2ec91SRalf Baechle return 1; 11949f2ec91SRalf Baechle } 12049f2ec91SRalf Baechle 12149f2ec91SRalf Baechle __setup("nowait", wait_disable); 12249f2ec91SRalf Baechle 12349f2ec91SRalf Baechle void __init check_wait(void) 12449f2ec91SRalf Baechle { 12549f2ec91SRalf Baechle struct cpuinfo_mips *c = ¤t_cpu_data; 12649f2ec91SRalf Baechle 12749f2ec91SRalf Baechle if (nowait) { 12849f2ec91SRalf Baechle printk("Wait instruction disabled.\n"); 12949f2ec91SRalf Baechle return; 13049f2ec91SRalf Baechle } 13149f2ec91SRalf Baechle 13249f2ec91SRalf Baechle switch (c->cputype) { 13349f2ec91SRalf Baechle case CPU_R3081: 13449f2ec91SRalf Baechle case CPU_R3081E: 13549f2ec91SRalf Baechle cpu_wait = r3081_wait; 13649f2ec91SRalf Baechle break; 13749f2ec91SRalf Baechle case CPU_TX3927: 13849f2ec91SRalf Baechle cpu_wait = r39xx_wait; 13949f2ec91SRalf Baechle break; 14049f2ec91SRalf Baechle case CPU_R4200: 14149f2ec91SRalf Baechle /* case CPU_R4300: */ 14249f2ec91SRalf Baechle case CPU_R4600: 14349f2ec91SRalf Baechle case CPU_R4640: 14449f2ec91SRalf Baechle case CPU_R4650: 14549f2ec91SRalf Baechle case CPU_R4700: 14649f2ec91SRalf Baechle case CPU_R5000: 14749f2ec91SRalf Baechle case CPU_R5500: 14849f2ec91SRalf Baechle case CPU_NEVADA: 14949f2ec91SRalf Baechle case CPU_4KC: 15049f2ec91SRalf Baechle case CPU_4KEC: 15149f2ec91SRalf Baechle case CPU_4KSC: 15249f2ec91SRalf Baechle case CPU_5KC: 15349f2ec91SRalf Baechle case CPU_25KF: 15449f2ec91SRalf Baechle case CPU_PR4450: 15549f2ec91SRalf Baechle case CPU_BMIPS3300: 15649f2ec91SRalf Baechle case CPU_BMIPS4350: 15749f2ec91SRalf Baechle case CPU_BMIPS4380: 15849f2ec91SRalf Baechle case CPU_BMIPS5000: 15949f2ec91SRalf Baechle case CPU_CAVIUM_OCTEON: 16049f2ec91SRalf Baechle case CPU_CAVIUM_OCTEON_PLUS: 16149f2ec91SRalf Baechle case CPU_CAVIUM_OCTEON2: 16249f2ec91SRalf Baechle case CPU_JZRISC: 16349f2ec91SRalf Baechle case CPU_LOONGSON1: 16449f2ec91SRalf Baechle case CPU_XLR: 16549f2ec91SRalf Baechle case CPU_XLP: 16649f2ec91SRalf Baechle cpu_wait = r4k_wait; 16749f2ec91SRalf Baechle break; 16849f2ec91SRalf Baechle 16949f2ec91SRalf Baechle case CPU_RM7000: 17049f2ec91SRalf Baechle cpu_wait = rm7k_wait_irqoff; 17149f2ec91SRalf Baechle break; 17249f2ec91SRalf Baechle 17349f2ec91SRalf Baechle case CPU_M14KC: 17449f2ec91SRalf Baechle case CPU_M14KEC: 17549f2ec91SRalf Baechle case CPU_24K: 17649f2ec91SRalf Baechle case CPU_34K: 17749f2ec91SRalf Baechle case CPU_1004K: 17849f2ec91SRalf Baechle cpu_wait = r4k_wait; 17949f2ec91SRalf Baechle if (read_c0_config7() & MIPS_CONF7_WII) 18049f2ec91SRalf Baechle cpu_wait = r4k_wait_irqoff; 18149f2ec91SRalf Baechle break; 18249f2ec91SRalf Baechle 18349f2ec91SRalf Baechle case CPU_74K: 18449f2ec91SRalf Baechle cpu_wait = r4k_wait; 18549f2ec91SRalf Baechle if ((c->processor_id & 0xff) >= PRID_REV_ENCODE_332(2, 1, 0)) 18649f2ec91SRalf Baechle cpu_wait = r4k_wait_irqoff; 18749f2ec91SRalf Baechle break; 18849f2ec91SRalf Baechle 18949f2ec91SRalf Baechle case CPU_TX49XX: 19049f2ec91SRalf Baechle cpu_wait = r4k_wait_irqoff; 19149f2ec91SRalf Baechle break; 19249f2ec91SRalf Baechle case CPU_ALCHEMY: 19349f2ec91SRalf Baechle cpu_wait = au1k_wait; 19449f2ec91SRalf Baechle break; 19549f2ec91SRalf Baechle case CPU_20KC: 19649f2ec91SRalf Baechle /* 19749f2ec91SRalf Baechle * WAIT on Rev1.0 has E1, E2, E3 and E16. 19849f2ec91SRalf Baechle * WAIT on Rev2.0 and Rev3.0 has E16. 19949f2ec91SRalf Baechle * Rev3.1 WAIT is nop, why bother 20049f2ec91SRalf Baechle */ 20149f2ec91SRalf Baechle if ((c->processor_id & 0xff) <= 0x64) 20249f2ec91SRalf Baechle break; 20349f2ec91SRalf Baechle 20449f2ec91SRalf Baechle /* 20549f2ec91SRalf Baechle * Another rev is incremeting c0_count at a reduced clock 20649f2ec91SRalf Baechle * rate while in WAIT mode. So we basically have the choice 20749f2ec91SRalf Baechle * between using the cp0 timer as clocksource or avoiding 20849f2ec91SRalf Baechle * the WAIT instruction. Until more details are known, 20949f2ec91SRalf Baechle * disable the use of WAIT for 20Kc entirely. 21049f2ec91SRalf Baechle cpu_wait = r4k_wait; 21149f2ec91SRalf Baechle */ 21249f2ec91SRalf Baechle break; 21349f2ec91SRalf Baechle case CPU_RM9000: 21449f2ec91SRalf Baechle if ((c->processor_id & 0x00ff) >= 0x40) 21549f2ec91SRalf Baechle cpu_wait = r4k_wait; 21649f2ec91SRalf Baechle break; 21749f2ec91SRalf Baechle default: 21849f2ec91SRalf Baechle break; 21949f2ec91SRalf Baechle } 22049f2ec91SRalf Baechle } 22149f2ec91SRalf Baechle 22200baf857SRalf Baechle static void smtc_idle_hook(void) 22349f2ec91SRalf Baechle { 22449f2ec91SRalf Baechle #ifdef CONFIG_MIPS_MT_SMTC 22500baf857SRalf Baechle void smtc_idle_loop_hook(void); 22649f2ec91SRalf Baechle 22749f2ec91SRalf Baechle smtc_idle_loop_hook(); 22849f2ec91SRalf Baechle #endif 22900baf857SRalf Baechle } 23000baf857SRalf Baechle 23100baf857SRalf Baechle void arch_cpu_idle(void) 23200baf857SRalf Baechle { 23300baf857SRalf Baechle smtc_idle_hook(); 23449f2ec91SRalf Baechle if (cpu_wait) 235c9b6869dSRalf Baechle cpu_wait(); 23649f2ec91SRalf Baechle else 23749f2ec91SRalf Baechle local_irq_enable(); 23849f2ec91SRalf Baechle } 239