Skip to content

Commit 9e99444

Browse files
Ben Skeggsairlied
authored andcommitted
drm/nouveau/disp/r535: initial support
Adds support for modesetting on RM. Signed-off-by: Ben Skeggs <[email protected]> Signed-off-by: Dave Airlie <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 5bf0257 commit 9e99444

File tree

35 files changed

+3202
-8
lines changed

35 files changed

+3202
-8
lines changed

drivers/gpu/drm/nouveau/dispnv50/core.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ nv50_core_new(struct nouveau_drm *drm, struct nv50_core **pcore)
4242
int version;
4343
int (*new)(struct nouveau_drm *, s32, struct nv50_core **);
4444
} cores[] = {
45+
{ AD102_DISP_CORE_CHANNEL_DMA, 0, corec57d_new },
4546
{ GA102_DISP_CORE_CHANNEL_DMA, 0, corec57d_new },
4647
{ TU102_DISP_CORE_CHANNEL_DMA, 0, corec57d_new },
4748
{ GV100_DISP_CORE_CHANNEL_DMA, 0, corec37d_new },

drivers/gpu/drm/nouveau/dispnv50/disp.c

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1592,6 +1592,146 @@ nv50_sor_atomic_disable(struct drm_encoder *encoder, struct drm_atomic_state *st
15921592
nv_encoder->crtc = NULL;
15931593
}
15941594

1595+
// common/inc/displayport/displayport.h
1596+
#define DP_CONFIG_WATERMARK_ADJUST 2
1597+
#define DP_CONFIG_WATERMARK_LIMIT 20
1598+
#define DP_CONFIG_INCREASED_WATERMARK_ADJUST 8
1599+
#define DP_CONFIG_INCREASED_WATERMARK_LIMIT 22
1600+
1601+
static bool
1602+
nv50_sor_dp_watermark_sst(struct nouveau_encoder *outp,
1603+
struct nv50_head *head, struct nv50_head_atom *asyh)
1604+
{
1605+
bool enhancedFraming = outp->dp.dpcd[DP_MAX_LANE_COUNT] & DP_ENHANCED_FRAME_CAP;
1606+
u64 minRate = outp->dp.link_bw * 1000;
1607+
unsigned tuSize = 64;
1608+
unsigned waterMark;
1609+
unsigned hBlankSym;
1610+
unsigned vBlankSym;
1611+
unsigned watermarkAdjust = DP_CONFIG_WATERMARK_ADJUST;
1612+
unsigned watermarkMinimum = DP_CONFIG_WATERMARK_LIMIT;
1613+
// depth is multiplied by 16 in case of DSC enable
1614+
s32 hblank_symbols;
1615+
// number of link clocks per line.
1616+
int vblank_symbols = 0;
1617+
bool bEnableDsc = false;
1618+
unsigned surfaceWidth = asyh->mode.h.blanks - asyh->mode.h.blanke;
1619+
unsigned rasterWidth = asyh->mode.h.active;
1620+
unsigned depth = asyh->or.bpc * 3;
1621+
unsigned DSC_FACTOR = bEnableDsc ? 16 : 1;
1622+
u64 pixelClockHz = asyh->mode.clock * 1000;
1623+
u64 PrecisionFactor = 100000, ratioF, watermarkF;
1624+
u32 numLanesPerLink = outp->dp.link_nr;
1625+
u32 numSymbolsPerLine;
1626+
u32 BlankingBits;
1627+
u32 surfaceWidthPerLink;
1628+
u32 PixelSteeringBits;
1629+
u64 NumBlankingLinkClocks;
1630+
u32 MinHBlank;
1631+
1632+
if (outp->outp.info.dp.increased_wm) {
1633+
watermarkAdjust = DP_CONFIG_INCREASED_WATERMARK_ADJUST;
1634+
watermarkMinimum = DP_CONFIG_INCREASED_WATERMARK_LIMIT;
1635+
}
1636+
1637+
if ((pixelClockHz * depth) >= (8 * minRate * outp->dp.link_nr * DSC_FACTOR))
1638+
{
1639+
return false;
1640+
}
1641+
1642+
//
1643+
// For DSC, if (pclk * bpp) < (1/64 * orclk * 8 * lanes) then some TU may end up with
1644+
// 0 active symbols. This may cause HW hang. Bug 200379426
1645+
//
1646+
if ((bEnableDsc) &&
1647+
((pixelClockHz * depth) < ((8 * minRate * outp->dp.link_nr * DSC_FACTOR) / 64)))
1648+
{
1649+
return false;
1650+
}
1651+
1652+
//
1653+
// Perform the SST calculation.
1654+
// For auto mode the watermark calculation does not need to track accumulated error the
1655+
// formulas for manual mode will not work. So below calculation was extracted from the DTB.
1656+
//
1657+
ratioF = ((u64)pixelClockHz * depth * PrecisionFactor) / DSC_FACTOR;
1658+
1659+
ratioF /= 8 * (u64) minRate * outp->dp.link_nr;
1660+
1661+
if (PrecisionFactor < ratioF) // Assert if we will end up with a negative number in below
1662+
return false;
1663+
1664+
watermarkF = ratioF * tuSize * (PrecisionFactor - ratioF) / PrecisionFactor;
1665+
waterMark = (unsigned)(watermarkAdjust + ((2 * (depth * PrecisionFactor / (8 * numLanesPerLink * DSC_FACTOR)) + watermarkF) / PrecisionFactor));
1666+
1667+
//
1668+
// Bounds check the watermark
1669+
//
1670+
numSymbolsPerLine = (surfaceWidth * depth) / (8 * outp->dp.link_nr * DSC_FACTOR);
1671+
1672+
if (WARN_ON(waterMark > 39 || waterMark > numSymbolsPerLine))
1673+
return false;
1674+
1675+
//
1676+
// Clamp the low side
1677+
//
1678+
if (waterMark < watermarkMinimum)
1679+
waterMark = watermarkMinimum;
1680+
1681+
//Bits to send BS/BE/Extra symbols due to pixel padding
1682+
//Also accounts for enhanced framing.
1683+
BlankingBits = 3*8*numLanesPerLink + (enhancedFraming ? 3*8*numLanesPerLink : 0);
1684+
1685+
//VBID/MVID/MAUD sent 4 times all the time
1686+
BlankingBits += 3*8*4;
1687+
1688+
surfaceWidthPerLink = surfaceWidth;
1689+
1690+
//Extra bits sent due to pixel steering
1691+
PixelSteeringBits = (surfaceWidthPerLink % numLanesPerLink) ? (((numLanesPerLink - surfaceWidthPerLink % numLanesPerLink) * depth) / DSC_FACTOR) : 0;
1692+
1693+
BlankingBits += PixelSteeringBits;
1694+
NumBlankingLinkClocks = (u64)BlankingBits * PrecisionFactor / (8 * numLanesPerLink);
1695+
MinHBlank = (u32)(NumBlankingLinkClocks * pixelClockHz/ minRate / PrecisionFactor);
1696+
MinHBlank += 12;
1697+
1698+
if (WARN_ON(MinHBlank > rasterWidth - surfaceWidth))
1699+
return false;
1700+
1701+
// Bug 702290 - Active Width should be greater than 60
1702+
if (WARN_ON(surfaceWidth <= 60))
1703+
return false;
1704+
1705+
1706+
hblank_symbols = (s32)(((u64)(rasterWidth - surfaceWidth - MinHBlank) * minRate) / pixelClockHz);
1707+
1708+
//reduce HBlank Symbols to account for secondary data packet
1709+
hblank_symbols -= 1; //Stuffer latency to send BS
1710+
hblank_symbols -= 3; //SPKT latency to send data to stuffer
1711+
1712+
hblank_symbols -= numLanesPerLink == 1 ? 9 : numLanesPerLink == 2 ? 6 : 3;
1713+
1714+
hBlankSym = (hblank_symbols < 0) ? 0 : hblank_symbols;
1715+
1716+
// Refer to dev_disp.ref for more information.
1717+
// # symbols/vblank = ((SetRasterBlankEnd.X + SetRasterSize.Width - SetRasterBlankStart.X - 40) * link_clk / pclk) - Y - 1;
1718+
// where Y = (# lanes == 4) 12 : (# lanes == 2) ? 21 : 39
1719+
if (surfaceWidth < 40)
1720+
{
1721+
vblank_symbols = 0;
1722+
}
1723+
else
1724+
{
1725+
vblank_symbols = (s32)(((u64)(surfaceWidth - 40) * minRate) / pixelClockHz) - 1;
1726+
1727+
vblank_symbols -= numLanesPerLink == 1 ? 39 : numLanesPerLink == 2 ? 21 : 12;
1728+
}
1729+
1730+
vBlankSym = (vblank_symbols < 0) ? 0 : vblank_symbols;
1731+
1732+
return nvif_outp_dp_sst(&outp->outp, head->base.index, waterMark, hBlankSym, vBlankSym);
1733+
}
1734+
15951735
static void
15961736
nv50_sor_atomic_enable(struct drm_encoder *encoder, struct drm_atomic_state *state)
15971737
{
@@ -1679,6 +1819,7 @@ nv50_sor_atomic_enable(struct drm_encoder *encoder, struct drm_atomic_state *sta
16791819
break;
16801820
case DCB_OUTPUT_DP:
16811821
nouveau_dp_train(nv_encoder, false, mode->clock, asyh->or.bpc);
1822+
nv50_sor_dp_watermark_sst(nv_encoder, head, asyh);
16821823
depth = nv50_dp_bpc_to_depth(asyh->or.bpc);
16831824

16841825
if (nv_encoder->outp.or.link & 1)

drivers/gpu/drm/nouveau/include/nvif/class.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@
104104
#define GV100_DISP /* if0010.h */ 0x0000c370
105105
#define TU102_DISP /* if0010.h */ 0x0000c570
106106
#define GA102_DISP /* if0010.h */ 0x0000c670
107+
#define AD102_DISP /* if0010.h */ 0x0000c770
107108

108109
#define GV100_DISP_CAPS 0x0000c373
109110

@@ -154,6 +155,7 @@
154155
#define GV100_DISP_CORE_CHANNEL_DMA /* if0014.h */ 0x0000c37d
155156
#define TU102_DISP_CORE_CHANNEL_DMA /* if0014.h */ 0x0000c57d
156157
#define GA102_DISP_CORE_CHANNEL_DMA /* if0014.h */ 0x0000c67d
158+
#define AD102_DISP_CORE_CHANNEL_DMA /* if0014.h */ 0x0000c77d
157159

158160
#define NV50_DISP_OVERLAY_CHANNEL_DMA /* if0014.h */ 0x0000507e
159161
#define G82_DISP_OVERLAY_CHANNEL_DMA /* if0014.h */ 0x0000827e

drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,29 @@
55
#include <core/engine.h>
66
#include <core/object.h>
77
#include <core/event.h>
8+
#include <subdev/gsp.h>
89

910
struct nvkm_disp {
1011
const struct nvkm_disp_func *func;
1112
struct nvkm_engine engine;
1213

14+
struct {
15+
struct nvkm_gsp_client client;
16+
struct nvkm_gsp_device device;
17+
18+
struct nvkm_gsp_object objcom;
19+
struct nvkm_gsp_object object;
20+
21+
#define NVKM_DPYID_PLUG BIT(0)
22+
#define NVKM_DPYID_UNPLUG BIT(1)
23+
#define NVKM_DPYID_IRQ BIT(2)
24+
struct nvkm_event event;
25+
struct nvkm_gsp_event hpd;
26+
struct nvkm_gsp_event irq;
27+
28+
u32 assigned_sors;
29+
} rm;
30+
1331
struct list_head heads;
1432
struct list_head iors;
1533
struct list_head outps;
@@ -69,4 +87,5 @@ int gp102_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct
6987
int gv100_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **);
7088
int tu102_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **);
7189
int ga102_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **);
90+
int ad102_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **);
7291
#endif

drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ void nvkm_gsp_sg_free(struct nvkm_device *, struct sg_table *);
2323

2424
typedef int (*nvkm_gsp_msg_ntfy_func)(void *priv, u32 fn, void *repv, u32 repc);
2525

26+
struct nvkm_gsp_event;
27+
typedef void (*nvkm_gsp_event_func)(struct nvkm_gsp_event *, void *repv, u32 repc);
28+
2629
struct nvkm_gsp {
2730
const struct nvkm_gsp_func *func;
2831
struct nvkm_subdev subdev;
@@ -150,6 +153,8 @@ struct nvkm_gsp {
150153
} object;
151154

152155
struct nvkm_gsp *gsp;
156+
157+
struct list_head events;
153158
} client;
154159

155160
struct nvkm_gsp_device {
@@ -191,6 +196,10 @@ struct nvkm_gsp {
191196

192197
int (*device_ctor)(struct nvkm_gsp_client *, struct nvkm_gsp_device *);
193198
void (*device_dtor)(struct nvkm_gsp_device *);
199+
200+
int (*event_ctor)(struct nvkm_gsp_device *, u32 handle, u32 id,
201+
nvkm_gsp_event_func, struct nvkm_gsp_event *);
202+
void (*event_dtor)(struct nvkm_gsp_event *);
194203
} *rm;
195204

196205
struct {
@@ -399,6 +408,32 @@ nvkm_gsp_client_device_ctor(struct nvkm_gsp *gsp,
399408
return ret;
400409
}
401410

411+
struct nvkm_gsp_event {
412+
struct nvkm_gsp_device *device;
413+
u32 id;
414+
nvkm_gsp_event_func func;
415+
416+
struct nvkm_gsp_object object;
417+
418+
struct list_head head;
419+
};
420+
421+
static inline int
422+
nvkm_gsp_device_event_ctor(struct nvkm_gsp_device *device, u32 handle, u32 id,
423+
nvkm_gsp_event_func func, struct nvkm_gsp_event *event)
424+
{
425+
return device->object.client->gsp->rm->event_ctor(device, handle, id, func, event);
426+
}
427+
428+
static inline void
429+
nvkm_gsp_event_dtor(struct nvkm_gsp_event *event)
430+
{
431+
struct nvkm_gsp_device *device = event->device;
432+
433+
if (device)
434+
device->object.client->gsp->rm->event_dtor(event);
435+
}
436+
402437
int nvkm_gsp_intr_stall(struct nvkm_gsp *, enum nvkm_subdev_type, int);
403438
int nvkm_gsp_intr_nonstall(struct nvkm_gsp *, enum nvkm_subdev_type, int);
404439

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#ifndef __src_common_sdk_nvidia_inc_class_cl0005_h__
2+
#define __src_common_sdk_nvidia_inc_class_cl0005_h__
3+
4+
/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.54.03 */
5+
6+
/*
7+
* SPDX-FileCopyrightText: Copyright (c) 2001-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
8+
* SPDX-License-Identifier: MIT
9+
*
10+
* Permission is hereby granted, free of charge, to any person obtaining a
11+
* copy of this software and associated documentation files (the "Software"),
12+
* to deal in the Software without restriction, including without limitation
13+
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
14+
* and/or sell copies of the Software, and to permit persons to whom the
15+
* Software is furnished to do so, subject to the following conditions:
16+
*
17+
* The above copyright notice and this permission notice shall be included in
18+
* all copies or substantial portions of the Software.
19+
*
20+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23+
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26+
* DEALINGS IN THE SOFTWARE.
27+
*/
28+
29+
typedef struct NV0005_ALLOC_PARAMETERS {
30+
NvHandle hParentClient;
31+
NvHandle hSrcResource;
32+
33+
NvV32 hClass;
34+
NvV32 notifyIndex;
35+
NV_DECLARE_ALIGNED(NvP64 data, 8);
36+
} NV0005_ALLOC_PARAMETERS;
37+
38+
#endif
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#ifndef __src_common_sdk_nvidia_inc_class_cl2080_notification_h__
2+
#define __src_common_sdk_nvidia_inc_class_cl2080_notification_h__
3+
4+
/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.54.03 */
5+
6+
/*
7+
* SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
8+
* SPDX-License-Identifier: MIT
9+
*
10+
* Permission is hereby granted, free of charge, to any person obtaining a
11+
* copy of this software and associated documentation files (the "Software"),
12+
* to deal in the Software without restriction, including without limitation
13+
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
14+
* and/or sell copies of the Software, and to permit persons to whom the
15+
* Software is furnished to do so, subject to the following conditions:
16+
*
17+
* The above copyright notice and this permission notice shall be included in
18+
* all copies or substantial portions of the Software.
19+
*
20+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23+
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26+
* DEALINGS IN THE SOFTWARE.
27+
*/
28+
29+
#define NV2080_NOTIFIERS_HOTPLUG (1)
30+
31+
#define NV2080_NOTIFIERS_DP_IRQ (7)
32+
33+
typedef struct {
34+
NvU32 plugDisplayMask;
35+
NvU32 unplugDisplayMask;
36+
} Nv2080HotplugNotification;
37+
38+
typedef struct Nv2080DpIrqNotificationRec {
39+
NvU32 displayId;
40+
} Nv2080DpIrqNotification;
41+
42+
#endif
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#ifndef __src_common_sdk_nvidia_inc_ctrl_ctrl0073_ctrl0073common_h__
2+
#define __src_common_sdk_nvidia_inc_ctrl_ctrl0073_ctrl0073common_h__
3+
4+
/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.54.03 */
5+
6+
/*
7+
* SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
8+
* SPDX-License-Identifier: MIT
9+
*
10+
* Permission is hereby granted, free of charge, to any person obtaining a
11+
* copy of this software and associated documentation files (the "Software"),
12+
* to deal in the Software without restriction, including without limitation
13+
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
14+
* and/or sell copies of the Software, and to permit persons to whom the
15+
* Software is furnished to do so, subject to the following conditions:
16+
*
17+
* The above copyright notice and this permission notice shall be included in
18+
* all copies or substantial portions of the Software.
19+
*
20+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23+
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26+
* DEALINGS IN THE SOFTWARE.
27+
*/
28+
29+
typedef struct NV0073_CTRL_CMD_DSC_CAP_PARAMS {
30+
NvBool bDscSupported;
31+
NvU32 encoderColorFormatMask;
32+
NvU32 lineBufferSizeKB;
33+
NvU32 rateBufferSizeKB;
34+
NvU32 bitsPerPixelPrecision;
35+
NvU32 maxNumHztSlices;
36+
NvU32 lineBufferBitDepth;
37+
} NV0073_CTRL_CMD_DSC_CAP_PARAMS;
38+
39+
#endif

0 commit comments

Comments
 (0)