File Index
Files and directories
Sign in
FILE

nbio_v7_9.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/amd/amdgpu/nbio_v7_9.c C
  1/*
  2 * Copyright 2022 Advanced Micro Devices, Inc.
  3 *
  4 * Permission is hereby granted, free of charge, to any person obtaining a
  5 * copy of this software and associated documentation files (the "Software"),
  6 * to deal in the Software without restriction, including without limitation
  7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8 * and/or sell copies of the Software, and to permit persons to whom the
  9 * Software is furnished to do so, subject to the following conditions:
 10 *
 11 * The above copyright notice and this permission notice shall be included in
 12 * all copies or substantial portions of the Software.
 13 *
 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 20 * OTHER DEALINGS IN THE SOFTWARE.
 21 *
 22 */
 23#include "amdgpu.h"
 24#include "nbio_v7_9.h"
 25#include "amdgpu_ras.h"
 26
 27#include "nbio/nbio_7_9_0_offset.h"
 28#include "nbio/nbio_7_9_0_sh_mask.h"
 29#include "ivsrcid/nbio/irqsrcs_nbif_7_4.h"
 30#include <uapi/linux/kfd_ioctl.h>
 31
 32#define NPS_MODE_MASK 0x000000FFL
 33
 34static void nbio_v7_9_remap_hdp_registers(struct amdgpu_device *adev)
 35{
 36	WREG32_SOC15(NBIO, 0, regBIF_BX0_REMAP_HDP_MEM_FLUSH_CNTL,
 37		adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL);
 38	WREG32_SOC15(NBIO, 0, regBIF_BX0_REMAP_HDP_REG_FLUSH_CNTL,
 39		adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_REG_FLUSH_CNTL);
 40}
 41
 42static u32 nbio_v7_9_get_rev_id(struct amdgpu_device *adev)
 43{
 44	u32 rev_id;
 45
 46	/*
 47	 * fetch the sub-revision field from the IP-discovery table
 48	 * (returns zero if the table entry is not populated).
 49	 */
 50	if (amdgpu_sriov_vf(adev)) {
 51		rev_id = IP_VERSION_SUBREV(amdgpu_ip_version_full(adev, NBIO_HWIP, 0));
 52	} else {
 53		rev_id = RREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0);
 54		rev_id = REG_GET_FIELD(rev_id, RCC_STRAP0_RCC_DEV0_EPF0_STRAP0,
 55				STRAP_ATI_REV_ID_DEV0_F0);
 56	}
 57
 58	return rev_id;
 59}
 60
 61static void nbio_v7_9_mc_access_enable(struct amdgpu_device *adev, bool enable)
 62{
 63	if (enable)
 64		WREG32_SOC15(NBIO, 0, regBIF_BX0_BIF_FB_EN,
 65			BIF_BX0_BIF_FB_EN__FB_READ_EN_MASK | BIF_BX0_BIF_FB_EN__FB_WRITE_EN_MASK);
 66	else
 67		WREG32_SOC15(NBIO, 0, regBIF_BX0_BIF_FB_EN, 0);
 68}
 69
 70static u32 nbio_v7_9_get_memsize(struct amdgpu_device *adev)
 71{
 72	return RREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF0_RCC_CONFIG_MEMSIZE);
 73}
 74
 75static void nbio_v7_9_sdma_doorbell_range(struct amdgpu_device *adev, int instance,
 76			bool use_doorbell, int doorbell_index, int doorbell_size)
 77{
 78	u32 doorbell_range = 0, doorbell_ctrl = 0;
 79	int aid_id, dev_inst;
 80
 81	dev_inst = GET_INST(SDMA0, instance);
 82	aid_id = adev->sdma.instance[instance].aid_id;
 83
 84	if (use_doorbell == false)
 85		return;
 86
 87	doorbell_range =
 88		REG_SET_FIELD(doorbell_range, DOORBELL0_CTRL_ENTRY_0,
 89			BIF_DOORBELL0_RANGE_OFFSET_ENTRY, doorbell_index);
 90	doorbell_range =
 91		REG_SET_FIELD(doorbell_range, DOORBELL0_CTRL_ENTRY_0,
 92			BIF_DOORBELL0_RANGE_SIZE_ENTRY, doorbell_size);
 93	doorbell_ctrl =
 94		REG_SET_FIELD(doorbell_ctrl, S2A_DOORBELL_ENTRY_1_CTRL,
 95			S2A_DOORBELL_PORT1_ENABLE, 1);
 96	doorbell_ctrl =
 97		REG_SET_FIELD(doorbell_ctrl, S2A_DOORBELL_ENTRY_1_CTRL,
 98			S2A_DOORBELL_PORT1_RANGE_SIZE, doorbell_size);
 99
100	switch (dev_inst % adev->sdma.num_inst_per_aid) {
101	case 0:
102		WREG32_SOC15_OFFSET(NBIO, 0, regDOORBELL0_CTRL_ENTRY_1,
103			4 * aid_id, doorbell_range);
104
105		doorbell_ctrl = REG_SET_FIELD(doorbell_ctrl,
106					S2A_DOORBELL_ENTRY_1_CTRL,
107					S2A_DOORBELL_PORT1_AWID, 0xe);
108		doorbell_ctrl = REG_SET_FIELD(doorbell_ctrl,
109					S2A_DOORBELL_ENTRY_1_CTRL,
110					S2A_DOORBELL_PORT1_RANGE_OFFSET, 0xe);
111		doorbell_ctrl = REG_SET_FIELD(doorbell_ctrl,
112					S2A_DOORBELL_ENTRY_1_CTRL,
113					S2A_DOORBELL_PORT1_AWADDR_31_28_VALUE,
114					0x1);
115		WREG32_SOC15_EXT(NBIO, aid_id, regS2A_DOORBELL_ENTRY_1_CTRL,
116			aid_id, doorbell_ctrl);
117		break;
118	case 1:
119		WREG32_SOC15_OFFSET(NBIO, 0, regDOORBELL0_CTRL_ENTRY_2,
120			4 * aid_id, doorbell_range);
121
122		doorbell_ctrl = REG_SET_FIELD(doorbell_ctrl,
123					S2A_DOORBELL_ENTRY_1_CTRL,
124					S2A_DOORBELL_PORT1_AWID, 0x8);
125		doorbell_ctrl = REG_SET_FIELD(doorbell_ctrl,
126					S2A_DOORBELL_ENTRY_1_CTRL,
127					S2A_DOORBELL_PORT1_RANGE_OFFSET, 0x8);
128		doorbell_ctrl = REG_SET_FIELD(doorbell_ctrl,
129					S2A_DOORBELL_ENTRY_1_CTRL,
130					S2A_DOORBELL_PORT1_AWADDR_31_28_VALUE,
131					0x2);
132		WREG32_SOC15_EXT(NBIO, aid_id, regS2A_DOORBELL_ENTRY_2_CTRL,
133			aid_id, doorbell_ctrl);
134		break;
135	case 2:
136		WREG32_SOC15_OFFSET(NBIO, 0, regDOORBELL0_CTRL_ENTRY_3,
137			4 * aid_id, doorbell_range);
138
139		doorbell_ctrl = REG_SET_FIELD(doorbell_ctrl,
140					S2A_DOORBELL_ENTRY_1_CTRL,
141					S2A_DOORBELL_PORT1_AWID, 0x9);
142		doorbell_ctrl = REG_SET_FIELD(doorbell_ctrl,
143					S2A_DOORBELL_ENTRY_1_CTRL,
144					S2A_DOORBELL_PORT1_RANGE_OFFSET, 0x9);
145		doorbell_ctrl = REG_SET_FIELD(doorbell_ctrl,
146					S2A_DOORBELL_ENTRY_1_CTRL,
147					S2A_DOORBELL_PORT1_AWADDR_31_28_VALUE,
148					0x8);
149		WREG32_SOC15_EXT(NBIO, aid_id, regS2A_DOORBELL_ENTRY_5_CTRL,
150			aid_id, doorbell_ctrl);
151		break;
152	case 3:
153		WREG32_SOC15_OFFSET(NBIO, 0, regDOORBELL0_CTRL_ENTRY_4,
154			4 * aid_id, doorbell_range);
155
156		doorbell_ctrl = REG_SET_FIELD(doorbell_ctrl,
157					S2A_DOORBELL_ENTRY_1_CTRL,
158					S2A_DOORBELL_PORT1_AWID, 0xa);
159		doorbell_ctrl = REG_SET_FIELD(doorbell_ctrl,
160					S2A_DOORBELL_ENTRY_1_CTRL,
161					S2A_DOORBELL_PORT1_RANGE_OFFSET, 0xa);
162		doorbell_ctrl = REG_SET_FIELD(doorbell_ctrl,
163					S2A_DOORBELL_ENTRY_1_CTRL,
164					S2A_DOORBELL_PORT1_AWADDR_31_28_VALUE,
165					0x9);
166		WREG32_SOC15_EXT(NBIO, aid_id, regS2A_DOORBELL_ENTRY_6_CTRL,
167			aid_id, doorbell_ctrl);
168		break;
169	default:
170		break;
171	}
172}
173
174static void nbio_v7_9_vcn_doorbell_range(struct amdgpu_device *adev, bool use_doorbell,
175					 int doorbell_index, int instance)
176{
177	u32 doorbell_range = 0, doorbell_ctrl = 0;
178	u32 aid_id = instance;
179	u32 range_size;
180
181	if (use_doorbell) {
182		range_size = (amdgpu_ip_version(adev, GC_HWIP, 0) ==
183						IP_VERSION(9, 5, 0)) ?
184						0xb : 0x9;
185		doorbell_range = REG_SET_FIELD(doorbell_range,
186				DOORBELL0_CTRL_ENTRY_0,
187				BIF_DOORBELL0_RANGE_OFFSET_ENTRY,
188				doorbell_index);
189		doorbell_range = REG_SET_FIELD(doorbell_range,
190				DOORBELL0_CTRL_ENTRY_0,
191				BIF_DOORBELL0_RANGE_SIZE_ENTRY,
192				range_size);
193		if (aid_id)
194			doorbell_range = REG_SET_FIELD(doorbell_range,
195					DOORBELL0_CTRL_ENTRY_0,
196					DOORBELL0_FENCE_ENABLE_ENTRY,
197					0x4);
198
199		doorbell_ctrl = REG_SET_FIELD(doorbell_ctrl,
200				S2A_DOORBELL_ENTRY_1_CTRL,
201				S2A_DOORBELL_PORT1_ENABLE, 1);
202		doorbell_ctrl = REG_SET_FIELD(doorbell_ctrl,
203				S2A_DOORBELL_ENTRY_1_CTRL,
204				S2A_DOORBELL_PORT1_AWID, 0x4);
205		doorbell_ctrl = REG_SET_FIELD(doorbell_ctrl,
206				S2A_DOORBELL_ENTRY_1_CTRL,
207				S2A_DOORBELL_PORT1_RANGE_OFFSET, 0x4);
208		doorbell_ctrl = REG_SET_FIELD(doorbell_ctrl,
209				S2A_DOORBELL_ENTRY_1_CTRL,
210				S2A_DOORBELL_PORT1_RANGE_SIZE, range_size);
211		doorbell_ctrl = REG_SET_FIELD(doorbell_ctrl,
212				S2A_DOORBELL_ENTRY_1_CTRL,
213				S2A_DOORBELL_PORT1_AWADDR_31_28_VALUE, 0x4);
214
215		WREG32_SOC15_OFFSET(NBIO, 0, regDOORBELL0_CTRL_ENTRY_17,
216					aid_id, doorbell_range);
217		WREG32_SOC15_EXT(NBIO, aid_id, regS2A_DOORBELL_ENTRY_4_CTRL,
218				aid_id, doorbell_ctrl);
219	} else {
220		doorbell_range = REG_SET_FIELD(doorbell_range,
221				DOORBELL0_CTRL_ENTRY_0,
222				BIF_DOORBELL0_RANGE_SIZE_ENTRY, 0);
223		doorbell_ctrl = REG_SET_FIELD(doorbell_ctrl,
224				S2A_DOORBELL_ENTRY_1_CTRL,
225				S2A_DOORBELL_PORT1_RANGE_SIZE, 0);
226
227		WREG32_SOC15_OFFSET(NBIO, 0, regDOORBELL0_CTRL_ENTRY_17,
228					aid_id, doorbell_range);
229		WREG32_SOC15_EXT(NBIO, aid_id, regS2A_DOORBELL_ENTRY_4_CTRL,
230				aid_id, doorbell_ctrl);
231	}
232}
233
234static void nbio_v7_9_enable_doorbell_aperture(struct amdgpu_device *adev,
235					       bool enable)
236{
237	/* Enable to allow doorbell pass thru on pre-silicon bare-metal */
238	WREG32_SOC15(NBIO, 0, regBIFC_DOORBELL_ACCESS_EN_PF, 0xfffff);
239	WREG32_FIELD15_PREREG(NBIO, 0, RCC_DEV0_EPF0_RCC_DOORBELL_APER_EN,
240			BIF_DOORBELL_APER_EN, enable ? 1 : 0);
241}
242
243static void nbio_v7_9_enable_doorbell_selfring_aperture(struct amdgpu_device *adev,
244							bool enable)
245{
246	u32 tmp = 0;
247
248	if (enable) {
249		tmp = REG_SET_FIELD(tmp, BIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_CNTL,
250				    DOORBELL_SELFRING_GPA_APER_EN, 1) |
251		      REG_SET_FIELD(tmp, BIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_CNTL,
252				    DOORBELL_SELFRING_GPA_APER_MODE, 1) |
253		      REG_SET_FIELD(tmp, BIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_CNTL,
254				    DOORBELL_SELFRING_GPA_APER_SIZE, 0);
255
256		WREG32_SOC15(NBIO, 0, regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_BASE_LOW,
257			     lower_32_bits(adev->doorbell.base));
258		WREG32_SOC15(NBIO, 0, regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_BASE_HIGH,
259			     upper_32_bits(adev->doorbell.base));
260	}
261
262	WREG32_SOC15(NBIO, 0, regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_CNTL, tmp);
263}
264
265static void nbio_v7_9_ih_doorbell_range(struct amdgpu_device *adev,
266					bool use_doorbell, int doorbell_index)
267{
268	u32 ih_doorbell_range = 0, ih_doorbell_ctrl = 0;
269
270	if (use_doorbell) {
271		ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range,
272				DOORBELL0_CTRL_ENTRY_0,
273				BIF_DOORBELL0_RANGE_OFFSET_ENTRY,
274				doorbell_index);
275		ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range,
276				DOORBELL0_CTRL_ENTRY_0,
277				BIF_DOORBELL0_RANGE_SIZE_ENTRY,
278				0x8);
279
280		ih_doorbell_ctrl = REG_SET_FIELD(ih_doorbell_ctrl,
281				S2A_DOORBELL_ENTRY_1_CTRL,
282				S2A_DOORBELL_PORT1_ENABLE, 1);
283		ih_doorbell_ctrl = REG_SET_FIELD(ih_doorbell_ctrl,
284				S2A_DOORBELL_ENTRY_1_CTRL,
285				S2A_DOORBELL_PORT1_AWID, 0);
286		ih_doorbell_ctrl = REG_SET_FIELD(ih_doorbell_ctrl,
287				S2A_DOORBELL_ENTRY_1_CTRL,
288				S2A_DOORBELL_PORT1_RANGE_OFFSET, 0);
289		ih_doorbell_ctrl = REG_SET_FIELD(ih_doorbell_ctrl,
290				S2A_DOORBELL_ENTRY_1_CTRL,
291				S2A_DOORBELL_PORT1_RANGE_SIZE, 0x8);
292		ih_doorbell_ctrl = REG_SET_FIELD(ih_doorbell_ctrl,
293				S2A_DOORBELL_ENTRY_1_CTRL,
294				S2A_DOORBELL_PORT1_AWADDR_31_28_VALUE, 0);
295	} else {
296		ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range,
297				DOORBELL0_CTRL_ENTRY_0,
298				BIF_DOORBELL0_RANGE_SIZE_ENTRY, 0);
299		ih_doorbell_ctrl = REG_SET_FIELD(ih_doorbell_ctrl,
300				S2A_DOORBELL_ENTRY_1_CTRL,
301				S2A_DOORBELL_PORT1_RANGE_SIZE, 0);
302	}
303
304	WREG32_SOC15(NBIO, 0, regDOORBELL0_CTRL_ENTRY_0, ih_doorbell_range);
305	WREG32_SOC15(NBIO, 0, regS2A_DOORBELL_ENTRY_3_CTRL, ih_doorbell_ctrl);
306}
307
308
309static void nbio_v7_9_update_medium_grain_clock_gating(struct amdgpu_device *adev,
310						       bool enable)
311{
312}
313
314static void nbio_v7_9_update_medium_grain_light_sleep(struct amdgpu_device *adev,
315						      bool enable)
316{
317}
318
319static void nbio_v7_9_get_clockgating_state(struct amdgpu_device *adev,
320					    u64 *flags)
321{
322}
323
324static void nbio_v7_9_ih_control(struct amdgpu_device *adev)
325{
326	u32 interrupt_cntl;
327
328	/* setup interrupt control */
329	WREG32_SOC15(NBIO, 0, regBIF_BX0_INTERRUPT_CNTL2, adev->dummy_page_addr >> 8);
330	interrupt_cntl = RREG32_SOC15(NBIO, 0, regBIF_BX0_INTERRUPT_CNTL);
331	/* INTERRUPT_CNTL__IH_DUMMY_RD_OVERRIDE_MASK=0 - dummy read disabled with msi, enabled without msi
332	 * INTERRUPT_CNTL__IH_DUMMY_RD_OVERRIDE_MASK=1 - dummy read controlled by IH_DUMMY_RD_EN
333	 */
334	interrupt_cntl =
335		REG_SET_FIELD(interrupt_cntl, BIF_BX0_INTERRUPT_CNTL, IH_DUMMY_RD_OVERRIDE, 0);
336	/* INTERRUPT_CNTL__IH_REQ_NONSNOOP_EN_MASK=1 if ring is in non-cacheable memory, e.g., vram */
337	interrupt_cntl =
338		REG_SET_FIELD(interrupt_cntl, BIF_BX0_INTERRUPT_CNTL, IH_REQ_NONSNOOP_EN, 0);
339	WREG32_SOC15(NBIO, 0, regBIF_BX0_INTERRUPT_CNTL, interrupt_cntl);
340}
341
342static u32 nbio_v7_9_get_hdp_flush_req_offset(struct amdgpu_device *adev)
343{
344	return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF0_GPU_HDP_FLUSH_REQ);
345}
346
347static u32 nbio_v7_9_get_hdp_flush_done_offset(struct amdgpu_device *adev)
348{
349	return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF0_GPU_HDP_FLUSH_DONE);
350}
351
352static u32 nbio_v7_9_get_pcie_index_offset(struct amdgpu_device *adev)
353{
354	return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX0_PCIE_INDEX2);
355}
356
357static u32 nbio_v7_9_get_pcie_data_offset(struct amdgpu_device *adev)
358{
359	return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX0_PCIE_DATA2);
360}
361
362static u32 nbio_v7_9_get_pcie_index_hi_offset(struct amdgpu_device *adev)
363{
364	return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX0_PCIE_INDEX2_HI);
365}
366
367const struct nbio_hdp_flush_reg nbio_v7_9_hdp_flush_reg = {
368	.ref_and_mask_cp0 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP0_MASK,
369	.ref_and_mask_cp1 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP1_MASK,
370	.ref_and_mask_cp2 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP2_MASK,
371	.ref_and_mask_cp3 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP3_MASK,
372	.ref_and_mask_cp4 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP4_MASK,
373	.ref_and_mask_cp5 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP5_MASK,
374	.ref_and_mask_cp6 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP6_MASK,
375	.ref_and_mask_cp7 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP7_MASK,
376	.ref_and_mask_cp8 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP8_MASK,
377	.ref_and_mask_cp9 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP9_MASK,
378	.ref_and_mask_sdma0 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__SDMA0_MASK,
379	.ref_and_mask_sdma1 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__SDMA1_MASK,
380	.ref_and_mask_sdma2 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__RSVD_ENG0_MASK,
381	.ref_and_mask_sdma3 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__RSVD_ENG1_MASK,
382	.ref_and_mask_sdma4 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__RSVD_ENG2_MASK,
383	.ref_and_mask_sdma5 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__RSVD_ENG3_MASK,
384	.ref_and_mask_sdma6 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__RSVD_ENG4_MASK,
385	.ref_and_mask_sdma7 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__RSVD_ENG5_MASK,
386};
387
388static void nbio_v7_9_enable_doorbell_interrupt(struct amdgpu_device *adev,
389						bool enable)
390{
391	WREG32_FIELD15_PREREG(NBIO, 0, BIF_BX0_BIF_DOORBELL_INT_CNTL,
392			      DOORBELL_INTERRUPT_DISABLE, enable ? 0 : 1);
393}
394
395static int nbio_v7_9_get_compute_partition_mode(struct amdgpu_device *adev)
396{
397	u32 tmp, px;
398
399	tmp = RREG32_SOC15(NBIO, 0, regBIF_BX_PF0_PARTITION_COMPUTE_STATUS);
400	px = REG_GET_FIELD(tmp, BIF_BX_PF0_PARTITION_COMPUTE_STATUS,
401			   PARTITION_MODE);
402
403	return px;
404}
405
406static bool nbio_v7_9_is_nps_switch_requested(struct amdgpu_device *adev)
407{
408	u32 tmp;
409
410	tmp = RREG32_SOC15(NBIO, 0, regBIF_BX_PF0_PARTITION_MEM_STATUS);
411	tmp = REG_GET_FIELD(tmp, BIF_BX_PF0_PARTITION_MEM_STATUS,
412			    CHANGE_STATUE);
413
414	/* 0x8 - NPS switch requested */
415	return (tmp == 0x8);
416}
417static u32 nbio_v7_9_get_memory_partition_mode(struct amdgpu_device *adev,
418					       u32 *supp_modes)
419{
420	u32 tmp;
421
422	tmp = RREG32_SOC15(NBIO, 0, regBIF_BX_PF0_PARTITION_MEM_STATUS);
423	tmp = REG_GET_FIELD(tmp, BIF_BX_PF0_PARTITION_MEM_STATUS, NPS_MODE);
424
425	if (supp_modes) {
426		*supp_modes =
427			RREG32_SOC15(NBIO, 0, regBIF_BX_PF0_PARTITION_MEM_CAP);
428	}
429
430	return ffs(tmp);
431}
432
433static void nbio_v7_9_init_registers(struct amdgpu_device *adev)
434{
435	u32 inst_mask;
436	int i;
437
438	WREG32_SOC15(NBIO, 0, regXCC_DOORBELL_FENCE,
439		0xff & ~(adev->gfx.xcc_mask));
440
441	WREG32_SOC15(NBIO, 0, regBIFC_GFX_INT_MONITOR_MASK, 0x7ff);
442
443	inst_mask = adev->aid_mask & ~1U;
444	for_each_inst(i, inst_mask) {
445		WREG32_SOC15_EXT(NBIO, i, regXCC_DOORBELL_FENCE, i,
446			XCC_DOORBELL_FENCE__SHUB_SLV_MODE_MASK);
447
448	}
449
450	if (!amdgpu_sriov_vf(adev)) {
451		u32 baco_cntl;
452		for_each_inst(i, adev->aid_mask) {
453			baco_cntl = RREG32_SOC15(NBIO, i, regBIF_BX0_BACO_CNTL);
454			if (baco_cntl & (BIF_BX0_BACO_CNTL__BACO_DUMMY_EN_MASK |
455					 BIF_BX0_BACO_CNTL__BACO_EN_MASK)) {
456				baco_cntl &= ~(
457					BIF_BX0_BACO_CNTL__BACO_DUMMY_EN_MASK |
458					BIF_BX0_BACO_CNTL__BACO_EN_MASK);
459				dev_dbg(adev->dev,
460					"Unsetting baco dummy mode %x",
461					baco_cntl);
462				WREG32_SOC15(NBIO, i, regBIF_BX0_BACO_CNTL,
463					     baco_cntl);
464			}
465		}
466	}
467}
468
469#define MMIO_REG_HOLE_OFFSET 0x1A000
470
471static void nbio_v7_9_set_reg_remap(struct amdgpu_device *adev)
472{
473	if (!amdgpu_sriov_vf(adev) && (PAGE_SIZE <= 4096)) {
474		adev->rmmio_remap.reg_offset = MMIO_REG_HOLE_OFFSET;
475		adev->rmmio_remap.bus_addr = adev->rmmio_base + MMIO_REG_HOLE_OFFSET;
476	} else {
477		adev->rmmio_remap.reg_offset =
478			SOC15_REG_OFFSET(
479				NBIO, 0,
480				regBIF_BX_DEV0_EPF0_VF0_HDP_MEM_COHERENCY_FLUSH_CNTL)
481			<< 2;
482		adev->rmmio_remap.bus_addr = 0;
483	}
484}
485
486const struct amdgpu_nbio_funcs nbio_v7_9_funcs = {
487	.get_hdp_flush_req_offset = nbio_v7_9_get_hdp_flush_req_offset,
488	.get_hdp_flush_done_offset = nbio_v7_9_get_hdp_flush_done_offset,
489	.get_pcie_index_offset = nbio_v7_9_get_pcie_index_offset,
490	.get_pcie_data_offset = nbio_v7_9_get_pcie_data_offset,
491	.get_pcie_index_hi_offset = nbio_v7_9_get_pcie_index_hi_offset,
492	.get_rev_id = nbio_v7_9_get_rev_id,
493	.mc_access_enable = nbio_v7_9_mc_access_enable,
494	.get_memsize = nbio_v7_9_get_memsize,
495	.sdma_doorbell_range = nbio_v7_9_sdma_doorbell_range,
496	.vcn_doorbell_range = nbio_v7_9_vcn_doorbell_range,
497	.enable_doorbell_aperture = nbio_v7_9_enable_doorbell_aperture,
498	.enable_doorbell_selfring_aperture = nbio_v7_9_enable_doorbell_selfring_aperture,
499	.ih_doorbell_range = nbio_v7_9_ih_doorbell_range,
500	.enable_doorbell_interrupt = nbio_v7_9_enable_doorbell_interrupt,
501	.update_medium_grain_clock_gating = nbio_v7_9_update_medium_grain_clock_gating,
502	.update_medium_grain_light_sleep = nbio_v7_9_update_medium_grain_light_sleep,
503	.get_clockgating_state = nbio_v7_9_get_clockgating_state,
504	.ih_control = nbio_v7_9_ih_control,
505	.remap_hdp_registers = nbio_v7_9_remap_hdp_registers,
506	.get_compute_partition_mode = nbio_v7_9_get_compute_partition_mode,
507	.get_memory_partition_mode = nbio_v7_9_get_memory_partition_mode,
508	.is_nps_switch_requested = nbio_v7_9_is_nps_switch_requested,
509	.init_registers = nbio_v7_9_init_registers,
510	.set_reg_remap = nbio_v7_9_set_reg_remap,
511};
512
513static void nbio_v7_9_query_ras_error_count(struct amdgpu_device *adev,
514					void *ras_error_status)
515{
516}
517
518static void nbio_v7_9_handle_ras_controller_intr_no_bifring(struct amdgpu_device *adev)
519{
520	uint32_t bif_doorbell_intr_cntl;
521	struct ras_manager *obj = amdgpu_ras_find_obj(adev, adev->nbio.ras_if);
522	struct ras_err_data err_data;
523	struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
524
525	if (amdgpu_ras_error_data_init(&err_data))
526		return;
527
528	bif_doorbell_intr_cntl = RREG32_SOC15(NBIO, 0, regBIF_BX0_BIF_DOORBELL_INT_CNTL);
529
530	if (REG_GET_FIELD(bif_doorbell_intr_cntl,
531		BIF_BX0_BIF_DOORBELL_INT_CNTL, RAS_CNTLR_INTERRUPT_STATUS)) {
532		/* driver has to clear the interrupt status when bif ring is disabled */
533		bif_doorbell_intr_cntl = REG_SET_FIELD(bif_doorbell_intr_cntl,
534						BIF_BX0_BIF_DOORBELL_INT_CNTL,
535						RAS_CNTLR_INTERRUPT_CLEAR, 1);
536		WREG32_SOC15(NBIO, 0, regBIF_BX0_BIF_DOORBELL_INT_CNTL, bif_doorbell_intr_cntl);
537
538		if (!ras->disable_ras_err_cnt_harvest) {
539			/*
540			 * clear error status after ras_controller_intr
541			 * according to hw team and count ue number
542			 * for query
543			 */
544			nbio_v7_9_query_ras_error_count(adev, &err_data);
545
546			/* logging on error cnt and printing for awareness */
547			obj->err_data.ue_count += err_data.ue_count;
548			obj->err_data.ce_count += err_data.ce_count;
549
550			if (err_data.ce_count)
551				dev_info(adev->dev, "%ld correctable hardware "
552						"errors detected in %s block\n",
553						obj->err_data.ce_count,
554						get_ras_block_str(adev->nbio.ras_if));
555
556			if (err_data.ue_count)
557				dev_info(adev->dev, "%ld uncorrectable hardware "
558						"errors detected in %s block\n",
559						obj->err_data.ue_count,
560						get_ras_block_str(adev->nbio.ras_if));
561		}
562
563		dev_info(adev->dev, "RAS controller interrupt triggered "
564					"by NBIF error\n");
565	}
566
567	amdgpu_ras_error_data_fini(&err_data);
568}
569
570static void nbio_v7_9_handle_ras_err_event_athub_intr_no_bifring(struct amdgpu_device *adev)
571{
572	uint32_t bif_doorbell_intr_cntl;
573
574	bif_doorbell_intr_cntl = RREG32_SOC15(NBIO, 0, regBIF_BX0_BIF_DOORBELL_INT_CNTL);
575
576	if (REG_GET_FIELD(bif_doorbell_intr_cntl,
577		BIF_BX0_BIF_DOORBELL_INT_CNTL, RAS_ATHUB_ERR_EVENT_INTERRUPT_STATUS)) {
578		/* driver has to clear the interrupt status when bif ring is disabled */
579		bif_doorbell_intr_cntl = REG_SET_FIELD(bif_doorbell_intr_cntl,
580						BIF_BX0_BIF_DOORBELL_INT_CNTL,
581						RAS_ATHUB_ERR_EVENT_INTERRUPT_CLEAR, 1);
582
583		WREG32_SOC15(NBIO, 0, regBIF_BX0_BIF_DOORBELL_INT_CNTL, bif_doorbell_intr_cntl);
584
585		amdgpu_ras_global_ras_isr(adev);
586	}
587}
588
589static int nbio_v7_9_set_ras_controller_irq_state(struct amdgpu_device *adev,
590						  struct amdgpu_irq_src *src,
591						  unsigned type,
592						  enum amdgpu_interrupt_state state)
593{
594	/* Dummy function, there is no initialization operation in driver */
595
596	return 0;
597}
598
599static int nbio_v7_9_process_ras_controller_irq(struct amdgpu_device *adev,
600						struct amdgpu_irq_src *source,
601						struct amdgpu_iv_entry *entry)
602{
603	/* By design, the ih cookie for ras_controller_irq should be written
604	 * to BIFring instead of general iv ring. However, due to known bif ring
605	 * hw bug, it has to be disabled. There is no chance the process function
606	 * will be involked. Just left it as a dummy one.
607	 */
608	return 0;
609}
610
611static int nbio_v7_9_set_ras_err_event_athub_irq_state(struct amdgpu_device *adev,
612						       struct amdgpu_irq_src *src,
613						       unsigned type,
614						       enum amdgpu_interrupt_state state)
615{
616	/* Dummy function, there is no initialization operation in driver */
617
618	return 0;
619}
620
621static int nbio_v7_9_process_err_event_athub_irq(struct amdgpu_device *adev,
622						 struct amdgpu_irq_src *source,
623						 struct amdgpu_iv_entry *entry)
624{
625	/* By design, the ih cookie for err_event_athub_irq should be written
626	 * to BIFring instead of general iv ring. However, due to known bif ring
627	 * hw bug, it has to be disabled. There is no chance the process function
628	 * will be involked. Just left it as a dummy one.
629	 */
630	return 0;
631}
632
633static const struct amdgpu_irq_src_funcs nbio_v7_9_ras_controller_irq_funcs = {
634	.set = nbio_v7_9_set_ras_controller_irq_state,
635	.process = nbio_v7_9_process_ras_controller_irq,
636};
637
638static const struct amdgpu_irq_src_funcs nbio_v7_9_ras_err_event_athub_irq_funcs = {
639	.set = nbio_v7_9_set_ras_err_event_athub_irq_state,
640	.process = nbio_v7_9_process_err_event_athub_irq,
641};
642
643static int nbio_v7_9_init_ras_controller_interrupt (struct amdgpu_device *adev)
644{
645	int r;
646
647	/* init the irq funcs */
648	adev->nbio.ras_controller_irq.funcs =
649		&nbio_v7_9_ras_controller_irq_funcs;
650	adev->nbio.ras_controller_irq.num_types = 1;
651
652	/* register ras controller interrupt */
653	r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_BIF,
654			      NBIF_7_4__SRCID__RAS_CONTROLLER_INTERRUPT,
655			      &adev->nbio.ras_controller_irq);
656
657	return r;
658}
659
660static int nbio_v7_9_init_ras_err_event_athub_interrupt (struct amdgpu_device *adev)
661{
662
663	int r;
664
665	/* init the irq funcs */
666	adev->nbio.ras_err_event_athub_irq.funcs =
667		&nbio_v7_9_ras_err_event_athub_irq_funcs;
668	adev->nbio.ras_err_event_athub_irq.num_types = 1;
669
670	/* register ras err event athub interrupt */
671	r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_BIF,
672			      NBIF_7_4__SRCID__ERREVENT_ATHUB_INTERRUPT,
673			      &adev->nbio.ras_err_event_athub_irq);
674
675	return r;
676}
677
678const struct amdgpu_ras_block_hw_ops nbio_v7_9_ras_hw_ops = {
679	.query_ras_error_count = nbio_v7_9_query_ras_error_count,
680};
681
682struct amdgpu_nbio_ras nbio_v7_9_ras = {
683	.ras_block = {
684		.ras_comm = {
685			.name = "pcie_bif",
686			.block = AMDGPU_RAS_BLOCK__PCIE_BIF,
687			.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE,
688		},
689		.hw_ops = &nbio_v7_9_ras_hw_ops,
690		.ras_late_init = amdgpu_nbio_ras_late_init,
691	},
692	.handle_ras_controller_intr_no_bifring = nbio_v7_9_handle_ras_controller_intr_no_bifring,
693	.handle_ras_err_event_athub_intr_no_bifring = nbio_v7_9_handle_ras_err_event_athub_intr_no_bifring,
694	.init_ras_controller_interrupt = nbio_v7_9_init_ras_controller_interrupt,
695	.init_ras_err_event_athub_interrupt = nbio_v7_9_init_ras_err_event_athub_interrupt,
696};
~/ Read-only file preview.