Skip to content

Commit 4e3b2f0

Browse files
committed
Merge tag 'drm-misc-fixes-2026-02-05' of https://gitlab.freedesktop.org/drm/misc/kernel into drm-fixes
drm-misc-fixes for v6.19 final: nouveau ------- Revert adding atomic commit functions as it regresses pre-nv50. Fix bugs exposed by enabling 570 firmware. gma500 ------ Revert a regression caused by vblank changes. mgag200 ------- Replace a busy loop with a polling loop to fix that blocking 1 cpu for 300 ms roughly every 20 minutes. bridge ------ imx8mp-hdmi-pa: Use runtime pm to fix a bug in channel ordering. Signed-off-by: Dave Airlie <[email protected]> From: Maarten Lankhorst <[email protected]> Link: https://patch.msgid.link/[email protected]
2 parents 18f7fcd + 40b24d9 commit 4e3b2f0

67 files changed

Lines changed: 207 additions & 138 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pai.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <linux/module.h>
99
#include <linux/of_platform.h>
1010
#include <linux/platform_device.h>
11+
#include <linux/pm_runtime.h>
1112
#include <linux/regmap.h>
1213
#include <drm/bridge/dw_hdmi.h>
1314
#include <sound/asoundef.h>
@@ -33,6 +34,7 @@
3334

3435
struct imx8mp_hdmi_pai {
3536
struct regmap *regmap;
37+
struct device *dev;
3638
};
3739

3840
static void imx8mp_hdmi_pai_enable(struct dw_hdmi *dw_hdmi, int channel,
@@ -43,6 +45,9 @@ static void imx8mp_hdmi_pai_enable(struct dw_hdmi *dw_hdmi, int channel,
4345
struct imx8mp_hdmi_pai *hdmi_pai = pdata->priv_audio;
4446
int val;
4547

48+
if (pm_runtime_resume_and_get(hdmi_pai->dev) < 0)
49+
return;
50+
4651
/* PAI set control extended */
4752
val = WTMK_HIGH(3) | WTMK_LOW(3);
4853
val |= NUM_CH(channel);
@@ -85,6 +90,8 @@ static void imx8mp_hdmi_pai_disable(struct dw_hdmi *dw_hdmi)
8590

8691
/* Stop PAI */
8792
regmap_write(hdmi_pai->regmap, HTX_PAI_CTRL, 0);
93+
94+
pm_runtime_put_sync(hdmi_pai->dev);
8895
}
8996

9097
static const struct regmap_config imx8mp_hdmi_pai_regmap_config = {
@@ -101,6 +108,7 @@ static int imx8mp_hdmi_pai_bind(struct device *dev, struct device *master, void
101108
struct imx8mp_hdmi_pai *hdmi_pai;
102109
struct resource *res;
103110
void __iomem *base;
111+
int ret;
104112

105113
hdmi_pai = devm_kzalloc(dev, sizeof(*hdmi_pai), GFP_KERNEL);
106114
if (!hdmi_pai)
@@ -121,6 +129,13 @@ static int imx8mp_hdmi_pai_bind(struct device *dev, struct device *master, void
121129
plat_data->disable_audio = imx8mp_hdmi_pai_disable;
122130
plat_data->priv_audio = hdmi_pai;
123131

132+
hdmi_pai->dev = dev;
133+
ret = devm_pm_runtime_enable(dev);
134+
if (ret < 0) {
135+
dev_err(dev, "failed to enable PM runtime: %d\n", ret);
136+
return ret;
137+
}
138+
124139
return 0;
125140
}
126141

drivers/gpu/drm/gma500/psb_irq.c

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,6 @@ static irqreturn_t gma_irq_handler(int irq, void *arg)
250250
void gma_irq_preinstall(struct drm_device *dev)
251251
{
252252
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
253-
struct drm_crtc *crtc;
254253
unsigned long irqflags;
255254

256255
spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
@@ -261,15 +260,10 @@ void gma_irq_preinstall(struct drm_device *dev)
261260
PSB_WSGX32(0x00000000, PSB_CR_EVENT_HOST_ENABLE);
262261
PSB_RSGX32(PSB_CR_EVENT_HOST_ENABLE);
263262

264-
drm_for_each_crtc(crtc, dev) {
265-
struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
266-
267-
if (vblank->enabled) {
268-
u32 mask = drm_crtc_index(crtc) ? _PSB_VSYNC_PIPEB_FLAG :
269-
_PSB_VSYNC_PIPEA_FLAG;
270-
dev_priv->vdc_irq_mask |= mask;
271-
}
272-
}
263+
if (dev->vblank[0].enabled)
264+
dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG;
265+
if (dev->vblank[1].enabled)
266+
dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEB_FLAG;
273267

274268
/* Revisit this area - want per device masks ? */
275269
if (dev_priv->ops->hotplug)
@@ -284,8 +278,8 @@ void gma_irq_preinstall(struct drm_device *dev)
284278
void gma_irq_postinstall(struct drm_device *dev)
285279
{
286280
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
287-
struct drm_crtc *crtc;
288281
unsigned long irqflags;
282+
unsigned int i;
289283

290284
spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
291285

@@ -298,13 +292,11 @@ void gma_irq_postinstall(struct drm_device *dev)
298292
PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
299293
PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
300294

301-
drm_for_each_crtc(crtc, dev) {
302-
struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
303-
304-
if (vblank->enabled)
305-
gma_enable_pipestat(dev_priv, drm_crtc_index(crtc), PIPE_VBLANK_INTERRUPT_ENABLE);
295+
for (i = 0; i < dev->num_crtcs; ++i) {
296+
if (dev->vblank[i].enabled)
297+
gma_enable_pipestat(dev_priv, i, PIPE_VBLANK_INTERRUPT_ENABLE);
306298
else
307-
gma_disable_pipestat(dev_priv, drm_crtc_index(crtc), PIPE_VBLANK_INTERRUPT_ENABLE);
299+
gma_disable_pipestat(dev_priv, i, PIPE_VBLANK_INTERRUPT_ENABLE);
308300
}
309301

310302
if (dev_priv->ops->hotplug_enable)
@@ -345,8 +337,8 @@ void gma_irq_uninstall(struct drm_device *dev)
345337
{
346338
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
347339
struct pci_dev *pdev = to_pci_dev(dev->dev);
348-
struct drm_crtc *crtc;
349340
unsigned long irqflags;
341+
unsigned int i;
350342

351343
if (!dev_priv->irq_enabled)
352344
return;
@@ -358,11 +350,9 @@ void gma_irq_uninstall(struct drm_device *dev)
358350

359351
PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
360352

361-
drm_for_each_crtc(crtc, dev) {
362-
struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
363-
364-
if (vblank->enabled)
365-
gma_disable_pipestat(dev_priv, drm_crtc_index(crtc), PIPE_VBLANK_INTERRUPT_ENABLE);
353+
for (i = 0; i < dev->num_crtcs; ++i) {
354+
if (dev->vblank[i].enabled)
355+
gma_disable_pipestat(dev_priv, i, PIPE_VBLANK_INTERRUPT_ENABLE);
366356
}
367357

368358
dev_priv->vdc_irq_mask &= _PSB_IRQ_SGX_FLAG |

drivers/gpu/drm/mgag200/mgag200_bmc.c

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// SPDX-License-Identifier: GPL-2.0-only
22

33
#include <linux/delay.h>
4+
#include <linux/iopoll.h>
45

56
#include <drm/drm_atomic_helper.h>
67
#include <drm/drm_edid.h>
@@ -12,7 +13,7 @@
1213
void mgag200_bmc_stop_scanout(struct mga_device *mdev)
1314
{
1415
u8 tmp;
15-
int iter_max;
16+
int ret;
1617

1718
/*
1819
* 1 - The first step is to inform the BMC of an upcoming mode
@@ -42,30 +43,22 @@ void mgag200_bmc_stop_scanout(struct mga_device *mdev)
4243

4344
/*
4445
* 3a- The third step is to verify if there is an active scan.
45-
* We are waiting for a 0 on remhsyncsts <XSPAREREG<0>).
46+
* We are waiting for a 0 on remhsyncsts (<XSPAREREG<0>).
4647
*/
47-
iter_max = 300;
48-
while (!(tmp & 0x1) && iter_max) {
49-
WREG8(DAC_INDEX, MGA1064_SPAREREG);
50-
tmp = RREG8(DAC_DATA);
51-
udelay(1000);
52-
iter_max--;
53-
}
48+
ret = read_poll_timeout(RREG_DAC, tmp, !(tmp & 0x1),
49+
1000, 300000, false,
50+
MGA1064_SPAREREG);
51+
if (ret == -ETIMEDOUT)
52+
return;
5453

5554
/*
56-
* 3b- This step occurs only if the remove is actually
55+
* 3b- This step occurs only if the remote BMC is actually
5756
* scanning. We are waiting for the end of the frame which is
5857
* a 1 on remvsyncsts (XSPAREREG<1>)
5958
*/
60-
if (iter_max) {
61-
iter_max = 300;
62-
while ((tmp & 0x2) && iter_max) {
63-
WREG8(DAC_INDEX, MGA1064_SPAREREG);
64-
tmp = RREG8(DAC_DATA);
65-
udelay(1000);
66-
iter_max--;
67-
}
68-
}
59+
(void)read_poll_timeout(RREG_DAC, tmp, (tmp & 0x2),
60+
1000, 300000, false,
61+
MGA1064_SPAREREG);
6962
}
7063

7164
void mgag200_bmc_start_scanout(struct mga_device *mdev)

drivers/gpu/drm/mgag200/mgag200_drv.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,12 @@
111111
#define DAC_INDEX 0x3c00
112112
#define DAC_DATA 0x3c0a
113113

114+
#define RREG_DAC(reg) \
115+
({ \
116+
WREG8(DAC_INDEX, reg); \
117+
RREG8(DAC_DATA); \
118+
}) \
119+
114120
#define WREG_DAC(reg, v) \
115121
do { \
116122
WREG8(DAC_INDEX, reg); \

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ struct nvif_client {
1111

1212
int nvif_client_ctor(struct nvif_client *parent, const char *name, struct nvif_client *);
1313
void nvif_client_dtor(struct nvif_client *);
14-
int nvif_client_suspend(struct nvif_client *);
14+
int nvif_client_suspend(struct nvif_client *, bool);
1515
int nvif_client_resume(struct nvif_client *);
1616

1717
/*XXX*/

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ struct nvif_driver {
88
const char *name;
99
int (*init)(const char *name, u64 device, const char *cfg,
1010
const char *dbg, void **priv);
11-
int (*suspend)(void *priv);
11+
int (*suspend)(void *priv, bool runtime);
1212
int (*resume)(void *priv);
1313
int (*ioctl)(void *priv, void *data, u32 size, void **hack);
1414
void __iomem *(*map)(void *priv, u64 handle, u32 size);

drivers/gpu/drm/nouveau/include/nvkm/core/device.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#ifndef __NVKM_DEVICE_H__
33
#define __NVKM_DEVICE_H__
44
#include <core/oclass.h>
5+
#include <core/suspend_state.h>
56
#include <core/intr.h>
67
enum nvkm_subdev_type;
78

@@ -93,7 +94,7 @@ struct nvkm_device_func {
9394
void *(*dtor)(struct nvkm_device *);
9495
int (*preinit)(struct nvkm_device *);
9596
int (*init)(struct nvkm_device *);
96-
void (*fini)(struct nvkm_device *, bool suspend);
97+
void (*fini)(struct nvkm_device *, enum nvkm_suspend_state suspend);
9798
int (*irq)(struct nvkm_device *);
9899
resource_size_t (*resource_addr)(struct nvkm_device *, enum nvkm_bar_id);
99100
resource_size_t (*resource_size)(struct nvkm_device *, enum nvkm_bar_id);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ struct nvkm_engine_func {
2020
int (*oneinit)(struct nvkm_engine *);
2121
int (*info)(struct nvkm_engine *, u64 mthd, u64 *data);
2222
int (*init)(struct nvkm_engine *);
23-
int (*fini)(struct nvkm_engine *, bool suspend);
23+
int (*fini)(struct nvkm_engine *, enum nvkm_suspend_state suspend);
2424
int (*reset)(struct nvkm_engine *);
2525
int (*nonstall)(struct nvkm_engine *);
2626
void (*intr)(struct nvkm_engine *);

drivers/gpu/drm/nouveau/include/nvkm/core/object.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#ifndef __NVKM_OBJECT_H__
33
#define __NVKM_OBJECT_H__
44
#include <core/oclass.h>
5+
#include <core/suspend_state.h>
56
struct nvkm_event;
67
struct nvkm_gpuobj;
78
struct nvkm_uevent;
@@ -27,7 +28,7 @@ enum nvkm_object_map {
2728
struct nvkm_object_func {
2829
void *(*dtor)(struct nvkm_object *);
2930
int (*init)(struct nvkm_object *);
30-
int (*fini)(struct nvkm_object *, bool suspend);
31+
int (*fini)(struct nvkm_object *, enum nvkm_suspend_state suspend);
3132
int (*mthd)(struct nvkm_object *, u32 mthd, void *data, u32 size);
3233
int (*ntfy)(struct nvkm_object *, u32 mthd, struct nvkm_event **);
3334
int (*map)(struct nvkm_object *, void *argv, u32 argc,
@@ -49,7 +50,7 @@ int nvkm_object_new(const struct nvkm_oclass *, void *data, u32 size,
4950
void nvkm_object_del(struct nvkm_object **);
5051
void *nvkm_object_dtor(struct nvkm_object *);
5152
int nvkm_object_init(struct nvkm_object *);
52-
int nvkm_object_fini(struct nvkm_object *, bool suspend);
53+
int nvkm_object_fini(struct nvkm_object *, enum nvkm_suspend_state);
5354
int nvkm_object_mthd(struct nvkm_object *, u32 mthd, void *data, u32 size);
5455
int nvkm_object_ntfy(struct nvkm_object *, u32 mthd, struct nvkm_event **);
5556
int nvkm_object_map(struct nvkm_object *, void *argv, u32 argc,

drivers/gpu/drm/nouveau/include/nvkm/core/oproxy.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ struct nvkm_oproxy {
1313
struct nvkm_oproxy_func {
1414
void (*dtor[2])(struct nvkm_oproxy *);
1515
int (*init[2])(struct nvkm_oproxy *);
16-
int (*fini[2])(struct nvkm_oproxy *, bool suspend);
16+
int (*fini[2])(struct nvkm_oproxy *, enum nvkm_suspend_state suspend);
1717
};
1818

1919
void nvkm_oproxy_ctor(const struct nvkm_oproxy_func *,

0 commit comments

Comments
 (0)