1 /*
2 * Copyright 2023 Red Hat 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 #include <engine/disp/priv.h>
23 #include <engine/disp/chan.h>
24 #include <engine/disp/conn.h>
25 #include <engine/disp/dp.h>
26 #include <engine/disp/head.h>
27 #include <engine/disp/ior.h>
28 #include <engine/disp/outp.h>
29
30 #include <core/ramht.h>
31 #include <subdev/bios.h>
32 #include <subdev/bios/conn.h>
33 #include <subdev/gsp.h>
34 #include <subdev/mmu.h>
35 #include <subdev/vfn.h>
36
37 #include <rm/gpu.h>
38
39 #include <nvhw/drf.h>
40
41 #include "nvrm/disp.h"
42
43 #include <linux/acpi.h>
44
45 static u64
r535_chan_user(struct nvkm_disp_chan * chan,u64 * psize)46 r535_chan_user(struct nvkm_disp_chan *chan, u64 *psize)
47 {
48 switch (chan->object.oclass & 0xff) {
49 case 0x7d: *psize = 0x10000; return 0x680000;
50 case 0x7e: *psize = 0x01000; return 0x690000 + (chan->head * *psize);
51 case 0x7b: *psize = 0x01000; return 0x6b0000 + (chan->head * *psize);
52 case 0x7a: *psize = 0x01000; return 0x6d8000 + (chan->head * *psize);
53 default:
54 BUG_ON(1);
55 break;
56 }
57
58 return 0ULL;
59 }
60
61 static void
r535_chan_intr(struct nvkm_disp_chan * chan,bool en)62 r535_chan_intr(struct nvkm_disp_chan *chan, bool en)
63 {
64 }
65
66 static void
r535_chan_fini(struct nvkm_disp_chan * chan)67 r535_chan_fini(struct nvkm_disp_chan *chan)
68 {
69 nvkm_gsp_rm_free(&chan->rm.object);
70 }
71
72 static int
r535_disp_chan_set_pushbuf(struct nvkm_disp * disp,s32 oclass,int inst,struct nvkm_memory * memory)73 r535_disp_chan_set_pushbuf(struct nvkm_disp *disp, s32 oclass, int inst, struct nvkm_memory *memory)
74 {
75 struct nvkm_gsp *gsp = disp->rm.objcom.client->gsp;
76 NV2080_CTRL_INTERNAL_DISPLAY_CHANNEL_PUSHBUFFER_PARAMS *ctrl;
77
78 ctrl = nvkm_gsp_rm_ctrl_get(&gsp->internal.device.subdevice,
79 NV2080_CTRL_CMD_INTERNAL_DISPLAY_CHANNEL_PUSHBUFFER,
80 sizeof(*ctrl));
81 if (IS_ERR(ctrl))
82 return PTR_ERR(ctrl);
83
84 if (memory) {
85 switch (nvkm_memory_target(memory)) {
86 case NVKM_MEM_TARGET_NCOH:
87 ctrl->addressSpace = ADDR_SYSMEM;
88 ctrl->cacheSnoop = 0;
89 break;
90 case NVKM_MEM_TARGET_HOST:
91 ctrl->addressSpace = ADDR_SYSMEM;
92 ctrl->cacheSnoop = 1;
93 break;
94 case NVKM_MEM_TARGET_VRAM:
95 ctrl->addressSpace = ADDR_FBMEM;
96 break;
97 default:
98 WARN_ON(1);
99 return -EINVAL;
100 }
101
102 ctrl->physicalAddr = nvkm_memory_addr(memory);
103 ctrl->limit = nvkm_memory_size(memory) - 1;
104 }
105
106 ctrl->hclass = oclass;
107 ctrl->channelInstance = inst;
108 ctrl->valid = ((oclass & 0xff) != 0x7a) ? 1 : 0;
109
110 return nvkm_gsp_rm_ctrl_wr(&gsp->internal.device.subdevice, ctrl);
111 }
112
113 static int
r535_curs_init(struct nvkm_disp_chan * chan)114 r535_curs_init(struct nvkm_disp_chan *chan)
115 {
116 const struct nvkm_rm_api *rmapi = chan->disp->rm.objcom.client->gsp->rm->api;
117 NV50VAIO_CHANNELPIO_ALLOCATION_PARAMETERS *args;
118 int ret;
119
120 ret = rmapi->disp->chan.set_pushbuf(chan->disp, chan->object.oclass, chan->head, NULL);
121 if (ret)
122 return ret;
123
124 args = nvkm_gsp_rm_alloc_get(&chan->disp->rm.object,
125 (chan->object.oclass << 16) | chan->head,
126 chan->object.oclass, sizeof(*args), &chan->rm.object);
127 if (IS_ERR(args))
128 return PTR_ERR(args);
129
130 args->channelInstance = chan->head;
131
132 return nvkm_gsp_rm_alloc_wr(&chan->rm.object, args);
133 }
134
135 static const struct nvkm_disp_chan_func
136 r535_curs_func = {
137 .init = r535_curs_init,
138 .fini = r535_chan_fini,
139 .intr = r535_chan_intr,
140 .user = r535_chan_user,
141 };
142
143 static const struct nvkm_disp_chan_user
144 r535_curs = {
145 .func = &r535_curs_func,
146 .user = 73,
147 };
148
149 static int
r535_dmac_bind(struct nvkm_disp_chan * chan,struct nvkm_object * object,u32 handle)150 r535_dmac_bind(struct nvkm_disp_chan *chan, struct nvkm_object *object, u32 handle)
151 {
152 return nvkm_ramht_insert(chan->disp->ramht, object, chan->chid.user, -9, handle,
153 chan->chid.user << 25 |
154 (chan->disp->rm.client.object.handle & 0x3fff));
155 }
156
157 static void
r535_dmac_fini(struct nvkm_disp_chan * chan)158 r535_dmac_fini(struct nvkm_disp_chan *chan)
159 {
160 struct nvkm_device *device = chan->disp->engine.subdev.device;
161 const u32 uoff = (chan->chid.user - 1) * 0x1000;
162
163 chan->suspend_put = nvkm_rd32(device, 0x690000 + uoff);
164 r535_chan_fini(chan);
165 }
166
167 static int
r535_dmac_alloc(struct nvkm_disp * disp,u32 oclass,int inst,u32 put_offset,struct nvkm_gsp_object * dmac)168 r535_dmac_alloc(struct nvkm_disp *disp, u32 oclass, int inst, u32 put_offset,
169 struct nvkm_gsp_object *dmac)
170 {
171 NV50VAIO_CHANNELDMA_ALLOCATION_PARAMETERS *args;
172
173 args = nvkm_gsp_rm_alloc_get(&disp->rm.object, (oclass << 16) | inst, oclass,
174 sizeof(*args), dmac);
175 if (IS_ERR(args))
176 return PTR_ERR(args);
177
178 args->channelInstance = inst;
179 args->offset = put_offset;
180
181 return nvkm_gsp_rm_alloc_wr(dmac, args);
182 }
183
184 static int
r535_dmac_init(struct nvkm_disp_chan * chan)185 r535_dmac_init(struct nvkm_disp_chan *chan)
186 {
187 const struct nvkm_rm_api *rmapi = chan->disp->rm.objcom.client->gsp->rm->api;
188 int ret;
189
190 ret = rmapi->disp->chan.set_pushbuf(chan->disp, chan->object.oclass, chan->head, chan->memory);
191 if (ret)
192 return ret;
193
194 return rmapi->disp->chan.dmac_alloc(chan->disp, chan->object.oclass, chan->head,
195 chan->suspend_put, &chan->rm.object);
196 }
197
198 static int
r535_dmac_push(struct nvkm_disp_chan * chan,u64 memory)199 r535_dmac_push(struct nvkm_disp_chan *chan, u64 memory)
200 {
201 chan->memory = nvkm_umem_search(chan->object.client, memory);
202 if (IS_ERR(chan->memory))
203 return PTR_ERR(chan->memory);
204
205 return 0;
206 }
207
208 static const struct nvkm_disp_chan_func
209 r535_dmac_func = {
210 .push = r535_dmac_push,
211 .init = r535_dmac_init,
212 .fini = r535_dmac_fini,
213 .intr = r535_chan_intr,
214 .user = r535_chan_user,
215 .bind = r535_dmac_bind,
216 };
217
218 static const struct nvkm_disp_chan_func
219 r535_wimm_func = {
220 .push = r535_dmac_push,
221 .init = r535_dmac_init,
222 .fini = r535_dmac_fini,
223 .intr = r535_chan_intr,
224 .user = r535_chan_user,
225 };
226
227 static const struct nvkm_disp_chan_user
228 r535_wimm = {
229 .func = &r535_wimm_func,
230 .user = 33,
231 };
232
233 static const struct nvkm_disp_chan_user
234 r535_wndw = {
235 .func = &r535_dmac_func,
236 .user = 1,
237 };
238
239 static void
r535_core_fini(struct nvkm_disp_chan * chan)240 r535_core_fini(struct nvkm_disp_chan *chan)
241 {
242 struct nvkm_device *device = chan->disp->engine.subdev.device;
243
244 chan->suspend_put = nvkm_rd32(device, 0x680000);
245 r535_chan_fini(chan);
246 }
247
248 static const struct nvkm_disp_chan_func
249 r535_core_func = {
250 .push = r535_dmac_push,
251 .init = r535_dmac_init,
252 .fini = r535_core_fini,
253 .intr = r535_chan_intr,
254 .user = r535_chan_user,
255 .bind = r535_dmac_bind,
256 };
257
258 static const struct nvkm_disp_chan_user
259 r535_core = {
260 .func = &r535_core_func,
261 .user = 0,
262 };
263
264 static int
r535_bl_ctrl(struct nvkm_disp * disp,unsigned display_id,bool set,int * pval)265 r535_bl_ctrl(struct nvkm_disp *disp, unsigned display_id, bool set, int *pval)
266 {
267 u32 cmd = set ? NV0073_CTRL_CMD_SPECIFIC_SET_BACKLIGHT_BRIGHTNESS :
268 NV0073_CTRL_CMD_SPECIFIC_GET_BACKLIGHT_BRIGHTNESS;
269 NV0073_CTRL_SPECIFIC_BACKLIGHT_BRIGHTNESS_PARAMS *ctrl;
270 int ret;
271
272 ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, cmd, sizeof(*ctrl));
273 if (IS_ERR(ctrl))
274 return PTR_ERR(ctrl);
275
276 ctrl->displayId = BIT(display_id);
277 ctrl->brightness = *pval;
278
279 ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl));
280 if (ret)
281 return ret;
282
283 *pval = ctrl->brightness;
284
285 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
286 return 0;
287 }
288
289 static int
r535_sor_bl_set(struct nvkm_ior * sor,int lvl)290 r535_sor_bl_set(struct nvkm_ior *sor, int lvl)
291 {
292 struct nvkm_disp *disp = sor->disp;
293 const struct nvkm_rm_api *rmapi = disp->engine.subdev.device->gsp->rm->api;
294
295 return rmapi->disp->bl_ctrl(disp, sor->asy.outp->index, true, &lvl);
296 }
297
298 static int
r535_sor_bl_get(struct nvkm_ior * sor)299 r535_sor_bl_get(struct nvkm_ior *sor)
300 {
301 struct nvkm_disp *disp = sor->disp;
302 const struct nvkm_rm_api *rmapi = disp->engine.subdev.device->gsp->rm->api;
303 int lvl, ret = rmapi->disp->bl_ctrl(disp, sor->asy.outp->index, false, &lvl);
304
305 return (ret == 0) ? lvl : ret;
306 }
307
308 static const struct nvkm_ior_func_bl
309 r535_sor_bl = {
310 .get = r535_sor_bl_get,
311 .set = r535_sor_bl_set,
312 };
313
314 static void
r535_sor_hda_eld(struct nvkm_ior * sor,int head,u8 * data,u8 size)315 r535_sor_hda_eld(struct nvkm_ior *sor, int head, u8 *data, u8 size)
316 {
317 struct nvkm_disp *disp = sor->disp;
318 NV0073_CTRL_DFP_SET_ELD_AUDIO_CAP_PARAMS *ctrl;
319
320 if (WARN_ON(size > sizeof(ctrl->bufferELD)))
321 return;
322
323 ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom,
324 NV0073_CTRL_CMD_DFP_SET_ELD_AUDIO_CAPS, sizeof(*ctrl));
325 if (WARN_ON(IS_ERR(ctrl)))
326 return;
327
328 ctrl->displayId = BIT(sor->asy.outp->index);
329 ctrl->numELDSize = size;
330 memcpy(ctrl->bufferELD, data, size);
331 ctrl->maxFreqSupported = 0; //XXX
332 ctrl->ctrl = NVDEF(NV0073, CTRL_DFP_ELD_AUDIO_CAPS_CTRL, PD, TRUE);
333 ctrl->ctrl |= NVDEF(NV0073, CTRL_DFP_ELD_AUDIO_CAPS_CTRL, ELDV, TRUE);
334 ctrl->deviceEntry = head;
335
336 WARN_ON(nvkm_gsp_rm_ctrl_wr(&disp->rm.objcom, ctrl));
337 }
338
339 static void
r535_sor_hda_hpd(struct nvkm_ior * sor,int head,bool present)340 r535_sor_hda_hpd(struct nvkm_ior *sor, int head, bool present)
341 {
342 struct nvkm_disp *disp = sor->disp;
343 NV0073_CTRL_DFP_SET_ELD_AUDIO_CAP_PARAMS *ctrl;
344
345 if (present)
346 return;
347
348 ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom,
349 NV0073_CTRL_CMD_DFP_SET_ELD_AUDIO_CAPS, sizeof(*ctrl));
350 if (WARN_ON(IS_ERR(ctrl)))
351 return;
352
353 ctrl->displayId = BIT(sor->asy.outp->index);
354 ctrl->deviceEntry = head;
355
356 WARN_ON(nvkm_gsp_rm_ctrl_wr(&disp->rm.objcom, ctrl));
357 }
358
359 static const struct nvkm_ior_func_hda
360 r535_sor_hda = {
361 .hpd = r535_sor_hda_hpd,
362 .eld = r535_sor_hda_eld,
363 };
364
365 static void
r535_sor_dp_audio_mute(struct nvkm_ior * sor,bool mute)366 r535_sor_dp_audio_mute(struct nvkm_ior *sor, bool mute)
367 {
368 struct nvkm_disp *disp = sor->disp;
369 NV0073_CTRL_DP_SET_AUDIO_MUTESTREAM_PARAMS *ctrl;
370
371 ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom,
372 NV0073_CTRL_CMD_DP_SET_AUDIO_MUTESTREAM, sizeof(*ctrl));
373 if (WARN_ON(IS_ERR(ctrl)))
374 return;
375
376 ctrl->displayId = BIT(sor->asy.outp->index);
377 ctrl->mute = mute;
378 WARN_ON(nvkm_gsp_rm_ctrl_wr(&disp->rm.objcom, ctrl));
379 }
380
381 static void
r535_sor_dp_audio(struct nvkm_ior * sor,int head,bool enable)382 r535_sor_dp_audio(struct nvkm_ior *sor, int head, bool enable)
383 {
384 struct nvkm_disp *disp = sor->disp;
385 NV0073_CTRL_DFP_SET_AUDIO_ENABLE_PARAMS *ctrl;
386
387 if (!enable)
388 r535_sor_dp_audio_mute(sor, true);
389
390 ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom,
391 NV0073_CTRL_CMD_DFP_SET_AUDIO_ENABLE, sizeof(*ctrl));
392 if (WARN_ON(IS_ERR(ctrl)))
393 return;
394
395 ctrl->displayId = BIT(sor->asy.outp->index);
396 ctrl->enable = enable;
397 WARN_ON(nvkm_gsp_rm_ctrl_wr(&disp->rm.objcom, ctrl));
398
399 if (enable)
400 r535_sor_dp_audio_mute(sor, false);
401 }
402
403 static int
r535_dp_vcpi(struct nvkm_ior * sor,int head,u8 slot,u8 slot_nr,u16 pbn,u16 aligned_pbn)404 r535_dp_vcpi(struct nvkm_ior *sor, int head, u8 slot, u8 slot_nr, u16 pbn, u16 aligned_pbn)
405 {
406 struct nvkm_disp *disp = sor->disp;
407 struct NV0073_CTRL_CMD_DP_CONFIG_STREAM_PARAMS *ctrl;
408
409 ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom,
410 NV0073_CTRL_CMD_DP_CONFIG_STREAM, sizeof(*ctrl));
411 if (IS_ERR(ctrl))
412 return PTR_ERR(ctrl);
413
414 ctrl->subDeviceInstance = 0;
415 ctrl->head = head;
416 ctrl->sorIndex = sor->id;
417 ctrl->dpLink = sor->asy.link == 2;
418 ctrl->bEnableOverride = 1;
419 ctrl->bMST = 1;
420 ctrl->hBlankSym = 0;
421 ctrl->vBlankSym = 0;
422 ctrl->colorFormat = 0;
423 ctrl->bEnableTwoHeadOneOr = 0;
424 ctrl->singleHeadMultistreamMode = 0;
425 ctrl->MST.slotStart = slot;
426 ctrl->MST.slotEnd = slot + slot_nr - 1;
427 ctrl->MST.PBN = pbn;
428 ctrl->MST.Timeslice = aligned_pbn;
429 ctrl->MST.sendACT = 0;
430 ctrl->MST.singleHeadMSTPipeline = 0;
431 ctrl->MST.bEnableAudioOverRightPanel = 0;
432 return nvkm_gsp_rm_ctrl_wr(&disp->rm.objcom, ctrl);
433 }
434
435 static void
r535_sor_dp_vcpi(struct nvkm_ior * sor,int head,u8 slot,u8 slot_nr,u16 pbn,u16 aligned_pbn)436 r535_sor_dp_vcpi(struct nvkm_ior *sor, int head, u8 slot, u8 slot_nr, u16 pbn, u16 aligned_pbn)
437 {
438 const struct nvkm_rm_api *rmapi = sor->disp->engine.subdev.device->gsp->rm->api;
439
440 WARN_ON(rmapi->disp->dp.vcpi(sor, head, slot, slot_nr, pbn, aligned_pbn));
441 }
442
443 static int
r535_dp_sst(struct nvkm_ior * sor,int head,bool ef,u32 watermark,u32 hblanksym,u32 vblanksym)444 r535_dp_sst(struct nvkm_ior *sor, int head, bool ef,
445 u32 watermark, u32 hblanksym, u32 vblanksym)
446 {
447 struct nvkm_disp *disp = sor->disp;
448 struct NV0073_CTRL_CMD_DP_CONFIG_STREAM_PARAMS *ctrl;
449
450 ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom,
451 NV0073_CTRL_CMD_DP_CONFIG_STREAM, sizeof(*ctrl));
452 if (IS_ERR(ctrl))
453 return PTR_ERR(ctrl);
454
455 ctrl->subDeviceInstance = 0;
456 ctrl->head = head;
457 ctrl->sorIndex = sor->id;
458 ctrl->dpLink = sor->asy.link == 2;
459 ctrl->bEnableOverride = 1;
460 ctrl->bMST = 0;
461 ctrl->hBlankSym = hblanksym;
462 ctrl->vBlankSym = vblanksym;
463 ctrl->colorFormat = 0;
464 ctrl->bEnableTwoHeadOneOr = 0;
465 ctrl->SST.bEnhancedFraming = ef;
466 ctrl->SST.tuSize = 64;
467 ctrl->SST.waterMark = watermark;
468 ctrl->SST.bEnableAudioOverRightPanel = 0;
469 return nvkm_gsp_rm_ctrl_wr(&disp->rm.objcom, ctrl);
470 }
471
472 static int
r535_sor_dp_sst(struct nvkm_ior * sor,int head,bool ef,u32 watermark,u32 hblanksym,u32 vblanksym)473 r535_sor_dp_sst(struct nvkm_ior *sor, int head, bool ef,
474 u32 watermark, u32 hblanksym, u32 vblanksym)
475 {
476 const struct nvkm_rm_api *rmapi = sor->disp->engine.subdev.device->gsp->rm->api;
477
478 return rmapi->disp->dp.sst(sor, head, ef, watermark, hblanksym, vblanksym);
479 }
480
481 static const struct nvkm_ior_func_dp
482 r535_sor_dp = {
483 .sst = r535_sor_dp_sst,
484 .vcpi = r535_sor_dp_vcpi,
485 .audio = r535_sor_dp_audio,
486 };
487
488 static void
r535_sor_hdmi_scdc(struct nvkm_ior * sor,u32 khz,bool support,bool scrambling,bool scrambling_low_rates)489 r535_sor_hdmi_scdc(struct nvkm_ior *sor, u32 khz, bool support, bool scrambling,
490 bool scrambling_low_rates)
491 {
492 struct nvkm_outp *outp = sor->asy.outp;
493 struct nvkm_disp *disp = outp->disp;
494 NV0073_CTRL_SPECIFIC_SET_HDMI_SINK_CAPS_PARAMS *ctrl;
495
496 ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom,
497 NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS, sizeof(*ctrl));
498 if (WARN_ON(IS_ERR(ctrl)))
499 return;
500
501 ctrl->displayId = BIT(outp->index);
502 ctrl->caps = 0;
503 if (support)
504 ctrl->caps |= NVDEF(NV0073_CTRL_CMD_SPECIFIC, SET_HDMI_SINK_CAPS, SCDC_SUPPORTED, TRUE);
505 if (scrambling)
506 ctrl->caps |= NVDEF(NV0073_CTRL_CMD_SPECIFIC, SET_HDMI_SINK_CAPS, GT_340MHZ_CLOCK_SUPPORTED, TRUE);
507 if (scrambling_low_rates)
508 ctrl->caps |= NVDEF(NV0073_CTRL_CMD_SPECIFIC, SET_HDMI_SINK_CAPS, LTE_340MHZ_SCRAMBLING_SUPPORTED, TRUE);
509
510 WARN_ON(nvkm_gsp_rm_ctrl_wr(&disp->rm.objcom, ctrl));
511 }
512
513 static void
r535_sor_hdmi_ctrl_audio_mute(struct nvkm_outp * outp,bool mute)514 r535_sor_hdmi_ctrl_audio_mute(struct nvkm_outp *outp, bool mute)
515 {
516 struct nvkm_disp *disp = outp->disp;
517 NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_AUDIO_MUTESTREAM_PARAMS *ctrl;
518
519 ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom,
520 NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_AUDIO_MUTESTREAM, sizeof(*ctrl));
521 if (WARN_ON(IS_ERR(ctrl)))
522 return;
523
524 ctrl->displayId = BIT(outp->index);
525 ctrl->mute = mute;
526 WARN_ON(nvkm_gsp_rm_ctrl_wr(&disp->rm.objcom, ctrl));
527 }
528
529 static void
r535_sor_hdmi_ctrl_audio(struct nvkm_outp * outp,bool enable)530 r535_sor_hdmi_ctrl_audio(struct nvkm_outp *outp, bool enable)
531 {
532 struct nvkm_disp *disp = outp->disp;
533 NV0073_CTRL_SPECIFIC_SET_OD_PACKET_PARAMS *ctrl;
534
535 ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom,
536 NV0073_CTRL_CMD_SPECIFIC_SET_OD_PACKET, sizeof(*ctrl));
537 if (WARN_ON(IS_ERR(ctrl)))
538 return;
539
540 ctrl->displayId = BIT(outp->index);
541 ctrl->transmitControl =
542 NVDEF(NV0073_CTRL_SPECIFIC, SET_OD_PACKET_TRANSMIT_CONTROL, ENABLE, YES) |
543 NVDEF(NV0073_CTRL_SPECIFIC, SET_OD_PACKET_TRANSMIT_CONTROL, OTHER_FRAME, DISABLE) |
544 NVDEF(NV0073_CTRL_SPECIFIC, SET_OD_PACKET_TRANSMIT_CONTROL, SINGLE_FRAME, DISABLE) |
545 NVDEF(NV0073_CTRL_SPECIFIC, SET_OD_PACKET_TRANSMIT_CONTROL, ON_HBLANK, DISABLE) |
546 NVDEF(NV0073_CTRL_SPECIFIC, SET_OD_PACKET_TRANSMIT_CONTROL, VIDEO_FMT, SW_CONTROLLED) |
547 NVDEF(NV0073_CTRL_SPECIFIC, SET_OD_PACKET_TRANSMIT_CONTROL, RESERVED_LEGACY_MODE, NO);
548 ctrl->packetSize = 10;
549 ctrl->aPacket[0] = 0x03;
550 ctrl->aPacket[1] = 0x00;
551 ctrl->aPacket[2] = 0x00;
552 ctrl->aPacket[3] = enable ? 0x10 : 0x01;
553 ctrl->aPacket[4] = 0x00;
554 ctrl->aPacket[5] = 0x00;
555 ctrl->aPacket[6] = 0x00;
556 ctrl->aPacket[7] = 0x00;
557 ctrl->aPacket[8] = 0x00;
558 ctrl->aPacket[9] = 0x00;
559 WARN_ON(nvkm_gsp_rm_ctrl_wr(&disp->rm.objcom, ctrl));
560 }
561
562 static void
r535_sor_hdmi_audio(struct nvkm_ior * sor,int head,bool enable)563 r535_sor_hdmi_audio(struct nvkm_ior *sor, int head, bool enable)
564 {
565 r535_sor_hdmi_ctrl_audio(sor->asy.outp, enable);
566 r535_sor_hdmi_ctrl_audio_mute(sor->asy.outp, !enable);
567 sor->disp->func->gsp.hdmi_gcp(sor, head, enable);
568 }
569
570 static void
r535_sor_hdmi_infoframe_avi(struct nvkm_ior * sor,int head,void * data,u32 size)571 r535_sor_hdmi_infoframe_avi(struct nvkm_ior *sor, int head, void *data, u32 size)
572 {
573 sor->disp->func->gsp.hdmi_infoframe_avi(sor, head, data, size);
574 }
575
576 static void
r535_sor_hdmi_infoframe_vsi(struct nvkm_ior * sor,int head,void * data,u32 size)577 r535_sor_hdmi_infoframe_vsi(struct nvkm_ior *sor, int head, void *data, u32 size)
578 {
579 sor->disp->func->gsp.hdmi_infoframe_vsi(sor, head, data, size);
580 }
581
582 static void
r535_sor_hdmi_ctrl(struct nvkm_ior * sor,int head,bool enable,u8 max_ac_packet,u8 rekey)583 r535_sor_hdmi_ctrl(struct nvkm_ior *sor, int head, bool enable, u8 max_ac_packet, u8 rekey)
584 {
585 struct nvkm_disp *disp = sor->disp;
586 NV0073_CTRL_SPECIFIC_SET_HDMI_ENABLE_PARAMS *ctrl;
587
588 if (!enable)
589 return;
590
591 ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom,
592 NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_ENABLE, sizeof(*ctrl));
593 if (WARN_ON(IS_ERR(ctrl)))
594 return;
595
596 ctrl->displayId = BIT(sor->asy.outp->index);
597 ctrl->enable = enable;
598
599 WARN_ON(nvkm_gsp_rm_ctrl_wr(&disp->rm.objcom, ctrl));
600 }
601
602 static const struct nvkm_ior_func_hdmi
603 r535_sor_hdmi = {
604 .ctrl = r535_sor_hdmi_ctrl,
605 .scdc = r535_sor_hdmi_scdc,
606 /*TODO: SF_USER -> KMS. */
607 .infoframe_avi = r535_sor_hdmi_infoframe_avi,
608 .infoframe_vsi = r535_sor_hdmi_infoframe_vsi,
609 .audio = r535_sor_hdmi_audio,
610 };
611
612 static const struct nvkm_ior_func
613 r535_sor = {
614 .hdmi = &r535_sor_hdmi,
615 .dp = &r535_sor_dp,
616 .hda = &r535_sor_hda,
617 .bl = &r535_sor_bl,
618 };
619
620 static int
r535_sor_new(struct nvkm_disp * disp,int id)621 r535_sor_new(struct nvkm_disp *disp, int id)
622 {
623 return nvkm_ior_new_(&r535_sor, disp, SOR, id, true/*XXX: hda cap*/);
624 }
625
626 static int
r535_sor_cnt(struct nvkm_disp * disp,unsigned long * pmask)627 r535_sor_cnt(struct nvkm_disp *disp, unsigned long *pmask)
628 {
629 *pmask = 0xf;
630 return 4;
631 }
632
633 static struct nvkm_conn *
r535_conn_new(struct nvkm_disp * disp,u32 id)634 r535_conn_new(struct nvkm_disp *disp, u32 id)
635 {
636 NV0073_CTRL_SPECIFIC_GET_CONNECTOR_DATA_PARAMS *ctrl;
637 struct nvbios_connE dcbE = {};
638 struct nvkm_conn *conn;
639 int ret, index;
640
641 ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom,
642 NV0073_CTRL_CMD_SPECIFIC_GET_CONNECTOR_DATA, sizeof(*ctrl));
643 if (IS_ERR(ctrl))
644 return ERR_CAST(ctrl);
645
646 ctrl->subDeviceInstance = 0;
647 ctrl->displayId = BIT(id);
648
649 ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl));
650 if (ret) {
651 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
652 return ERR_PTR(ret);
653 }
654
655 list_for_each_entry(conn, &disp->conns, head) {
656 if (conn->index == ctrl->data[0].index) {
657 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
658 return conn;
659 }
660 }
661
662 dcbE.type = ctrl->data[0].type;
663 index = ctrl->data[0].index;
664 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
665
666 ret = nvkm_conn_new(disp, index, &dcbE, &conn);
667 if (ret)
668 return ERR_PTR(ret);
669
670 list_add_tail(&conn->head, &disp->conns);
671 return conn;
672 }
673
674 static void
r535_outp_release(struct nvkm_outp * outp)675 r535_outp_release(struct nvkm_outp *outp)
676 {
677 outp->disp->rm.assigned_sors &= ~BIT(outp->ior->id);
678 outp->ior->asy.outp = NULL;
679 outp->ior = NULL;
680 }
681
682 static int
r535_outp_acquire(struct nvkm_outp * outp,bool hda)683 r535_outp_acquire(struct nvkm_outp *outp, bool hda)
684 {
685 struct nvkm_disp *disp = outp->disp;
686 struct nvkm_ior *ior;
687 NV0073_CTRL_DFP_ASSIGN_SOR_PARAMS *ctrl;
688 int ret, or;
689
690 ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom,
691 NV0073_CTRL_CMD_DFP_ASSIGN_SOR, sizeof(*ctrl));
692 if (IS_ERR(ctrl))
693 return PTR_ERR(ctrl);
694
695 ctrl->subDeviceInstance = 0;
696 ctrl->displayId = BIT(outp->index);
697 ctrl->sorExcludeMask = disp->rm.assigned_sors;
698 if (hda)
699 ctrl->flags |= NVDEF(NV0073_CTRL, DFP_ASSIGN_SOR_FLAGS, AUDIO, OPTIMAL);
700
701 ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl));
702 if (ret) {
703 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
704 return ret;
705 }
706
707 for (or = 0; or < ARRAY_SIZE(ctrl->sorAssignListWithTag); or++) {
708 if (ctrl->sorAssignListWithTag[or].displayMask & BIT(outp->index)) {
709 disp->rm.assigned_sors |= BIT(or);
710 break;
711 }
712 }
713
714 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
715
716 if (WARN_ON(or == ARRAY_SIZE(ctrl->sorAssignListWithTag)))
717 return -EINVAL;
718
719 ior = nvkm_ior_find(disp, SOR, or);
720 if (WARN_ON(!ior))
721 return -EINVAL;
722
723 nvkm_outp_acquire_ior(outp, NVKM_OUTP_USER, ior);
724 return 0;
725 }
726
727 static int
r535_disp_get_active(struct nvkm_disp * disp,unsigned head,u32 * displayid)728 r535_disp_get_active(struct nvkm_disp *disp, unsigned head, u32 *displayid)
729 {
730 NV0073_CTRL_SYSTEM_GET_ACTIVE_PARAMS *ctrl;
731 int ret;
732
733 ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom,
734 NV0073_CTRL_CMD_SYSTEM_GET_ACTIVE, sizeof(*ctrl));
735 if (IS_ERR(ctrl))
736 return PTR_ERR(ctrl);
737
738 ctrl->subDeviceInstance = 0;
739 ctrl->head = head;
740
741 ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl));
742 if (ret) {
743 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
744 return ret;
745 }
746
747 *displayid = ctrl->displayId;
748 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
749 return 0;
750 }
751
752 static struct nvkm_ior *
r535_outp_inherit(struct nvkm_outp * outp)753 r535_outp_inherit(struct nvkm_outp *outp)
754 {
755 struct nvkm_disp *disp = outp->disp;
756 struct nvkm_head *head;
757 u32 displayid;
758 int ret;
759
760 list_for_each_entry(head, &disp->heads, head) {
761 const struct nvkm_rm_api *rmapi = disp->rm.objcom.client->gsp->rm->api;
762
763 ret = rmapi->disp->get_active(disp, head->id, &displayid);
764 if (WARN_ON(ret))
765 return NULL;
766
767 if (displayid == BIT(outp->index)) {
768 NV0073_CTRL_SPECIFIC_OR_GET_INFO_PARAMS *ctrl;
769 u32 id, proto;
770 struct nvkm_ior *ior;
771
772 ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom,
773 NV0073_CTRL_CMD_SPECIFIC_OR_GET_INFO,
774 sizeof(*ctrl));
775 if (IS_ERR(ctrl))
776 return NULL;
777
778 ctrl->subDeviceInstance = 0;
779 ctrl->displayId = displayid;
780
781 ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl));
782 if (ret) {
783 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
784 return NULL;
785 }
786
787 id = ctrl->index;
788 proto = ctrl->protocol;
789 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
790
791 ior = nvkm_ior_find(disp, SOR, id);
792 if (WARN_ON(!ior))
793 return NULL;
794
795 switch (proto) {
796 case NV0073_CTRL_SPECIFIC_OR_PROTOCOL_SOR_SINGLE_TMDS_A:
797 ior->arm.proto = TMDS;
798 ior->arm.link = 1;
799 break;
800 case NV0073_CTRL_SPECIFIC_OR_PROTOCOL_SOR_SINGLE_TMDS_B:
801 ior->arm.proto = TMDS;
802 ior->arm.link = 2;
803 break;
804 case NV0073_CTRL_SPECIFIC_OR_PROTOCOL_SOR_DUAL_TMDS:
805 ior->arm.proto = TMDS;
806 ior->arm.link = 3;
807 break;
808 case NV0073_CTRL_SPECIFIC_OR_PROTOCOL_SOR_DP_A:
809 ior->arm.proto = DP;
810 ior->arm.link = 1;
811 break;
812 case NV0073_CTRL_SPECIFIC_OR_PROTOCOL_SOR_DP_B:
813 ior->arm.proto = DP;
814 ior->arm.link = 2;
815 break;
816 default:
817 WARN_ON(1);
818 return NULL;
819 }
820
821 ior->arm.proto_evo = proto;
822 ior->arm.head = BIT(head->id);
823 disp->rm.assigned_sors |= BIT(ior->id);
824 return ior;
825 }
826 }
827
828 return NULL;
829 }
830
831 static int
r535_outp_dfp_get_info(struct nvkm_outp * outp)832 r535_outp_dfp_get_info(struct nvkm_outp *outp)
833 {
834 NV0073_CTRL_DFP_GET_INFO_PARAMS *ctrl;
835 struct nvkm_disp *disp = outp->disp;
836 int ret;
837
838 ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, NV0073_CTRL_CMD_DFP_GET_INFO, sizeof(*ctrl));
839 if (IS_ERR(ctrl))
840 return PTR_ERR(ctrl);
841
842 ctrl->displayId = BIT(outp->index);
843
844 ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl));
845 if (ret) {
846 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
847 return ret;
848 }
849
850 nvkm_debug(&disp->engine.subdev, "DFP %08x: flags:%08x flags2:%08x\n",
851 ctrl->displayId, ctrl->flags, ctrl->flags2);
852
853 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
854 return 0;
855 }
856
857 static int
r535_disp_get_connect_state(struct nvkm_disp * disp,unsigned display_id)858 r535_disp_get_connect_state(struct nvkm_disp *disp, unsigned display_id)
859 {
860 NV0073_CTRL_SYSTEM_GET_CONNECT_STATE_PARAMS *ctrl;
861 int ret;
862
863 ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom,
864 NV0073_CTRL_CMD_SYSTEM_GET_CONNECT_STATE, sizeof(*ctrl));
865 if (IS_ERR(ctrl))
866 return PTR_ERR(ctrl);
867
868 ctrl->subDeviceInstance = 0;
869 ctrl->displayMask = BIT(display_id);
870
871 ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl));
872 if (ret == 0 && (ctrl->displayMask & BIT(display_id)))
873 ret = 1;
874
875 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
876 return ret;
877 }
878
879 static int
r535_outp_detect(struct nvkm_outp * outp)880 r535_outp_detect(struct nvkm_outp *outp)
881 {
882 const struct nvkm_rm_api *rmapi = outp->disp->rm.objcom.client->gsp->rm->api;
883 int ret;
884
885 ret = rmapi->disp->get_connect_state(outp->disp, outp->index);
886 if (ret == 1) {
887 ret = r535_outp_dfp_get_info(outp);
888 if (ret == 0)
889 ret = 1;
890 }
891
892 return ret;
893 }
894
895 static int
r535_dp_mst_id_put(struct nvkm_outp * outp,u32 id)896 r535_dp_mst_id_put(struct nvkm_outp *outp, u32 id)
897 {
898 NV0073_CTRL_CMD_DP_TOPOLOGY_FREE_DISPLAYID_PARAMS *ctrl;
899 struct nvkm_disp *disp = outp->disp;
900
901 ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom,
902 NV0073_CTRL_CMD_DP_TOPOLOGY_FREE_DISPLAYID, sizeof(*ctrl));
903 if (IS_ERR(ctrl))
904 return PTR_ERR(ctrl);
905
906 ctrl->subDeviceInstance = 0;
907 ctrl->displayId = id;
908 return nvkm_gsp_rm_ctrl_wr(&disp->rm.objcom, ctrl);
909 }
910
911 static int
r535_dp_mst_id_get(struct nvkm_outp * outp,u32 * pid)912 r535_dp_mst_id_get(struct nvkm_outp *outp, u32 *pid)
913 {
914 NV0073_CTRL_CMD_DP_TOPOLOGY_ALLOCATE_DISPLAYID_PARAMS *ctrl;
915 struct nvkm_disp *disp = outp->disp;
916 int ret;
917
918 ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom,
919 NV0073_CTRL_CMD_DP_TOPOLOGY_ALLOCATE_DISPLAYID,
920 sizeof(*ctrl));
921 if (IS_ERR(ctrl))
922 return PTR_ERR(ctrl);
923
924 ctrl->subDeviceInstance = 0;
925 ctrl->displayId = BIT(outp->index);
926 ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl));
927 if (ret) {
928 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
929 return ret;
930 }
931
932 *pid = ctrl->displayIdAssigned;
933 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
934 return 0;
935 }
936
937 static int
r535_dp_drive(struct nvkm_outp * outp,u8 lanes,u8 pe[4],u8 vs[4])938 r535_dp_drive(struct nvkm_outp *outp, u8 lanes, u8 pe[4], u8 vs[4])
939 {
940 NV0073_CTRL_DP_LANE_DATA_PARAMS *ctrl;
941 struct nvkm_disp *disp = outp->disp;
942
943 ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom,
944 NV0073_CTRL_CMD_DP_SET_LANE_DATA, sizeof(*ctrl));
945 if (IS_ERR(ctrl))
946 return PTR_ERR(ctrl);
947
948 ctrl->displayId = BIT(outp->index);
949 ctrl->numLanes = lanes;
950 for (int i = 0; i < lanes; i++)
951 ctrl->data[i] = NVVAL(NV0073_CTRL, DP_LANE_DATA, PREEMPHASIS, pe[i]) |
952 NVVAL(NV0073_CTRL, DP_LANE_DATA, DRIVECURRENT, vs[i]);
953
954 return nvkm_gsp_rm_ctrl_wr(&disp->rm.objcom, ctrl);
955 }
956
957 static int
r535_dp_train_target(struct nvkm_outp * outp,u8 target,bool mst,u8 link_nr,u8 link_bw)958 r535_dp_train_target(struct nvkm_outp *outp, u8 target, bool mst, u8 link_nr, u8 link_bw)
959 {
960 struct nvkm_disp *disp = outp->disp;
961 NV0073_CTRL_DP_CTRL_PARAMS *ctrl;
962 int ret, retries;
963 u32 cmd, data;
964
965 cmd = NVDEF(NV0073_CTRL, DP_CMD, SET_LANE_COUNT, TRUE) |
966 NVDEF(NV0073_CTRL, DP_CMD, SET_LINK_BW, TRUE) |
967 NVDEF(NV0073_CTRL, DP_CMD, TRAIN_PHY_REPEATER, YES);
968 data = NVVAL(NV0073_CTRL, DP_DATA, SET_LANE_COUNT, link_nr) |
969 NVVAL(NV0073_CTRL, DP_DATA, SET_LINK_BW, link_bw) |
970 NVVAL(NV0073_CTRL, DP_DATA, TARGET, target);
971
972 if (mst)
973 cmd |= NVDEF(NV0073_CTRL, DP_CMD, SET_FORMAT_MODE, MULTI_STREAM);
974
975 if (outp->dp.dpcd[DPCD_RC02] & DPCD_RC02_ENHANCED_FRAME_CAP)
976 cmd |= NVDEF(NV0073_CTRL, DP_CMD, SET_ENHANCED_FRAMING, TRUE);
977
978 if (target == 0 &&
979 (outp->dp.dpcd[DPCD_RC02] & 0x20) &&
980 !(outp->dp.dpcd[DPCD_RC03] & DPCD_RC03_TPS4_SUPPORTED))
981 cmd |= NVDEF(NV0073_CTRL, DP_CMD, POST_LT_ADJ_REQ_GRANTED, YES);
982
983 /* We should retry up to 3 times, but only if GSP asks politely */
984 for (retries = 0; retries < 3; ++retries) {
985 ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, NV0073_CTRL_CMD_DP_CTRL,
986 sizeof(*ctrl));
987 if (IS_ERR(ctrl))
988 return PTR_ERR(ctrl);
989
990 ctrl->subDeviceInstance = 0;
991 ctrl->displayId = BIT(outp->index);
992 ctrl->retryTimeMs = 0;
993 ctrl->cmd = cmd;
994 ctrl->data = data;
995
996 ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl));
997 if ((ret == -EAGAIN || ret == -EBUSY) && ctrl->retryTimeMs) {
998 /*
999 * Device (likely an eDP panel) isn't ready yet, wait for the time specified
1000 * by GSP before retrying again
1001 */
1002 nvkm_debug(&disp->engine.subdev,
1003 "Waiting %dms for GSP LT panel delay before retrying\n",
1004 ctrl->retryTimeMs);
1005 msleep(ctrl->retryTimeMs);
1006 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
1007 } else {
1008 /* GSP didn't say to retry, or we were successful */
1009 if (ctrl->err)
1010 ret = -EIO;
1011 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
1012 break;
1013 }
1014 }
1015
1016 return ret;
1017 }
1018
1019 static int
r535_dp_train(struct nvkm_outp * outp,bool retrain)1020 r535_dp_train(struct nvkm_outp *outp, bool retrain)
1021 {
1022 for (int target = outp->dp.lttprs; target >= 0; target--) {
1023 int ret = r535_dp_train_target(outp, target, outp->dp.lt.mst,
1024 outp->dp.lt.nr,
1025 outp->dp.lt.bw);
1026 if (ret)
1027 return ret;
1028 }
1029
1030 return 0;
1031 }
1032
1033 static int
r535_dp_set_indexed_link_rates(struct nvkm_outp * outp)1034 r535_dp_set_indexed_link_rates(struct nvkm_outp *outp)
1035 {
1036 NV0073_CTRL_CMD_DP_CONFIG_INDEXED_LINK_RATES_PARAMS *ctrl;
1037 struct nvkm_disp *disp = outp->disp;
1038
1039 if (WARN_ON(outp->dp.rates > ARRAY_SIZE(ctrl->linkRateTbl)))
1040 return -EINVAL;
1041
1042 ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom,
1043 NV0073_CTRL_CMD_DP_CONFIG_INDEXED_LINK_RATES, sizeof(*ctrl));
1044 if (IS_ERR(ctrl))
1045 return PTR_ERR(ctrl);
1046
1047 ctrl->displayId = BIT(outp->index);
1048 for (int i = 0; i < outp->dp.rates; i++)
1049 ctrl->linkRateTbl[outp->dp.rate[i].dpcd] = outp->dp.rate[i].rate * 10 / 200;
1050
1051 return nvkm_gsp_rm_ctrl_wr(&disp->rm.objcom, ctrl);
1052 }
1053
1054 static int
r535_dp_rates(struct nvkm_outp * outp)1055 r535_dp_rates(struct nvkm_outp *outp)
1056 {
1057 struct nvkm_rm *rm = outp->disp->rm.objcom.client->gsp->rm;
1058
1059 if (outp->conn->info.type != DCB_CONNECTOR_eDP ||
1060 !outp->dp.rates || outp->dp.rate[0].dpcd < 0)
1061 return 0;
1062
1063 return rm->api->disp->dp.set_indexed_link_rates(outp);
1064 }
1065
1066 static int
r535_dp_aux_xfer(struct nvkm_outp * outp,u8 type,u32 addr,u8 * data,u8 * psize)1067 r535_dp_aux_xfer(struct nvkm_outp *outp, u8 type, u32 addr, u8 *data, u8 *psize)
1068 {
1069 struct nvkm_disp *disp = outp->disp;
1070 NV0073_CTRL_DP_AUXCH_CTRL_PARAMS *ctrl;
1071 u8 size = *psize;
1072 int ret;
1073 int retries;
1074
1075 for (retries = 0; retries < 3; ++retries) {
1076 ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, NV0073_CTRL_CMD_DP_AUXCH_CTRL, sizeof(*ctrl));
1077 if (IS_ERR(ctrl))
1078 return PTR_ERR(ctrl);
1079
1080 ctrl->subDeviceInstance = 0;
1081 ctrl->displayId = BIT(outp->index);
1082 ctrl->bAddrOnly = !size;
1083 ctrl->cmd = type;
1084 if (ctrl->bAddrOnly) {
1085 ctrl->cmd = NVDEF_SET(ctrl->cmd, NV0073_CTRL, DP_AUXCH_CMD, REQ_TYPE, WRITE);
1086 ctrl->cmd = NVDEF_SET(ctrl->cmd, NV0073_CTRL, DP_AUXCH_CMD, I2C_MOT, FALSE);
1087 }
1088 ctrl->addr = addr;
1089 ctrl->size = !ctrl->bAddrOnly ? (size - 1) : 0;
1090 memcpy(ctrl->data, data, size);
1091
1092 ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl));
1093 if ((ret == -EAGAIN || ret == -EBUSY) && ctrl->retryTimeMs) {
1094 /*
1095 * Device (likely an eDP panel) isn't ready yet, wait for the time specified
1096 * by GSP before retrying again
1097 */
1098 nvkm_debug(&disp->engine.subdev,
1099 "Waiting %dms for GSP LT panel delay before retrying in AUX\n",
1100 ctrl->retryTimeMs);
1101 msleep(ctrl->retryTimeMs);
1102 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
1103 } else {
1104 memcpy(data, ctrl->data, size);
1105 *psize = ctrl->size;
1106 ret = ctrl->replyType;
1107 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
1108 break;
1109 }
1110 }
1111 return ret;
1112 }
1113
1114 static int
r535_dp_aux_pwr(struct nvkm_outp * outp,bool pu)1115 r535_dp_aux_pwr(struct nvkm_outp *outp, bool pu)
1116 {
1117 return 0;
1118 }
1119
1120 static void
r535_dp_release(struct nvkm_outp * outp)1121 r535_dp_release(struct nvkm_outp *outp)
1122 {
1123 if (!outp->dp.lt.bw) {
1124 if (!WARN_ON(!outp->dp.rates))
1125 outp->dp.lt.bw = outp->dp.rate[0].rate / 27000;
1126 else
1127 outp->dp.lt.bw = 0x06;
1128 }
1129
1130 outp->dp.lt.nr = 0;
1131
1132 r535_dp_train_target(outp, 0, outp->dp.lt.mst, outp->dp.lt.nr, outp->dp.lt.bw);
1133 r535_outp_release(outp);
1134 }
1135
1136 static int
r535_dp_acquire(struct nvkm_outp * outp,bool hda)1137 r535_dp_acquire(struct nvkm_outp *outp, bool hda)
1138 {
1139 int ret;
1140
1141 ret = r535_outp_acquire(outp, hda);
1142 if (ret)
1143 return ret;
1144
1145 return 0;
1146 }
1147
1148 static const struct nvkm_outp_func
1149 r535_dp = {
1150 .detect = r535_outp_detect,
1151 .inherit = r535_outp_inherit,
1152 .acquire = r535_dp_acquire,
1153 .release = r535_dp_release,
1154 .dp.aux_pwr = r535_dp_aux_pwr,
1155 .dp.aux_xfer = r535_dp_aux_xfer,
1156 .dp.mst_id_get = r535_dp_mst_id_get,
1157 .dp.mst_id_put = r535_dp_mst_id_put,
1158 .dp.rates = r535_dp_rates,
1159 .dp.train = r535_dp_train,
1160 .dp.drive = r535_dp_drive,
1161 };
1162
1163 static int
r535_dp_get_caps(struct nvkm_disp * disp,int * plink_bw,bool * pmst,bool * pwm)1164 r535_dp_get_caps(struct nvkm_disp *disp, int *plink_bw, bool *pmst, bool *pwm)
1165 {
1166 NV0073_CTRL_CMD_DP_GET_CAPS_PARAMS *ctrl;
1167 int ret;
1168
1169 ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom,
1170 NV0073_CTRL_CMD_DP_GET_CAPS, sizeof(*ctrl));
1171 if (IS_ERR(ctrl))
1172 return PTR_ERR(ctrl);
1173
1174 ctrl->sorIndex = ~0;
1175
1176 ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl));
1177 if (ret) {
1178 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
1179 return ret;
1180 }
1181
1182 switch (NVVAL_GET(ctrl->maxLinkRate, NV0073_CTRL_CMD, DP_GET_CAPS, MAX_LINK_RATE)) {
1183 case NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_1_62:
1184 *plink_bw = 0x06;
1185 break;
1186 case NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_2_70:
1187 *plink_bw = 0x0a;
1188 break;
1189 case NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_5_40:
1190 *plink_bw = 0x14;
1191 break;
1192 case NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_8_10:
1193 *plink_bw = 0x1e;
1194 break;
1195 default:
1196 *plink_bw = 0x00;
1197 break;
1198 }
1199
1200 *pmst = ctrl->bIsMultistreamSupported;
1201 *pwm = ctrl->bHasIncreasedWatermarkLimits;
1202 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
1203 return 0;
1204 }
1205
1206 static int
r535_tmds_edid_get(struct nvkm_outp * outp,u8 * data,u16 * psize)1207 r535_tmds_edid_get(struct nvkm_outp *outp, u8 *data, u16 *psize)
1208 {
1209 NV0073_CTRL_SPECIFIC_GET_EDID_V2_PARAMS *ctrl;
1210 struct nvkm_disp *disp = outp->disp;
1211 int ret = -E2BIG;
1212
1213 ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom,
1214 NV0073_CTRL_CMD_SPECIFIC_GET_EDID_V2, sizeof(*ctrl));
1215 if (IS_ERR(ctrl))
1216 return PTR_ERR(ctrl);
1217
1218 ctrl->subDeviceInstance = 0;
1219 ctrl->displayId = BIT(outp->index);
1220
1221 ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl));
1222 if (ret) {
1223 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
1224 return ret;
1225 }
1226
1227 ret = -E2BIG;
1228 if (ctrl->bufferSize <= *psize) {
1229 memcpy(data, ctrl->edidBuffer, ctrl->bufferSize);
1230 *psize = ctrl->bufferSize;
1231 ret = 0;
1232 }
1233
1234 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
1235 return ret;
1236 }
1237
1238 static const struct nvkm_outp_func
1239 r535_tmds = {
1240 .detect = r535_outp_detect,
1241 .inherit = r535_outp_inherit,
1242 .acquire = r535_outp_acquire,
1243 .release = r535_outp_release,
1244 .edid_get = r535_tmds_edid_get,
1245 };
1246
1247 static int
r535_outp_new(struct nvkm_disp * disp,u32 id)1248 r535_outp_new(struct nvkm_disp *disp, u32 id)
1249 {
1250 const struct nvkm_rm_api *rmapi = disp->rm.objcom.client->gsp->rm->api;
1251 NV0073_CTRL_SPECIFIC_OR_GET_INFO_PARAMS *ctrl;
1252 enum nvkm_ior_proto proto;
1253 struct dcb_output dcbE = {};
1254 struct nvkm_conn *conn;
1255 struct nvkm_outp *outp;
1256 u8 locn, link = 0;
1257 int ret;
1258
1259 ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom,
1260 NV0073_CTRL_CMD_SPECIFIC_OR_GET_INFO, sizeof(*ctrl));
1261 if (IS_ERR(ctrl))
1262 return PTR_ERR(ctrl);
1263
1264 ctrl->subDeviceInstance = 0;
1265 ctrl->displayId = BIT(id);
1266
1267 ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl));
1268 if (ret) {
1269 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
1270 return ret;
1271 }
1272
1273 switch (ctrl->type) {
1274 case NV0073_CTRL_SPECIFIC_OR_TYPE_NONE:
1275 return 0;
1276 case NV0073_CTRL_SPECIFIC_OR_TYPE_SOR:
1277 switch (ctrl->protocol) {
1278 case NV0073_CTRL_SPECIFIC_OR_PROTOCOL_SOR_SINGLE_TMDS_A:
1279 proto = TMDS;
1280 link = 1;
1281 break;
1282 case NV0073_CTRL_SPECIFIC_OR_PROTOCOL_SOR_SINGLE_TMDS_B:
1283 proto = TMDS;
1284 link = 2;
1285 break;
1286 case NV0073_CTRL_SPECIFIC_OR_PROTOCOL_SOR_DUAL_TMDS:
1287 proto = TMDS;
1288 link = 3;
1289 break;
1290 case NV0073_CTRL_SPECIFIC_OR_PROTOCOL_SOR_DP_A:
1291 proto = DP;
1292 link = 1;
1293 break;
1294 case NV0073_CTRL_SPECIFIC_OR_PROTOCOL_SOR_DP_B:
1295 proto = DP;
1296 link = 2;
1297 break;
1298 default:
1299 WARN_ON(1);
1300 return -EINVAL;
1301 }
1302
1303 break;
1304 default:
1305 WARN_ON(1);
1306 return -EINVAL;
1307 }
1308
1309 locn = ctrl->location;
1310 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
1311
1312 conn = r535_conn_new(disp, id);
1313 if (IS_ERR(conn))
1314 return PTR_ERR(conn);
1315
1316 switch (proto) {
1317 case TMDS: dcbE.type = DCB_OUTPUT_TMDS; break;
1318 case DP: dcbE.type = DCB_OUTPUT_DP; break;
1319 default:
1320 WARN_ON(1);
1321 return -EINVAL;
1322 }
1323
1324 dcbE.location = locn;
1325 dcbE.connector = conn->index;
1326 dcbE.heads = disp->head.mask;
1327 dcbE.i2c_index = 0xff;
1328 dcbE.link = dcbE.sorconf.link = link;
1329
1330 if (proto == TMDS) {
1331 ret = nvkm_outp_new_(&r535_tmds, disp, id, &dcbE, &outp);
1332 if (ret)
1333 return ret;
1334 } else {
1335 bool mst, wm;
1336
1337 ret = rmapi->disp->dp.get_caps(disp, &dcbE.dpconf.link_bw, &mst, &wm);
1338 if (ret)
1339 return ret;
1340
1341 if (WARN_ON(!dcbE.dpconf.link_bw))
1342 return -EINVAL;
1343
1344 dcbE.dpconf.link_nr = 4;
1345
1346 ret = nvkm_outp_new_(&r535_dp, disp, id, &dcbE, &outp);
1347 if (ret)
1348 return ret;
1349
1350 outp->dp.mst = mst;
1351 outp->dp.increased_wm = wm;
1352 }
1353
1354
1355 outp->conn = conn;
1356 list_add_tail(&outp->head, &disp->outps);
1357 return 0;
1358 }
1359
1360 static void
r535_disp_irq(struct nvkm_gsp_event * event,void * repv,u32 repc)1361 r535_disp_irq(struct nvkm_gsp_event *event, void *repv, u32 repc)
1362 {
1363 struct nvkm_disp *disp = container_of(event, typeof(*disp), rm.irq);
1364 Nv2080DpIrqNotification *irq = repv;
1365
1366 if (WARN_ON(repc < sizeof(*irq)))
1367 return;
1368
1369 nvkm_debug(&disp->engine.subdev, "event: dp irq displayId %08x\n", irq->displayId);
1370
1371 if (irq->displayId)
1372 nvkm_event_ntfy(&disp->rm.event, fls(irq->displayId) - 1, NVKM_DPYID_IRQ);
1373 }
1374
1375 static void
r535_disp_hpd(struct nvkm_gsp_event * event,void * repv,u32 repc)1376 r535_disp_hpd(struct nvkm_gsp_event *event, void *repv, u32 repc)
1377 {
1378 struct nvkm_disp *disp = container_of(event, typeof(*disp), rm.hpd);
1379 Nv2080HotplugNotification *hpd = repv;
1380
1381 if (WARN_ON(repc < sizeof(*hpd)))
1382 return;
1383
1384 nvkm_debug(&disp->engine.subdev, "event: hpd plug %08x unplug %08x\n",
1385 hpd->plugDisplayMask, hpd->unplugDisplayMask);
1386
1387 for (int i = 0; i < 31; i++) {
1388 u32 mask = 0;
1389
1390 if (hpd->plugDisplayMask & BIT(i))
1391 mask |= NVKM_DPYID_PLUG;
1392 if (hpd->unplugDisplayMask & BIT(i))
1393 mask |= NVKM_DPYID_UNPLUG;
1394
1395 if (mask)
1396 nvkm_event_ntfy(&disp->rm.event, i, mask);
1397 }
1398 }
1399
1400 static const struct nvkm_event_func
1401 r535_disp_event = {
1402 };
1403
1404 static void
r535_disp_fini(struct nvkm_disp * disp,bool suspend)1405 r535_disp_fini(struct nvkm_disp *disp, bool suspend)
1406 {
1407 if (!disp->engine.subdev.use.enabled)
1408 return;
1409
1410 nvkm_gsp_rm_free(&disp->rm.object);
1411
1412 if (!suspend) {
1413 nvkm_gsp_event_dtor(&disp->rm.irq);
1414 nvkm_gsp_event_dtor(&disp->rm.hpd);
1415 nvkm_event_fini(&disp->rm.event);
1416
1417 nvkm_gsp_rm_free(&disp->rm.objcom);
1418 nvkm_gsp_device_dtor(&disp->rm.device);
1419 nvkm_gsp_client_dtor(&disp->rm.client);
1420 }
1421 }
1422
1423 static int
r535_disp_init(struct nvkm_disp * disp)1424 r535_disp_init(struct nvkm_disp *disp)
1425 {
1426 int ret;
1427
1428 ret = nvkm_gsp_rm_alloc(&disp->rm.device.object, disp->func->root.oclass << 16,
1429 disp->func->root.oclass, 0, &disp->rm.object);
1430 if (ret)
1431 return ret;
1432
1433 return 0;
1434 }
1435
1436 static int
r535_disp_get_supported(struct nvkm_disp * disp,unsigned long * pmask)1437 r535_disp_get_supported(struct nvkm_disp *disp, unsigned long *pmask)
1438 {
1439 NV0073_CTRL_SYSTEM_GET_SUPPORTED_PARAMS *ctrl;
1440
1441 ctrl = nvkm_gsp_rm_ctrl_rd(&disp->rm.objcom,
1442 NV0073_CTRL_CMD_SYSTEM_GET_SUPPORTED, sizeof(*ctrl));
1443 if (IS_ERR(ctrl))
1444 return PTR_ERR(ctrl);
1445
1446 *pmask = ctrl->displayMask;
1447 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
1448 return 0;
1449 }
1450
1451 static int
r535_disp_get_static_info(struct nvkm_disp * disp)1452 r535_disp_get_static_info(struct nvkm_disp *disp)
1453 {
1454 NV2080_CTRL_INTERNAL_DISPLAY_GET_STATIC_INFO_PARAMS *ctrl;
1455 struct nvkm_gsp *gsp = disp->rm.objcom.client->gsp;
1456
1457 ctrl = nvkm_gsp_rm_ctrl_rd(&gsp->internal.device.subdevice,
1458 NV2080_CTRL_CMD_INTERNAL_DISPLAY_GET_STATIC_INFO,
1459 sizeof(*ctrl));
1460 if (IS_ERR(ctrl))
1461 return PTR_ERR(ctrl);
1462
1463 disp->wndw.mask = ctrl->windowPresentMask;
1464 disp->wndw.nr = fls(disp->wndw.mask);
1465
1466 nvkm_gsp_rm_ctrl_done(&gsp->internal.device.subdevice, ctrl);
1467 return 0;
1468 }
1469
1470 static int
r535_disp_oneinit(struct nvkm_disp * disp)1471 r535_disp_oneinit(struct nvkm_disp *disp)
1472 {
1473 struct nvkm_device *device = disp->engine.subdev.device;
1474 struct nvkm_gsp *gsp = device->gsp;
1475 const struct nvkm_rm_api *rmapi = gsp->rm->api;
1476 NV2080_CTRL_INTERNAL_DISPLAY_WRITE_INST_MEM_PARAMS *ctrl;
1477 unsigned long mask;
1478 int ret, i;
1479
1480 /* RAMIN. */
1481 ret = nvkm_gpuobj_new(device, 0x10000, 0x10000, false, NULL, &disp->inst);
1482 if (ret)
1483 return ret;
1484
1485 if (WARN_ON(nvkm_memory_target(disp->inst->memory) != NVKM_MEM_TARGET_VRAM))
1486 return -EINVAL;
1487
1488 ctrl = nvkm_gsp_rm_ctrl_get(&gsp->internal.device.subdevice,
1489 NV2080_CTRL_CMD_INTERNAL_DISPLAY_WRITE_INST_MEM,
1490 sizeof(*ctrl));
1491 if (IS_ERR(ctrl))
1492 return PTR_ERR(ctrl);
1493
1494 ctrl->instMemPhysAddr = nvkm_memory_addr(disp->inst->memory);
1495 ctrl->instMemSize = nvkm_memory_size(disp->inst->memory);
1496 ctrl->instMemAddrSpace = ADDR_FBMEM;
1497 ctrl->instMemCpuCacheAttr = NV_MEMORY_WRITECOMBINED;
1498
1499 ret = nvkm_gsp_rm_ctrl_wr(&gsp->internal.device.subdevice, ctrl);
1500 if (ret)
1501 return ret;
1502
1503 /* OBJs. */
1504 ret = nvkm_gsp_client_device_ctor(gsp, &disp->rm.client, &disp->rm.device);
1505 if (ret)
1506 return ret;
1507
1508 ret = nvkm_gsp_rm_alloc(&disp->rm.device.object, NVKM_RM_DISP, NV04_DISPLAY_COMMON, 0,
1509 &disp->rm.objcom);
1510 if (ret)
1511 return ret;
1512
1513 ret = rmapi->disp->get_static_info(disp);
1514 if (ret)
1515 return ret;
1516
1517 /* */
1518 {
1519 #if defined(CONFIG_ACPI) && defined(CONFIG_X86)
1520 NV2080_CTRL_INTERNAL_INIT_BRIGHTC_STATE_LOAD_PARAMS *ctrl;
1521 struct nvkm_gsp_object *subdevice = &disp->rm.client.gsp->internal.device.subdevice;
1522
1523 ctrl = nvkm_gsp_rm_ctrl_get(subdevice,
1524 NV2080_CTRL_CMD_INTERNAL_INIT_BRIGHTC_STATE_LOAD,
1525 sizeof(*ctrl));
1526 if (IS_ERR(ctrl))
1527 return PTR_ERR(ctrl);
1528
1529 ctrl->status = 0x56; /* NV_ERR_NOT_SUPPORTED */
1530
1531 {
1532 const guid_t NBCI_DSM_GUID =
1533 GUID_INIT(0xD4A50B75, 0x65C7, 0x46F7,
1534 0xBF, 0xB7, 0x41, 0x51, 0x4C, 0xEA, 0x02, 0x44);
1535 u64 NBCI_DSM_REV = 0x00000102;
1536 const guid_t NVHG_DSM_GUID =
1537 GUID_INIT(0x9D95A0A0, 0x0060, 0x4D48,
1538 0xB3, 0x4D, 0x7E, 0x5F, 0xEA, 0x12, 0x9F, 0xD4);
1539 u64 NVHG_DSM_REV = 0x00000102;
1540 acpi_handle handle = ACPI_HANDLE(device->dev);
1541
1542 if (handle && acpi_has_method(handle, "_DSM")) {
1543 bool nbci = acpi_check_dsm(handle, &NBCI_DSM_GUID, NBCI_DSM_REV,
1544 1ULL << 0x00000014);
1545 bool nvhg = acpi_check_dsm(handle, &NVHG_DSM_GUID, NVHG_DSM_REV,
1546 1ULL << 0x00000014);
1547
1548 if (nbci || nvhg) {
1549 union acpi_object argv4 = {
1550 .buffer.type = ACPI_TYPE_BUFFER,
1551 .buffer.length = sizeof(ctrl->backLightData),
1552 .buffer.pointer = kmalloc(argv4.buffer.length, GFP_KERNEL),
1553 }, *obj;
1554
1555 obj = acpi_evaluate_dsm(handle, nbci ? &NBCI_DSM_GUID : &NVHG_DSM_GUID,
1556 0x00000102, 0x14, &argv4);
1557 if (!obj) {
1558 acpi_handle_info(handle, "failed to evaluate _DSM\n");
1559 } else {
1560 for (int i = 0; i < obj->package.count; i++) {
1561 union acpi_object *elt = &obj->package.elements[i];
1562 u32 size;
1563
1564 if (elt->integer.value & ~0xffffffffULL)
1565 size = 8;
1566 else
1567 size = 4;
1568
1569 memcpy(&ctrl->backLightData[ctrl->backLightDataSize], &elt->integer.value, size);
1570 ctrl->backLightDataSize += size;
1571 }
1572
1573 ctrl->status = 0;
1574 ACPI_FREE(obj);
1575 }
1576
1577 kfree(argv4.buffer.pointer);
1578 }
1579 }
1580 }
1581
1582 ret = nvkm_gsp_rm_ctrl_wr(subdevice, ctrl);
1583 if (ret)
1584 return ret;
1585 #endif
1586 }
1587
1588 /* */
1589 {
1590 NV0073_CTRL_CMD_DP_SET_MANUAL_DISPLAYPORT_PARAMS *ctrl;
1591
1592 ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom,
1593 NV0073_CTRL_CMD_DP_SET_MANUAL_DISPLAYPORT,
1594 sizeof(*ctrl));
1595 if (IS_ERR(ctrl))
1596 return PTR_ERR(ctrl);
1597
1598 ret = nvkm_gsp_rm_ctrl_wr(&disp->rm.objcom, ctrl);
1599 if (ret)
1600 return ret;
1601 }
1602
1603 /* */
1604 {
1605 NV0073_CTRL_SYSTEM_GET_NUM_HEADS_PARAMS *ctrl;
1606
1607 ctrl = nvkm_gsp_rm_ctrl_rd(&disp->rm.objcom,
1608 NV0073_CTRL_CMD_SYSTEM_GET_NUM_HEADS, sizeof(*ctrl));
1609 if (IS_ERR(ctrl))
1610 return PTR_ERR(ctrl);
1611
1612 disp->head.nr = ctrl->numHeads;
1613 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
1614 }
1615
1616 /* */
1617 {
1618 NV0073_CTRL_SPECIFIC_GET_ALL_HEAD_MASK_PARAMS *ctrl;
1619
1620 ctrl = nvkm_gsp_rm_ctrl_rd(&disp->rm.objcom,
1621 NV0073_CTRL_CMD_SPECIFIC_GET_ALL_HEAD_MASK,
1622 sizeof(*ctrl));
1623 if (IS_ERR(ctrl))
1624 return PTR_ERR(ctrl);
1625
1626 disp->head.mask = ctrl->headMask;
1627 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
1628
1629 for_each_set_bit(i, &disp->head.mask, disp->head.nr) {
1630 ret = nvkm_head_new_(disp->func->gsp.head, disp, i);
1631 if (ret)
1632 return ret;
1633 }
1634 }
1635
1636 disp->sor.nr = disp->func->sor.cnt(disp, &disp->sor.mask);
1637 nvkm_debug(&disp->engine.subdev, " SOR(s): %d (%02lx)\n", disp->sor.nr, disp->sor.mask);
1638 for_each_set_bit(i, &disp->sor.mask, disp->sor.nr) {
1639 ret = disp->func->sor.new(disp, i);
1640 if (ret)
1641 return ret;
1642 }
1643
1644 ret = rmapi->disp->get_supported(disp, &mask);
1645 if (ret)
1646 return ret;
1647
1648 for_each_set_bit(i, &mask, 32) {
1649 ret = r535_outp_new(disp, i);
1650 if (ret)
1651 return ret;
1652 }
1653
1654 ret = nvkm_event_init(&r535_disp_event, &gsp->subdev, 3, 32, &disp->rm.event);
1655 if (WARN_ON(ret))
1656 return ret;
1657
1658 ret = nvkm_gsp_device_event_ctor(&disp->rm.device, 0x007e0000, NV2080_NOTIFIERS_HOTPLUG,
1659 r535_disp_hpd, &disp->rm.hpd);
1660 if (ret)
1661 return ret;
1662
1663 ret = nvkm_gsp_device_event_ctor(&disp->rm.device, 0x007e0001, NV2080_NOTIFIERS_DP_IRQ,
1664 r535_disp_irq, &disp->rm.irq);
1665 if (ret)
1666 return ret;
1667
1668 /* RAMHT. */
1669 ret = nvkm_ramht_new(device, disp->func->ramht_size ? disp->func->ramht_size :
1670 0x1000, 0, disp->inst, &disp->ramht);
1671 if (ret)
1672 return ret;
1673
1674 /* Chips that raise head-timing interrupts on a separate low-latency
1675 * vector report it as a second DISP interrupt table entry, exposed
1676 * as instance 1 by the RM engine-index translation (see
1677 * r570_gsp_xlat_mc_engine_idx()). Their high-latency vector
1678 * (instance 0) is left unhandled as no event nouveau enables is
1679 * routed to it, and without a handler it stays masked.
1680 */
1681 ret = nvkm_gsp_intr_stall(gsp, disp->engine.subdev.type,
1682 disp->func->gsp.intr_low_latency ? 1 : disp->engine.subdev.inst);
1683 if (ret < 0)
1684 return ret;
1685
1686 ret = nvkm_inth_add(&device->vfn->intr, ret, NVKM_INTR_PRIO_NORMAL, &disp->engine.subdev,
1687 disp->func->gsp.intr, &disp->engine.subdev.inth);
1688 if (ret)
1689 return ret;
1690
1691 nvkm_inth_allow(&disp->engine.subdev.inth);
1692 return 0;
1693 }
1694
1695 static void
r535_disp_dtor(struct nvkm_disp * disp)1696 r535_disp_dtor(struct nvkm_disp *disp)
1697 {
1698 kfree(disp->func);
1699 }
1700
1701 int
r535_disp_new(const struct nvkm_disp_func * hw,struct nvkm_device * device,enum nvkm_subdev_type type,int inst,struct nvkm_disp ** pdisp)1702 r535_disp_new(const struct nvkm_disp_func *hw, struct nvkm_device *device,
1703 enum nvkm_subdev_type type, int inst, struct nvkm_disp **pdisp)
1704 {
1705 const struct nvkm_rm_gpu *gpu = device->gsp->rm->gpu;
1706 struct nvkm_disp_func *rm;
1707 int ret;
1708
1709 rm = kzalloc_flex(*rm, user, 6);
1710 if (!rm)
1711 return -ENOMEM;
1712
1713 rm->dtor = r535_disp_dtor;
1714 rm->oneinit = r535_disp_oneinit;
1715 rm->init = r535_disp_init;
1716 rm->fini = r535_disp_fini;
1717 rm->uevent = hw->uevent;
1718 rm->sor.cnt = r535_sor_cnt;
1719 rm->sor.new = r535_sor_new;
1720 rm->gsp = hw->gsp;
1721 rm->ramht_size = hw->ramht_size;
1722
1723 rm->root.oclass = gpu->disp.class.root;
1724
1725 rm->user[0].base.oclass = gpu->disp.class.caps;
1726 rm->user[0].ctor = gv100_disp_caps_new;
1727
1728 rm->user[1].base.oclass = gpu->disp.class.core;
1729 rm->user[1].ctor = nvkm_disp_core_new;
1730 rm->user[1].chan = &r535_core;
1731
1732 rm->user[2].base.oclass = gpu->disp.class.wndw;
1733 rm->user[2].ctor = nvkm_disp_wndw_new;
1734 rm->user[2].chan = &r535_wndw;
1735
1736 rm->user[3].base.oclass = gpu->disp.class.wimm;
1737 rm->user[3].ctor = nvkm_disp_wndw_new;
1738 rm->user[3].chan = &r535_wimm;
1739
1740 rm->user[4].base.oclass = gpu->disp.class.curs;
1741 rm->user[4].ctor = nvkm_disp_chan_new;
1742 rm->user[4].chan = &r535_curs;
1743
1744 ret = nvkm_disp_new_(rm, device, type, inst, pdisp);
1745 if (ret)
1746 kfree(rm);
1747
1748 mutex_init(&(*pdisp)->super.mutex); //XXX
1749 return ret;
1750 }
1751
1752 const struct nvkm_rm_api_disp
1753 r535_disp = {
1754 .get_static_info = r535_disp_get_static_info,
1755 .get_supported = r535_disp_get_supported,
1756 .get_connect_state = r535_disp_get_connect_state,
1757 .get_active = r535_disp_get_active,
1758 .bl_ctrl = r535_bl_ctrl,
1759 .dp = {
1760 .get_caps = r535_dp_get_caps,
1761 .set_indexed_link_rates = r535_dp_set_indexed_link_rates,
1762 .sst = r535_dp_sst,
1763 .vcpi = r535_dp_vcpi,
1764 },
1765 .chan = {
1766 .set_pushbuf = r535_disp_chan_set_pushbuf,
1767 .dmac_alloc = r535_dmac_alloc,
1768 }
1769 };
1770