1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * AMD Address Translation Library
4 *
5 * internal.h : Helper functions and common defines
6 *
7 * Copyright (c) 2023, Advanced Micro Devices, Inc.
8 * All Rights Reserved.
9 *
10 * Author: Yazen Ghannam <Yazen.Ghannam@amd.com>
11 */
12
13#ifndef __AMD_ATL_INTERNAL_H__
14#define __AMD_ATL_INTERNAL_H__
15
16#include <linux/bitfield.h>
17#include <linux/bitops.h>
18#include <linux/ras.h>
19
20#include <asm/amd_nb.h>
21
22#include "reg_fields.h"
23
24/* Maximum possible number of Coherent Stations within a single Data Fabric. */
25#define MAX_COH_ST_CHANNELS		32
26
27/* PCI ID for Zen4 Server DF Function 0. */
28#define DF_FUNC0_ID_ZEN4_SERVER		0x14AD1022
29
30/* PCI IDs for MI300 DF Function 0. */
31#define DF_FUNC0_ID_MI300		0x15281022
32
33/* Shift needed for adjusting register values to true values. */
34#define DF_DRAM_BASE_LIMIT_LSB		28
35#define MI300_DRAM_LIMIT_LSB		20
36
37enum df_revisions {
38	UNKNOWN,
39	DF2,
40	DF3,
41	DF3p5,
42	DF4,
43	DF4p5,
44};
45
46/* These are mapped 1:1 to the hardware values. Special cases are set at > 0x20. */
47enum intlv_modes {
48	NONE				= 0x00,
49	NOHASH_2CHAN			= 0x01,
50	NOHASH_4CHAN			= 0x03,
51	NOHASH_8CHAN			= 0x05,
52	DF3_6CHAN			= 0x06,
53	NOHASH_16CHAN			= 0x07,
54	NOHASH_32CHAN			= 0x08,
55	DF3_COD4_2CHAN_HASH		= 0x0C,
56	DF3_COD2_4CHAN_HASH		= 0x0D,
57	DF3_COD1_8CHAN_HASH		= 0x0E,
58	DF4_NPS4_2CHAN_HASH		= 0x10,
59	DF4_NPS2_4CHAN_HASH		= 0x11,
60	DF4_NPS1_8CHAN_HASH		= 0x12,
61	DF4_NPS4_3CHAN_HASH		= 0x13,
62	DF4_NPS2_6CHAN_HASH		= 0x14,
63	DF4_NPS1_12CHAN_HASH		= 0x15,
64	DF4_NPS2_5CHAN_HASH		= 0x16,
65	DF4_NPS1_10CHAN_HASH		= 0x17,
66	MI3_HASH_8CHAN			= 0x18,
67	MI3_HASH_16CHAN			= 0x19,
68	MI3_HASH_32CHAN			= 0x1A,
69	DF2_2CHAN_HASH			= 0x21,
70	/* DF4.5 modes are all IntLvNumChan + 0x20 */
71	DF4p5_NPS1_16CHAN_1K_HASH	= 0x2C,
72	DF4p5_NPS0_24CHAN_1K_HASH	= 0x2E,
73	DF4p5_NPS4_2CHAN_1K_HASH	= 0x30,
74	DF4p5_NPS2_4CHAN_1K_HASH	= 0x31,
75	DF4p5_NPS1_8CHAN_1K_HASH	= 0x32,
76	DF4p5_NPS4_3CHAN_1K_HASH	= 0x33,
77	DF4p5_NPS2_6CHAN_1K_HASH	= 0x34,
78	DF4p5_NPS1_12CHAN_1K_HASH	= 0x35,
79	DF4p5_NPS2_5CHAN_1K_HASH	= 0x36,
80	DF4p5_NPS1_10CHAN_1K_HASH	= 0x37,
81	DF4p5_NPS4_2CHAN_2K_HASH	= 0x40,
82	DF4p5_NPS2_4CHAN_2K_HASH	= 0x41,
83	DF4p5_NPS1_8CHAN_2K_HASH	= 0x42,
84	DF4p5_NPS1_16CHAN_2K_HASH	= 0x43,
85	DF4p5_NPS4_3CHAN_2K_HASH	= 0x44,
86	DF4p5_NPS2_6CHAN_2K_HASH	= 0x45,
87	DF4p5_NPS1_12CHAN_2K_HASH	= 0x46,
88	DF4p5_NPS0_24CHAN_2K_HASH	= 0x47,
89	DF4p5_NPS2_5CHAN_2K_HASH	= 0x48,
90	DF4p5_NPS1_10CHAN_2K_HASH	= 0x49,
91};
92
93struct df_flags {
94	__u8	legacy_ficaa		: 1,
95		socket_id_shift_quirk	: 1,
96		heterogeneous		: 1,
97		__reserved_0		: 5;
98};
99
100struct df_config {
101	enum df_revisions rev;
102
103	/*
104	 * These masks operate on the 16-bit Coherent Station IDs,
105	 * e.g. Instance, Fabric, Destination, etc.
106	 */
107	u16 component_id_mask;
108	u16 die_id_mask;
109	u16 node_id_mask;
110	u16 socket_id_mask;
111
112	/*
113	 * Least-significant bit of Node ID portion of the
114	 * system-wide Coherent Station Fabric ID.
115	 */
116	u8 node_id_shift;
117
118	/*
119	 * Least-significant bit of Die portion of the Node ID.
120	 * Adjusted to include the Node ID shift in order to apply
121	 * to the Coherent Station Fabric ID.
122	 */
123	u8 die_id_shift;
124
125	/*
126	 * Least-significant bit of Socket portion of the Node ID.
127	 * Adjusted to include the Node ID shift in order to apply
128	 * to the Coherent Station Fabric ID.
129	 */
130	u8 socket_id_shift;
131
132	/* Number of DRAM Address maps visible in a Coherent Station. */
133	u8 num_coh_st_maps;
134
135	/* Global flags to handle special cases. */
136	struct df_flags flags;
137};
138
139extern struct df_config df_cfg;
140
141struct dram_addr_map {
142	/*
143	 * Each DRAM Address Map can operate independently
144	 * in different interleaving modes.
145	 */
146	enum intlv_modes intlv_mode;
147
148	/* System-wide number for this address map. */
149	u8 num;
150
151	/* Raw register values */
152	u32 base;
153	u32 limit;
154	u32 ctl;
155	u32 intlv;
156
157	/*
158	 * Logical to Physical Coherent Station Remapping array
159	 *
160	 * Index: Logical Coherent Station Instance ID
161	 * Value: Physical Coherent Station Instance ID
162	 *
163	 * phys_coh_st_inst_id = remap_array[log_coh_st_inst_id]
164	 */
165	u8 remap_array[MAX_COH_ST_CHANNELS];
166
167	/*
168	 * Number of bits covering DRAM Address map 0
169	 * when interleaving is non-power-of-2.
170	 *
171	 * Used only for DF3_6CHAN.
172	 */
173	u8 np2_bits;
174
175	/* Position of the 'interleave bit'. */
176	u8 intlv_bit_pos;
177	/* Number of channels interleaved in this map. */
178	u8 num_intlv_chan;
179	/* Number of dies interleaved in this map. */
180	u8 num_intlv_dies;
181	/* Number of sockets interleaved in this map. */
182	u8 num_intlv_sockets;
183	/*
184	 * Total number of channels interleaved accounting
185	 * for die and socket interleaving.
186	 */
187	u8 total_intlv_chan;
188	/* Total bits needed to cover 'total_intlv_chan'. */
189	u8 total_intlv_bits;
190};
191
192/* Original input values cached for debug printing. */
193struct addr_ctx_inputs {
194	u64 norm_addr;
195	u8 socket_id;
196	u8 die_id;
197	u8 coh_st_inst_id;
198};
199
200struct addr_ctx {
201	u64 ret_addr;
202
203	struct addr_ctx_inputs inputs;
204	struct dram_addr_map map;
205
206	/* AMD Node ID calculated from Socket and Die IDs. */
207	u8 node_id;
208
209	/*
210	 * Coherent Station Instance ID
211	 * Local ID used within a 'node'.
212	 */
213	u16 inst_id;
214
215	/*
216	 * Coherent Station Fabric ID
217	 * System-wide ID that includes 'node' bits.
218	 */
219	u16 coh_st_fabric_id;
220};
221
222int df_indirect_read_instance(u16 node, u8 func, u16 reg, u8 instance_id, u32 *lo);
223int df_indirect_read_broadcast(u16 node, u8 func, u16 reg, u32 *lo);
224
225int get_df_system_info(void);
226int determine_node_id(struct addr_ctx *ctx, u8 socket_num, u8 die_num);
227int get_addr_hash_mi300(void);
228
229int get_address_map(struct addr_ctx *ctx);
230
231int denormalize_address(struct addr_ctx *ctx);
232int dehash_address(struct addr_ctx *ctx);
233
234unsigned long norm_to_sys_addr(u8 socket_id, u8 die_id, u8 coh_st_inst_id, unsigned long addr);
235unsigned long convert_umc_mca_addr_to_sys_addr(struct atl_err *err);
236
237/*
238 * Make a gap in @data that is @num_bits long starting at @bit_num.
239 * e.g. data		= 11111111'b
240 *	bit_num		= 3
241 *	num_bits	= 2
242 *	result		= 1111100111'b
243 */
244static inline u64 expand_bits(u8 bit_num, u8 num_bits, u64 data)
245{
246	u64 temp1, temp2;
247
248	if (!num_bits)
249		return data;
250
251	if (!bit_num) {
252		WARN_ON_ONCE(num_bits >= BITS_PER_LONG);
253		return data << num_bits;
254	}
255
256	WARN_ON_ONCE(bit_num >= BITS_PER_LONG);
257
258	temp1 = data & GENMASK_ULL(bit_num - 1, 0);
259
260	temp2 = data & GENMASK_ULL(63, bit_num);
261	temp2 <<= num_bits;
262
263	return temp1 | temp2;
264}
265
266/*
267 * Remove bits in @data between @low_bit and @high_bit inclusive.
268 * e.g. data		= XXXYYZZZ'b
269 *	low_bit		= 3
270 *	high_bit	= 4
271 *	result		= XXXZZZ'b
272 */
273static inline u64 remove_bits(u8 low_bit, u8 high_bit, u64 data)
274{
275	u64 temp1, temp2;
276
277	WARN_ON_ONCE(high_bit >= BITS_PER_LONG);
278	WARN_ON_ONCE(low_bit  >= BITS_PER_LONG);
279	WARN_ON_ONCE(low_bit  >  high_bit);
280
281	if (!low_bit)
282		return data >> (high_bit++);
283
284	temp1 = GENMASK_ULL(low_bit - 1, 0) & data;
285	temp2 = GENMASK_ULL(63, high_bit + 1) & data;
286	temp2 >>= high_bit - low_bit + 1;
287
288	return temp1 | temp2;
289}
290
291#define atl_debug(ctx, fmt, arg...) \
292	pr_debug("socket_id=%u die_id=%u coh_st_inst_id=%u norm_addr=0x%016llx: " fmt,\
293		 (ctx)->inputs.socket_id, (ctx)->inputs.die_id,\
294		 (ctx)->inputs.coh_st_inst_id, (ctx)->inputs.norm_addr, ##arg)
295
296static inline void atl_debug_on_bad_df_rev(void)
297{
298	pr_debug("Unrecognized DF rev: %u", df_cfg.rev);
299}
300
301static inline void atl_debug_on_bad_intlv_mode(struct addr_ctx *ctx)
302{
303	atl_debug(ctx, "Unrecognized interleave mode: %u", ctx->map.intlv_mode);
304}
305
306#endif /* __AMD_ATL_INTERNAL_H__ */
307