File Index
Files and directories
Sign in
FILE

gsp.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c C
  1/* SPDX-License-Identifier: MIT
  2 *
  3 * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.
  4 */
  5#include <rm/rm.h>
  6#include <rm/rpc.h>
  7
  8#include <asm-generic/video.h>
  9
 10#include "nvrm/gsp.h"
 11#include "nvrm/rpcfn.h"
 12#include "nvrm/msgfn.h"
 13
 14#include <core/pci.h>
 15#include <subdev/pci/priv.h>
 16
 17static u32
 18r570_gsp_sr_data_size(struct nvkm_gsp *gsp)
 19{
 20	GspFwWprMeta *meta = gsp->wpr_meta.data;
 21
 22	return (meta->frtsOffset + meta->frtsSize) -
 23	       (meta->nonWprHeapOffset + meta->nonWprHeapSize);
 24}
 25
 26static void
 27r570_gsp_drop_post_nocat_record(struct nvkm_gsp *gsp)
 28{
 29	if (gsp->subdev.debug < NV_DBG_DEBUG) {
 30		r535_gsp_msg_ntfy_add(gsp, NV_VGPU_MSG_EVENT_GSP_POST_NOCAT_RECORD, NULL, NULL);
 31		r535_gsp_msg_ntfy_add(gsp, NV_VGPU_MSG_EVENT_GSP_LOCKDOWN_NOTICE, NULL, NULL);
 32	}
 33}
 34
 35static bool
 36r570_gsp_xlat_mc_engine_idx(u32 mc_engine_idx, enum nvkm_subdev_type *ptype, int *pinst)
 37{
 38	switch (mc_engine_idx) {
 39	case MC_ENGINE_IDX_GSP:
 40		*ptype = NVKM_SUBDEV_GSP;
 41		*pinst = 0;
 42		return true;
 43	case MC_ENGINE_IDX_DISP:
 44		*ptype = NVKM_ENGINE_DISP;
 45		*pinst = 0;
 46		return true;
 47	case MC_ENGINE_IDX_CE0 ... MC_ENGINE_IDX_CE19:
 48		*ptype = NVKM_ENGINE_CE;
 49		*pinst = mc_engine_idx - MC_ENGINE_IDX_CE0;
 50		return true;
 51	case MC_ENGINE_IDX_GR0:
 52		*ptype = NVKM_ENGINE_GR;
 53		*pinst = 0;
 54		return true;
 55	case MC_ENGINE_IDX_NVDEC0 ... MC_ENGINE_IDX_NVDEC7:
 56		*ptype = NVKM_ENGINE_NVDEC;
 57		*pinst = mc_engine_idx - MC_ENGINE_IDX_NVDEC0;
 58		return true;
 59	case MC_ENGINE_IDX_NVENC ... MC_ENGINE_IDX_NVENC3:
 60		*ptype = NVKM_ENGINE_NVENC;
 61		*pinst = mc_engine_idx - MC_ENGINE_IDX_NVENC;
 62		return true;
 63	case MC_ENGINE_IDX_NVJPEG0 ... MC_ENGINE_IDX_NVJPEG7:
 64		*ptype = NVKM_ENGINE_NVJPG;
 65		*pinst = mc_engine_idx - MC_ENGINE_IDX_NVJPEG0;
 66		return true;
 67	case MC_ENGINE_IDX_OFA0 ... MC_ENGINE_IDX_OFA1:
 68		*ptype = NVKM_ENGINE_OFA;
 69		*pinst = mc_engine_idx - MC_ENGINE_IDX_OFA0;
 70		return true;
 71	default:
 72		return false;
 73	}
 74}
 75
 76static int
 77r570_gsp_get_static_info(struct nvkm_gsp *gsp)
 78{
 79	GspStaticConfigInfo *rpc;
 80	u32 gpc_mask;
 81	u32 tpc_mask;
 82	int ret;
 83
 84	rpc = nvkm_gsp_rpc_rd(gsp, NV_VGPU_MSG_FUNCTION_GET_GSP_STATIC_INFO, sizeof(*rpc));
 85	if (IS_ERR(rpc))
 86		return PTR_ERR(rpc);
 87
 88	gsp->internal.client.object.client = &gsp->internal.client;
 89	gsp->internal.client.object.parent = NULL;
 90	gsp->internal.client.object.handle = rpc->hInternalClient;
 91	gsp->internal.client.gsp = gsp;
 92	INIT_LIST_HEAD(&gsp->internal.client.events);
 93
 94	gsp->internal.device.object.client = &gsp->internal.client;
 95	gsp->internal.device.object.parent = &gsp->internal.client.object;
 96	gsp->internal.device.object.handle = rpc->hInternalDevice;
 97
 98	gsp->internal.device.subdevice.client = &gsp->internal.client;
 99	gsp->internal.device.subdevice.parent = &gsp->internal.device.object;
100	gsp->internal.device.subdevice.handle = rpc->hInternalSubdevice;
101
102	gsp->bar.rm_bar1_pdb = rpc->bar1PdeBase;
103	gsp->bar.rm_bar2_pdb = rpc->bar2PdeBase;
104
105	r535_gsp_get_static_info_fb(gsp, &rpc->fbRegionInfoParams);
106
107	if (gsp->rm->wpr->offset_set_by_acr) {
108		GspFwWprMeta *meta = gsp->wpr_meta.data;
109
110		meta->nonWprHeapOffset = rpc->fwWprLayoutOffset.nonWprHeapOffset;
111		meta->frtsOffset = rpc->fwWprLayoutOffset.frtsOffset;
112	}
113
114	nvkm_gsp_rpc_done(gsp, rpc);
115
116	ret = r570_gr_gpc_mask(gsp, &gpc_mask);
117	if (ret)
118		return ret;
119
120	for (int gpc = 0; gpc < 32; gpc++) {
121		if (gpc_mask & BIT(gpc)) {
122			ret = r570_gr_tpc_mask(gsp, gpc, &tpc_mask);
123			if (ret)
124				return ret;
125
126			gsp->gr.tpcs += hweight32(tpc_mask);
127			gsp->gr.gpcs++;
128		}
129	}
130
131	return 0;
132}
133
134static void
135r570_gsp_acpi_info(struct nvkm_gsp *gsp, ACPI_METHOD_DATA *acpi)
136{
137#if defined(CONFIG_ACPI) && defined(CONFIG_X86)
138	acpi_handle handle = ACPI_HANDLE(gsp->subdev.device->dev);
139
140	if (!handle)
141		return;
142
143	acpi->bValid = 1;
144
145	r535_gsp_acpi_dod(handle, &acpi->dodMethodData);
146	r535_gsp_acpi_jt(handle, &acpi->jtMethodData);
147	r535_gsp_acpi_caps(handle, &acpi->capsMethodData);
148#endif
149}
150
151static int
152r570_gsp_set_system_info(struct nvkm_gsp *gsp)
153{
154	struct nvkm_device *device = gsp->subdev.device;
155	struct pci_dev *pdev = container_of(device, struct nvkm_device_pci, device)->pdev;
156	GspSystemInfo *info;
157
158	if (WARN_ON(device->type == NVKM_DEVICE_TEGRA))
159		return -ENOSYS;
160
161	info = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_GSP_SET_SYSTEM_INFO, sizeof(*info));
162	if (IS_ERR(info))
163		return PTR_ERR(info);
164
165	info->gpuPhysAddr = device->func->resource_addr(device, NVKM_BAR0_PRI);
166	info->gpuPhysFbAddr = device->func->resource_addr(device, NVKM_BAR1_FB);
167	info->gpuPhysInstAddr = device->func->resource_addr(device, NVKM_BAR2_INST);
168	info->nvDomainBusDeviceFunc = pci_dev_id(pdev);
169	info->maxUserVa = TASK_SIZE;
170	info->pciConfigMirrorBase = device->pci->func->cfg.addr;
171	info->pciConfigMirrorSize = device->pci->func->cfg.size;
172	info->PCIDeviceID = (pdev->device << 16) | pdev->vendor;
173	info->PCISubDeviceID = (pdev->subsystem_device << 16) | pdev->subsystem_vendor;
174	info->PCIRevisionID = pdev->revision;
175	r570_gsp_acpi_info(gsp, &info->acpiMethodData);
176	info->bIsPrimary = video_is_primary_device(device->dev);
177	info->bPreserveVideoMemoryAllocations = false;
178
179	return nvkm_gsp_rpc_wr(gsp, info, NVKM_GSP_RPC_REPLY_NOSEQ);
180}
181
182static void
183r570_gsp_set_rmargs(struct nvkm_gsp *gsp, bool resume)
184{
185	GSP_ARGUMENTS_CACHED *args;
186
187	args = gsp->rmargs.data;
188	args->messageQueueInitArguments.sharedMemPhysAddr = gsp->shm.mem.addr;
189	args->messageQueueInitArguments.pageTableEntryCount = gsp->shm.ptes.nr;
190	args->messageQueueInitArguments.cmdQueueOffset =
191		(u8 *)gsp->shm.cmdq.ptr - (u8 *)gsp->shm.mem.data;
192	args->messageQueueInitArguments.statQueueOffset =
193		(u8 *)gsp->shm.msgq.ptr - (u8 *)gsp->shm.mem.data;
194
195	if (!resume) {
196		args->srInitArguments.oldLevel = 0;
197		args->srInitArguments.flags = 0;
198		args->srInitArguments.bInPMTransition = 0;
199	} else {
200		args->srInitArguments.oldLevel = NV2080_CTRL_GPU_SET_POWER_STATE_GPU_LEVEL_3;
201		args->srInitArguments.flags = 0;
202		args->srInitArguments.bInPMTransition = 1;
203	}
204
205	args->bDmemStack = 1;
206}
207
208const struct nvkm_rm_api_gsp
209r570_gsp = {
210	.set_rmargs = r570_gsp_set_rmargs,
211	.set_system_info = r570_gsp_set_system_info,
212	.get_static_info = r570_gsp_get_static_info,
213	.xlat_mc_engine_idx = r570_gsp_xlat_mc_engine_idx,
214	.drop_post_nocat_record = r570_gsp_drop_post_nocat_record,
215	.sr_data_size = r570_gsp_sr_data_size,
216};
~/ Read-only file preview.