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> 2169f24d17SRalf Baechle #include <asm/cpu-type.h> 22bdc92d74SRalf Baechle #include <asm/idle.h> 2349f2ec91SRalf Baechle #include <asm/mipsregs.h> 2449f2ec91SRalf Baechle 2549f2ec91SRalf Baechle /* 2649f2ec91SRalf Baechle * Not all of the MIPS CPUs have the "wait" instruction available. Moreover, 2749f2ec91SRalf Baechle * the implementation of the "wait" feature differs between CPU families. This 2849f2ec91SRalf Baechle * points to the function that implements CPU specific wait. 2949f2ec91SRalf Baechle * The wait instruction stops the pipeline and reduces the power consumption of 3049f2ec91SRalf Baechle * the CPU very much. 3149f2ec91SRalf Baechle */ 3249f2ec91SRalf Baechle void (*cpu_wait)(void); 3349f2ec91SRalf Baechle EXPORT_SYMBOL(cpu_wait); 3449f2ec91SRalf Baechle 3549f2ec91SRalf Baechle static void r3081_wait(void) 3649f2ec91SRalf Baechle { 3749f2ec91SRalf Baechle unsigned long cfg = read_c0_conf(); 3849f2ec91SRalf Baechle write_c0_conf(cfg | R30XX_CONF_HALT); 39fb40bc3eSRalf Baechle local_irq_enable(); 4049f2ec91SRalf Baechle } 4149f2ec91SRalf Baechle 4249f2ec91SRalf Baechle static void r39xx_wait(void) 4349f2ec91SRalf Baechle { 4449f2ec91SRalf Baechle if (!need_resched()) 4549f2ec91SRalf Baechle write_c0_conf(read_c0_conf() | TX39_CONF_HALT); 4649f2ec91SRalf Baechle local_irq_enable(); 4749f2ec91SRalf Baechle } 4849f2ec91SRalf Baechle 49087d990bSRalf Baechle void r4k_wait(void) 50087d990bSRalf Baechle { 51087d990bSRalf Baechle local_irq_enable(); 52087d990bSRalf Baechle __r4k_wait(); 53087d990bSRalf Baechle } 54087d990bSRalf Baechle 5549f2ec91SRalf Baechle /* 5649f2ec91SRalf Baechle * This variant is preferable as it allows testing need_resched and going to 5749f2ec91SRalf Baechle * sleep depending on the outcome atomically. Unfortunately the "It is 5849f2ec91SRalf Baechle * implementation-dependent whether the pipeline restarts when a non-enabled 5949f2ec91SRalf Baechle * interrupt is requested" restriction in the MIPS32/MIPS64 architecture makes 6049f2ec91SRalf Baechle * using this version a gamble. 6149f2ec91SRalf Baechle */ 6249f2ec91SRalf Baechle void r4k_wait_irqoff(void) 6349f2ec91SRalf Baechle { 6449f2ec91SRalf Baechle if (!need_resched()) 65f91a148aSRalf Baechle __asm__( 66f91a148aSRalf Baechle " .set push \n" 67a809d460SRalf Baechle " .set arch=r4000 \n" 6849f2ec91SRalf Baechle " wait \n" 6949f2ec91SRalf Baechle " .set pop \n"); 7049f2ec91SRalf Baechle local_irq_enable(); 71f91a148aSRalf Baechle __asm__( 72f91a148aSRalf Baechle " .globl __pastwait \n" 7349f2ec91SRalf Baechle "__pastwait: \n"); 7449f2ec91SRalf Baechle } 7549f2ec91SRalf Baechle 7649f2ec91SRalf Baechle /* 7749f2ec91SRalf Baechle * The RM7000 variant has to handle erratum 38. The workaround is to not 7849f2ec91SRalf Baechle * have any pending stores when the WAIT instruction is executed. 7949f2ec91SRalf Baechle */ 8049f2ec91SRalf Baechle static void rm7k_wait_irqoff(void) 8149f2ec91SRalf Baechle { 8249f2ec91SRalf Baechle if (!need_resched()) 8349f2ec91SRalf Baechle __asm__( 8449f2ec91SRalf Baechle " .set push \n" 85a809d460SRalf Baechle " .set arch=r4000 \n" 8649f2ec91SRalf Baechle " .set noat \n" 8749f2ec91SRalf Baechle " mfc0 $1, $12 \n" 8849f2ec91SRalf Baechle " sync \n" 8949f2ec91SRalf Baechle " mtc0 $1, $12 # stalls until W stage \n" 9049f2ec91SRalf Baechle " wait \n" 9149f2ec91SRalf Baechle " mtc0 $1, $12 # stalls until W stage \n" 9249f2ec91SRalf Baechle " .set pop \n"); 9349f2ec91SRalf Baechle local_irq_enable(); 9449f2ec91SRalf Baechle } 9549f2ec91SRalf Baechle 9649f2ec91SRalf Baechle /* 97e63a24ddSManuel Lauss * Au1 'wait' is only useful when the 32kHz counter is used as timer, 98e63a24ddSManuel Lauss * since coreclock (and the cp0 counter) stops upon executing it. Only an 99e63a24ddSManuel Lauss * interrupt can wake it, so they must be enabled before entering idle modes. 10049f2ec91SRalf Baechle */ 10149f2ec91SRalf Baechle static void au1k_wait(void) 10249f2ec91SRalf Baechle { 103e63a24ddSManuel Lauss unsigned long c0status = read_c0_status() | 1; /* irqs on */ 104e63a24ddSManuel Lauss 105f91a148aSRalf Baechle __asm__( 106a809d460SRalf Baechle " .set arch=r4000 \n" 10749f2ec91SRalf Baechle " cache 0x14, 0(%0) \n" 10849f2ec91SRalf Baechle " cache 0x14, 32(%0) \n" 10949f2ec91SRalf Baechle " sync \n" 110e63a24ddSManuel Lauss " mtc0 %1, $12 \n" /* wr c0status */ 11149f2ec91SRalf Baechle " wait \n" 11249f2ec91SRalf Baechle " nop \n" 11349f2ec91SRalf Baechle " nop \n" 11449f2ec91SRalf Baechle " nop \n" 11549f2ec91SRalf Baechle " nop \n" 11649f2ec91SRalf Baechle " .set mips0 \n" 117e63a24ddSManuel Lauss : : "r" (au1k_wait), "r" (c0status)); 11849f2ec91SRalf Baechle } 11949f2ec91SRalf Baechle 12049f2ec91SRalf Baechle static int __initdata nowait; 12149f2ec91SRalf Baechle 12249f2ec91SRalf Baechle static int __init wait_disable(char *s) 12349f2ec91SRalf Baechle { 12449f2ec91SRalf Baechle nowait = 1; 12549f2ec91SRalf Baechle 12649f2ec91SRalf Baechle return 1; 12749f2ec91SRalf Baechle } 12849f2ec91SRalf Baechle 12949f2ec91SRalf Baechle __setup("nowait", wait_disable); 13049f2ec91SRalf Baechle 13149f2ec91SRalf Baechle void __init check_wait(void) 13249f2ec91SRalf Baechle { 13349f2ec91SRalf Baechle struct cpuinfo_mips *c = ¤t_cpu_data; 13449f2ec91SRalf Baechle 13549f2ec91SRalf Baechle if (nowait) { 13649f2ec91SRalf Baechle printk("Wait instruction disabled.\n"); 13749f2ec91SRalf Baechle return; 13849f2ec91SRalf Baechle } 13949f2ec91SRalf Baechle 14069f24d17SRalf Baechle switch (current_cpu_type()) { 14149f2ec91SRalf Baechle case CPU_R3081: 14249f2ec91SRalf Baechle case CPU_R3081E: 14349f2ec91SRalf Baechle cpu_wait = r3081_wait; 14449f2ec91SRalf Baechle break; 14549f2ec91SRalf Baechle case CPU_TX3927: 14649f2ec91SRalf Baechle cpu_wait = r39xx_wait; 14749f2ec91SRalf Baechle break; 14849f2ec91SRalf Baechle case CPU_R4200: 14949f2ec91SRalf Baechle /* case CPU_R4300: */ 15049f2ec91SRalf Baechle case CPU_R4600: 15149f2ec91SRalf Baechle case CPU_R4640: 15249f2ec91SRalf Baechle case CPU_R4650: 15349f2ec91SRalf Baechle case CPU_R4700: 15449f2ec91SRalf Baechle case CPU_R5000: 15549f2ec91SRalf Baechle case CPU_R5500: 15649f2ec91SRalf Baechle case CPU_NEVADA: 15749f2ec91SRalf Baechle case CPU_4KC: 15849f2ec91SRalf Baechle case CPU_4KEC: 15949f2ec91SRalf Baechle case CPU_4KSC: 16049f2ec91SRalf Baechle case CPU_5KC: 16149f2ec91SRalf Baechle case CPU_25KF: 16249f2ec91SRalf Baechle case CPU_PR4450: 16349f2ec91SRalf Baechle case CPU_BMIPS3300: 16449f2ec91SRalf Baechle case CPU_BMIPS4350: 16549f2ec91SRalf Baechle case CPU_BMIPS4380: 16649f2ec91SRalf Baechle case CPU_BMIPS5000: 16749f2ec91SRalf Baechle case CPU_CAVIUM_OCTEON: 16849f2ec91SRalf Baechle case CPU_CAVIUM_OCTEON_PLUS: 16949f2ec91SRalf Baechle case CPU_CAVIUM_OCTEON2: 1704122af0aSDavid Daney case CPU_CAVIUM_OCTEON3: 17149f2ec91SRalf Baechle case CPU_JZRISC: 17249f2ec91SRalf Baechle case CPU_LOONGSON1: 17349f2ec91SRalf Baechle case CPU_XLR: 17449f2ec91SRalf Baechle case CPU_XLP: 17549f2ec91SRalf Baechle cpu_wait = r4k_wait; 17649f2ec91SRalf Baechle break; 17749f2ec91SRalf Baechle 17849f2ec91SRalf Baechle case CPU_RM7000: 17949f2ec91SRalf Baechle cpu_wait = rm7k_wait_irqoff; 18049f2ec91SRalf Baechle break; 18149f2ec91SRalf Baechle 18249f2ec91SRalf Baechle case CPU_M14KC: 18349f2ec91SRalf Baechle case CPU_M14KEC: 18449f2ec91SRalf Baechle case CPU_24K: 18549f2ec91SRalf Baechle case CPU_34K: 18649f2ec91SRalf Baechle case CPU_1004K: 187442e14a2SSteven J. Hill case CPU_1074K: 18826ab96dfSLeonid Yegoshin case CPU_INTERAPTIV: 189708ac4b8SLeonid Yegoshin case CPU_PROAPTIV: 190aced4cbdSJames Hogan case CPU_P5600: 191f36c4720SLeonid Yegoshin case CPU_M5150: 19249f2ec91SRalf Baechle cpu_wait = r4k_wait; 19349f2ec91SRalf Baechle if (read_c0_config7() & MIPS_CONF7_WII) 19449f2ec91SRalf Baechle cpu_wait = r4k_wait_irqoff; 19549f2ec91SRalf Baechle break; 19649f2ec91SRalf Baechle 19749f2ec91SRalf Baechle case CPU_74K: 19849f2ec91SRalf Baechle cpu_wait = r4k_wait; 19949f2ec91SRalf Baechle if ((c->processor_id & 0xff) >= PRID_REV_ENCODE_332(2, 1, 0)) 20049f2ec91SRalf Baechle cpu_wait = r4k_wait_irqoff; 20149f2ec91SRalf Baechle break; 20249f2ec91SRalf Baechle 20349f2ec91SRalf Baechle case CPU_TX49XX: 20449f2ec91SRalf Baechle cpu_wait = r4k_wait_irqoff; 20549f2ec91SRalf Baechle break; 20649f2ec91SRalf Baechle case CPU_ALCHEMY: 20749f2ec91SRalf Baechle cpu_wait = au1k_wait; 20849f2ec91SRalf Baechle break; 20949f2ec91SRalf Baechle case CPU_20KC: 21049f2ec91SRalf Baechle /* 21149f2ec91SRalf Baechle * WAIT on Rev1.0 has E1, E2, E3 and E16. 21249f2ec91SRalf Baechle * WAIT on Rev2.0 and Rev3.0 has E16. 21349f2ec91SRalf Baechle * Rev3.1 WAIT is nop, why bother 21449f2ec91SRalf Baechle */ 21549f2ec91SRalf Baechle if ((c->processor_id & 0xff) <= 0x64) 21649f2ec91SRalf Baechle break; 21749f2ec91SRalf Baechle 21849f2ec91SRalf Baechle /* 21949f2ec91SRalf Baechle * Another rev is incremeting c0_count at a reduced clock 22049f2ec91SRalf Baechle * rate while in WAIT mode. So we basically have the choice 22149f2ec91SRalf Baechle * between using the cp0 timer as clocksource or avoiding 22249f2ec91SRalf Baechle * the WAIT instruction. Until more details are known, 22349f2ec91SRalf Baechle * disable the use of WAIT for 20Kc entirely. 22449f2ec91SRalf Baechle cpu_wait = r4k_wait; 22549f2ec91SRalf Baechle */ 22649f2ec91SRalf Baechle break; 22749f2ec91SRalf Baechle case CPU_RM9000: 22849f2ec91SRalf Baechle if ((c->processor_id & 0x00ff) >= 0x40) 22949f2ec91SRalf Baechle cpu_wait = r4k_wait; 23049f2ec91SRalf Baechle break; 23149f2ec91SRalf Baechle default: 23249f2ec91SRalf Baechle break; 23349f2ec91SRalf Baechle } 23449f2ec91SRalf Baechle } 23549f2ec91SRalf Baechle 23600baf857SRalf Baechle static void smtc_idle_hook(void) 23749f2ec91SRalf Baechle { 23849f2ec91SRalf Baechle #ifdef CONFIG_MIPS_MT_SMTC 23900baf857SRalf Baechle void smtc_idle_loop_hook(void); 24049f2ec91SRalf Baechle 24149f2ec91SRalf Baechle smtc_idle_loop_hook(); 24249f2ec91SRalf Baechle #endif 24300baf857SRalf Baechle } 24400baf857SRalf Baechle 24500baf857SRalf Baechle void arch_cpu_idle(void) 24600baf857SRalf Baechle { 24700baf857SRalf Baechle smtc_idle_hook(); 24849f2ec91SRalf Baechle if (cpu_wait) 249c9b6869dSRalf Baechle cpu_wait(); 25049f2ec91SRalf Baechle else 25149f2ec91SRalf Baechle local_irq_enable(); 25249f2ec91SRalf Baechle } 253da9f970fSPaul Burton 254da9f970fSPaul Burton #ifdef CONFIG_CPU_IDLE 255da9f970fSPaul Burton 256da9f970fSPaul Burton int mips_cpuidle_wait_enter(struct cpuidle_device *dev, 257da9f970fSPaul Burton struct cpuidle_driver *drv, int index) 258da9f970fSPaul Burton { 259da9f970fSPaul Burton arch_cpu_idle(); 260da9f970fSPaul Burton return index; 261da9f970fSPaul Burton } 262da9f970fSPaul Burton 263da9f970fSPaul Burton #endif 264