aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/mips/include/asm/pm-cps.h6
-rw-r--r--arch/mips/kernel/pm-cps.c22
2 files changed, 22 insertions, 6 deletions
diff --git a/arch/mips/include/asm/pm-cps.h b/arch/mips/include/asm/pm-cps.h
index 625eda53d571..89d58d80b77b 100644
--- a/arch/mips/include/asm/pm-cps.h
+++ b/arch/mips/include/asm/pm-cps.h
@@ -13,10 +13,12 @@
13 13
14/* 14/*
15 * The CM & CPC can only handle coherence & power control on a per-core basis, 15 * The CM & CPC can only handle coherence & power control on a per-core basis,
16 * thus in an MT system the VPEs within each core are coupled and can only 16 * thus in an MT system the VP(E)s within each core are coupled and can only
17 * enter or exit states requiring CM or CPC assistance in unison. 17 * enter or exit states requiring CM or CPC assistance in unison.
18 */ 18 */
19#ifdef CONFIG_MIPS_MT 19#if defined(CONFIG_CPU_MIPSR6)
20# define coupled_coherence cpu_has_vp
21#elif defined(CONFIG_MIPS_MT)
20# define coupled_coherence cpu_has_mipsmt 22# define coupled_coherence cpu_has_mipsmt
21#else 23#else
22# define coupled_coherence 0 24# define coupled_coherence 0
diff --git a/arch/mips/kernel/pm-cps.c b/arch/mips/kernel/pm-cps.c
index b3a7d36ada5a..440e79259566 100644
--- a/arch/mips/kernel/pm-cps.c
+++ b/arch/mips/kernel/pm-cps.c
@@ -129,7 +129,7 @@ int cps_pm_enter_state(enum cps_pm_state state)
129 return -EINVAL; 129 return -EINVAL;
130 130
131 /* Calculate which coupled CPUs (VPEs) are online */ 131 /* Calculate which coupled CPUs (VPEs) are online */
132#ifdef CONFIG_MIPS_MT 132#if defined(CONFIG_MIPS_MT) || defined(CONFIG_CPU_MIPSR6)
133 if (cpu_online(cpu)) { 133 if (cpu_online(cpu)) {
134 cpumask_and(coupled_mask, cpu_online_mask, 134 cpumask_and(coupled_mask, cpu_online_mask,
135 &cpu_sibling_map[cpu]); 135 &cpu_sibling_map[cpu]);
@@ -431,7 +431,8 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state)
431 uasm_i_lw(&p, t0, 0, r_nc_count); 431 uasm_i_lw(&p, t0, 0, r_nc_count);
432 uasm_il_bltz(&p, &r, t0, lbl_secondary_cont); 432 uasm_il_bltz(&p, &r, t0, lbl_secondary_cont);
433 uasm_i_ehb(&p); 433 uasm_i_ehb(&p);
434 uasm_i_yield(&p, zero, t1); 434 if (cpu_has_mipsmt)
435 uasm_i_yield(&p, zero, t1);
435 uasm_il_b(&p, &r, lbl_poll_cont); 436 uasm_il_b(&p, &r, lbl_poll_cont);
436 uasm_i_nop(&p); 437 uasm_i_nop(&p);
437 } else { 438 } else {
@@ -439,8 +440,21 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state)
439 * The core will lose power & this VPE will not continue 440 * The core will lose power & this VPE will not continue
440 * so it can simply halt here. 441 * so it can simply halt here.
441 */ 442 */
442 uasm_i_addiu(&p, t0, zero, TCHALT_H); 443 if (cpu_has_mipsmt) {
443 uasm_i_mtc0(&p, t0, 2, 4); 444 /* Halt the VPE via C0 tchalt register */
445 uasm_i_addiu(&p, t0, zero, TCHALT_H);
446 uasm_i_mtc0(&p, t0, 2, 4);
447 } else if (cpu_has_vp) {
448 /* Halt the VP via the CPC VP_STOP register */
449 unsigned int vpe_id;
450
451 vpe_id = cpu_vpe_id(&cpu_data[cpu]);
452 uasm_i_addiu(&p, t0, zero, 1 << vpe_id);
453 UASM_i_LA(&p, t1, (long)addr_cpc_cl_vp_stop());
454 uasm_i_sw(&p, t0, 0, t1);
455 } else {
456 BUG();
457 }
444 uasm_build_label(&l, p, lbl_secondary_hang); 458 uasm_build_label(&l, p, lbl_secondary_hang);
445 uasm_il_b(&p, &r, lbl_secondary_hang); 459 uasm_il_b(&p, &r, lbl_secondary_hang);
446 uasm_i_nop(&p); 460 uasm_i_nop(&p);