18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2013 Imagination Technologies 48c2ecf20Sopenharmony_ci * Author: Paul Burton <paul.burton@mips.com> 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#ifndef __MIPS_ASM_MIPS_CPS_H__ 88c2ecf20Sopenharmony_ci# error Please include asm/mips-cps.h rather than asm/mips-cm.h 98c2ecf20Sopenharmony_ci#endif 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#ifndef __MIPS_ASM_MIPS_CM_H__ 128c2ecf20Sopenharmony_ci#define __MIPS_ASM_MIPS_CM_H__ 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#include <linux/bitfield.h> 158c2ecf20Sopenharmony_ci#include <linux/bitops.h> 168c2ecf20Sopenharmony_ci#include <linux/errno.h> 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci/* The base address of the CM GCR block */ 198c2ecf20Sopenharmony_ciextern void __iomem *mips_gcr_base; 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci/* The base address of the CM L2-only sync region */ 228c2ecf20Sopenharmony_ciextern void __iomem *mips_cm_l2sync_base; 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci/** 258c2ecf20Sopenharmony_ci * __mips_cm_phys_base - retrieve the physical base address of the CM 268c2ecf20Sopenharmony_ci * 278c2ecf20Sopenharmony_ci * This function returns the physical base address of the Coherence Manager 288c2ecf20Sopenharmony_ci * global control block, or 0 if no Coherence Manager is present. It provides 298c2ecf20Sopenharmony_ci * a default implementation which reads the CMGCRBase register where available, 308c2ecf20Sopenharmony_ci * and may be overridden by platforms which determine this address in a 318c2ecf20Sopenharmony_ci * different way by defining a function with the same prototype except for the 328c2ecf20Sopenharmony_ci * name mips_cm_phys_base (without underscores). 338c2ecf20Sopenharmony_ci */ 348c2ecf20Sopenharmony_ciextern phys_addr_t __mips_cm_phys_base(void); 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci/* 378c2ecf20Sopenharmony_ci * mips_cm_is64 - determine CM register width 388c2ecf20Sopenharmony_ci * 398c2ecf20Sopenharmony_ci * The CM register width is determined by the version of the CM, with CM3 408c2ecf20Sopenharmony_ci * introducing 64 bit GCRs and all prior CM versions having 32 bit GCRs. 418c2ecf20Sopenharmony_ci * However we may run a kernel built for MIPS32 on a system with 64 bit GCRs, 428c2ecf20Sopenharmony_ci * or vice-versa. This variable indicates the width of the memory accesses 438c2ecf20Sopenharmony_ci * that the kernel will perform to GCRs, which may differ from the actual 448c2ecf20Sopenharmony_ci * width of the GCRs. 458c2ecf20Sopenharmony_ci * 468c2ecf20Sopenharmony_ci * It's set to 0 for 32-bit accesses and 1 for 64-bit accesses. 478c2ecf20Sopenharmony_ci */ 488c2ecf20Sopenharmony_ciextern int mips_cm_is64; 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci/** 518c2ecf20Sopenharmony_ci * mips_cm_error_report - Report CM cache errors 528c2ecf20Sopenharmony_ci */ 538c2ecf20Sopenharmony_ci#ifdef CONFIG_MIPS_CM 548c2ecf20Sopenharmony_ciextern void mips_cm_error_report(void); 558c2ecf20Sopenharmony_ci#else 568c2ecf20Sopenharmony_cistatic inline void mips_cm_error_report(void) {} 578c2ecf20Sopenharmony_ci#endif 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci/** 608c2ecf20Sopenharmony_ci * mips_cm_probe - probe for a Coherence Manager 618c2ecf20Sopenharmony_ci * 628c2ecf20Sopenharmony_ci * Attempt to detect the presence of a Coherence Manager. Returns 0 if a CM 638c2ecf20Sopenharmony_ci * is successfully detected, else -errno. 648c2ecf20Sopenharmony_ci */ 658c2ecf20Sopenharmony_ci#ifdef CONFIG_MIPS_CM 668c2ecf20Sopenharmony_ciextern int mips_cm_probe(void); 678c2ecf20Sopenharmony_ci#else 688c2ecf20Sopenharmony_cistatic inline int mips_cm_probe(void) 698c2ecf20Sopenharmony_ci{ 708c2ecf20Sopenharmony_ci return -ENODEV; 718c2ecf20Sopenharmony_ci} 728c2ecf20Sopenharmony_ci#endif 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci/** 758c2ecf20Sopenharmony_ci * mips_cm_present - determine whether a Coherence Manager is present 768c2ecf20Sopenharmony_ci * 778c2ecf20Sopenharmony_ci * Returns true if a CM is present in the system, else false. 788c2ecf20Sopenharmony_ci */ 798c2ecf20Sopenharmony_cistatic inline bool mips_cm_present(void) 808c2ecf20Sopenharmony_ci{ 818c2ecf20Sopenharmony_ci#ifdef CONFIG_MIPS_CM 828c2ecf20Sopenharmony_ci return mips_gcr_base != NULL; 838c2ecf20Sopenharmony_ci#else 848c2ecf20Sopenharmony_ci return false; 858c2ecf20Sopenharmony_ci#endif 868c2ecf20Sopenharmony_ci} 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci/** 898c2ecf20Sopenharmony_ci * mips_cm_has_l2sync - determine whether an L2-only sync region is present 908c2ecf20Sopenharmony_ci * 918c2ecf20Sopenharmony_ci * Returns true if the system implements an L2-only sync region, else false. 928c2ecf20Sopenharmony_ci */ 938c2ecf20Sopenharmony_cistatic inline bool mips_cm_has_l2sync(void) 948c2ecf20Sopenharmony_ci{ 958c2ecf20Sopenharmony_ci#ifdef CONFIG_MIPS_CM 968c2ecf20Sopenharmony_ci return mips_cm_l2sync_base != NULL; 978c2ecf20Sopenharmony_ci#else 988c2ecf20Sopenharmony_ci return false; 998c2ecf20Sopenharmony_ci#endif 1008c2ecf20Sopenharmony_ci} 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci/* Offsets to register blocks from the CM base address */ 1038c2ecf20Sopenharmony_ci#define MIPS_CM_GCB_OFS 0x0000 /* Global Control Block */ 1048c2ecf20Sopenharmony_ci#define MIPS_CM_CLCB_OFS 0x2000 /* Core Local Control Block */ 1058c2ecf20Sopenharmony_ci#define MIPS_CM_COCB_OFS 0x4000 /* Core Other Control Block */ 1068c2ecf20Sopenharmony_ci#define MIPS_CM_GDB_OFS 0x6000 /* Global Debug Block */ 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci/* Total size of the CM memory mapped registers */ 1098c2ecf20Sopenharmony_ci#define MIPS_CM_GCR_SIZE 0x8000 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci/* Size of the L2-only sync region */ 1128c2ecf20Sopenharmony_ci#define MIPS_CM_L2SYNC_SIZE 0x1000 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci#define GCR_ACCESSOR_RO(sz, off, name) \ 1158c2ecf20Sopenharmony_ci CPS_ACCESSOR_RO(gcr, sz, MIPS_CM_GCB_OFS + off, name) \ 1168c2ecf20Sopenharmony_ci CPS_ACCESSOR_RO(gcr, sz, MIPS_CM_COCB_OFS + off, redir_##name) 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci#define GCR_ACCESSOR_RW(sz, off, name) \ 1198c2ecf20Sopenharmony_ci CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_GCB_OFS + off, name) \ 1208c2ecf20Sopenharmony_ci CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_COCB_OFS + off, redir_##name) 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci#define GCR_CX_ACCESSOR_RO(sz, off, name) \ 1238c2ecf20Sopenharmony_ci CPS_ACCESSOR_RO(gcr, sz, MIPS_CM_CLCB_OFS + off, cl_##name) \ 1248c2ecf20Sopenharmony_ci CPS_ACCESSOR_RO(gcr, sz, MIPS_CM_COCB_OFS + off, co_##name) 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci#define GCR_CX_ACCESSOR_RW(sz, off, name) \ 1278c2ecf20Sopenharmony_ci CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_CLCB_OFS + off, cl_##name) \ 1288c2ecf20Sopenharmony_ci CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_COCB_OFS + off, co_##name) 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci/* GCR_CONFIG - Information about the system */ 1318c2ecf20Sopenharmony_ciGCR_ACCESSOR_RO(64, 0x000, config) 1328c2ecf20Sopenharmony_ci#define CM_GCR_CONFIG_CLUSTER_COH_CAPABLE BIT_ULL(43) 1338c2ecf20Sopenharmony_ci#define CM_GCR_CONFIG_CLUSTER_ID GENMASK_ULL(39, 32) 1348c2ecf20Sopenharmony_ci#define CM_GCR_CONFIG_NUM_CLUSTERS GENMASK(29, 23) 1358c2ecf20Sopenharmony_ci#define CM_GCR_CONFIG_NUMIOCU GENMASK(15, 8) 1368c2ecf20Sopenharmony_ci#define CM_GCR_CONFIG_PCORES GENMASK(7, 0) 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci/* GCR_BASE - Base address of the Global Configuration Registers (GCRs) */ 1398c2ecf20Sopenharmony_ciGCR_ACCESSOR_RW(64, 0x008, base) 1408c2ecf20Sopenharmony_ci#define CM_GCR_BASE_GCRBASE GENMASK_ULL(47, 15) 1418c2ecf20Sopenharmony_ci#define CM_GCR_BASE_CMDEFTGT GENMASK(1, 0) 1428c2ecf20Sopenharmony_ci#define CM_GCR_BASE_CMDEFTGT_MEM 0 1438c2ecf20Sopenharmony_ci#define CM_GCR_BASE_CMDEFTGT_RESERVED 1 1448c2ecf20Sopenharmony_ci#define CM_GCR_BASE_CMDEFTGT_IOCU0 2 1458c2ecf20Sopenharmony_ci#define CM_GCR_BASE_CMDEFTGT_IOCU1 3 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci/* GCR_ACCESS - Controls core/IOCU access to GCRs */ 1488c2ecf20Sopenharmony_ciGCR_ACCESSOR_RW(32, 0x020, access) 1498c2ecf20Sopenharmony_ci#define CM_GCR_ACCESS_ACCESSEN GENMASK(7, 0) 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci/* GCR_REV - Indicates the Coherence Manager revision */ 1528c2ecf20Sopenharmony_ciGCR_ACCESSOR_RO(32, 0x030, rev) 1538c2ecf20Sopenharmony_ci#define CM_GCR_REV_MAJOR GENMASK(15, 8) 1548c2ecf20Sopenharmony_ci#define CM_GCR_REV_MINOR GENMASK(7, 0) 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci#define CM_ENCODE_REV(major, minor) \ 1578c2ecf20Sopenharmony_ci (FIELD_PREP(CM_GCR_REV_MAJOR, major) | \ 1588c2ecf20Sopenharmony_ci FIELD_PREP(CM_GCR_REV_MINOR, minor)) 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci#define CM_REV_CM2 CM_ENCODE_REV(6, 0) 1618c2ecf20Sopenharmony_ci#define CM_REV_CM2_5 CM_ENCODE_REV(7, 0) 1628c2ecf20Sopenharmony_ci#define CM_REV_CM3 CM_ENCODE_REV(8, 0) 1638c2ecf20Sopenharmony_ci#define CM_REV_CM3_5 CM_ENCODE_REV(9, 0) 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci/* GCR_ERR_CONTROL - Control error checking logic */ 1668c2ecf20Sopenharmony_ciGCR_ACCESSOR_RW(32, 0x038, err_control) 1678c2ecf20Sopenharmony_ci#define CM_GCR_ERR_CONTROL_L2_ECC_EN BIT(1) 1688c2ecf20Sopenharmony_ci#define CM_GCR_ERR_CONTROL_L2_ECC_SUPPORT BIT(0) 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci/* GCR_ERR_MASK - Control which errors are reported as interrupts */ 1718c2ecf20Sopenharmony_ciGCR_ACCESSOR_RW(64, 0x040, error_mask) 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci/* GCR_ERR_CAUSE - Indicates the type of error that occurred */ 1748c2ecf20Sopenharmony_ciGCR_ACCESSOR_RW(64, 0x048, error_cause) 1758c2ecf20Sopenharmony_ci#define CM_GCR_ERROR_CAUSE_ERRTYPE GENMASK(31, 27) 1768c2ecf20Sopenharmony_ci#define CM3_GCR_ERROR_CAUSE_ERRTYPE GENMASK_ULL(63, 58) 1778c2ecf20Sopenharmony_ci#define CM_GCR_ERROR_CAUSE_ERRINFO GENMASK(26, 0) 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci/* GCR_ERR_ADDR - Indicates the address associated with an error */ 1808c2ecf20Sopenharmony_ciGCR_ACCESSOR_RW(64, 0x050, error_addr) 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ci/* GCR_ERR_MULT - Indicates when multiple errors have occurred */ 1838c2ecf20Sopenharmony_ciGCR_ACCESSOR_RW(64, 0x058, error_mult) 1848c2ecf20Sopenharmony_ci#define CM_GCR_ERROR_MULT_ERR2ND GENMASK(4, 0) 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_ci/* GCR_L2_ONLY_SYNC_BASE - Base address of the L2 cache-only sync region */ 1878c2ecf20Sopenharmony_ciGCR_ACCESSOR_RW(64, 0x070, l2_only_sync_base) 1888c2ecf20Sopenharmony_ci#define CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE GENMASK(31, 12) 1898c2ecf20Sopenharmony_ci#define CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN BIT(0) 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ci/* GCR_GIC_BASE - Base address of the Global Interrupt Controller (GIC) */ 1928c2ecf20Sopenharmony_ciGCR_ACCESSOR_RW(64, 0x080, gic_base) 1938c2ecf20Sopenharmony_ci#define CM_GCR_GIC_BASE_GICBASE GENMASK(31, 17) 1948c2ecf20Sopenharmony_ci#define CM_GCR_GIC_BASE_GICEN BIT(0) 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci/* GCR_CPC_BASE - Base address of the Cluster Power Controller (CPC) */ 1978c2ecf20Sopenharmony_ciGCR_ACCESSOR_RW(64, 0x088, cpc_base) 1988c2ecf20Sopenharmony_ci#define CM_GCR_CPC_BASE_CPCBASE GENMASK(31, 15) 1998c2ecf20Sopenharmony_ci#define CM_GCR_CPC_BASE_CPCEN BIT(0) 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ci/* GCR_REGn_BASE - Base addresses of CM address regions */ 2028c2ecf20Sopenharmony_ciGCR_ACCESSOR_RW(64, 0x090, reg0_base) 2038c2ecf20Sopenharmony_ciGCR_ACCESSOR_RW(64, 0x0a0, reg1_base) 2048c2ecf20Sopenharmony_ciGCR_ACCESSOR_RW(64, 0x0b0, reg2_base) 2058c2ecf20Sopenharmony_ciGCR_ACCESSOR_RW(64, 0x0c0, reg3_base) 2068c2ecf20Sopenharmony_ci#define CM_GCR_REGn_BASE_BASEADDR GENMASK(31, 16) 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_ci/* GCR_REGn_MASK - Size & destination of CM address regions */ 2098c2ecf20Sopenharmony_ciGCR_ACCESSOR_RW(64, 0x098, reg0_mask) 2108c2ecf20Sopenharmony_ciGCR_ACCESSOR_RW(64, 0x0a8, reg1_mask) 2118c2ecf20Sopenharmony_ciGCR_ACCESSOR_RW(64, 0x0b8, reg2_mask) 2128c2ecf20Sopenharmony_ciGCR_ACCESSOR_RW(64, 0x0c8, reg3_mask) 2138c2ecf20Sopenharmony_ci#define CM_GCR_REGn_MASK_ADDRMASK GENMASK(31, 16) 2148c2ecf20Sopenharmony_ci#define CM_GCR_REGn_MASK_CCAOVR GENMASK(7, 5) 2158c2ecf20Sopenharmony_ci#define CM_GCR_REGn_MASK_CCAOVREN BIT(4) 2168c2ecf20Sopenharmony_ci#define CM_GCR_REGn_MASK_DROPL2 BIT(2) 2178c2ecf20Sopenharmony_ci#define CM_GCR_REGn_MASK_CMTGT GENMASK(1, 0) 2188c2ecf20Sopenharmony_ci#define CM_GCR_REGn_MASK_CMTGT_DISABLED 0x0 2198c2ecf20Sopenharmony_ci#define CM_GCR_REGn_MASK_CMTGT_MEM 0x1 2208c2ecf20Sopenharmony_ci#define CM_GCR_REGn_MASK_CMTGT_IOCU0 0x2 2218c2ecf20Sopenharmony_ci#define CM_GCR_REGn_MASK_CMTGT_IOCU1 0x3 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_ci/* GCR_GIC_STATUS - Indicates presence of a Global Interrupt Controller (GIC) */ 2248c2ecf20Sopenharmony_ciGCR_ACCESSOR_RO(32, 0x0d0, gic_status) 2258c2ecf20Sopenharmony_ci#define CM_GCR_GIC_STATUS_EX BIT(0) 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_ci/* GCR_CPC_STATUS - Indicates presence of a Cluster Power Controller (CPC) */ 2288c2ecf20Sopenharmony_ciGCR_ACCESSOR_RO(32, 0x0f0, cpc_status) 2298c2ecf20Sopenharmony_ci#define CM_GCR_CPC_STATUS_EX BIT(0) 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_ci/* GCR_L2_CONFIG - Indicates L2 cache configuration when Config5.L2C=1 */ 2328c2ecf20Sopenharmony_ciGCR_ACCESSOR_RW(32, 0x130, l2_config) 2338c2ecf20Sopenharmony_ci#define CM_GCR_L2_CONFIG_BYPASS BIT(20) 2348c2ecf20Sopenharmony_ci#define CM_GCR_L2_CONFIG_SET_SIZE GENMASK(15, 12) 2358c2ecf20Sopenharmony_ci#define CM_GCR_L2_CONFIG_LINE_SIZE GENMASK(11, 8) 2368c2ecf20Sopenharmony_ci#define CM_GCR_L2_CONFIG_ASSOC GENMASK(7, 0) 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_ci/* GCR_SYS_CONFIG2 - Further information about the system */ 2398c2ecf20Sopenharmony_ciGCR_ACCESSOR_RO(32, 0x150, sys_config2) 2408c2ecf20Sopenharmony_ci#define CM_GCR_SYS_CONFIG2_MAXVPW GENMASK(3, 0) 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_ci/* GCR_L2_PFT_CONTROL - Controls hardware L2 prefetching */ 2438c2ecf20Sopenharmony_ciGCR_ACCESSOR_RW(32, 0x300, l2_pft_control) 2448c2ecf20Sopenharmony_ci#define CM_GCR_L2_PFT_CONTROL_PAGEMASK GENMASK(31, 12) 2458c2ecf20Sopenharmony_ci#define CM_GCR_L2_PFT_CONTROL_PFTEN BIT(8) 2468c2ecf20Sopenharmony_ci#define CM_GCR_L2_PFT_CONTROL_NPFT GENMASK(7, 0) 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci/* GCR_L2_PFT_CONTROL_B - Controls hardware L2 prefetching */ 2498c2ecf20Sopenharmony_ciGCR_ACCESSOR_RW(32, 0x308, l2_pft_control_b) 2508c2ecf20Sopenharmony_ci#define CM_GCR_L2_PFT_CONTROL_B_CEN BIT(8) 2518c2ecf20Sopenharmony_ci#define CM_GCR_L2_PFT_CONTROL_B_PORTID GENMASK(7, 0) 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_ci/* GCR_L2SM_COP - L2 cache op state machine control */ 2548c2ecf20Sopenharmony_ciGCR_ACCESSOR_RW(32, 0x620, l2sm_cop) 2558c2ecf20Sopenharmony_ci#define CM_GCR_L2SM_COP_PRESENT BIT(31) 2568c2ecf20Sopenharmony_ci#define CM_GCR_L2SM_COP_RESULT GENMASK(8, 6) 2578c2ecf20Sopenharmony_ci#define CM_GCR_L2SM_COP_RESULT_DONTCARE 0 2588c2ecf20Sopenharmony_ci#define CM_GCR_L2SM_COP_RESULT_DONE_OK 1 2598c2ecf20Sopenharmony_ci#define CM_GCR_L2SM_COP_RESULT_DONE_ERROR 2 2608c2ecf20Sopenharmony_ci#define CM_GCR_L2SM_COP_RESULT_ABORT_OK 3 2618c2ecf20Sopenharmony_ci#define CM_GCR_L2SM_COP_RESULT_ABORT_ERROR 4 2628c2ecf20Sopenharmony_ci#define CM_GCR_L2SM_COP_RUNNING BIT(5) 2638c2ecf20Sopenharmony_ci#define CM_GCR_L2SM_COP_TYPE GENMASK(4, 2) 2648c2ecf20Sopenharmony_ci#define CM_GCR_L2SM_COP_TYPE_IDX_WBINV 0 2658c2ecf20Sopenharmony_ci#define CM_GCR_L2SM_COP_TYPE_IDX_STORETAG 1 2668c2ecf20Sopenharmony_ci#define CM_GCR_L2SM_COP_TYPE_IDX_STORETAGDATA 2 2678c2ecf20Sopenharmony_ci#define CM_GCR_L2SM_COP_TYPE_HIT_INV 4 2688c2ecf20Sopenharmony_ci#define CM_GCR_L2SM_COP_TYPE_HIT_WBINV 5 2698c2ecf20Sopenharmony_ci#define CM_GCR_L2SM_COP_TYPE_HIT_WB 6 2708c2ecf20Sopenharmony_ci#define CM_GCR_L2SM_COP_TYPE_FETCHLOCK 7 2718c2ecf20Sopenharmony_ci#define CM_GCR_L2SM_COP_CMD GENMASK(1, 0) 2728c2ecf20Sopenharmony_ci#define CM_GCR_L2SM_COP_CMD_START 1 /* only when idle */ 2738c2ecf20Sopenharmony_ci#define CM_GCR_L2SM_COP_CMD_ABORT 3 /* only when running */ 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_ci/* GCR_L2SM_TAG_ADDR_COP - L2 cache op state machine address control */ 2768c2ecf20Sopenharmony_ciGCR_ACCESSOR_RW(64, 0x628, l2sm_tag_addr_cop) 2778c2ecf20Sopenharmony_ci#define CM_GCR_L2SM_TAG_ADDR_COP_NUM_LINES GENMASK_ULL(63, 48) 2788c2ecf20Sopenharmony_ci#define CM_GCR_L2SM_TAG_ADDR_COP_START_TAG GENMASK_ULL(47, 6) 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci/* GCR_BEV_BASE - Controls the location of the BEV for powered up cores */ 2818c2ecf20Sopenharmony_ciGCR_ACCESSOR_RW(64, 0x680, bev_base) 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ci/* GCR_Cx_RESET_RELEASE - Controls core reset for CM 1.x */ 2848c2ecf20Sopenharmony_ciGCR_CX_ACCESSOR_RW(32, 0x000, reset_release) 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_ci/* GCR_Cx_COHERENCE - Controls core coherence */ 2878c2ecf20Sopenharmony_ciGCR_CX_ACCESSOR_RW(32, 0x008, coherence) 2888c2ecf20Sopenharmony_ci#define CM_GCR_Cx_COHERENCE_COHDOMAINEN GENMASK(7, 0) 2898c2ecf20Sopenharmony_ci#define CM3_GCR_Cx_COHERENCE_COHEN BIT(0) 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_ci/* GCR_Cx_CONFIG - Information about a core's configuration */ 2928c2ecf20Sopenharmony_ciGCR_CX_ACCESSOR_RO(32, 0x010, config) 2938c2ecf20Sopenharmony_ci#define CM_GCR_Cx_CONFIG_IOCUTYPE GENMASK(11, 10) 2948c2ecf20Sopenharmony_ci#define CM_GCR_Cx_CONFIG_PVPE GENMASK(9, 0) 2958c2ecf20Sopenharmony_ci 2968c2ecf20Sopenharmony_ci/* GCR_Cx_OTHER - Configure the core-other/redirect GCR block */ 2978c2ecf20Sopenharmony_ciGCR_CX_ACCESSOR_RW(32, 0x018, other) 2988c2ecf20Sopenharmony_ci#define CM_GCR_Cx_OTHER_CORENUM GENMASK(31, 16) /* CM < 3 */ 2998c2ecf20Sopenharmony_ci#define CM_GCR_Cx_OTHER_CLUSTER_EN BIT(31) /* CM >= 3.5 */ 3008c2ecf20Sopenharmony_ci#define CM_GCR_Cx_OTHER_GIC_EN BIT(30) /* CM >= 3.5 */ 3018c2ecf20Sopenharmony_ci#define CM_GCR_Cx_OTHER_BLOCK GENMASK(25, 24) /* CM >= 3.5 */ 3028c2ecf20Sopenharmony_ci#define CM_GCR_Cx_OTHER_BLOCK_LOCAL 0 3038c2ecf20Sopenharmony_ci#define CM_GCR_Cx_OTHER_BLOCK_GLOBAL 1 3048c2ecf20Sopenharmony_ci#define CM_GCR_Cx_OTHER_BLOCK_USER 2 3058c2ecf20Sopenharmony_ci#define CM_GCR_Cx_OTHER_BLOCK_GLOBAL_HIGH 3 3068c2ecf20Sopenharmony_ci#define CM_GCR_Cx_OTHER_CLUSTER GENMASK(21, 16) /* CM >= 3.5 */ 3078c2ecf20Sopenharmony_ci#define CM3_GCR_Cx_OTHER_CORE GENMASK(13, 8) /* CM >= 3 */ 3088c2ecf20Sopenharmony_ci#define CM_GCR_Cx_OTHER_CORE_CM 32 3098c2ecf20Sopenharmony_ci#define CM3_GCR_Cx_OTHER_VP GENMASK(2, 0) /* CM >= 3 */ 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_ci/* GCR_Cx_RESET_BASE - Configure where powered up cores will fetch from */ 3128c2ecf20Sopenharmony_ciGCR_CX_ACCESSOR_RW(32, 0x020, reset_base) 3138c2ecf20Sopenharmony_ci#define CM_GCR_Cx_RESET_BASE_BEVEXCBASE GENMASK(31, 12) 3148c2ecf20Sopenharmony_ci 3158c2ecf20Sopenharmony_ci/* GCR_Cx_ID - Identify the current core */ 3168c2ecf20Sopenharmony_ciGCR_CX_ACCESSOR_RO(32, 0x028, id) 3178c2ecf20Sopenharmony_ci#define CM_GCR_Cx_ID_CLUSTER GENMASK(15, 8) 3188c2ecf20Sopenharmony_ci#define CM_GCR_Cx_ID_CORE GENMASK(7, 0) 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci/* GCR_Cx_RESET_EXT_BASE - Configure behaviour when cores reset or power up */ 3218c2ecf20Sopenharmony_ciGCR_CX_ACCESSOR_RW(32, 0x030, reset_ext_base) 3228c2ecf20Sopenharmony_ci#define CM_GCR_Cx_RESET_EXT_BASE_EVARESET BIT(31) 3238c2ecf20Sopenharmony_ci#define CM_GCR_Cx_RESET_EXT_BASE_UEB BIT(30) 3248c2ecf20Sopenharmony_ci#define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCMASK GENMASK(27, 20) 3258c2ecf20Sopenharmony_ci#define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCPA GENMASK(7, 1) 3268c2ecf20Sopenharmony_ci#define CM_GCR_Cx_RESET_EXT_BASE_PRESENT BIT(0) 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_ci/** 3298c2ecf20Sopenharmony_ci * mips_cm_l2sync - perform an L2-only sync operation 3308c2ecf20Sopenharmony_ci * 3318c2ecf20Sopenharmony_ci * If an L2-only sync region is present in the system then this function 3328c2ecf20Sopenharmony_ci * performs and L2-only sync and returns zero. Otherwise it returns -ENODEV. 3338c2ecf20Sopenharmony_ci */ 3348c2ecf20Sopenharmony_cistatic inline int mips_cm_l2sync(void) 3358c2ecf20Sopenharmony_ci{ 3368c2ecf20Sopenharmony_ci if (!mips_cm_has_l2sync()) 3378c2ecf20Sopenharmony_ci return -ENODEV; 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ci writel(0, mips_cm_l2sync_base); 3408c2ecf20Sopenharmony_ci return 0; 3418c2ecf20Sopenharmony_ci} 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_ci/** 3448c2ecf20Sopenharmony_ci * mips_cm_revision() - return CM revision 3458c2ecf20Sopenharmony_ci * 3468c2ecf20Sopenharmony_ci * Return: The revision of the CM, from GCR_REV, or 0 if no CM is present. The 3478c2ecf20Sopenharmony_ci * return value should be checked against the CM_REV_* macros. 3488c2ecf20Sopenharmony_ci */ 3498c2ecf20Sopenharmony_cistatic inline int mips_cm_revision(void) 3508c2ecf20Sopenharmony_ci{ 3518c2ecf20Sopenharmony_ci if (!mips_cm_present()) 3528c2ecf20Sopenharmony_ci return 0; 3538c2ecf20Sopenharmony_ci 3548c2ecf20Sopenharmony_ci return read_gcr_rev(); 3558c2ecf20Sopenharmony_ci} 3568c2ecf20Sopenharmony_ci 3578c2ecf20Sopenharmony_ci/** 3588c2ecf20Sopenharmony_ci * mips_cm_max_vp_width() - return the width in bits of VP indices 3598c2ecf20Sopenharmony_ci * 3608c2ecf20Sopenharmony_ci * Return: the width, in bits, of VP indices in fields that combine core & VP 3618c2ecf20Sopenharmony_ci * indices. 3628c2ecf20Sopenharmony_ci */ 3638c2ecf20Sopenharmony_cistatic inline unsigned int mips_cm_max_vp_width(void) 3648c2ecf20Sopenharmony_ci{ 3658c2ecf20Sopenharmony_ci extern int smp_num_siblings; 3668c2ecf20Sopenharmony_ci 3678c2ecf20Sopenharmony_ci if (mips_cm_revision() >= CM_REV_CM3) 3688c2ecf20Sopenharmony_ci return FIELD_GET(CM_GCR_SYS_CONFIG2_MAXVPW, 3698c2ecf20Sopenharmony_ci read_gcr_sys_config2()); 3708c2ecf20Sopenharmony_ci 3718c2ecf20Sopenharmony_ci if (mips_cm_present()) { 3728c2ecf20Sopenharmony_ci /* 3738c2ecf20Sopenharmony_ci * We presume that all cores in the system will have the same 3748c2ecf20Sopenharmony_ci * number of VP(E)s, and if that ever changes then this will 3758c2ecf20Sopenharmony_ci * need revisiting. 3768c2ecf20Sopenharmony_ci */ 3778c2ecf20Sopenharmony_ci return FIELD_GET(CM_GCR_Cx_CONFIG_PVPE, read_gcr_cl_config()) + 1; 3788c2ecf20Sopenharmony_ci } 3798c2ecf20Sopenharmony_ci 3808c2ecf20Sopenharmony_ci if (IS_ENABLED(CONFIG_SMP)) 3818c2ecf20Sopenharmony_ci return smp_num_siblings; 3828c2ecf20Sopenharmony_ci 3838c2ecf20Sopenharmony_ci return 1; 3848c2ecf20Sopenharmony_ci} 3858c2ecf20Sopenharmony_ci 3868c2ecf20Sopenharmony_ci/** 3878c2ecf20Sopenharmony_ci * mips_cm_vp_id() - calculate the hardware VP ID for a CPU 3888c2ecf20Sopenharmony_ci * @cpu: the CPU whose VP ID to calculate 3898c2ecf20Sopenharmony_ci * 3908c2ecf20Sopenharmony_ci * Hardware such as the GIC uses identifiers for VPs which may not match the 3918c2ecf20Sopenharmony_ci * CPU numbers used by Linux. This function calculates the hardware VP 3928c2ecf20Sopenharmony_ci * identifier corresponding to a given CPU. 3938c2ecf20Sopenharmony_ci * 3948c2ecf20Sopenharmony_ci * Return: the VP ID for the CPU. 3958c2ecf20Sopenharmony_ci */ 3968c2ecf20Sopenharmony_cistatic inline unsigned int mips_cm_vp_id(unsigned int cpu) 3978c2ecf20Sopenharmony_ci{ 3988c2ecf20Sopenharmony_ci unsigned int core = cpu_core(&cpu_data[cpu]); 3998c2ecf20Sopenharmony_ci unsigned int vp = cpu_vpe_id(&cpu_data[cpu]); 4008c2ecf20Sopenharmony_ci 4018c2ecf20Sopenharmony_ci return (core * mips_cm_max_vp_width()) + vp; 4028c2ecf20Sopenharmony_ci} 4038c2ecf20Sopenharmony_ci 4048c2ecf20Sopenharmony_ci#ifdef CONFIG_MIPS_CM 4058c2ecf20Sopenharmony_ci 4068c2ecf20Sopenharmony_ci/** 4078c2ecf20Sopenharmony_ci * mips_cm_lock_other - lock access to redirect/other region 4088c2ecf20Sopenharmony_ci * @cluster: the other cluster to be accessed 4098c2ecf20Sopenharmony_ci * @core: the other core to be accessed 4108c2ecf20Sopenharmony_ci * @vp: the VP within the other core to be accessed 4118c2ecf20Sopenharmony_ci * @block: the register block to be accessed 4128c2ecf20Sopenharmony_ci * 4138c2ecf20Sopenharmony_ci * Configure the redirect/other region for the local core/VP (depending upon 4148c2ecf20Sopenharmony_ci * the CM revision) to target the specified @cluster, @core, @vp & register 4158c2ecf20Sopenharmony_ci * @block. Must be called before using the redirect/other region, and followed 4168c2ecf20Sopenharmony_ci * by a call to mips_cm_unlock_other() when access to the redirect/other region 4178c2ecf20Sopenharmony_ci * is complete. 4188c2ecf20Sopenharmony_ci * 4198c2ecf20Sopenharmony_ci * This function acquires a spinlock such that code between it & 4208c2ecf20Sopenharmony_ci * mips_cm_unlock_other() calls cannot be pre-empted by anything which may 4218c2ecf20Sopenharmony_ci * reconfigure the redirect/other region, and cannot be interfered with by 4228c2ecf20Sopenharmony_ci * another VP in the core. As such calls to this function should not be nested. 4238c2ecf20Sopenharmony_ci */ 4248c2ecf20Sopenharmony_ciextern void mips_cm_lock_other(unsigned int cluster, unsigned int core, 4258c2ecf20Sopenharmony_ci unsigned int vp, unsigned int block); 4268c2ecf20Sopenharmony_ci 4278c2ecf20Sopenharmony_ci/** 4288c2ecf20Sopenharmony_ci * mips_cm_unlock_other - unlock access to redirect/other region 4298c2ecf20Sopenharmony_ci * 4308c2ecf20Sopenharmony_ci * Must be called after mips_cm_lock_other() once all required access to the 4318c2ecf20Sopenharmony_ci * redirect/other region has been completed. 4328c2ecf20Sopenharmony_ci */ 4338c2ecf20Sopenharmony_ciextern void mips_cm_unlock_other(void); 4348c2ecf20Sopenharmony_ci 4358c2ecf20Sopenharmony_ci#else /* !CONFIG_MIPS_CM */ 4368c2ecf20Sopenharmony_ci 4378c2ecf20Sopenharmony_cistatic inline void mips_cm_lock_other(unsigned int cluster, unsigned int core, 4388c2ecf20Sopenharmony_ci unsigned int vp, unsigned int block) { } 4398c2ecf20Sopenharmony_cistatic inline void mips_cm_unlock_other(void) { } 4408c2ecf20Sopenharmony_ci 4418c2ecf20Sopenharmony_ci#endif /* !CONFIG_MIPS_CM */ 4428c2ecf20Sopenharmony_ci 4438c2ecf20Sopenharmony_ci/** 4448c2ecf20Sopenharmony_ci * mips_cm_lock_other_cpu - lock access to redirect/other region 4458c2ecf20Sopenharmony_ci * @cpu: the other CPU whose register we want to access 4468c2ecf20Sopenharmony_ci * 4478c2ecf20Sopenharmony_ci * Configure the redirect/other region for the local core/VP (depending upon 4488c2ecf20Sopenharmony_ci * the CM revision) to target the specified @cpu & register @block. This is 4498c2ecf20Sopenharmony_ci * equivalent to calling mips_cm_lock_other() but accepts a Linux CPU number 4508c2ecf20Sopenharmony_ci * for convenience. 4518c2ecf20Sopenharmony_ci */ 4528c2ecf20Sopenharmony_cistatic inline void mips_cm_lock_other_cpu(unsigned int cpu, unsigned int block) 4538c2ecf20Sopenharmony_ci{ 4548c2ecf20Sopenharmony_ci struct cpuinfo_mips *d = &cpu_data[cpu]; 4558c2ecf20Sopenharmony_ci 4568c2ecf20Sopenharmony_ci mips_cm_lock_other(cpu_cluster(d), cpu_core(d), cpu_vpe_id(d), block); 4578c2ecf20Sopenharmony_ci} 4588c2ecf20Sopenharmony_ci 4598c2ecf20Sopenharmony_ci#endif /* __MIPS_ASM_MIPS_CM_H__ */ 460