File Index
Files and directories
Sign in
FILE

disp.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/disp.c C
  1/* SPDX-License-Identifier: MIT
  2 *
  3 * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.
  4 */
  5#include <rm/rm.h>
  6
  7#include <engine/disp.h>
  8#include <engine/disp/outp.h>
  9
 10#include "nvhw/drf.h"
 11
 12#include "nvrm/disp.h"
 13
 14static int
 15r570_dmac_alloc(struct nvkm_disp *disp, u32 oclass, int inst, u32 put_offset,
 16		struct nvkm_gsp_object *dmac)
 17{
 18	NV50VAIO_CHANNELDMA_ALLOCATION_PARAMETERS *args;
 19
 20	args = nvkm_gsp_rm_alloc_get(&disp->rm.object, (oclass << 16) | inst, oclass,
 21				     sizeof(*args), dmac);
 22	if (IS_ERR(args))
 23		return PTR_ERR(args);
 24
 25	args->channelInstance = inst;
 26	args->offset = put_offset;
 27	args->subDeviceId = BIT(0);
 28
 29	return nvkm_gsp_rm_alloc_wr(dmac, args);
 30}
 31
 32static int
 33r570_disp_chan_set_pushbuf(struct nvkm_disp *disp, s32 oclass, int inst, struct nvkm_memory *memory)
 34{
 35	struct nvkm_gsp *gsp = disp->rm.objcom.client->gsp;
 36	NV2080_CTRL_INTERNAL_DISPLAY_CHANNEL_PUSHBUFFER_PARAMS *ctrl;
 37
 38	ctrl = nvkm_gsp_rm_ctrl_get(&gsp->internal.device.subdevice,
 39				    NV2080_CTRL_CMD_INTERNAL_DISPLAY_CHANNEL_PUSHBUFFER,
 40				    sizeof(*ctrl));
 41	if (IS_ERR(ctrl))
 42		return PTR_ERR(ctrl);
 43
 44	if (memory) {
 45		switch (nvkm_memory_target(memory)) {
 46		case NVKM_MEM_TARGET_NCOH:
 47			ctrl->addressSpace = ADDR_SYSMEM;
 48			ctrl->cacheSnoop = 0;
 49			ctrl->pbTargetAperture = PHYS_PCI;
 50			break;
 51		case NVKM_MEM_TARGET_HOST:
 52			ctrl->addressSpace = ADDR_SYSMEM;
 53			ctrl->cacheSnoop = 1;
 54			ctrl->pbTargetAperture = PHYS_PCI_COHERENT;
 55			break;
 56		case NVKM_MEM_TARGET_VRAM:
 57			ctrl->addressSpace = ADDR_FBMEM;
 58			ctrl->pbTargetAperture = PHYS_NVM;
 59			break;
 60		default:
 61			WARN_ON(1);
 62			return -EINVAL;
 63		}
 64
 65		ctrl->physicalAddr = nvkm_memory_addr(memory);
 66		ctrl->limit = nvkm_memory_size(memory) - 1;
 67	}
 68
 69	ctrl->hclass = oclass;
 70	ctrl->channelInstance = inst;
 71	ctrl->valid = ((oclass & 0xff) != 0x7a) ? 1 : 0;
 72	ctrl->subDeviceId = BIT(0);
 73
 74	return nvkm_gsp_rm_ctrl_wr(&gsp->internal.device.subdevice, ctrl);
 75}
 76
 77static int
 78r570_dp_set_indexed_link_rates(struct nvkm_outp *outp)
 79{
 80	NV0073_CTRL_CMD_DP_CONFIG_INDEXED_LINK_RATES_PARAMS *ctrl;
 81	struct nvkm_disp *disp = outp->disp;
 82
 83	if (WARN_ON(outp->dp.rates > ARRAY_SIZE(ctrl->linkRateTbl)))
 84		return -EINVAL;
 85
 86	ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom,
 87				    NV0073_CTRL_CMD_DP_CONFIG_INDEXED_LINK_RATES, sizeof(*ctrl));
 88	if (IS_ERR(ctrl))
 89		return PTR_ERR(ctrl);
 90
 91	ctrl->displayId = BIT(outp->index);
 92	for (int i = 0; i < outp->dp.rates; i++)
 93		ctrl->linkRateTbl[outp->dp.rate[i].dpcd] = outp->dp.rate[i].rate * 10 / 200;
 94
 95	return nvkm_gsp_rm_ctrl_wr(&disp->rm.objcom, ctrl);
 96}
 97
 98static int
 99r570_dp_get_caps(struct nvkm_disp *disp, int *plink_bw, bool *pmst, bool *pwm)
100{
101	NV0073_CTRL_CMD_DP_GET_CAPS_PARAMS *ctrl;
102	int ret;
103
104	ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom,
105				    NV0073_CTRL_CMD_DP_GET_CAPS, sizeof(*ctrl));
106	if (IS_ERR(ctrl))
107		return PTR_ERR(ctrl);
108
109	ctrl->sorIndex = ~0;
110
111	ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl));
112	if (ret) {
113		nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
114		return ret;
115	}
116
117	switch (NVVAL_GET(ctrl->maxLinkRate, NV0073_CTRL_CMD, DP_GET_CAPS, MAX_LINK_RATE)) {
118	case NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_1_62:
119		*plink_bw = 0x06;
120		break;
121	case NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_2_70:
122		*plink_bw = 0x0a;
123		break;
124	case NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_5_40:
125		*plink_bw = 0x14;
126		break;
127	case NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_8_10:
128		*plink_bw = 0x1e;
129		break;
130	default:
131		*plink_bw = 0x00;
132		break;
133	}
134
135	*pmst = ctrl->bIsMultistreamSupported;
136	*pwm = ctrl->bHasIncreasedWatermarkLimits;
137	nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
138	return 0;
139}
140
141static int
142r570_bl_ctrl(struct nvkm_disp *disp, unsigned display_id, bool set, int *pval)
143{
144	u32 cmd = set ? NV0073_CTRL_CMD_SPECIFIC_SET_BACKLIGHT_BRIGHTNESS :
145			NV0073_CTRL_CMD_SPECIFIC_GET_BACKLIGHT_BRIGHTNESS;
146	NV0073_CTRL_SPECIFIC_BACKLIGHT_BRIGHTNESS_PARAMS *ctrl;
147	int ret;
148
149	ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, cmd, sizeof(*ctrl));
150	if (IS_ERR(ctrl))
151		return PTR_ERR(ctrl);
152
153	ctrl->displayId = BIT(display_id);
154	ctrl->brightness = *pval;
155	ctrl->brightnessType = NV0073_CTRL_SPECIFIC_BACKLIGHT_BRIGHTNESS_TYPE_PERCENT100;
156
157	ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl));
158	if (ret)
159		return ret;
160
161	*pval = ctrl->brightness;
162
163	nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
164	return 0;
165}
166
167static int
168r570_disp_get_active(struct nvkm_disp *disp, unsigned head, u32 *displayid)
169{
170	NV0073_CTRL_SYSTEM_GET_ACTIVE_PARAMS *ctrl;
171	int ret;
172
173	ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom,
174				    NV0073_CTRL_CMD_SYSTEM_GET_ACTIVE, sizeof(*ctrl));
175	if (IS_ERR(ctrl))
176		return PTR_ERR(ctrl);
177
178	ctrl->subDeviceInstance = 0;
179	ctrl->head = head;
180
181	ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl));
182	if (ret) {
183		nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
184		return ret;
185	}
186
187	*displayid = ctrl->displayId;
188	nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
189	return 0;
190}
191static int
192r570_disp_get_connect_state(struct nvkm_disp *disp, unsigned display_id)
193{
194	NV0073_CTRL_SYSTEM_GET_CONNECT_STATE_PARAMS *ctrl;
195	int ret;
196
197	ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom,
198				    NV0073_CTRL_CMD_SYSTEM_GET_CONNECT_STATE, sizeof(*ctrl));
199	if (IS_ERR(ctrl))
200		return PTR_ERR(ctrl);
201
202	ctrl->subDeviceInstance = 0;
203	ctrl->displayMask = BIT(display_id);
204
205	ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl));
206	if (ret == 0 && (ctrl->displayMask & BIT(display_id)))
207		ret = 1;
208
209	nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
210	return ret;
211}
212
213static int
214r570_disp_get_supported(struct nvkm_disp *disp, unsigned long *pmask)
215{
216	NV0073_CTRL_SYSTEM_GET_SUPPORTED_PARAMS *ctrl;
217
218	ctrl = nvkm_gsp_rm_ctrl_rd(&disp->rm.objcom,
219				   NV0073_CTRL_CMD_SYSTEM_GET_SUPPORTED, sizeof(*ctrl));
220	if (IS_ERR(ctrl))
221		return PTR_ERR(ctrl);
222
223	*pmask = ctrl->displayMask;
224
225	nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
226	return 0;
227}
228
229static int
230r570_disp_get_static_info(struct nvkm_disp *disp)
231{
232	NV2080_CTRL_INTERNAL_DISPLAY_GET_STATIC_INFO_PARAMS *ctrl;
233	struct nvkm_gsp *gsp = disp->engine.subdev.device->gsp;
234
235	ctrl = nvkm_gsp_rm_ctrl_rd(&gsp->internal.device.subdevice,
236				   NV2080_CTRL_CMD_INTERNAL_DISPLAY_GET_STATIC_INFO,
237				   sizeof(*ctrl));
238	if (IS_ERR(ctrl))
239		return PTR_ERR(ctrl);
240
241	disp->wndw.mask = ctrl->windowPresentMask;
242	disp->wndw.nr = fls(disp->wndw.mask);
243
244	nvkm_gsp_rm_ctrl_done(&gsp->internal.device.subdevice, ctrl);
245	return 0;
246}
247
248const struct nvkm_rm_api_disp
249r570_disp = {
250	.get_static_info = r570_disp_get_static_info,
251	.get_supported = r570_disp_get_supported,
252	.get_connect_state = r570_disp_get_connect_state,
253	.get_active = r570_disp_get_active,
254	.bl_ctrl = r570_bl_ctrl,
255	.dp = {
256		.get_caps = r570_dp_get_caps,
257		.set_indexed_link_rates = r570_dp_set_indexed_link_rates,
258	},
259	.chan = {
260		.set_pushbuf = r570_disp_chan_set_pushbuf,
261		.dmac_alloc = r570_dmac_alloc,
262	},
263};
~/ Read-only file preview.