162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2013 Imagination Technologies
462306a36Sopenharmony_ci * Author: Paul Burton <paul.burton@mips.com>
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#ifndef __MIPS_ASM_MIPS_CPS_H__
862306a36Sopenharmony_ci# error Please include asm/mips-cps.h rather than asm/mips-cpc.h
962306a36Sopenharmony_ci#endif
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#ifndef __MIPS_ASM_MIPS_CPC_H__
1262306a36Sopenharmony_ci#define __MIPS_ASM_MIPS_CPC_H__
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include <linux/bitops.h>
1562306a36Sopenharmony_ci#include <linux/errno.h>
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci/* The base address of the CPC registers */
1862306a36Sopenharmony_ciextern void __iomem *mips_cpc_base;
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci/**
2162306a36Sopenharmony_ci * mips_cpc_default_phys_base - retrieve the default physical base address of
2262306a36Sopenharmony_ci *                              the CPC
2362306a36Sopenharmony_ci *
2462306a36Sopenharmony_ci * Returns the default physical base address of the Cluster Power Controller
2562306a36Sopenharmony_ci * memory mapped registers. This is platform dependant & must therefore be
2662306a36Sopenharmony_ci * implemented per-platform.
2762306a36Sopenharmony_ci */
2862306a36Sopenharmony_ciextern phys_addr_t mips_cpc_default_phys_base(void);
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci/**
3162306a36Sopenharmony_ci * mips_cpc_probe - probe for a Cluster Power Controller
3262306a36Sopenharmony_ci *
3362306a36Sopenharmony_ci * Attempt to detect the presence of a Cluster Power Controller. Returns 0 if
3462306a36Sopenharmony_ci * a CPC is successfully detected, else -errno.
3562306a36Sopenharmony_ci */
3662306a36Sopenharmony_ci#ifdef CONFIG_MIPS_CPC
3762306a36Sopenharmony_ciextern int mips_cpc_probe(void);
3862306a36Sopenharmony_ci#else
3962306a36Sopenharmony_cistatic inline int mips_cpc_probe(void)
4062306a36Sopenharmony_ci{
4162306a36Sopenharmony_ci	return -ENODEV;
4262306a36Sopenharmony_ci}
4362306a36Sopenharmony_ci#endif
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci/**
4662306a36Sopenharmony_ci * mips_cpc_present - determine whether a Cluster Power Controller is present
4762306a36Sopenharmony_ci *
4862306a36Sopenharmony_ci * Returns true if a CPC is present in the system, else false.
4962306a36Sopenharmony_ci */
5062306a36Sopenharmony_cistatic inline bool mips_cpc_present(void)
5162306a36Sopenharmony_ci{
5262306a36Sopenharmony_ci#ifdef CONFIG_MIPS_CPC
5362306a36Sopenharmony_ci	return mips_cpc_base != NULL;
5462306a36Sopenharmony_ci#else
5562306a36Sopenharmony_ci	return false;
5662306a36Sopenharmony_ci#endif
5762306a36Sopenharmony_ci}
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci/* Offsets from the CPC base address to various control blocks */
6062306a36Sopenharmony_ci#define MIPS_CPC_GCB_OFS	0x0000
6162306a36Sopenharmony_ci#define MIPS_CPC_CLCB_OFS	0x2000
6262306a36Sopenharmony_ci#define MIPS_CPC_COCB_OFS	0x4000
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci#define CPC_ACCESSOR_RO(sz, off, name)					\
6562306a36Sopenharmony_ci	CPS_ACCESSOR_RO(cpc, sz, MIPS_CPC_GCB_OFS + off, name)		\
6662306a36Sopenharmony_ci	CPS_ACCESSOR_RO(cpc, sz, MIPS_CPC_COCB_OFS + off, redir_##name)
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci#define CPC_ACCESSOR_RW(sz, off, name)					\
6962306a36Sopenharmony_ci	CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_GCB_OFS + off, name)		\
7062306a36Sopenharmony_ci	CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_COCB_OFS + off, redir_##name)
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci#define CPC_CX_ACCESSOR_RO(sz, off, name)				\
7362306a36Sopenharmony_ci	CPS_ACCESSOR_RO(cpc, sz, MIPS_CPC_CLCB_OFS + off, cl_##name)	\
7462306a36Sopenharmony_ci	CPS_ACCESSOR_RO(cpc, sz, MIPS_CPC_COCB_OFS + off, co_##name)
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci#define CPC_CX_ACCESSOR_RW(sz, off, name)				\
7762306a36Sopenharmony_ci	CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_CLCB_OFS + off, cl_##name)	\
7862306a36Sopenharmony_ci	CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_COCB_OFS + off, co_##name)
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci/* CPC_ACCESS - Control core/IOCU access to CPC registers prior to CM 3 */
8162306a36Sopenharmony_ciCPC_ACCESSOR_RW(32, 0x000, access)
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci/* CPC_SEQDEL - Configure delays between command sequencer steps */
8462306a36Sopenharmony_ciCPC_ACCESSOR_RW(32, 0x008, seqdel)
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci/* CPC_RAIL - Configure the delay from rail power-up to stability */
8762306a36Sopenharmony_ciCPC_ACCESSOR_RW(32, 0x010, rail)
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci/* CPC_RESETLEN - Configure the length of reset sequences */
9062306a36Sopenharmony_ciCPC_ACCESSOR_RW(32, 0x018, resetlen)
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci/* CPC_REVISION - Indicates the revisison of the CPC */
9362306a36Sopenharmony_ciCPC_ACCESSOR_RO(32, 0x020, revision)
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci/* CPC_PWRUP_CTL - Control power to the Coherence Manager (CM) */
9662306a36Sopenharmony_ciCPC_ACCESSOR_RW(32, 0x030, pwrup_ctl)
9762306a36Sopenharmony_ci#define CPC_PWRUP_CTL_CM_PWRUP			BIT(0)
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci/* CPC_CONFIG - Mirrors GCR_CONFIG */
10062306a36Sopenharmony_ciCPC_ACCESSOR_RW(64, 0x138, config)
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci/* CPC_SYS_CONFIG - Control cluster endianness */
10362306a36Sopenharmony_ciCPC_ACCESSOR_RW(32, 0x140, sys_config)
10462306a36Sopenharmony_ci#define CPC_SYS_CONFIG_BE_IMMEDIATE		BIT(2)
10562306a36Sopenharmony_ci#define CPC_SYS_CONFIG_BE_STATUS		BIT(1)
10662306a36Sopenharmony_ci#define CPC_SYS_CONFIG_BE			BIT(0)
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ci/* CPC_Cx_CMD - Instruct the CPC to take action on a core */
10962306a36Sopenharmony_ciCPC_CX_ACCESSOR_RW(32, 0x000, cmd)
11062306a36Sopenharmony_ci#define CPC_Cx_CMD				GENMASK(3, 0)
11162306a36Sopenharmony_ci#define  CPC_Cx_CMD_CLOCKOFF			0x1
11262306a36Sopenharmony_ci#define  CPC_Cx_CMD_PWRDOWN			0x2
11362306a36Sopenharmony_ci#define  CPC_Cx_CMD_PWRUP			0x3
11462306a36Sopenharmony_ci#define  CPC_Cx_CMD_RESET			0x4
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ci/* CPC_Cx_STAT_CONF - Indicates core configuration & state */
11762306a36Sopenharmony_ciCPC_CX_ACCESSOR_RW(32, 0x008, stat_conf)
11862306a36Sopenharmony_ci#define CPC_Cx_STAT_CONF_PWRUPE			BIT(23)
11962306a36Sopenharmony_ci#define CPC_Cx_STAT_CONF_SEQSTATE		GENMASK(22, 19)
12062306a36Sopenharmony_ci#define  CPC_Cx_STAT_CONF_SEQSTATE_D0		0x0
12162306a36Sopenharmony_ci#define  CPC_Cx_STAT_CONF_SEQSTATE_U0		0x1
12262306a36Sopenharmony_ci#define  CPC_Cx_STAT_CONF_SEQSTATE_U1		0x2
12362306a36Sopenharmony_ci#define  CPC_Cx_STAT_CONF_SEQSTATE_U2		0x3
12462306a36Sopenharmony_ci#define  CPC_Cx_STAT_CONF_SEQSTATE_U3		0x4
12562306a36Sopenharmony_ci#define  CPC_Cx_STAT_CONF_SEQSTATE_U4		0x5
12662306a36Sopenharmony_ci#define  CPC_Cx_STAT_CONF_SEQSTATE_U5		0x6
12762306a36Sopenharmony_ci#define  CPC_Cx_STAT_CONF_SEQSTATE_U6		0x7
12862306a36Sopenharmony_ci#define  CPC_Cx_STAT_CONF_SEQSTATE_D1		0x8
12962306a36Sopenharmony_ci#define  CPC_Cx_STAT_CONF_SEQSTATE_D3		0x9
13062306a36Sopenharmony_ci#define  CPC_Cx_STAT_CONF_SEQSTATE_D2		0xa
13162306a36Sopenharmony_ci#define CPC_Cx_STAT_CONF_CLKGAT_IMPL		BIT(17)
13262306a36Sopenharmony_ci#define CPC_Cx_STAT_CONF_PWRDN_IMPL		BIT(16)
13362306a36Sopenharmony_ci#define CPC_Cx_STAT_CONF_EJTAG_PROBE		BIT(15)
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci/* CPC_Cx_OTHER - Configure the core-other register block prior to CM 3 */
13662306a36Sopenharmony_ciCPC_CX_ACCESSOR_RW(32, 0x010, other)
13762306a36Sopenharmony_ci#define CPC_Cx_OTHER_CORENUM			GENMASK(23, 16)
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci/* CPC_Cx_VP_STOP - Stop Virtual Processors (VPs) within a core from running */
14062306a36Sopenharmony_ciCPC_CX_ACCESSOR_RW(32, 0x020, vp_stop)
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci/* CPC_Cx_VP_START - Start Virtual Processors (VPs) within a core running */
14362306a36Sopenharmony_ciCPC_CX_ACCESSOR_RW(32, 0x028, vp_run)
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_ci/* CPC_Cx_VP_RUNNING - Indicate which Virtual Processors (VPs) are running */
14662306a36Sopenharmony_ciCPC_CX_ACCESSOR_RW(32, 0x030, vp_running)
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ci/* CPC_Cx_CONFIG - Mirrors GCR_Cx_CONFIG */
14962306a36Sopenharmony_ciCPC_CX_ACCESSOR_RW(32, 0x090, config)
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ci#ifdef CONFIG_MIPS_CPC
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_ci/**
15462306a36Sopenharmony_ci * mips_cpc_lock_other - lock access to another core
15562306a36Sopenharmony_ci * core: the other core to be accessed
15662306a36Sopenharmony_ci *
15762306a36Sopenharmony_ci * Call before operating upon a core via the 'other' register region in
15862306a36Sopenharmony_ci * order to prevent the region being moved during access. Must be called
15962306a36Sopenharmony_ci * within the bounds of a mips_cm_{lock,unlock}_other pair, and followed
16062306a36Sopenharmony_ci * by a call to mips_cpc_unlock_other.
16162306a36Sopenharmony_ci */
16262306a36Sopenharmony_ciextern void mips_cpc_lock_other(unsigned int core);
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ci/**
16562306a36Sopenharmony_ci * mips_cpc_unlock_other - unlock access to another core
16662306a36Sopenharmony_ci *
16762306a36Sopenharmony_ci * Call after operating upon another core via the 'other' register region.
16862306a36Sopenharmony_ci * Must be called after mips_cpc_lock_other.
16962306a36Sopenharmony_ci */
17062306a36Sopenharmony_ciextern void mips_cpc_unlock_other(void);
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ci#else /* !CONFIG_MIPS_CPC */
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_cistatic inline void mips_cpc_lock_other(unsigned int core) { }
17562306a36Sopenharmony_cistatic inline void mips_cpc_unlock_other(void) { }
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_ci#endif /* !CONFIG_MIPS_CPC */
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ci#endif /* __MIPS_ASM_MIPS_CPC_H__ */
180