blob: 9de7addb59ba40c0a1f6daa5bd46ce52ef24f2d2 [file] [log] [blame]
Paul Burton9c38cf42014-01-15 10:31:52 +00001/*
2 * Copyright (C) 2013 Imagination Technologies
3 * Author: Paul Burton <paul.burton@imgtec.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 */
10
11#ifndef __MIPS_ASM_MIPS_CPC_H__
12#define __MIPS_ASM_MIPS_CPC_H__
13
14#include <linux/io.h>
15#include <linux/types.h>
Paul Burton2c981e32017-08-12 19:49:28 -070016#include <asm/mips-cps.h>
Paul Burton9c38cf42014-01-15 10:31:52 +000017
18/* The base address of the CPC registers */
19extern void __iomem *mips_cpc_base;
20
21/**
22 * mips_cpc_default_phys_base - retrieve the default physical base address of
23 * the CPC
24 *
25 * Returns the default physical base address of the Cluster Power Controller
26 * memory mapped registers. This is platform dependant & must therefore be
27 * implemented per-platform.
28 */
Ralf Baechle15d45cc2014-11-22 00:22:09 +010029extern phys_addr_t mips_cpc_default_phys_base(void);
Paul Burton9c38cf42014-01-15 10:31:52 +000030
31/**
Paul Burton9c38cf42014-01-15 10:31:52 +000032 * mips_cpc_probe - probe for a Cluster Power Controller
33 *
34 * Attempt to detect the presence of a Cluster Power Controller. Returns 0 if
35 * a CPC is successfully detected, else -errno.
36 */
37#ifdef CONFIG_MIPS_CPC
38extern int mips_cpc_probe(void);
39#else
40static inline int mips_cpc_probe(void)
41{
42 return -ENODEV;
43}
44#endif
45
46/**
47 * mips_cpc_present - determine whether a Cluster Power Controller is present
48 *
49 * Returns true if a CPC is present in the system, else false.
50 */
51static inline bool mips_cpc_present(void)
52{
53#ifdef CONFIG_MIPS_CPC
54 return mips_cpc_base != NULL;
55#else
56 return false;
57#endif
58}
59
60/* Offsets from the CPC base address to various control blocks */
61#define MIPS_CPC_GCB_OFS 0x0000
62#define MIPS_CPC_CLCB_OFS 0x2000
63#define MIPS_CPC_COCB_OFS 0x4000
64
Paul Burton2c981e32017-08-12 19:49:28 -070065#define CPC_ACCESSOR_RO(sz, off, name) \
66 CPS_ACCESSOR_RO(cpc, sz, MIPS_CPC_GCB_OFS + off, name)
Paul Burton9c38cf42014-01-15 10:31:52 +000067
Paul Burton2c981e32017-08-12 19:49:28 -070068#define CPC_ACCESSOR_RW(sz, off, name) \
69 CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_GCB_OFS + off, name)
Paul Burton9c38cf42014-01-15 10:31:52 +000070
Paul Burton2c981e32017-08-12 19:49:28 -070071#define CPC_CX_ACCESSOR_RO(sz, off, name) \
72 CPS_ACCESSOR_RO(cpc, sz, MIPS_CPC_CLCB_OFS + off, cl_##name) \
73 CPS_ACCESSOR_RO(cpc, sz, MIPS_CPC_COCB_OFS + off, co_##name)
Paul Burton9c38cf42014-01-15 10:31:52 +000074
Paul Burton2c981e32017-08-12 19:49:28 -070075#define CPC_CX_ACCESSOR_RW(sz, off, name) \
76 CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_CLCB_OFS + off, cl_##name) \
77 CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_COCB_OFS + off, co_##name)
Paul Burton9c38cf42014-01-15 10:31:52 +000078
79/* GCB register accessor functions */
Paul Burton2c981e32017-08-12 19:49:28 -070080CPC_ACCESSOR_RW(32, 0x000, access)
81CPC_ACCESSOR_RW(32, 0x008, seqdel)
82CPC_ACCESSOR_RW(32, 0x010, rail)
83CPC_ACCESSOR_RW(32, 0x018, resetlen)
84CPC_ACCESSOR_RO(32, 0x020, revision)
Paul Burton9c38cf42014-01-15 10:31:52 +000085
86/* Core Local & Core Other accessor functions */
Paul Burton2c981e32017-08-12 19:49:28 -070087CPC_CX_ACCESSOR_RW(32, 0x000, cmd)
88CPC_CX_ACCESSOR_RW(32, 0x008, stat_conf)
89CPC_CX_ACCESSOR_RW(32, 0x010, other)
90CPC_CX_ACCESSOR_RW(32, 0x020, vp_stop)
91CPC_CX_ACCESSOR_RW(32, 0x028, vp_run)
92CPC_CX_ACCESSOR_RW(32, 0x030, vp_running)
Paul Burton9c38cf42014-01-15 10:31:52 +000093
94/* CPC_Cx_CMD register fields */
95#define CPC_Cx_CMD_SHF 0
96#define CPC_Cx_CMD_MSK (_ULCAST_(0xf) << 0)
97#define CPC_Cx_CMD_CLOCKOFF (_ULCAST_(0x1) << 0)
98#define CPC_Cx_CMD_PWRDOWN (_ULCAST_(0x2) << 0)
99#define CPC_Cx_CMD_PWRUP (_ULCAST_(0x3) << 0)
100#define CPC_Cx_CMD_RESET (_ULCAST_(0x4) << 0)
101
102/* CPC_Cx_STAT_CONF register fields */
103#define CPC_Cx_STAT_CONF_PWRUPE_SHF 23
104#define CPC_Cx_STAT_CONF_PWRUPE_MSK (_ULCAST_(0x1) << 23)
105#define CPC_Cx_STAT_CONF_SEQSTATE_SHF 19
106#define CPC_Cx_STAT_CONF_SEQSTATE_MSK (_ULCAST_(0xf) << 19)
107#define CPC_Cx_STAT_CONF_SEQSTATE_D0 (_ULCAST_(0x0) << 19)
108#define CPC_Cx_STAT_CONF_SEQSTATE_U0 (_ULCAST_(0x1) << 19)
109#define CPC_Cx_STAT_CONF_SEQSTATE_U1 (_ULCAST_(0x2) << 19)
110#define CPC_Cx_STAT_CONF_SEQSTATE_U2 (_ULCAST_(0x3) << 19)
111#define CPC_Cx_STAT_CONF_SEQSTATE_U3 (_ULCAST_(0x4) << 19)
112#define CPC_Cx_STAT_CONF_SEQSTATE_U4 (_ULCAST_(0x5) << 19)
113#define CPC_Cx_STAT_CONF_SEQSTATE_U5 (_ULCAST_(0x6) << 19)
114#define CPC_Cx_STAT_CONF_SEQSTATE_U6 (_ULCAST_(0x7) << 19)
115#define CPC_Cx_STAT_CONF_SEQSTATE_D1 (_ULCAST_(0x8) << 19)
116#define CPC_Cx_STAT_CONF_SEQSTATE_D3 (_ULCAST_(0x9) << 19)
117#define CPC_Cx_STAT_CONF_SEQSTATE_D2 (_ULCAST_(0xa) << 19)
118#define CPC_Cx_STAT_CONF_CLKGAT_IMPL_SHF 17
119#define CPC_Cx_STAT_CONF_CLKGAT_IMPL_MSK (_ULCAST_(0x1) << 17)
120#define CPC_Cx_STAT_CONF_PWRDN_IMPL_SHF 16
121#define CPC_Cx_STAT_CONF_PWRDN_IMPL_MSK (_ULCAST_(0x1) << 16)
122#define CPC_Cx_STAT_CONF_EJTAG_PROBE_SHF 15
123#define CPC_Cx_STAT_CONF_EJTAG_PROBE_MSK (_ULCAST_(0x1) << 15)
124
125/* CPC_Cx_OTHER register fields */
126#define CPC_Cx_OTHER_CORENUM_SHF 16
127#define CPC_Cx_OTHER_CORENUM_MSK (_ULCAST_(0xff) << 16)
128
Paul Burton76ae6582014-02-14 09:28:06 +0000129#ifdef CONFIG_MIPS_CPC
130
131/**
132 * mips_cpc_lock_other - lock access to another core
133 * core: the other core to be accessed
134 *
135 * Call before operating upon a core via the 'other' register region in
Paul Burton4ede3162015-09-22 11:12:17 -0700136 * order to prevent the region being moved during access. Must be called
137 * within the bounds of a mips_cm_{lock,unlock}_other pair, and followed
Paul Burton76ae6582014-02-14 09:28:06 +0000138 * by a call to mips_cpc_unlock_other.
139 */
140extern void mips_cpc_lock_other(unsigned int core);
141
142/**
143 * mips_cpc_unlock_other - unlock access to another core
144 *
145 * Call after operating upon another core via the 'other' register region.
146 * Must be called after mips_cpc_lock_other.
147 */
148extern void mips_cpc_unlock_other(void);
149
150#else /* !CONFIG_MIPS_CPC */
151
152static inline void mips_cpc_lock_other(unsigned int core) { }
153static inline void mips_cpc_unlock_other(void) { }
154
155#endif /* !CONFIG_MIPS_CPC */
156
Paul Burton9c38cf42014-01-15 10:31:52 +0000157#endif /* __MIPS_ASM_MIPS_CPC_H__ */