Short summary of fixes pull:

bochs:
 - fix managed cleanup
 
 bridge:
 - tda998x: fix sparse warnings on type correctness
 
 etnaviv:
 - schedule armed jobs
 
 exynos:
 - managed bridge cleanup
 
 fb-helper:
 - fix clipping
 
 ivpu:
 - disallow reexport of GEM buffer objects
 
 noveau:
 - revert support for GA100
 
 panel:
 - boe-tv101wum-nl16: use correct MIPI_DSI mode
 - feyjang-fy07024di26a30d: fix error reporting
 - himax-hx83102: use correct MIPI_DSI mode
 - himax-hx83121a: fix error checks
 - himax-hx83121a: select DRM_DISPLAY_DSC_HELPER
 
 qaic:
 - fix RAS message handling
 
 qxl:
 - clean up polling
 
 sti:
 - managed bridge cleanup
 
 ttm:
 - update GPU MM stats on pool shrinking
 -----BEGIN PGP SIGNATURE-----
 
 iQFPBAABCgA5FiEEchf7rIzpz2NEoWjlaA3BHVMLeiMFAmn8fKsbFIAAAAAABAAO
 bWFudTIsMi41KzEuMTIsMiwyAAoJEGgNwR1TC3oj8z0IAJXVTUYQRwu9tazwt2co
 blbmVz8l14tHXjUwaroKncAPyofs4MQ8Hbb32TwLU3LykFJH5EkTBNysNmRNFzUp
 UXtuZh8qRlPi3GkUfbE2fP778LR0LvIMYE+gpVB5HYtZdrzCZXgmFPPr4l+61RzV
 m893w8hGe65aA8HSaFtp5XtTfppYTdCT17zeFc5J1hbarZcPNgHUY6Ikhv93cWLm
 suf8gsaLYvx86MLtgCjpAnwDVCFoyRQvjDNRVlf27qUjC/a+5mzyJMBff4APCTai
 GDMTutJGqxozIN+WdwPoTXdfoN1SnMjfzlUZF2J/nOHX0pFcBCQ7sQC62hbr6KyC
 N8w=
 =YdY+
 -----END PGP SIGNATURE-----

Merge tag 'drm-misc-fixes-2026-05-07' of https://gitlab.freedesktop.org/drm/misc/kernel into drm-fixes

Short summary of fixes pull:

bochs:
- fix managed cleanup

bridge:
- tda998x: fix sparse warnings on type correctness

etnaviv:
- schedule armed jobs

exynos:
- managed bridge cleanup

fb-helper:
- fix clipping

ivpu:
- disallow reexport of GEM buffer objects

noveau:
- revert support for GA100

panel:
- boe-tv101wum-nl16: use correct MIPI_DSI mode
- feyjang-fy07024di26a30d: fix error reporting
- himax-hx83102: use correct MIPI_DSI mode
- himax-hx83121a: fix error checks
- himax-hx83121a: select DRM_DISPLAY_DSC_HELPER

qaic:
- fix RAS message handling

qxl:
- clean up polling

sti:
- managed bridge cleanup

ttm:
- update GPU MM stats on pool shrinking

Signed-off-by: Dave Airlie <airlied@redhat.com>

From: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patch.msgid.link/20260507115213.GA206508@linux.fritz.box
This commit is contained in:
Dave Airlie 2026-05-08 12:03:01 +10:00
commit 765e717dfb
18 changed files with 87 additions and 56 deletions

View File

@ -537,6 +537,26 @@ static const struct file_operations ivpu_fops = {
#endif
};
static int ivpu_gem_prime_handle_to_fd(struct drm_device *dev, struct drm_file *file_priv,
u32 handle, u32 flags, int *prime_fd)
{
struct drm_gem_object *obj;
obj = drm_gem_object_lookup(file_priv, handle);
if (!obj)
return -ENOENT;
if (drm_gem_is_imported(obj)) {
/* Do not allow re-exporting */
drm_gem_object_put(obj);
return -EOPNOTSUPP;
}
drm_gem_object_put(obj);
return drm_gem_prime_handle_to_fd(dev, file_priv, handle, flags, prime_fd);
}
static const struct drm_driver driver = {
.driver_features = DRIVER_GEM | DRIVER_COMPUTE_ACCEL,
@ -545,6 +565,7 @@ static const struct drm_driver driver = {
.gem_create_object = ivpu_gem_create_object,
.gem_prime_import = ivpu_gem_prime_import,
.prime_handle_to_fd = ivpu_gem_prime_handle_to_fd,
.ioctls = ivpu_drm_ioctls,
.num_ioctls = ARRAY_SIZE(ivpu_drm_ioctls),

View File

@ -497,11 +497,11 @@ static void decode_ras_msg(struct qaic_device *qdev, struct ras_data *msg)
qdev->ce_count++;
break;
case UE:
if (qdev->ce_count != UINT_MAX)
if (qdev->ue_count != UINT_MAX)
qdev->ue_count++;
break;
case UE_NF:
if (qdev->ce_count != UINT_MAX)
if (qdev->ue_nf_count != UINT_MAX)
qdev->ue_nf_count++;
break;
default:

View File

@ -1293,7 +1293,7 @@ static const struct drm_edid *tda998x_edid_read(struct tda998x_priv *priv,
* can't handle signals gracefully.
*/
if (tda998x_edid_delay_wait(priv))
return 0;
return NULL;
if (priv->rev == TDA19988)
reg_clear(priv, REG_TX4, TX4_PD_RAM);
@ -1762,7 +1762,7 @@ static const struct drm_bridge_funcs tda998x_bridge_funcs = {
static int tda998x_get_audio_ports(struct tda998x_priv *priv,
struct device_node *np)
{
const u32 *port_data;
const __be32 *port_data;
u32 size;
int i;

View File

@ -490,7 +490,7 @@ static void drm_fb_helper_memory_range_to_clip(struct fb_info *info, off_t off,
* the number of horizontal pixels that need an update.
*/
off_t bit_off = (off % line_length) * 8;
off_t bit_end = (end % line_length) * 8;
off_t bit_end = bit_off + len * 8;
x1 = bit_off / info->var.bits_per_pixel;
x2 = DIV_ROUND_UP(bit_end, info->var.bits_per_pixel);

View File

@ -116,16 +116,18 @@ int etnaviv_sched_push_job(struct etnaviv_gem_submit *submit)
*/
mutex_lock(&gpu->sched_lock);
ret = xa_alloc_cyclic(&gpu->user_fences, &submit->out_fence_id,
NULL, xa_limit_32b, &gpu->next_user_fence,
GFP_KERNEL);
if (ret < 0)
goto out_unlock;
drm_sched_job_arm(&submit->sched_job);
submit->out_fence = dma_fence_get(&submit->sched_job.s_fence->finished);
ret = xa_alloc_cyclic(&gpu->user_fences, &submit->out_fence_id,
submit->out_fence, xa_limit_32b,
&gpu->next_user_fence, GFP_KERNEL);
if (ret < 0) {
drm_sched_job_cleanup(&submit->sched_job);
goto out_unlock;
}
xa_store(&gpu->user_fences, submit->out_fence_id,
submit->out_fence, GFP_KERNEL);
/* the scheduler holds on to the job now */
kref_get(&submit->refcount);

View File

@ -423,7 +423,9 @@ static int exynos_mic_probe(struct platform_device *pdev)
mic->bridge.of_node = dev->of_node;
drm_bridge_add(&mic->bridge);
ret = devm_drm_bridge_add(dev, &mic->bridge);
if (ret)
goto err;
pm_runtime_enable(dev);
@ -443,12 +445,8 @@ static int exynos_mic_probe(struct platform_device *pdev)
static void exynos_mic_remove(struct platform_device *pdev)
{
struct exynos_mic *mic = platform_get_drvdata(pdev);
component_del(&pdev->dev, &exynos_mic_component_ops);
pm_runtime_disable(&pdev->dev);
drm_bridge_remove(&mic->bridge);
}
static const struct of_device_id exynos_mic_of_match[] = {

View File

@ -2513,6 +2513,7 @@ static const struct nvkm_device_chip
nv170_chipset = {
.name = "GA100",
.bar = { 0x00000001, tu102_bar_new },
.bios = { 0x00000001, nvkm_bios_new },
.devinit = { 0x00000001, ga100_devinit_new },
.fault = { 0x00000001, tu102_fault_new },
.fb = { 0x00000001, ga100_fb_new },
@ -2529,7 +2530,6 @@ nv170_chipset = {
.vfn = { 0x00000001, ga100_vfn_new },
.ce = { 0x000003ff, ga100_ce_new },
.fifo = { 0x00000001, ga100_fifo_new },
.sec2 = { 0x00000001, tu102_sec2_new },
};
static const struct nvkm_device_chip
@ -3341,7 +3341,6 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
case 0x166: device->chip = &nv166_chipset; break;
case 0x167: device->chip = &nv167_chipset; break;
case 0x168: device->chip = &nv168_chipset; break;
case 0x170: device->chip = &nv170_chipset; break;
case 0x172: device->chip = &nv172_chipset; break;
case 0x173: device->chip = &nv173_chipset; break;
case 0x174: device->chip = &nv174_chipset; break;
@ -3361,6 +3360,14 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
case 0x1b6: device->chip = &nv1b6_chipset; break;
case 0x1b7: device->chip = &nv1b7_chipset; break;
default:
if (nvkm_boolopt(device->cfgopt, "NvEnableUnsupportedChipsets", false)) {
switch (device->chipset) {
case 0x170: device->chip = &nv170_chipset; break;
default:
break;
}
}
if (!device->chip) {
nvdev_error(device, "unknown chipset (%08x)\n", boot0);
ret = -ENODEV;

View File

@ -41,11 +41,15 @@ ga100_gsp_flcn = {
static const struct nvkm_gsp_func
ga100_gsp = {
.flcn = &ga100_gsp_flcn,
.fwsec = &tu102_gsp_fwsec,
.sig_section = ".fwsignature_ga100",
.booter.ctor = tu102_gsp_booter_ctor,
.fwsec_sb.ctor = tu102_gsp_fwsec_sb_ctor,
.fwsec_sb.dtor = tu102_gsp_fwsec_sb_dtor,
.dtor = r535_gsp_dtor,
.oneinit = tu102_gsp_oneinit,
.init = tu102_gsp_init,

View File

@ -318,13 +318,8 @@ tu102_gsp_oneinit(struct nvkm_gsp *gsp)
if (ret)
return ret;
/*
* Calculate FB layout. FRTS is a memory region created by the FWSEC-FRTS firmware.
* FWSEC comes from VBIOS. So on systems with no VBIOS (e.g. GA100), the FRTS does
* not exist. Therefore, use the existence of VBIOS to determine whether to reserve
* an FRTS region.
*/
gsp->fb.wpr2.frts.size = device->bios ? 0x100000 : 0;
/* Calculate FB layout. */
gsp->fb.wpr2.frts.size = 0x100000;
gsp->fb.wpr2.frts.addr = ALIGN_DOWN(gsp->fb.bios.addr, 0x20000) - gsp->fb.wpr2.frts.size;
gsp->fb.wpr2.boot.size = gsp->boot.fw.size;
@ -348,12 +343,9 @@ tu102_gsp_oneinit(struct nvkm_gsp *gsp)
if (ret)
return ret;
/* Only boot FWSEC-FRTS if it actually exists */
if (gsp->fb.wpr2.frts.size) {
ret = nvkm_gsp_fwsec_frts(gsp);
if (WARN_ON(ret))
return ret;
}
ret = nvkm_gsp_fwsec_frts(gsp);
if (WARN_ON(ret))
return ret;
/* Reset GSP into RISC-V mode. */
ret = gsp->func->reset(gsp);

View File

@ -208,6 +208,7 @@ config DRM_PANEL_HIMAX_HX83121A
depends on OF
depends on DRM_MIPI_DSI
depends on BACKLIGHT_CLASS_DEVICE
select DRM_DISPLAY_DSC_HELPER
select DRM_KMS_HELPER
help
Say Y here if you want to enable support for Himax HX83121A-based

View File

@ -1324,6 +1324,8 @@ static int boe_panel_disable(struct drm_panel *panel)
mipi_dsi_dcs_set_display_off_multi(&ctx);
mipi_dsi_dcs_enter_sleep_mode_multi(&ctx);
boe->dsi->mode_flags |= MIPI_DSI_MODE_LPM;
mipi_dsi_msleep(&ctx, 150);
return ctx.accum_err;

View File

@ -98,9 +98,7 @@ static int feiyang_enable(struct drm_panel *panel)
/* T12 (video & logic signal rise + backlight rise) T12 >= 200ms */
msleep(200);
mipi_dsi_dcs_set_display_on(ctx->dsi);
return 0;
return mipi_dsi_dcs_set_display_on(ctx->dsi);
}
static int feiyang_disable(struct drm_panel *panel)

View File

@ -937,6 +937,8 @@ static int hx83102_disable(struct drm_panel *panel)
mipi_dsi_dcs_set_display_off_multi(&dsi_ctx);
mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx);
dsi->mode_flags |= MIPI_DSI_MODE_LPM;
mipi_dsi_msleep(&dsi_ctx, 150);
return dsi_ctx.accum_err;

View File

@ -596,8 +596,8 @@ static int himax_probe(struct mipi_dsi_device *dsi)
ctx = devm_drm_panel_alloc(dev, struct himax, panel, &himax_panel_funcs,
DRM_MODE_CONNECTOR_DSI);
if (!ctx)
return -ENOMEM;
if (IS_ERR(ctx))
return PTR_ERR(ctx);
ret = devm_regulator_bulk_get_const(&dsi->dev,
ARRAY_SIZE(himax_supplies),

View File

@ -118,12 +118,13 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* Complete initialization. */
ret = drm_dev_register(&qdev->ddev, ent->driver_data);
if (ret)
goto modeset_cleanup;
goto poll_fini;
drm_client_setup(&qdev->ddev, NULL);
return 0;
modeset_cleanup:
poll_fini:
drm_kms_helper_poll_fini(&qdev->ddev);
qxl_modeset_fini(qdev);
unload:
qxl_device_fini(qdev);
@ -154,6 +155,7 @@ qxl_pci_remove(struct pci_dev *pdev)
{
struct drm_device *dev = pci_get_drvdata(pdev);
drm_kms_helper_poll_fini(dev);
drm_dev_unregister(dev);
drm_atomic_helper_shutdown(dev);
if (pci_is_vga(pdev) && pdev->revision < 5)

View File

@ -741,6 +741,7 @@ static int sti_hda_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct sti_hda *hda;
struct resource *res;
int ret;
DRM_INFO("%s\n", __func__);
@ -779,7 +780,9 @@ static int sti_hda_probe(struct platform_device *pdev)
return PTR_ERR(hda->clk_hddac);
}
drm_bridge_add(&hda->bridge);
ret = devm_drm_bridge_add(dev, &hda->bridge);
if (ret)
return ret;
platform_set_drvdata(pdev, hda);
@ -788,10 +791,7 @@ static int sti_hda_probe(struct platform_device *pdev)
static void sti_hda_remove(struct platform_device *pdev)
{
struct sti_hda *hda = platform_get_drvdata(pdev);
component_del(&pdev->dev, &sti_hda_ops);
drm_bridge_remove(&hda->bridge);
}
static const struct of_device_id hda_of_match[] = {

View File

@ -761,25 +761,21 @@ static int bochs_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent
ret = pcim_enable_device(pdev);
if (ret)
goto err_free_dev;
return ret;
pci_set_drvdata(pdev, dev);
ret = bochs_load(bochs);
if (ret)
goto err_free_dev;
return ret;
ret = drm_dev_register(dev, 0);
if (ret)
goto err_free_dev;
return ret;
drm_client_setup(dev, NULL);
return ret;
err_free_dev:
drm_dev_put(dev);
return ret;
}
static void bochs_pci_remove(struct pci_dev *pdev)

View File

@ -206,6 +206,14 @@ static struct page *ttm_pool_alloc_page(struct ttm_pool *pool, gfp_t gfp_flags,
return NULL;
}
static void __free_pages_gpu_account(struct page *p, unsigned int order,
bool reclaim)
{
mod_lruvec_page_state(p, reclaim ? NR_GPU_RECLAIM : NR_GPU_ACTIVE,
-(1 << order));
__free_pages(p, order);
}
/* Reset the caching and pages of size 1 << order */
static void ttm_pool_free_page(struct ttm_pool *pool, enum ttm_caching caching,
unsigned int order, struct page *p, bool reclaim)
@ -223,9 +231,7 @@ static void ttm_pool_free_page(struct ttm_pool *pool, enum ttm_caching caching,
#endif
if (!pool || !ttm_pool_uses_dma_alloc(pool)) {
mod_lruvec_page_state(p, reclaim ? NR_GPU_RECLAIM : NR_GPU_ACTIVE,
-(1 << order));
__free_pages(p, order);
__free_pages_gpu_account(p, order, reclaim);
return;
}
@ -606,7 +612,7 @@ static int ttm_pool_restore_commit(struct ttm_pool_tt_restore *restore,
*/
ttm_pool_split_for_swap(restore->pool, p);
copy_highpage(restore->alloced_page + i, p);
__free_pages(p, 0);
__free_pages_gpu_account(p, 0, false);
}
restore->restored_pages++;
@ -1068,7 +1074,7 @@ long ttm_pool_backup(struct ttm_pool *pool, struct ttm_tt *tt,
if (flags->purge) {
shrunken += num_pages;
page->private = 0;
__free_pages(page, order);
__free_pages_gpu_account(page, order, false);
memset(tt->pages + i, 0,
num_pages * sizeof(*tt->pages));
}
@ -1109,7 +1115,7 @@ long ttm_pool_backup(struct ttm_pool *pool, struct ttm_tt *tt,
}
handle = shandle;
tt->pages[i] = ttm_backup_handle_to_page_ptr(handle);
put_page(page);
__free_pages_gpu_account(page, 0, false);
shrunken++;
}