1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 #ifndef CPU_PPC64_SCOM_H
4 #define CPU_PPC64_SCOM_H
6 #include <arch/byteorder.h> // PPC_BIT(), PPC_BITMASK()
12 // | | | | | 1 1| |1 1 1 1| |1 1 1 1| |2 2 2 2| |2 2 2 2| |2 2 3 3|
13 // |0 1 2 3| |4 5 6 7| |8 9 0 1| |2 3 4 5| |6 7 8 9| |0 1 2 3| |4 5 6 7| |8 9 0 1|
14 // {A}{ B } { C } { D }{ E }{ F }
16 // A - Is multiCast if bit 1 = 0x1
17 // B - Contains Chiplet ID (6 bits) [2:7]
18 // C - Contains Port Number (4 bits) [12:15]
19 // D - Ring (4 bits) [18:21]
20 // E - Sat ID (4 bits) [22:25]
21 // F - Sat Offset (6 bits) [26:31]
23 // For 64b SCOM address all of the fields are shifted 32b to the right:
24 // A - Is multiCast if bit 33 = 0x1
25 // B - Contains Chiplet ID (6 bits) [34:39]
26 // C - Contains Port Number (4 bits) [44:47]
27 // D - Ring (4 bits) [50:53]
28 // E - Sat ID (4 bits) [54:57]
29 // F - Sat Offset (6 bits) [58:63]
30 // Higher bits specify indirect address
32 #define XSCOM_ADDR_IND_FLAG PPC_BIT(0)
38 // TODO: these are probably specific to POWER9
40 PIB_CHIPLET_ID
= 0x00, ///< PIB chiplet
41 PERV_CHIPLET_ID
= 0x01, ///< TP chiplet
42 N0_CHIPLET_ID
= 0x02, ///< Nest0 (North) chiplet
43 N1_CHIPLET_ID
= 0x03, ///< Nest1 (East) chiplet
44 N2_CHIPLET_ID
= 0x04, ///< Nest2 (South) chiplet
45 N3_CHIPLET_ID
= 0x05, ///< Nest3 (West) chiplet
46 XB_CHIPLET_ID
= 0x06, ///< XBus chiplet
47 MC01_CHIPLET_ID
= 0x07, ///< MC01 (West) chiplet
48 MC23_CHIPLET_ID
= 0x08, ///< MC23 (East) chiplet
49 OB0_CHIPLET_ID
= 0x09, ///< OBus0 chiplet
50 OB1_CHIPLET_ID
= 0x0A, ///< OBus1 chiplet (Cumulus only)
51 OB2_CHIPLET_ID
= 0x0B, ///< OBus2 chiplet (Cumulus only)
52 OB3_CHIPLET_ID
= 0x0C, ///< OBus3 chiplet
53 PCI0_CHIPLET_ID
= 0x0D, ///< PCIe0 chiplet
54 PCI1_CHIPLET_ID
= 0x0E, ///< PCIe1 chiplet
55 PCI2_CHIPLET_ID
= 0x0F, ///< PCIe2 chiplet
56 EP00_CHIPLET_ID
= 0x10, ///< Quad0 chiplet (EX0/1)
57 EP01_CHIPLET_ID
= 0x11, ///< Quad1 chiplet (EX2/3)
58 EP02_CHIPLET_ID
= 0x12, ///< Quad2 chiplet (EX4/5)
59 EP03_CHIPLET_ID
= 0x13, ///< Quad3 chiplet (EX6/7)
60 EP04_CHIPLET_ID
= 0x14, ///< Quad4 chiplet (EX8/9)
61 EP05_CHIPLET_ID
= 0x15, ///< Quad5 chiplet (EX10/11)
62 EC00_CHIPLET_ID
= 0x20, ///< Core0 chiplet (Quad0, EX0, C0)
63 EC01_CHIPLET_ID
= 0x21, ///< Core1 chiplet (Quad0, EX0, C1)
64 EC02_CHIPLET_ID
= 0x22, ///< Core2 chiplet (Quad0, EX1, C0)
65 EC03_CHIPLET_ID
= 0x23, ///< Core3 chiplet (Quad0, EX1, C1)
66 EC04_CHIPLET_ID
= 0x24, ///< Core4 chiplet (Quad1, EX2, C0)
67 EC05_CHIPLET_ID
= 0x25, ///< Core5 chiplet (Quad1, EX2, C1)
68 EC06_CHIPLET_ID
= 0x26, ///< Core6 chiplet (Quad1, EX3, C0)
69 EC07_CHIPLET_ID
= 0x27, ///< Core7 chiplet (Quad1, EX3, C1)
70 EC08_CHIPLET_ID
= 0x28, ///< Core8 chiplet (Quad2, EX4, C0)
71 EC09_CHIPLET_ID
= 0x29, ///< Core9 chiplet (Quad2, EX4, C1)
72 EC10_CHIPLET_ID
= 0x2A, ///< Core10 chiplet (Quad2, EX5, C0)
73 EC11_CHIPLET_ID
= 0x2B, ///< Core11 chiplet (Quad2, EX5, C1)
74 EC12_CHIPLET_ID
= 0x2C, ///< Core12 chiplet (Quad3, EX6, C0)
75 EC13_CHIPLET_ID
= 0x2D, ///< Core13 chiplet (Quad3, EX6, C1)
76 EC14_CHIPLET_ID
= 0x2E, ///< Core14 chiplet (Quad3, EX7, C0)
77 EC15_CHIPLET_ID
= 0x2F, ///< Core15 chiplet (Quad3, EX7, C1)
78 EC16_CHIPLET_ID
= 0x30, ///< Core16 chiplet (Quad4, EX8, C0)
79 EC17_CHIPLET_ID
= 0x31, ///< Core17 chiplet (Quad4, EX8, C1)
80 EC18_CHIPLET_ID
= 0x32, ///< Core18 chiplet (Quad4, EX9, C0)
81 EC19_CHIPLET_ID
= 0x33, ///< Core19 chiplet (Quad4, EX9, C1)
82 EC20_CHIPLET_ID
= 0x34, ///< Core20 chiplet (Quad5, EX10, C0)
83 EC21_CHIPLET_ID
= 0x35, ///< Core21 chiplet (Quad5, EX10, C1)
84 EC22_CHIPLET_ID
= 0x36, ///< Core22 chiplet (Quad5, EX11, C0)
85 EC23_CHIPLET_ID
= 0x37 ///< Core23 chiplet (Quad5, EX11, C1)
88 uint64_t read_scom_direct(uint64_t reg_address
);
89 void write_scom_direct(uint64_t reg_address
, uint64_t data
);
91 uint64_t read_scom_indirect(uint64_t reg_address
);
92 void write_scom_indirect(uint64_t reg_address
, uint64_t data
);
94 static inline void write_scom(uint64_t addr
, uint64_t data
)
96 if (addr
& XSCOM_ADDR_IND_FLAG
)
97 write_scom_indirect(addr
, data
);
99 write_scom_direct(addr
, data
);
102 static inline uint64_t read_scom(uint64_t addr
)
104 if (addr
& XSCOM_ADDR_IND_FLAG
)
105 return read_scom_indirect(addr
);
107 return read_scom_direct(addr
);
110 static inline void scom_and_or(uint64_t addr
, uint64_t and, uint64_t or)
112 uint64_t data
= read_scom(addr
);
113 write_scom(addr
, (data
& and) | or);
116 static inline void scom_and(uint64_t addr
, uint64_t and)
118 scom_and_or(addr
, and, 0);
121 static inline void scom_or(uint64_t addr
, uint64_t or)
123 scom_and_or(addr
, ~0, or);
126 static inline void write_scom_for_chiplet(chiplet_id_t chiplet
, uint64_t addr
, uint64_t data
)
128 addr
&= ~PPC_BITMASK(34, 39);
129 addr
|= ((chiplet
& 0x3F) << 24);
130 write_scom(addr
, data
);
133 static inline uint64_t read_scom_for_chiplet(chiplet_id_t chiplet
, uint64_t addr
)
135 addr
&= ~PPC_BITMASK(34, 39);
136 addr
|= ((chiplet
& 0x3F) << 24);
137 return read_scom(addr
);
140 static inline void scom_and_or_for_chiplet(chiplet_id_t chiplet
, uint64_t addr
,
141 uint64_t and, uint64_t or)
143 uint64_t data
= read_scom_for_chiplet(chiplet
, addr
);
144 write_scom_for_chiplet(chiplet
, addr
, (data
& and) | or);
147 static inline void scom_and_for_chiplet(chiplet_id_t chiplet
, uint64_t addr
, uint64_t and)
149 scom_and_or_for_chiplet(chiplet
, addr
, and, 0);
152 static inline void scom_or_for_chiplet(chiplet_id_t chiplet
, uint64_t addr
, uint64_t or)
154 scom_and_or_for_chiplet(chiplet
, addr
, ~0, or);
157 #endif /* __ASSEMBLER__ */
158 #endif /* CPU_PPC64_SCOM_H */