diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2024-08-08 18:58:45 +0200 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2024-08-08 18:58:46 +0200 |
commit | 91dae758bdb854367bf0811d97acb84e791764d9 (patch) | |
tree | 127bead858c1321276754befd3fb385e55df70de /drivers/gpu/drm/stm | |
parent | a4172af3040cdc207f1b60efffcdd219156093c9 (diff) | |
parent | d97e71e449373efbd2403f1d7a32d416599f32ac (diff) |
Merge tag 'drm-misc-next-2024-08-01' of https://gitlab.freedesktop.org/drm/misc/kernel into drm-next
drm-misc-next for v6.12:
UAPI Changes:
virtio:
- Define DRM capset
Cross-subsystem Changes:
dma-buf:
- heaps: Clean up documentation
printk:
- Pass description to kmsg_dump()
Core Changes:
CI:
- Update IGT tests
- Point upstream repo to GitLab instance
modesetting:
- Introduce Power Saving Policy property for connectors
- Add might_fault() to drm_modeset_lock priming
- Add dynamic per-crtc vblank configuration support
panic:
- Avoid build-time interference with framebuffer console
docs:
- Document Colorspace property
scheduler:
- Remove full_recover from drm_sched_start
TTM:
- Make LRU walk restartable after dropping locks
- Allow direct reclaim to allocate local memory
Driver Changes:
amdgpu:
- Support Power Saving Policy connector property
ast:
- astdp: Support AST2600 with VGA; Clean up HPD
bridge:
- Silence error message on -EPROBE_DEFER
- analogix: Clean aup
- bridge-connector: Fix double free
- lt6505: Disable interrupt when powered off
- tc358767: Make default DP port preemphasis configurable
gma500:
- Update i2c terminology
ivpu:
- Add MODULE_FIRMWARE()
lcdif:
- Fix pixel clock
loongson:
- Use GEM refcount over TTM's
mgag200:
- Improve BMC handling
- Support VBLANK intterupts
nouveau:
- Refactor and clean up internals
- Use GEM refcount over TTM's
panel:
- Shutdown fixes plus documentation
- Refactor several drivers for better code sharing
- boe-th101mb31ig002: Support for starry-er88577 MIPI-DSI panel plus
DT; Fix porch parameter
- edp: Support AOU B116XTN02.3, AUO B116XAN06.1, AOU B116XAT04.1,
BOE NV140WUM-N41, BOE NV133WUM-N63, BOE NV116WHM-A4D, CMN N116BCA-EA2,
CMN N116BCP-EA2, CSW MNB601LS1-4
- himax-hx8394: Support Microchip AC40T08A MIPI Display panel plus DT
- ilitek-ili9806e: Support Densitron DMT028VGHMCMI-1D TFT plus DT
- jd9365da: Support Melfas lmfbx101117480 MIPI-DSI panel plus DT; Refactor
for code sharing
sti:
- Fix module owner
stm:
- Avoid UAF wih managed plane and CRTC helpers
- Fix module owner
- Fix error handling in probe
- Depend on COMMON_CLK
- ltdc: Fix transparency after disabling plane; Remove unused interrupt
tegra:
- Call drm_atomic_helper_shutdown()
v3d:
- Clean up perfmon
vkms:
- Clean up
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
From: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20240801121406.GA102996@linux.fritz.box
Diffstat (limited to 'drivers/gpu/drm/stm')
-rw-r--r-- | drivers/gpu/drm/stm/Kconfig | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/stm/drv.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/stm/ltdc.c | 107 | ||||
-rw-r--r-- | drivers/gpu/drm/stm/lvds.c | 1 |
4 files changed, 39 insertions, 77 deletions
diff --git a/drivers/gpu/drm/stm/Kconfig b/drivers/gpu/drm/stm/Kconfig index 1cc6b6cbdfa9..d7f41a87808e 100644 --- a/drivers/gpu/drm/stm/Kconfig +++ b/drivers/gpu/drm/stm/Kconfig @@ -2,6 +2,7 @@ config DRM_STM tristate "DRM Support for STMicroelectronics SoC Series" depends on DRM && (ARCH_STM32 || COMPILE_TEST) + depends on COMMON_CLK select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER select DRM_PANEL_BRIDGE diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c index e8523abef27a..e1232f74dfa5 100644 --- a/drivers/gpu/drm/stm/drv.c +++ b/drivers/gpu/drm/stm/drv.c @@ -25,6 +25,7 @@ #include <drm/drm_module.h> #include <drm/drm_probe_helper.h> #include <drm/drm_vblank.h> +#include <drm/drm_managed.h> #include "ltdc.h" @@ -75,7 +76,7 @@ static int drv_load(struct drm_device *ddev) DRM_DEBUG("%s\n", __func__); - ldev = devm_kzalloc(ddev->dev, sizeof(*ldev), GFP_KERNEL); + ldev = drmm_kzalloc(ddev, sizeof(*ldev), GFP_KERNEL); if (!ldev) return -ENOMEM; @@ -203,12 +204,14 @@ static int stm_drm_platform_probe(struct platform_device *pdev) ret = drm_dev_register(ddev, 0); if (ret) - goto err_put; + goto err_unload; drm_fbdev_dma_setup(ddev, 16); return 0; +err_unload: + drv_unload(ddev); err_put: drm_dev_put(ddev); diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c index 5576fdae4962..54a73753eff9 100644 --- a/drivers/gpu/drm/stm/ltdc.c +++ b/drivers/gpu/drm/stm/ltdc.c @@ -36,6 +36,7 @@ #include <drm/drm_probe_helper.h> #include <drm/drm_simple_kms_helper.h> #include <drm/drm_vblank.h> +#include <drm/drm_managed.h> #include <video/videomode.h> @@ -169,6 +170,7 @@ #define IER_RRIE BIT(3) /* Register Reload Interrupt Enable */ #define IER_FUEIE BIT(6) /* Fifo Underrun Error Interrupt Enable */ #define IER_CRCIE BIT(7) /* CRC Error Interrupt Enable */ +#define IER_MASK (IER_LIE | IER_FUWIE | IER_TERRIE | IER_RRIE | IER_FUEIE | IER_CRCIE) #define CPSR_CYPOS GENMASK(15, 0) /* Current Y position */ @@ -187,6 +189,7 @@ #define LXCR_COLKEN BIT(1) /* Color Keying Enable */ #define LXCR_CLUTEN BIT(4) /* Color Look-Up Table ENable */ #define LXCR_HMEN BIT(8) /* Horizontal Mirroring ENable */ +#define LXCR_MASK (LXCR_LEN | LXCR_COLKEN | LXCR_CLUTEN | LXCR_HMEN) #define LXWHPCR_WHSTPOS GENMASK(11, 0) /* Window Horizontal StarT POSition */ #define LXWHPCR_WHSPPOS GENMASK(27, 16) /* Window Horizontal StoP POSition */ @@ -491,11 +494,6 @@ static inline struct ltdc_device *plane_to_ltdc(struct drm_plane *plane) return (struct ltdc_device *)plane->dev->dev_private; } -static inline struct ltdc_device *encoder_to_ltdc(struct drm_encoder *enc) -{ - return (struct ltdc_device *)enc->dev->dev_private; -} - static inline enum ltdc_pix_fmt to_ltdc_pixelformat(u32 drm_fmt) { enum ltdc_pix_fmt pf; @@ -784,7 +782,7 @@ static void ltdc_crtc_atomic_enable(struct drm_crtc *crtc, regmap_write(ldev->regmap, LTDC_BCCR, BCCR_BCBLACK); /* Enable IRQ */ - regmap_set_bits(ldev->regmap, LTDC_IER, IER_FUWIE | IER_FUEIE | IER_RRIE | IER_TERRIE); + regmap_set_bits(ldev->regmap, LTDC_IER, IER_FUWIE | IER_FUEIE | IER_TERRIE); /* Commit shadow registers = update planes at next vblank */ if (!ldev->caps.plane_reg_shadow) @@ -806,11 +804,10 @@ static void ltdc_crtc_atomic_disable(struct drm_crtc *crtc, /* Disable all layers */ for (layer_index = 0; layer_index < ldev->caps.nb_layers; layer_index++) - regmap_write_bits(ldev->regmap, LTDC_L1CR + layer_index * LAY_OFS, - LXCR_CLUTEN | LXCR_LEN, 0); + regmap_write_bits(ldev->regmap, LTDC_L1CR + layer_index * LAY_OFS, LXCR_MASK, 0); - /* disable IRQ */ - regmap_clear_bits(ldev->regmap, LTDC_IER, IER_FUWIE | IER_FUEIE | IER_RRIE | IER_TERRIE); + /* Disable IRQ */ + regmap_clear_bits(ldev->regmap, LTDC_IER, IER_FUWIE | IER_FUEIE | IER_TERRIE); /* immediately commit disable of layers before switching off LTDC */ if (!ldev->caps.plane_reg_shadow) @@ -1199,7 +1196,6 @@ static void ltdc_crtc_atomic_print_state(struct drm_printer *p, } static const struct drm_crtc_funcs ltdc_crtc_funcs = { - .destroy = drm_crtc_cleanup, .set_config = drm_atomic_helper_set_config, .page_flip = drm_atomic_helper_page_flip, .reset = drm_atomic_helper_crtc_reset, @@ -1212,7 +1208,6 @@ static const struct drm_crtc_funcs ltdc_crtc_funcs = { }; static const struct drm_crtc_funcs ltdc_crtc_with_crc_support_funcs = { - .destroy = drm_crtc_cleanup, .set_config = drm_atomic_helper_set_config, .page_flip = drm_atomic_helper_page_flip, .reset = drm_atomic_helper_crtc_reset, @@ -1474,7 +1469,7 @@ static void ltdc_plane_atomic_update(struct drm_plane *plane, if (newstate->rotation & DRM_MODE_REFLECT_X) val |= LXCR_HMEN; - regmap_write_bits(ldev->regmap, LTDC_L1CR + lofs, LXCR_LEN | LXCR_CLUTEN | LXCR_HMEN, val); + regmap_write_bits(ldev->regmap, LTDC_L1CR + lofs, LXCR_MASK, val); /* Commit shadow registers = update plane at next vblank */ if (ldev->caps.plane_reg_shadow) @@ -1512,7 +1507,10 @@ static void ltdc_plane_atomic_disable(struct drm_plane *plane, u32 lofs = plane->index * LAY_OFS; /* Disable layer */ - regmap_write_bits(ldev->regmap, LTDC_L1CR + lofs, LXCR_LEN | LXCR_CLUTEN | LXCR_HMEN, 0); + regmap_write_bits(ldev->regmap, LTDC_L1CR + lofs, LXCR_MASK, 0); + + /* Reset the layer transparency to hide any related background color */ + regmap_write_bits(ldev->regmap, LTDC_L1CACR + lofs, LXCACR_CONSTA, 0x00); /* Commit shadow registers = update plane at next vblank */ if (ldev->caps.plane_reg_shadow) @@ -1545,7 +1543,6 @@ static void ltdc_plane_atomic_print_state(struct drm_printer *p, static const struct drm_plane_funcs ltdc_plane_funcs = { .update_plane = drm_atomic_helper_update_plane, .disable_plane = drm_atomic_helper_disable_plane, - .destroy = drm_plane_cleanup, .reset = drm_atomic_helper_plane_reset, .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, @@ -1572,7 +1569,6 @@ static struct drm_plane *ltdc_plane_create(struct drm_device *ddev, const u64 *modifiers = ltdc_format_modifiers; u32 lofs = index * LAY_OFS; u32 val; - int ret; /* Allocate the biggest size according to supported color formats */ formats = devm_kzalloc(dev, (ldev->caps.pix_fmt_nb + @@ -1580,6 +1576,8 @@ static struct drm_plane *ltdc_plane_create(struct drm_device *ddev, ARRAY_SIZE(ltdc_drm_fmt_ycbcr_sp) + ARRAY_SIZE(ltdc_drm_fmt_ycbcr_fp)) * sizeof(*formats), GFP_KERNEL); + if (!formats) + return NULL; for (i = 0; i < ldev->caps.pix_fmt_nb; i++) { drm_fmt = ldev->caps.pix_fmt_drm[i]; @@ -1613,14 +1611,10 @@ static struct drm_plane *ltdc_plane_create(struct drm_device *ddev, } } - plane = devm_kzalloc(dev, sizeof(*plane), GFP_KERNEL); - if (!plane) - return NULL; - - ret = drm_universal_plane_init(ddev, plane, possible_crtcs, - <dc_plane_funcs, formats, nb_fmt, - modifiers, type, NULL); - if (ret < 0) + plane = drmm_universal_plane_alloc(ddev, struct drm_plane, dev, + possible_crtcs, <dc_plane_funcs, formats, + nb_fmt, modifiers, type, NULL); + if (IS_ERR(plane)) return NULL; if (ldev->caps.ycbcr_input) { @@ -1643,15 +1637,6 @@ static struct drm_plane *ltdc_plane_create(struct drm_device *ddev, return plane; } -static void ltdc_plane_destroy_all(struct drm_device *ddev) -{ - struct drm_plane *plane, *plane_temp; - - list_for_each_entry_safe(plane, plane_temp, - &ddev->mode_config.plane_list, head) - drm_plane_cleanup(plane); -} - static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc) { struct ltdc_device *ldev = ddev->dev_private; @@ -1677,14 +1662,14 @@ static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc) /* Init CRTC according to its hardware features */ if (ldev->caps.crc) - ret = drm_crtc_init_with_planes(ddev, crtc, primary, NULL, - <dc_crtc_with_crc_support_funcs, NULL); + ret = drmm_crtc_init_with_planes(ddev, crtc, primary, NULL, + <dc_crtc_with_crc_support_funcs, NULL); else - ret = drm_crtc_init_with_planes(ddev, crtc, primary, NULL, - <dc_crtc_funcs, NULL); + ret = drmm_crtc_init_with_planes(ddev, crtc, primary, NULL, + <dc_crtc_funcs, NULL); if (ret) { DRM_ERROR("Can not initialize CRTC\n"); - goto cleanup; + return ret; } drm_crtc_helper_add(crtc, <dc_crtc_helper_funcs); @@ -1698,9 +1683,8 @@ static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc) for (i = 1; i < ldev->caps.nb_layers; i++) { overlay = ltdc_plane_create(ddev, DRM_PLANE_TYPE_OVERLAY, i); if (!overlay) { - ret = -ENOMEM; DRM_ERROR("Can not create overlay plane %d\n", i); - goto cleanup; + return -ENOMEM; } if (ldev->caps.dynamic_zorder) drm_plane_create_zpos_property(overlay, i, 0, ldev->caps.nb_layers - 1); @@ -1713,10 +1697,6 @@ static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc) } return 0; - -cleanup: - ltdc_plane_destroy_all(ddev); - return ret; } static void ltdc_encoder_disable(struct drm_encoder *encoder) @@ -1776,23 +1756,19 @@ static int ltdc_encoder_init(struct drm_device *ddev, struct drm_bridge *bridge) struct drm_encoder *encoder; int ret; - encoder = devm_kzalloc(ddev->dev, sizeof(*encoder), GFP_KERNEL); - if (!encoder) - return -ENOMEM; + encoder = drmm_simple_encoder_alloc(ddev, struct drm_encoder, dev, + DRM_MODE_ENCODER_DPI); + if (IS_ERR(encoder)) + return PTR_ERR(encoder); encoder->possible_crtcs = CRTC_MASK; encoder->possible_clones = 0; /* No cloning support */ - drm_simple_encoder_init(ddev, encoder, DRM_MODE_ENCODER_DPI); - drm_encoder_helper_add(encoder, <dc_encoder_helper_funcs); ret = drm_bridge_attach(encoder, bridge, NULL, 0); - if (ret) { - if (ret != -EPROBE_DEFER) - drm_encoder_cleanup(encoder); + if (ret) return ret; - } DRM_DEBUG_DRIVER("Bridge encoder:%d created\n", encoder->base.id); @@ -1962,8 +1938,7 @@ int ltdc_load(struct drm_device *ddev) goto err; if (panel) { - bridge = drm_panel_bridge_add_typed(panel, - DRM_MODE_CONNECTOR_DPI); + bridge = drmm_panel_bridge_add(ddev, panel); if (IS_ERR(bridge)) { DRM_ERROR("panel-bridge endpoint %d\n", i); ret = PTR_ERR(bridge); @@ -2013,13 +1988,8 @@ int ltdc_load(struct drm_device *ddev) goto err; } - /* Disable interrupts */ - if (ldev->caps.fifo_threshold) - regmap_clear_bits(ldev->regmap, LTDC_IER, IER_LIE | IER_RRIE | IER_FUWIE | - IER_TERRIE); - else - regmap_clear_bits(ldev->regmap, LTDC_IER, IER_LIE | IER_RRIE | IER_FUWIE | - IER_TERRIE | IER_FUEIE); + /* Disable all interrupts */ + regmap_clear_bits(ldev->regmap, LTDC_IER, IER_MASK); DRM_DEBUG_DRIVER("ltdc hw version 0x%08x\n", ldev->caps.hw_version); @@ -2045,7 +2015,7 @@ int ltdc_load(struct drm_device *ddev) } } - crtc = devm_kzalloc(dev, sizeof(*crtc), GFP_KERNEL); + crtc = drmm_kzalloc(ddev, sizeof(*crtc), GFP_KERNEL); if (!crtc) { DRM_ERROR("Failed to allocate crtc\n"); ret = -ENOMEM; @@ -2072,9 +2042,6 @@ int ltdc_load(struct drm_device *ddev) return 0; err: - for (i = 0; i < nb_endpoints; i++) - drm_of_panel_bridge_remove(ddev->dev->of_node, 0, i); - clk_disable_unprepare(ldev->pixel_clk); return ret; @@ -2082,16 +2049,8 @@ err: void ltdc_unload(struct drm_device *ddev) { - struct device *dev = ddev->dev; - int nb_endpoints, i; - DRM_DEBUG_DRIVER("\n"); - nb_endpoints = of_graph_get_endpoint_count(dev->of_node); - - for (i = 0; i < nb_endpoints; i++) - drm_of_panel_bridge_remove(ddev->dev->of_node, 0, i); - pm_runtime_disable(ddev->dev); } diff --git a/drivers/gpu/drm/stm/lvds.c b/drivers/gpu/drm/stm/lvds.c index 2fa2c81784e9..06f2d7a56cc9 100644 --- a/drivers/gpu/drm/stm/lvds.c +++ b/drivers/gpu/drm/stm/lvds.c @@ -1210,7 +1210,6 @@ static struct platform_driver lvds_platform_driver = { .remove = lvds_remove, .driver = { .name = "stm32-display-lvds", - .owner = THIS_MODULE, .of_match_table = lvds_dt_ids, }, }; |