linux-next: manual merge of the drm-misc-fixes tree with the origin tree

From: Mark Brown

Date: Wed Aug 26 2026 - 07:53:04 EST


Hi all,

Today's linux-next merge of the drm-misc-fixes tree got conflicts in:

drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h
drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c

between commit:

804cb093b245c ("drm/nouveau/disp/r535: Add scanline position support + head state support")

from the origin tree and commits:

c6659e0ffc19b ("drm/nouveau/disp: move GSP head-timing ISR and vblank helpers to tu102.c")
5bb489b333237 ("drm/nouveau/gsp: fix vblank interrupts on GB20x")

from the drm-misc-fixes tree.

I fixed it up (see below) and can carry the fix as necessary. This
is now fixed as far as linux-next is concerned, but any non trivial
conflicts should be mentioned to your upstream maintainer when your tree
is submitted for merging. You may also want to consider cooperating
with the maintainer of the conflicting tree to minimise any particularly
complex conflicts.

diff --combined drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h
index b642729c254fe,5976498da9094..0000000000000
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h
@@@ -56,6 -56,8 +56,8 @@@ int gv100_head_new(struct nvkm_disp *,
void gv100_head_state(struct nvkm_head *head, struct nvkm_head_state *state);
void gv100_head_rgpos(struct nvkm_head *head, u16 *hline, u16 *vline);

+ extern const struct nvkm_head_func tu102_gsp_head;
+
#define HEAD_MSG(h,l,f,a...) do { \
struct nvkm_head *_h = (h); \
nvkm_##l(&_h->disp->engine.subdev, "head-%d: "f"\n", _h->id, ##a); \
diff --combined drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c
index e77733a5d9c3c,f5f22173fc2c1..0000000000000
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c
@@@ -400,16 -400,16 +400,16 @@@ r535_sor_dp_audio(struct nvkm_ior *sor
r535_sor_dp_audio_mute(sor, false);
}

- static void
- r535_sor_dp_vcpi(struct nvkm_ior *sor, int head, u8 slot, u8 slot_nr, u16 pbn, u16 aligned_pbn)
+ static int
+ r535_dp_vcpi(struct nvkm_ior *sor, int head, u8 slot, u8 slot_nr, u16 pbn, u16 aligned_pbn)
{
struct nvkm_disp *disp = sor->disp;
struct NV0073_CTRL_CMD_DP_CONFIG_STREAM_PARAMS *ctrl;

ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom,
NV0073_CTRL_CMD_DP_CONFIG_STREAM, sizeof(*ctrl));
- if (WARN_ON(IS_ERR(ctrl)))
- return;
+ if (IS_ERR(ctrl))
+ return PTR_ERR(ctrl);

ctrl->subDeviceInstance = 0;
ctrl->head = head;
@@@ -429,12 -429,20 +429,20 @@@
ctrl->MST.sendACT = 0;
ctrl->MST.singleHeadMSTPipeline = 0;
ctrl->MST.bEnableAudioOverRightPanel = 0;
- WARN_ON(nvkm_gsp_rm_ctrl_wr(&disp->rm.objcom, ctrl));
+ return nvkm_gsp_rm_ctrl_wr(&disp->rm.objcom, ctrl);
+ }
+
+ static void
+ r535_sor_dp_vcpi(struct nvkm_ior *sor, int head, u8 slot, u8 slot_nr, u16 pbn, u16 aligned_pbn)
+ {
+ const struct nvkm_rm_api *rmapi = sor->disp->engine.subdev.device->gsp->rm->api;
+
+ WARN_ON(rmapi->disp->dp.vcpi(sor, head, slot, slot_nr, pbn, aligned_pbn));
}

static int
- r535_sor_dp_sst(struct nvkm_ior *sor, int head, bool ef,
- u32 watermark, u32 hblanksym, u32 vblanksym)
+ r535_dp_sst(struct nvkm_ior *sor, int head, bool ef,
+ u32 watermark, u32 hblanksym, u32 vblanksym)
{
struct nvkm_disp *disp = sor->disp;
struct NV0073_CTRL_CMD_DP_CONFIG_STREAM_PARAMS *ctrl;
@@@ -461,6 -469,15 +469,15 @@@
return nvkm_gsp_rm_ctrl_wr(&disp->rm.objcom, ctrl);
}

+ static int
+ r535_sor_dp_sst(struct nvkm_ior *sor, int head, bool ef,
+ u32 watermark, u32 hblanksym, u32 vblanksym)
+ {
+ const struct nvkm_rm_api *rmapi = sor->disp->engine.subdev.device->gsp->rm->api;
+
+ return rmapi->disp->dp.sst(sor, head, ef, watermark, hblanksym, vblanksym);
+ }
+
static const struct nvkm_ior_func_dp
r535_sor_dp = {
.sst = r535_sor_dp_sst,
@@@ -545,16 -562,21 +562,21 @@@ r535_sor_hdmi_ctrl_audio(struct nvkm_ou
static void
r535_sor_hdmi_audio(struct nvkm_ior *sor, int head, bool enable)
{
- struct nvkm_device *device = sor->disp->engine.subdev.device;
- const u32 hdmi = head * 0x400;
-
r535_sor_hdmi_ctrl_audio(sor->asy.outp, enable);
r535_sor_hdmi_ctrl_audio_mute(sor->asy.outp, !enable);
+ sor->disp->func->gsp.hdmi_gcp(sor, head, enable);
+ }

- /* General Control (GCP). */
- nvkm_mask(device, 0x6f00c0 + hdmi, 0x00000001, 0x00000000);
- nvkm_wr32(device, 0x6f00cc + hdmi, !enable ? 0x00000001 : 0x00000010);
- nvkm_mask(device, 0x6f00c0 + hdmi, 0x00000001, 0x00000001);
+ static void
+ r535_sor_hdmi_infoframe_avi(struct nvkm_ior *sor, int head, void *data, u32 size)
+ {
+ sor->disp->func->gsp.hdmi_infoframe_avi(sor, head, data, size);
+ }
+
+ static void
+ r535_sor_hdmi_infoframe_vsi(struct nvkm_ior *sor, int head, void *data, u32 size)
+ {
+ sor->disp->func->gsp.hdmi_infoframe_vsi(sor, head, data, size);
}

static void
@@@ -582,8 -604,8 +604,8 @@@ r535_sor_hdmi =
.ctrl = r535_sor_hdmi_ctrl,
.scdc = r535_sor_hdmi_scdc,
/*TODO: SF_USER -> KMS. */
- .infoframe_avi = gv100_sor_hdmi_infoframe_avi,
- .infoframe_vsi = gv100_sor_hdmi_infoframe_vsi,
+ .infoframe_avi = r535_sor_hdmi_infoframe_avi,
+ .infoframe_vsi = r535_sor_hdmi_infoframe_vsi,
.audio = r535_sor_hdmi_audio,
};

@@@ -608,31 -630,6 +630,6 @@@ r535_sor_cnt(struct nvkm_disp *disp, un
return 4;
}

- static void
- r535_head_vblank_put(struct nvkm_head *head)
- {
- struct nvkm_device *device = head->disp->engine.subdev.device;
-
- nvkm_mask(device, 0x611d80 + (head->id * 4), 0x00000002, 0x00000000);
- }
-
- static void
- r535_head_vblank_get(struct nvkm_head *head)
- {
- struct nvkm_device *device = head->disp->engine.subdev.device;
-
- nvkm_wr32(device, 0x611800 + (head->id * 4), 0x00000002);
- nvkm_mask(device, 0x611d80 + (head->id * 4), 0x00000002, 0x00000002);
- }
-
- static const struct nvkm_head_func
- r535_head = {
- .state = gv100_head_state,
- .rgpos = gv100_head_rgpos,
- .vblank_get = r535_head_vblank_get,
- .vblank_put = r535_head_vblank_put,
- };
-
static struct nvkm_conn *
r535_conn_new(struct nvkm_disp *disp, u32 id)
{
@@@ -1404,35 -1401,6 +1401,6 @@@ static const struct nvkm_event_fun
r535_disp_event = {
};

- static void
- r535_disp_intr_head_timing(struct nvkm_disp *disp, int head)
- {
- struct nvkm_subdev *subdev = &disp->engine.subdev;
- struct nvkm_device *device = subdev->device;
- u32 stat = nvkm_rd32(device, 0x611c00 + (head * 0x04));
-
- if (stat & 0x00000002) {
- nvkm_disp_vblank(disp, head);
-
- nvkm_wr32(device, 0x611800 + (head * 0x04), 0x00000002);
- }
- }
-
- static irqreturn_t
- r535_disp_intr(struct nvkm_inth *inth)
- {
- struct nvkm_disp *disp = container_of(inth, typeof(*disp), engine.subdev.inth);
- struct nvkm_subdev *subdev = &disp->engine.subdev;
- struct nvkm_device *device = subdev->device;
- unsigned long mask = nvkm_rd32(device, 0x611ec0) & 0x000000ff;
- int head;
-
- for_each_set_bit(head, &mask, 8)
- r535_disp_intr_head_timing(disp, head);
-
- return IRQ_HANDLED;
- }
-
static void
r535_disp_fini(struct nvkm_disp *disp, bool suspend)
{
@@@ -1659,7 -1627,7 +1627,7 @@@ r535_disp_oneinit(struct nvkm_disp *dis
nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);

for_each_set_bit(i, &disp->head.mask, disp->head.nr) {
- ret = nvkm_head_new_(&r535_head, disp, i);
+ ret = nvkm_head_new_(disp->func->gsp.head, disp, i);
if (ret)
return ret;
}
@@@ -1703,12 -1671,20 +1671,20 @@@
if (ret)
return ret;

- ret = nvkm_gsp_intr_stall(gsp, disp->engine.subdev.type, disp->engine.subdev.inst);
+ /* Chips that raise head-timing interrupts on a separate low-latency
+ * vector report it as a second DISP interrupt table entry, exposed
+ * as instance 1 by the RM engine-index translation (see
+ * r570_gsp_xlat_mc_engine_idx()). Their high-latency vector
+ * (instance 0) is left unhandled as no event nouveau enables is
+ * routed to it, and without a handler it stays masked.
+ */
+ ret = nvkm_gsp_intr_stall(gsp, disp->engine.subdev.type,
+ disp->func->gsp.intr_low_latency ? 1 : disp->engine.subdev.inst);
if (ret < 0)
return ret;

ret = nvkm_inth_add(&device->vfn->intr, ret, NVKM_INTR_PRIO_NORMAL, &disp->engine.subdev,
- r535_disp_intr, &disp->engine.subdev.inth);
+ disp->func->gsp.intr, &disp->engine.subdev.inth);
if (ret)
return ret;

@@@ -1741,6 -1717,7 +1717,7 @@@ r535_disp_new(const struct nvkm_disp_fu
rm->uevent = hw->uevent;
rm->sor.cnt = r535_sor_cnt;
rm->sor.new = r535_sor_new;
+ rm->gsp = hw->gsp;
rm->ramht_size = hw->ramht_size;

rm->root.oclass = gpu->disp.class.root;
@@@ -1782,6 -1759,8 +1759,8 @@@ r535_disp =
.dp = {
.get_caps = r535_dp_get_caps,
.set_indexed_link_rates = r535_dp_set_indexed_link_rates,
+ .sst = r535_dp_sst,
+ .vcpi = r535_dp_vcpi,
},
.chan = {
.set_pushbuf = r535_disp_chan_set_pushbuf,

Attachment: signature.asc
Description: PGP signature