Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3179d37e authored by Paul Burton's avatar Paul Burton
Browse files

MIPS: pm-cps: add PM state entry code for CPS systems



This patch adds code to generate entry & exit code for various low power
states available on systems based around the MIPS Coherent Processing
System architecture (ie. those with a Coherence Manager, Global
Interrupt Controller & for >=CM2 a Cluster Power Controller). States
supported are:

  - Non-coherent wait. This state first leaves the coherent domain and
    then executes a regular MIPS wait instruction. Power savings are
    found from the elimination of coherency interventions between the
    core and any other coherent requestors in the system.

  - Clock gated. This state leaves the coherent domain and then gates
    the clock input to the core. This removes all dynamic power from the
    core but leaves the core at the mercy of another to restart its
    clock. Register state is preserved, but the core can not service
    interrupts whilst its clock is gated.

  - Power gated. This deepest state removes all power input to the core.
    All register state is lost and the core will restart execution from
    its BEV when another core powers it back up. Because register state
    is lost this state requires cooperation with the CONFIG_MIPS_CPS SMP
    implementation in order for the core to exit the state successfully.

The code will detect which states are available on the current system
during boot & generate the entry/exit code for those states. This will
be used by cpuidle & hotplug implementations.

Signed-off-by: default avatarPaul Burton <paul.burton@imgtec.com>
parent dd9233d0
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -2071,6 +2071,9 @@ config MIPS_CPS
	  no external assistance. It is safe to enable this when hardware
	  support is unavailable.

config MIPS_CPS_PM
	bool

config MIPS_GIC_IPI
	bool

+51 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2014 Imagination Technologies
 * Author: Paul Burton <paul.burton@imgtec.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation;  either version 2 of the  License, or (at your
 * option) any later version.
 */

#ifndef __MIPS_ASM_PM_CPS_H__
#define __MIPS_ASM_PM_CPS_H__

/*
 * The CM & CPC can only handle coherence & power control on a per-core basis,
 * thus in an MT system the VPEs within each core are coupled and can only
 * enter or exit states requiring CM or CPC assistance in unison.
 */
#ifdef CONFIG_MIPS_MT
# define coupled_coherence cpu_has_mipsmt
#else
# define coupled_coherence 0
#endif

/* Enumeration of possible PM states */
enum cps_pm_state {
	CPS_PM_NC_WAIT,		/* MIPS wait instruction, non-coherent */
	CPS_PM_CLOCK_GATED,	/* Core clock gated */
	CPS_PM_POWER_GATED,	/* Core power gated */
	CPS_PM_STATE_COUNT,
};

/**
 * cps_pm_support_state - determine whether the system supports a PM state
 * @state: the state to test for support
 *
 * Returns true if the system supports the given state, otherwise false.
 */
extern bool cps_pm_support_state(enum cps_pm_state state);

/**
 * cps_pm_enter_state - enter a PM state
 * @state: the state to enter
 *
 * Enter the given PM state. If coupled_coherence is non-zero then it is
 * expected that this function be called at approximately the same time on
 * each coupled CPU. Returns 0 on successful entry & exit, otherwise -errno.
 */
extern int cps_pm_enter_state(enum cps_pm_state state);

#endif /* __MIPS_ASM_PM_CPS_H__ */
+3 −0
Original line number Diff line number Diff line
@@ -33,6 +33,9 @@ extern struct vpe_boot_config *mips_cps_boot_vpes(void);

extern bool mips_cps_smp_in_use(void);

extern void mips_cps_pm_save(void);
extern void mips_cps_pm_restore(void);

#else /* __ASSEMBLY__ */

.extern mips_cps_bootcfg;
+1 −0
Original line number Diff line number Diff line
@@ -108,6 +108,7 @@ obj-$(CONFIG_MIPS_CM) += mips-cm.o
obj-$(CONFIG_MIPS_CPC)		+= mips-cpc.o

obj-$(CONFIG_CPU_PM)		+= pm.o
obj-$(CONFIG_MIPS_CPS_PM)	+= pm-cps.o

#
# DSP ASE supported for MIPS32 or MIPS64 Release 2 cores only. It is not
+35 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
#include <asm/cacheops.h>
#include <asm/mipsregs.h>
#include <asm/mipsmtregs.h>
#include <asm/pm.h>

#define GCR_CL_COHERENCE_OFS	0x2008
#define GCR_CL_ID_OFS		0x2028
@@ -447,3 +448,37 @@ LEAF(mips_cps_boot_vpes)
	jr	ra
	 nop
	END(mips_cps_boot_vpes)

#if defined(CONFIG_MIPS_CPS_PM) && defined(CONFIG_CPU_PM)

	/* Calculate a pointer to this CPUs struct mips_static_suspend_state */
	.macro	psstate	dest
	.set	push
	.set	noat
	lw	$1, TI_CPU(gp)
	sll	$1, $1, LONGLOG
	la	\dest, __per_cpu_offset
	addu	$1, $1, \dest
	lw	$1, 0($1)
	la	\dest, cps_cpu_state
	addu	\dest, \dest, $1
	.set	pop
	.endm

LEAF(mips_cps_pm_save)
	/* Save CPU state */
	SUSPEND_SAVE_REGS
	psstate	t1
	SUSPEND_SAVE_STATIC
	jr	v0
	 nop
	END(mips_cps_pm_save)

LEAF(mips_cps_pm_restore)
	/* Restore CPU state */
	psstate	t1
	RESUME_RESTORE_STATIC
	RESUME_RESTORE_REGS_RETURN
	END(mips_cps_pm_restore)

#endif /* CONFIG_MIPS_CPS_PM && CONFIG_CPU_PM */
Loading