12874c5fdSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
29f98f3ddSPaul Burton /*
39f98f3ddSPaul Burton * Copyright (C) 2013 Imagination Technologies
448c834beSPaul Burton * Author: Paul Burton <paul.burton@mips.com>
59f98f3ddSPaul Burton */
69f98f3ddSPaul Burton
7e83f7e02SPaul Burton #ifndef __MIPS_ASM_MIPS_CPS_H__
8e83f7e02SPaul Burton # error Please include asm/mips-cps.h rather than asm/mips-cm.h
9e83f7e02SPaul Burton #endif
10e83f7e02SPaul Burton
119f98f3ddSPaul Burton #ifndef __MIPS_ASM_MIPS_CM_H__
129f98f3ddSPaul Burton #define __MIPS_ASM_MIPS_CM_H__
139f98f3ddSPaul Burton
1418b8f5b6SGeert Uytterhoeven #include <linux/bitfield.h>
1547b26a46SPaul Burton #include <linux/bitops.h>
1656d4c99bSPaul Burton #include <linux/errno.h>
179f98f3ddSPaul Burton
189f98f3ddSPaul Burton /* The base address of the CM GCR block */
19abe852eaSPaul Burton extern void __iomem *mips_gcr_base;
209f98f3ddSPaul Burton
219f98f3ddSPaul Burton /* The base address of the CM L2-only sync region */
229f98f3ddSPaul Burton extern void __iomem *mips_cm_l2sync_base;
239f98f3ddSPaul Burton
249f98f3ddSPaul Burton /**
259f98f3ddSPaul Burton * __mips_cm_phys_base - retrieve the physical base address of the CM
269f98f3ddSPaul Burton *
279f98f3ddSPaul Burton * This function returns the physical base address of the Coherence Manager
289f98f3ddSPaul Burton * global control block, or 0 if no Coherence Manager is present. It provides
299f98f3ddSPaul Burton * a default implementation which reads the CMGCRBase register where available,
3092a76f6dSAdam Buchbinder * and may be overridden by platforms which determine this address in a
319f98f3ddSPaul Burton * different way by defining a function with the same prototype except for the
329f98f3ddSPaul Burton * name mips_cm_phys_base (without underscores).
339f98f3ddSPaul Burton */
3415d45cceSRalf Baechle extern phys_addr_t __mips_cm_phys_base(void);
359f98f3ddSPaul Burton
36c0b584a2SMarkos Chandras /*
37c0b584a2SMarkos Chandras * mips_cm_is64 - determine CM register width
38c0b584a2SMarkos Chandras *
397784494aSPaul Burton * The CM register width is determined by the version of the CM, with CM3
407784494aSPaul Burton * introducing 64 bit GCRs and all prior CM versions having 32 bit GCRs.
417784494aSPaul Burton * However we may run a kernel built for MIPS32 on a system with 64 bit GCRs,
427784494aSPaul Burton * or vice-versa. This variable indicates the width of the memory accesses
437784494aSPaul Burton * that the kernel will perform to GCRs, which may differ from the actual
447784494aSPaul Burton * width of the GCRs.
45c0b584a2SMarkos Chandras *
46c0b584a2SMarkos Chandras * It's set to 0 for 32-bit accesses and 1 for 64-bit accesses.
47c0b584a2SMarkos Chandras */
48c0b584a2SMarkos Chandras extern int mips_cm_is64;
49c0b584a2SMarkos Chandras
509f98f3ddSPaul Burton /**
513885c2b4SMarkos Chandras * mips_cm_error_report - Report CM cache errors
523885c2b4SMarkos Chandras */
533885c2b4SMarkos Chandras #ifdef CONFIG_MIPS_CM
543885c2b4SMarkos Chandras extern void mips_cm_error_report(void);
553885c2b4SMarkos Chandras #else
mips_cm_error_report(void)563885c2b4SMarkos Chandras static inline void mips_cm_error_report(void) {}
573885c2b4SMarkos Chandras #endif
583885c2b4SMarkos Chandras
593885c2b4SMarkos Chandras /**
609f98f3ddSPaul Burton * mips_cm_probe - probe for a Coherence Manager
619f98f3ddSPaul Burton *
629f98f3ddSPaul Burton * Attempt to detect the presence of a Coherence Manager. Returns 0 if a CM
639f98f3ddSPaul Burton * is successfully detected, else -errno.
649f98f3ddSPaul Burton */
659f98f3ddSPaul Burton #ifdef CONFIG_MIPS_CM
669f98f3ddSPaul Burton extern int mips_cm_probe(void);
679f98f3ddSPaul Burton #else
mips_cm_probe(void)689f98f3ddSPaul Burton static inline int mips_cm_probe(void)
699f98f3ddSPaul Burton {
709f98f3ddSPaul Burton return -ENODEV;
719f98f3ddSPaul Burton }
729f98f3ddSPaul Burton #endif
739f98f3ddSPaul Burton
749f98f3ddSPaul Burton /**
759f98f3ddSPaul Burton * mips_cm_present - determine whether a Coherence Manager is present
769f98f3ddSPaul Burton *
779f98f3ddSPaul Burton * Returns true if a CM is present in the system, else false.
789f98f3ddSPaul Burton */
mips_cm_present(void)799f98f3ddSPaul Burton static inline bool mips_cm_present(void)
809f98f3ddSPaul Burton {
819f98f3ddSPaul Burton #ifdef CONFIG_MIPS_CM
82abe852eaSPaul Burton return mips_gcr_base != NULL;
839f98f3ddSPaul Burton #else
849f98f3ddSPaul Burton return false;
859f98f3ddSPaul Burton #endif
869f98f3ddSPaul Burton }
879f98f3ddSPaul Burton
889f98f3ddSPaul Burton /**
899f98f3ddSPaul Burton * mips_cm_has_l2sync - determine whether an L2-only sync region is present
909f98f3ddSPaul Burton *
919f98f3ddSPaul Burton * Returns true if the system implements an L2-only sync region, else false.
929f98f3ddSPaul Burton */
mips_cm_has_l2sync(void)939f98f3ddSPaul Burton static inline bool mips_cm_has_l2sync(void)
949f98f3ddSPaul Burton {
959f98f3ddSPaul Burton #ifdef CONFIG_MIPS_CM
969f98f3ddSPaul Burton return mips_cm_l2sync_base != NULL;
979f98f3ddSPaul Burton #else
989f98f3ddSPaul Burton return false;
999f98f3ddSPaul Burton #endif
1009f98f3ddSPaul Burton }
1019f98f3ddSPaul Burton
1029f98f3ddSPaul Burton /* Offsets to register blocks from the CM base address */
1039f98f3ddSPaul Burton #define MIPS_CM_GCB_OFS 0x0000 /* Global Control Block */
1049f98f3ddSPaul Burton #define MIPS_CM_CLCB_OFS 0x2000 /* Core Local Control Block */
1059f98f3ddSPaul Burton #define MIPS_CM_COCB_OFS 0x4000 /* Core Other Control Block */
1069f98f3ddSPaul Burton #define MIPS_CM_GDB_OFS 0x6000 /* Global Debug Block */
1079f98f3ddSPaul Burton
1089f98f3ddSPaul Burton /* Total size of the CM memory mapped registers */
1099f98f3ddSPaul Burton #define MIPS_CM_GCR_SIZE 0x8000
1109f98f3ddSPaul Burton
1119f98f3ddSPaul Burton /* Size of the L2-only sync region */
1129f98f3ddSPaul Burton #define MIPS_CM_L2SYNC_SIZE 0x1000
1139f98f3ddSPaul Burton
114b025d518SPaul Burton #define GCR_ACCESSOR_RO(sz, off, name) \
11523cb600eSPaul Burton CPS_ACCESSOR_RO(gcr, sz, MIPS_CM_GCB_OFS + off, name) \
11623cb600eSPaul Burton CPS_ACCESSOR_RO(gcr, sz, MIPS_CM_COCB_OFS + off, redir_##name)
1179f98f3ddSPaul Burton
118b025d518SPaul Burton #define GCR_ACCESSOR_RW(sz, off, name) \
11923cb600eSPaul Burton CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_GCB_OFS + off, name) \
12023cb600eSPaul Burton CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_COCB_OFS + off, redir_##name)
1219f98f3ddSPaul Burton
122b025d518SPaul Burton #define GCR_CX_ACCESSOR_RO(sz, off, name) \
123b025d518SPaul Burton CPS_ACCESSOR_RO(gcr, sz, MIPS_CM_CLCB_OFS + off, cl_##name) \
124b025d518SPaul Burton CPS_ACCESSOR_RO(gcr, sz, MIPS_CM_COCB_OFS + off, co_##name)
1259f98f3ddSPaul Burton
126b025d518SPaul Burton #define GCR_CX_ACCESSOR_RW(sz, off, name) \
127b025d518SPaul Burton CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_CLCB_OFS + off, cl_##name) \
128b025d518SPaul Burton CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_COCB_OFS + off, co_##name)
1299f98f3ddSPaul Burton
13093c5bba5SPaul Burton /* GCR_CONFIG - Information about the system */
131b025d518SPaul Burton GCR_ACCESSOR_RO(64, 0x000, config)
13223cb600eSPaul Burton #define CM_GCR_CONFIG_CLUSTER_COH_CAPABLE BIT_ULL(43)
13323cb600eSPaul Burton #define CM_GCR_CONFIG_CLUSTER_ID GENMASK_ULL(39, 32)
13423cb600eSPaul Burton #define CM_GCR_CONFIG_NUM_CLUSTERS GENMASK(29, 23)
13593c5bba5SPaul Burton #define CM_GCR_CONFIG_NUMIOCU GENMASK(15, 8)
13693c5bba5SPaul Burton #define CM_GCR_CONFIG_PCORES GENMASK(7, 0)
13793c5bba5SPaul Burton
13893c5bba5SPaul Burton /* GCR_BASE - Base address of the Global Configuration Registers (GCRs) */
139b025d518SPaul Burton GCR_ACCESSOR_RW(64, 0x008, base)
14093c5bba5SPaul Burton #define CM_GCR_BASE_GCRBASE GENMASK_ULL(47, 15)
14193c5bba5SPaul Burton #define CM_GCR_BASE_CMDEFTGT GENMASK(1, 0)
1426a6cba1dSPaul Burton #define CM_GCR_BASE_CMDEFTGT_MEM 0
1436a6cba1dSPaul Burton #define CM_GCR_BASE_CMDEFTGT_RESERVED 1
1449f98f3ddSPaul Burton #define CM_GCR_BASE_CMDEFTGT_IOCU0 2
1459f98f3ddSPaul Burton #define CM_GCR_BASE_CMDEFTGT_IOCU1 3
1469f98f3ddSPaul Burton
14793c5bba5SPaul Burton /* GCR_ACCESS - Controls core/IOCU access to GCRs */
14893c5bba5SPaul Burton GCR_ACCESSOR_RW(32, 0x020, access)
14993c5bba5SPaul Burton #define CM_GCR_ACCESS_ACCESSEN GENMASK(7, 0)
150497e803eSMatt Redfearn
15193c5bba5SPaul Burton /* GCR_REV - Indicates the Coherence Manager revision */
15293c5bba5SPaul Burton GCR_ACCESSOR_RO(32, 0x030, rev)
15393c5bba5SPaul Burton #define CM_GCR_REV_MAJOR GENMASK(15, 8)
15493c5bba5SPaul Burton #define CM_GCR_REV_MINOR GENMASK(7, 0)
1559f98f3ddSPaul Burton
156197e89e0SPaul Burton #define CM_ENCODE_REV(major, minor) \
15718b8f5b6SGeert Uytterhoeven (FIELD_PREP(CM_GCR_REV_MAJOR, major) | \
15818b8f5b6SGeert Uytterhoeven FIELD_PREP(CM_GCR_REV_MINOR, minor))
159197e89e0SPaul Burton
160197e89e0SPaul Burton #define CM_REV_CM2 CM_ENCODE_REV(6, 0)
1614d035516SPaul Burton #define CM_REV_CM2_5 CM_ENCODE_REV(7, 0)
162197e89e0SPaul Burton #define CM_REV_CM3 CM_ENCODE_REV(8, 0)
16323cb600eSPaul Burton #define CM_REV_CM3_5 CM_ENCODE_REV(9, 0)
164197e89e0SPaul Burton
16593c5bba5SPaul Burton /* GCR_ERR_CONTROL - Control error checking logic */
16693c5bba5SPaul Burton GCR_ACCESSOR_RW(32, 0x038, err_control)
16793c5bba5SPaul Burton #define CM_GCR_ERR_CONTROL_L2_ECC_EN BIT(1)
16893c5bba5SPaul Burton #define CM_GCR_ERR_CONTROL_L2_ECC_SUPPORT BIT(0)
16935e6de38SPaul Burton
17093c5bba5SPaul Burton /* GCR_ERR_MASK - Control which errors are reported as interrupts */
17193c5bba5SPaul Burton GCR_ACCESSOR_RW(64, 0x040, error_mask)
1729f98f3ddSPaul Burton
17393c5bba5SPaul Burton /* GCR_ERR_CAUSE - Indicates the type of error that occurred */
17493c5bba5SPaul Burton GCR_ACCESSOR_RW(64, 0x048, error_cause)
17593c5bba5SPaul Burton #define CM_GCR_ERROR_CAUSE_ERRTYPE GENMASK(31, 27)
17693c5bba5SPaul Burton #define CM3_GCR_ERROR_CAUSE_ERRTYPE GENMASK_ULL(63, 58)
17793c5bba5SPaul Burton #define CM_GCR_ERROR_CAUSE_ERRINFO GENMASK(26, 0)
1789f98f3ddSPaul Burton
17993c5bba5SPaul Burton /* GCR_ERR_ADDR - Indicates the address associated with an error */
18093c5bba5SPaul Burton GCR_ACCESSOR_RW(64, 0x050, error_addr)
1819f98f3ddSPaul Burton
18293c5bba5SPaul Burton /* GCR_ERR_MULT - Indicates when multiple errors have occurred */
18393c5bba5SPaul Burton GCR_ACCESSOR_RW(64, 0x058, error_mult)
18493c5bba5SPaul Burton #define CM_GCR_ERROR_MULT_ERR2ND GENMASK(4, 0)
1859f98f3ddSPaul Burton
18693c5bba5SPaul Burton /* GCR_L2_ONLY_SYNC_BASE - Base address of the L2 cache-only sync region */
18793c5bba5SPaul Burton GCR_ACCESSOR_RW(64, 0x070, l2_only_sync_base)
18893c5bba5SPaul Burton #define CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE GENMASK(31, 12)
18993c5bba5SPaul Burton #define CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN BIT(0)
1909f98f3ddSPaul Burton
19193c5bba5SPaul Burton /* GCR_GIC_BASE - Base address of the Global Interrupt Controller (GIC) */
19293c5bba5SPaul Burton GCR_ACCESSOR_RW(64, 0x080, gic_base)
19393c5bba5SPaul Burton #define CM_GCR_GIC_BASE_GICBASE GENMASK(31, 17)
19493c5bba5SPaul Burton #define CM_GCR_GIC_BASE_GICEN BIT(0)
195921d55e3SPaul Burton
19693c5bba5SPaul Burton /* GCR_CPC_BASE - Base address of the Cluster Power Controller (CPC) */
19793c5bba5SPaul Burton GCR_ACCESSOR_RW(64, 0x088, cpc_base)
19893c5bba5SPaul Burton #define CM_GCR_CPC_BASE_CPCBASE GENMASK(31, 15)
19993c5bba5SPaul Burton #define CM_GCR_CPC_BASE_CPCEN BIT(0)
2009f98f3ddSPaul Burton
20193c5bba5SPaul Burton /* GCR_REGn_BASE - Base addresses of CM address regions */
20293c5bba5SPaul Burton GCR_ACCESSOR_RW(64, 0x090, reg0_base)
20393c5bba5SPaul Burton GCR_ACCESSOR_RW(64, 0x0a0, reg1_base)
20493c5bba5SPaul Burton GCR_ACCESSOR_RW(64, 0x0b0, reg2_base)
20593c5bba5SPaul Burton GCR_ACCESSOR_RW(64, 0x0c0, reg3_base)
20693c5bba5SPaul Burton #define CM_GCR_REGn_BASE_BASEADDR GENMASK(31, 16)
2079f98f3ddSPaul Burton
20893c5bba5SPaul Burton /* GCR_REGn_MASK - Size & destination of CM address regions */
20993c5bba5SPaul Burton GCR_ACCESSOR_RW(64, 0x098, reg0_mask)
21093c5bba5SPaul Burton GCR_ACCESSOR_RW(64, 0x0a8, reg1_mask)
21193c5bba5SPaul Burton GCR_ACCESSOR_RW(64, 0x0b8, reg2_mask)
21293c5bba5SPaul Burton GCR_ACCESSOR_RW(64, 0x0c8, reg3_mask)
21393c5bba5SPaul Burton #define CM_GCR_REGn_MASK_ADDRMASK GENMASK(31, 16)
21493c5bba5SPaul Burton #define CM_GCR_REGn_MASK_CCAOVR GENMASK(7, 5)
21593c5bba5SPaul Burton #define CM_GCR_REGn_MASK_CCAOVREN BIT(4)
21693c5bba5SPaul Burton #define CM_GCR_REGn_MASK_DROPL2 BIT(2)
21793c5bba5SPaul Burton #define CM_GCR_REGn_MASK_CMTGT GENMASK(1, 0)
21893c5bba5SPaul Burton #define CM_GCR_REGn_MASK_CMTGT_DISABLED 0x0
21993c5bba5SPaul Burton #define CM_GCR_REGn_MASK_CMTGT_MEM 0x1
22093c5bba5SPaul Burton #define CM_GCR_REGn_MASK_CMTGT_IOCU0 0x2
22193c5bba5SPaul Burton #define CM_GCR_REGn_MASK_CMTGT_IOCU1 0x3
2229f98f3ddSPaul Burton
22393c5bba5SPaul Burton /* GCR_GIC_STATUS - Indicates presence of a Global Interrupt Controller (GIC) */
22493c5bba5SPaul Burton GCR_ACCESSOR_RO(32, 0x0d0, gic_status)
22593c5bba5SPaul Burton #define CM_GCR_GIC_STATUS_EX BIT(0)
2269f98f3ddSPaul Burton
22793c5bba5SPaul Burton /* GCR_CPC_STATUS - Indicates presence of a Cluster Power Controller (CPC) */
22893c5bba5SPaul Burton GCR_ACCESSOR_RO(32, 0x0f0, cpc_status)
22993c5bba5SPaul Burton #define CM_GCR_CPC_STATUS_EX BIT(0)
2300ba3c125SPaul Burton
231*1f07fab9SGregory CLEMENT /* GCR_ACCESS - Controls core/IOCU access to GCRs */
232*1f07fab9SGregory CLEMENT GCR_ACCESSOR_RW(32, 0x120, access_cm3)
233*1f07fab9SGregory CLEMENT #define CM_GCR_ACCESS_ACCESSEN GENMASK(7, 0)
234*1f07fab9SGregory CLEMENT
23593c5bba5SPaul Burton /* GCR_L2_CONFIG - Indicates L2 cache configuration when Config5.L2C=1 */
23693c5bba5SPaul Burton GCR_ACCESSOR_RW(32, 0x130, l2_config)
23793c5bba5SPaul Burton #define CM_GCR_L2_CONFIG_BYPASS BIT(20)
23893c5bba5SPaul Burton #define CM_GCR_L2_CONFIG_SET_SIZE GENMASK(15, 12)
23993c5bba5SPaul Burton #define CM_GCR_L2_CONFIG_LINE_SIZE GENMASK(11, 8)
24093c5bba5SPaul Burton #define CM_GCR_L2_CONFIG_ASSOC GENMASK(7, 0)
2417573b94eSPaul Burton
24293c5bba5SPaul Burton /* GCR_SYS_CONFIG2 - Further information about the system */
24393c5bba5SPaul Burton GCR_ACCESSOR_RO(32, 0x150, sys_config2)
24493c5bba5SPaul Burton #define CM_GCR_SYS_CONFIG2_MAXVPW GENMASK(3, 0)
2454d035516SPaul Burton
24693c5bba5SPaul Burton /* GCR_L2_PFT_CONTROL - Controls hardware L2 prefetching */
24793c5bba5SPaul Burton GCR_ACCESSOR_RW(32, 0x300, l2_pft_control)
24893c5bba5SPaul Burton #define CM_GCR_L2_PFT_CONTROL_PAGEMASK GENMASK(31, 12)
24993c5bba5SPaul Burton #define CM_GCR_L2_PFT_CONTROL_PFTEN BIT(8)
25093c5bba5SPaul Burton #define CM_GCR_L2_PFT_CONTROL_NPFT GENMASK(7, 0)
2514d035516SPaul Burton
25293c5bba5SPaul Burton /* GCR_L2_PFT_CONTROL_B - Controls hardware L2 prefetching */
25393c5bba5SPaul Burton GCR_ACCESSOR_RW(32, 0x308, l2_pft_control_b)
25493c5bba5SPaul Burton #define CM_GCR_L2_PFT_CONTROL_B_CEN BIT(8)
25593c5bba5SPaul Burton #define CM_GCR_L2_PFT_CONTROL_B_PORTID GENMASK(7, 0)
2569f98f3ddSPaul Burton
25723cb600eSPaul Burton /* GCR_L2SM_COP - L2 cache op state machine control */
25823cb600eSPaul Burton GCR_ACCESSOR_RW(32, 0x620, l2sm_cop)
25923cb600eSPaul Burton #define CM_GCR_L2SM_COP_PRESENT BIT(31)
26023cb600eSPaul Burton #define CM_GCR_L2SM_COP_RESULT GENMASK(8, 6)
26123cb600eSPaul Burton #define CM_GCR_L2SM_COP_RESULT_DONTCARE 0
26223cb600eSPaul Burton #define CM_GCR_L2SM_COP_RESULT_DONE_OK 1
26323cb600eSPaul Burton #define CM_GCR_L2SM_COP_RESULT_DONE_ERROR 2
26423cb600eSPaul Burton #define CM_GCR_L2SM_COP_RESULT_ABORT_OK 3
26523cb600eSPaul Burton #define CM_GCR_L2SM_COP_RESULT_ABORT_ERROR 4
26623cb600eSPaul Burton #define CM_GCR_L2SM_COP_RUNNING BIT(5)
26723cb600eSPaul Burton #define CM_GCR_L2SM_COP_TYPE GENMASK(4, 2)
26823cb600eSPaul Burton #define CM_GCR_L2SM_COP_TYPE_IDX_WBINV 0
26923cb600eSPaul Burton #define CM_GCR_L2SM_COP_TYPE_IDX_STORETAG 1
27023cb600eSPaul Burton #define CM_GCR_L2SM_COP_TYPE_IDX_STORETAGDATA 2
27123cb600eSPaul Burton #define CM_GCR_L2SM_COP_TYPE_HIT_INV 4
27223cb600eSPaul Burton #define CM_GCR_L2SM_COP_TYPE_HIT_WBINV 5
27323cb600eSPaul Burton #define CM_GCR_L2SM_COP_TYPE_HIT_WB 6
27423cb600eSPaul Burton #define CM_GCR_L2SM_COP_TYPE_FETCHLOCK 7
27523cb600eSPaul Burton #define CM_GCR_L2SM_COP_CMD GENMASK(1, 0)
27623cb600eSPaul Burton #define CM_GCR_L2SM_COP_CMD_START 1 /* only when idle */
27723cb600eSPaul Burton #define CM_GCR_L2SM_COP_CMD_ABORT 3 /* only when running */
27823cb600eSPaul Burton
27923cb600eSPaul Burton /* GCR_L2SM_TAG_ADDR_COP - L2 cache op state machine address control */
28023cb600eSPaul Burton GCR_ACCESSOR_RW(64, 0x628, l2sm_tag_addr_cop)
28123cb600eSPaul Burton #define CM_GCR_L2SM_TAG_ADDR_COP_NUM_LINES GENMASK_ULL(63, 48)
28223cb600eSPaul Burton #define CM_GCR_L2SM_TAG_ADDR_COP_START_TAG GENMASK_ULL(47, 6)
28323cb600eSPaul Burton
28493c5bba5SPaul Burton /* GCR_BEV_BASE - Controls the location of the BEV for powered up cores */
28593c5bba5SPaul Burton GCR_ACCESSOR_RW(64, 0x680, bev_base)
2869f98f3ddSPaul Burton
28793c5bba5SPaul Burton /* GCR_Cx_RESET_RELEASE - Controls core reset for CM 1.x */
28893c5bba5SPaul Burton GCR_CX_ACCESSOR_RW(32, 0x000, reset_release)
2899f98f3ddSPaul Burton
29093c5bba5SPaul Burton /* GCR_Cx_COHERENCE - Controls core coherence */
29193c5bba5SPaul Burton GCR_CX_ACCESSOR_RW(32, 0x008, coherence)
29293c5bba5SPaul Burton #define CM_GCR_Cx_COHERENCE_COHDOMAINEN GENMASK(7, 0)
29393c5bba5SPaul Burton #define CM3_GCR_Cx_COHERENCE_COHEN BIT(0)
2949f98f3ddSPaul Burton
29593c5bba5SPaul Burton /* GCR_Cx_CONFIG - Information about a core's configuration */
29693c5bba5SPaul Burton GCR_CX_ACCESSOR_RO(32, 0x010, config)
29793c5bba5SPaul Burton #define CM_GCR_Cx_CONFIG_IOCUTYPE GENMASK(11, 10)
29893c5bba5SPaul Burton #define CM_GCR_Cx_CONFIG_PVPE GENMASK(9, 0)
29993c5bba5SPaul Burton
30093c5bba5SPaul Burton /* GCR_Cx_OTHER - Configure the core-other/redirect GCR block */
30193c5bba5SPaul Burton GCR_CX_ACCESSOR_RW(32, 0x018, other)
30223cb600eSPaul Burton #define CM_GCR_Cx_OTHER_CORENUM GENMASK(31, 16) /* CM < 3 */
30323cb600eSPaul Burton #define CM_GCR_Cx_OTHER_CLUSTER_EN BIT(31) /* CM >= 3.5 */
30423cb600eSPaul Burton #define CM_GCR_Cx_OTHER_GIC_EN BIT(30) /* CM >= 3.5 */
30523cb600eSPaul Burton #define CM_GCR_Cx_OTHER_BLOCK GENMASK(25, 24) /* CM >= 3.5 */
30623cb600eSPaul Burton #define CM_GCR_Cx_OTHER_BLOCK_LOCAL 0
30723cb600eSPaul Burton #define CM_GCR_Cx_OTHER_BLOCK_GLOBAL 1
30823cb600eSPaul Burton #define CM_GCR_Cx_OTHER_BLOCK_USER 2
30923cb600eSPaul Burton #define CM_GCR_Cx_OTHER_BLOCK_GLOBAL_HIGH 3
31023cb600eSPaul Burton #define CM_GCR_Cx_OTHER_CLUSTER GENMASK(21, 16) /* CM >= 3.5 */
31123cb600eSPaul Burton #define CM3_GCR_Cx_OTHER_CORE GENMASK(13, 8) /* CM >= 3 */
31223cb600eSPaul Burton #define CM_GCR_Cx_OTHER_CORE_CM 32
31323cb600eSPaul Burton #define CM3_GCR_Cx_OTHER_VP GENMASK(2, 0) /* CM >= 3 */
31493c5bba5SPaul Burton
31593c5bba5SPaul Burton /* GCR_Cx_RESET_BASE - Configure where powered up cores will fetch from */
31693c5bba5SPaul Burton GCR_CX_ACCESSOR_RW(32, 0x020, reset_base)
31793c5bba5SPaul Burton #define CM_GCR_Cx_RESET_BASE_BEVEXCBASE GENMASK(31, 12)
31893c5bba5SPaul Burton
31993c5bba5SPaul Burton /* GCR_Cx_ID - Identify the current core */
32093c5bba5SPaul Burton GCR_CX_ACCESSOR_RO(32, 0x028, id)
32123cb600eSPaul Burton #define CM_GCR_Cx_ID_CLUSTER GENMASK(15, 8)
32223cb600eSPaul Burton #define CM_GCR_Cx_ID_CORE GENMASK(7, 0)
32393c5bba5SPaul Burton
32493c5bba5SPaul Burton /* GCR_Cx_RESET_EXT_BASE - Configure behaviour when cores reset or power up */
32593c5bba5SPaul Burton GCR_CX_ACCESSOR_RW(32, 0x030, reset_ext_base)
32693c5bba5SPaul Burton #define CM_GCR_Cx_RESET_EXT_BASE_EVARESET BIT(31)
32793c5bba5SPaul Burton #define CM_GCR_Cx_RESET_EXT_BASE_UEB BIT(30)
32893c5bba5SPaul Burton #define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCMASK GENMASK(27, 20)
32993c5bba5SPaul Burton #define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCPA GENMASK(7, 1)
33093c5bba5SPaul Burton #define CM_GCR_Cx_RESET_EXT_BASE_PRESENT BIT(0)
3319f98f3ddSPaul Burton
3329f98f3ddSPaul Burton /**
3339f98f3ddSPaul Burton * mips_cm_l2sync - perform an L2-only sync operation
3349f98f3ddSPaul Burton *
3359f98f3ddSPaul Burton * If an L2-only sync region is present in the system then this function
3369f98f3ddSPaul Burton * performs and L2-only sync and returns zero. Otherwise it returns -ENODEV.
3379f98f3ddSPaul Burton */
mips_cm_l2sync(void)3389f98f3ddSPaul Burton static inline int mips_cm_l2sync(void)
3399f98f3ddSPaul Burton {
3409f98f3ddSPaul Burton if (!mips_cm_has_l2sync())
3419f98f3ddSPaul Burton return -ENODEV;
3429f98f3ddSPaul Burton
3439f98f3ddSPaul Burton writel(0, mips_cm_l2sync_base);
3449f98f3ddSPaul Burton return 0;
3459f98f3ddSPaul Burton }
3469f98f3ddSPaul Burton
347197e89e0SPaul Burton /**
348197e89e0SPaul Burton * mips_cm_revision() - return CM revision
349197e89e0SPaul Burton *
350197e89e0SPaul Burton * Return: The revision of the CM, from GCR_REV, or 0 if no CM is present. The
351197e89e0SPaul Burton * return value should be checked against the CM_REV_* macros.
352197e89e0SPaul Burton */
mips_cm_revision(void)353197e89e0SPaul Burton static inline int mips_cm_revision(void)
354197e89e0SPaul Burton {
355197e89e0SPaul Burton if (!mips_cm_present())
356197e89e0SPaul Burton return 0;
357197e89e0SPaul Burton
358197e89e0SPaul Burton return read_gcr_rev();
359197e89e0SPaul Burton }
360197e89e0SPaul Burton
3617573b94eSPaul Burton /**
3627573b94eSPaul Burton * mips_cm_max_vp_width() - return the width in bits of VP indices
3637573b94eSPaul Burton *
3647573b94eSPaul Burton * Return: the width, in bits, of VP indices in fields that combine core & VP
3657573b94eSPaul Burton * indices.
3667573b94eSPaul Burton */
mips_cm_max_vp_width(void)3677573b94eSPaul Burton static inline unsigned int mips_cm_max_vp_width(void)
3687573b94eSPaul Burton {
3697573b94eSPaul Burton extern int smp_num_siblings;
3707573b94eSPaul Burton
3717573b94eSPaul Burton if (mips_cm_revision() >= CM_REV_CM3)
37218b8f5b6SGeert Uytterhoeven return FIELD_GET(CM_GCR_SYS_CONFIG2_MAXVPW,
37318b8f5b6SGeert Uytterhoeven read_gcr_sys_config2());
3747573b94eSPaul Burton
3756605d156SPaul Burton if (mips_cm_present()) {
3766605d156SPaul Burton /*
3776605d156SPaul Burton * We presume that all cores in the system will have the same
3786605d156SPaul Burton * number of VP(E)s, and if that ever changes then this will
3796605d156SPaul Burton * need revisiting.
3806605d156SPaul Burton */
38118b8f5b6SGeert Uytterhoeven return FIELD_GET(CM_GCR_Cx_CONFIG_PVPE, read_gcr_cl_config()) + 1;
3826605d156SPaul Burton }
3836605d156SPaul Burton
38497f2645fSMasahiro Yamada if (IS_ENABLED(CONFIG_SMP))
3857573b94eSPaul Burton return smp_num_siblings;
386a60ae81eSPaul Burton
387a60ae81eSPaul Burton return 1;
3887573b94eSPaul Burton }
3897573b94eSPaul Burton
3907573b94eSPaul Burton /**
3917573b94eSPaul Burton * mips_cm_vp_id() - calculate the hardware VP ID for a CPU
3927573b94eSPaul Burton * @cpu: the CPU whose VP ID to calculate
3937573b94eSPaul Burton *
3947573b94eSPaul Burton * Hardware such as the GIC uses identifiers for VPs which may not match the
3957573b94eSPaul Burton * CPU numbers used by Linux. This function calculates the hardware VP
3967573b94eSPaul Burton * identifier corresponding to a given CPU.
3977573b94eSPaul Burton *
3987573b94eSPaul Burton * Return: the VP ID for the CPU.
3997573b94eSPaul Burton */
mips_cm_vp_id(unsigned int cpu)4007573b94eSPaul Burton static inline unsigned int mips_cm_vp_id(unsigned int cpu)
4017573b94eSPaul Burton {
402f875a832SPaul Burton unsigned int core = cpu_core(&cpu_data[cpu]);
4037573b94eSPaul Burton unsigned int vp = cpu_vpe_id(&cpu_data[cpu]);
4047573b94eSPaul Burton
4057573b94eSPaul Burton return (core * mips_cm_max_vp_width()) + vp;
4067573b94eSPaul Burton }
4077573b94eSPaul Burton
40823d5de8eSPaul Burton #ifdef CONFIG_MIPS_CM
40923d5de8eSPaul Burton
41023d5de8eSPaul Burton /**
41168923cdcSPaul Burton * mips_cm_lock_other - lock access to redirect/other region
41268923cdcSPaul Burton * @cluster: the other cluster to be accessed
41323d5de8eSPaul Burton * @core: the other core to be accessed
41423d5de8eSPaul Burton * @vp: the VP within the other core to be accessed
41568923cdcSPaul Burton * @block: the register block to be accessed
41623d5de8eSPaul Burton *
41768923cdcSPaul Burton * Configure the redirect/other region for the local core/VP (depending upon
41868923cdcSPaul Burton * the CM revision) to target the specified @cluster, @core, @vp & register
41968923cdcSPaul Burton * @block. Must be called before using the redirect/other region, and followed
42068923cdcSPaul Burton * by a call to mips_cm_unlock_other() when access to the redirect/other region
42168923cdcSPaul Burton * is complete.
42268923cdcSPaul Burton *
42368923cdcSPaul Burton * This function acquires a spinlock such that code between it &
42468923cdcSPaul Burton * mips_cm_unlock_other() calls cannot be pre-empted by anything which may
42568923cdcSPaul Burton * reconfigure the redirect/other region, and cannot be interfered with by
42668923cdcSPaul Burton * another VP in the core. As such calls to this function should not be nested.
42723d5de8eSPaul Burton */
42868923cdcSPaul Burton extern void mips_cm_lock_other(unsigned int cluster, unsigned int core,
42968923cdcSPaul Burton unsigned int vp, unsigned int block);
43023d5de8eSPaul Burton
43123d5de8eSPaul Burton /**
43268923cdcSPaul Burton * mips_cm_unlock_other - unlock access to redirect/other region
43323d5de8eSPaul Burton *
43468923cdcSPaul Burton * Must be called after mips_cm_lock_other() once all required access to the
43568923cdcSPaul Burton * redirect/other region has been completed.
43623d5de8eSPaul Burton */
43723d5de8eSPaul Burton extern void mips_cm_unlock_other(void);
43823d5de8eSPaul Burton
43923d5de8eSPaul Burton #else /* !CONFIG_MIPS_CM */
44023d5de8eSPaul Burton
mips_cm_lock_other(unsigned int cluster,unsigned int core,unsigned int vp,unsigned int block)44168923cdcSPaul Burton static inline void mips_cm_lock_other(unsigned int cluster, unsigned int core,
44268923cdcSPaul Burton unsigned int vp, unsigned int block) { }
mips_cm_unlock_other(void)44323d5de8eSPaul Burton static inline void mips_cm_unlock_other(void) { }
44423d5de8eSPaul Burton
44523d5de8eSPaul Burton #endif /* !CONFIG_MIPS_CM */
44623d5de8eSPaul Burton
44768923cdcSPaul Burton /**
44868923cdcSPaul Burton * mips_cm_lock_other_cpu - lock access to redirect/other region
44968923cdcSPaul Burton * @cpu: the other CPU whose register we want to access
45068923cdcSPaul Burton *
45168923cdcSPaul Burton * Configure the redirect/other region for the local core/VP (depending upon
45268923cdcSPaul Burton * the CM revision) to target the specified @cpu & register @block. This is
45368923cdcSPaul Burton * equivalent to calling mips_cm_lock_other() but accepts a Linux CPU number
45468923cdcSPaul Burton * for convenience.
45568923cdcSPaul Burton */
mips_cm_lock_other_cpu(unsigned int cpu,unsigned int block)45668923cdcSPaul Burton static inline void mips_cm_lock_other_cpu(unsigned int cpu, unsigned int block)
45768923cdcSPaul Burton {
45868923cdcSPaul Burton struct cpuinfo_mips *d = &cpu_data[cpu];
45968923cdcSPaul Burton
46068923cdcSPaul Burton mips_cm_lock_other(cpu_cluster(d), cpu_core(d), cpu_vpe_id(d), block);
46168923cdcSPaul Burton }
46268923cdcSPaul Burton
4639f98f3ddSPaul Burton #endif /* __MIPS_ASM_MIPS_CM_H__ */
464