[PATCH 1/1] drm/mediatek: fine tune the dsi panel's power sequence
Add the drm_panel_prepare_power and drm_panel_unprepare_power control. Turn on panel power(drm_panel_prepare_power) and control before dsi enable. And then dsi enable, send dcs cmd in drm_panel_prepare, last turn on backlight. Signed-off-by: Jitao Shi --- drivers/gpu/drm/mediatek/mtk_dsi.c | 19 +-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c index 224afb666881..b635724b209b 100644 --- a/drivers/gpu/drm/mediatek/mtk_dsi.c +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c @@ -563,10 +563,15 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi) dsi->data_rate = DIV_ROUND_UP_ULL(pixel_clock * total_bits, htotal * dsi->lanes); + if (dsi->panel) { + if (drm_panel_prepare_power(dsi->panel)) + DRM_INFO("can't prepare power the panel\n"); + } + ret = clk_set_rate(dsi->hs_clk, dsi->data_rate); if (ret < 0) { dev_err(dev, "Failed to set data rate: %d\n", ret); - goto err_refcount; + goto err_prepare_power; } phy_power_on(dsi->phy); @@ -605,13 +610,18 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi) } return 0; + err_disable_digital_clk: clk_disable_unprepare(dsi->digital_clk); err_disable_engine_clk: clk_disable_unprepare(dsi->engine_clk); err_phy_power_off: phy_power_off(dsi->phy); -err_refcount: +err_prepare_power: + if (dsi->panel) { + if (drm_panel_unprepare_power(dsi->panel)) + DRM_INFO("Can't unprepare power the panel\n"); + } dsi->refcount--; return ret; } @@ -652,6 +662,11 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi) clk_disable_unprepare(dsi->digital_clk); phy_power_off(dsi->phy); + + if (dsi->panel) { + if (drm_panel_unprepare_power(dsi->panel)) + DRM_INFO("Can't unprepare power the panel\n"); + } } static void mtk_output_dsi_enable(struct mtk_dsi *dsi) -- 2.21.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 0/1] fine tune the dsi panel's power sequence
This patch is based on v5.4-rc6 and these patches: https://patchwork.kernel.org/patch/11229375/ Jitao Shi (1): drm/mediatek: fine tune the dsi panel's power sequence drivers/gpu/drm/mediatek/mtk_dsi.c | 19 +-- 1 file changed, 17 insertions(+), 2 deletions(-) -- 2.21.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 1/1] drm/panel: boe-tv101wum-n16 seperate the panel power control
Seperate the panel power control from prepare/unprepare. Signed-off-by: Jitao Shi --- .../gpu/drm/panel/panel-boe-tv101wum-nl6.c| 69 +-- 1 file changed, 49 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c index e2496a334ab6..5b1b285a2194 100644 --- a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c +++ b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c @@ -50,6 +50,7 @@ struct boe_panel { struct regulator *avdd; struct gpio_desc *enable_gpio; + bool prepared_power; bool prepared; bool enabled; @@ -501,12 +502,11 @@ static int boe_panel_disable(struct drm_panel *panel) return 0; } -static int boe_panel_unprepare(struct drm_panel *panel) +static int boe_panel_unprepare_power(struct drm_panel *panel) { struct boe_panel *boe = to_boe_panel(panel); - int ret; - if (!boe->prepared) + if (!boe->prepared_power) return 0; if (boe->desc->discharge_on_disable) { @@ -518,12 +518,6 @@ static int boe_panel_unprepare(struct drm_panel *panel) usleep_range(5000, 7000); regulator_disable(boe->pp1800); } else { - ret = boe_panel_off(boe); - if (ret < 0) { - dev_err(panel->dev, "failed to set panel off: %d\n", - ret); - return ret; - } msleep(150); gpiod_set_value(boe->enable_gpio, 0); usleep_range(500, 1000); @@ -533,17 +527,39 @@ static int boe_panel_unprepare(struct drm_panel *panel) regulator_disable(boe->pp1800); } + boe->prepared_power = false; + + return 0; +} + +static int boe_panel_unprepare(struct drm_panel *panel) +{ + struct boe_panel *boe = to_boe_panel(panel); + int ret; + + if (!boe->prepared) + return 0; + + if (!boe->desc->discharge_on_disable) { + ret = boe_panel_off(boe); + if (ret < 0) { + dev_err(panel->dev, "failed to set panel off: %d\n", + ret); + return ret; + } + } + boe->prepared = false; return 0; } -static int boe_panel_prepare(struct drm_panel *panel) +static int boe_panel_prepare_power(struct drm_panel *panel) { struct boe_panel *boe = to_boe_panel(panel); int ret; - if (boe->prepared) + if (boe->prepared_power) return 0; gpiod_set_value(boe->enable_gpio, 0); @@ -571,18 +587,10 @@ static int boe_panel_prepare(struct drm_panel *panel) gpiod_set_value(boe->enable_gpio, 1); usleep_range(6000, 1); - ret = boe_panel_init(boe); - if (ret < 0) { - dev_err(panel->dev, "failed to init panel: %d\n", ret); - goto poweroff; - } - - boe->prepared = true; + boe->prepared_power = true; return 0; -poweroff: - regulator_disable(boe->avee); poweroffavdd: regulator_disable(boe->avdd); poweroff1v8: @@ -593,6 +601,25 @@ static int boe_panel_prepare(struct drm_panel *panel) return ret; } +static int boe_panel_prepare(struct drm_panel *panel) +{ + struct boe_panel *boe = to_boe_panel(panel); + int ret; + + if (boe->prepared) + return 0; + + ret = boe_panel_init(boe); + if (ret < 0) { + dev_err(panel->dev, "failed to init panel: %d\n", ret); + return ret; + } + + boe->prepared = true; + + return 0; +} + static int boe_panel_enable(struct drm_panel *panel) { struct boe_panel *boe = to_boe_panel(panel); @@ -754,7 +781,9 @@ static int boe_panel_get_modes(struct drm_panel *panel) static const struct drm_panel_funcs boe_panel_funcs = { .disable = boe_panel_disable, .unprepare = boe_panel_unprepare, + .unprepare_power = boe_panel_unprepare_power, .prepare = boe_panel_prepare, + .prepare_power = boe_panel_prepare_power, .enable = boe_panel_enable, .get_modes = boe_panel_get_modes, }; -- 2.21.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 0/1] boe-tv101wum-n16 seperate the panel power control
This patch is based on v5.4-rc6 and these patches: https://patchwork.kernel.org/patch/11229375/ https://patchwork.kernel.org/patch/11229609/ https://patchwork.kernel.org/patch/11186565/ https://patchwork.kernel.org/patch/11186569/ https://patchwork.kernel.org/patch/11186571/ https://patchwork.kernel.org/patch/11186577/ https://patchwork.kernel.org/patch/11186581/ https://patchwork.kernel.org/patch/11186585/ https://patchwork.kernel.org/patch/11186589/ https://patchwork.kernel.org/patch/11186595/ Jitao Shi (1): drm/panel: boe-tv101wum-n16 seperate the panel power control .../gpu/drm/panel/panel-boe-tv101wum-nl6.c| 69 +-- 1 file changed, 49 insertions(+), 20 deletions(-) -- 2.21.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 1/2] drm/fb-helper: Remove drm_fb_helper_defio_init() and update docs
Hi Am 05.11.19 um 10:30 schrieb Daniel Vetter: > On Mon, Nov 04, 2019 at 07:48:35PM +0100, Thomas Zimmermann wrote: >> Hi Daniel >> >> Am 04.11.19 um 10:55 schrieb Daniel Vetter: >>> On Mon, Oct 28, 2019 at 09:13:47AM +0100, Thomas Zimmermann wrote: Hi Am 25.10.19 um 20:54 schrieb Daniel Vetter: > On Fri, Oct 25, 2019 at 7:26 PM Thomas Zimmermann > wrote: >> >> Hi >> >> Am 25.10.19 um 17:46 schrieb Noralf Trønnes: >>> >>> >>> Den 25.10.2019 11.27, skrev Thomas Zimmermann: There are no users of drm_fb_helper_defio_init(), so we can remove it. The documenation around defio support is a bit misleading and should mention compatibility issues with SHMEM helpers. Clarify this. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/drm_fb_helper.c | 61 +++-- include/drm/drm_fb_helper.h | 1 - 2 files changed, 13 insertions(+), 49 deletions(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index b75ae8555baf..8ebeccdeed23 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -92,9 +92,12 @@ static DEFINE_MUTEX(kernel_fb_helper_lock); * * Drivers that support a dumb buffer with a virtual address and mmap support, * should try out the generic fbdev emulation using drm_fbdev_generic_setup(). + * It will automatically set up deferred I/O if the driver requires a shadow + * buffer. * - * Setup fbdev emulation by calling drm_fb_helper_fbdev_setup() and tear it - * down by calling drm_fb_helper_fbdev_teardown(). + * For other drivers, setup fbdev emulation by calling + * drm_fb_helper_fbdev_setup() and tear it down by calling + * drm_fb_helper_fbdev_teardown(). * * At runtime drivers should restore the fbdev console by using * drm_fb_helper_lastclose() as their &drm_driver.lastclose callback. @@ -127,8 +130,10 @@ static DEFINE_MUTEX(kernel_fb_helper_lock); * always run in process context since the fb_*() function could be running in * atomic context. If drm_fb_helper_deferred_io() is used as the deferred_io * callback it will also schedule dirty_work with the damage collected from the - * mmap page writes. Drivers can use drm_fb_helper_defio_init() to setup - * deferred I/O (coupled with drm_fb_helper_fbdev_teardown()). + * mmap page writes. + * + * Deferred I/O is not compatible with SHMEM. Such drivers should request an + * fbdev shadow buffer and call drm_fbdev_generic_setup() instead. */ static void drm_fb_helper_restore_lut_atomic(struct drm_crtc *crtc) @@ -679,49 +684,6 @@ void drm_fb_helper_deferred_io(struct fb_info *info, } EXPORT_SYMBOL(drm_fb_helper_deferred_io); -/** - * drm_fb_helper_defio_init - fbdev deferred I/O initialization - * @fb_helper: driver-allocated fbdev helper - * - * This function allocates &fb_deferred_io, sets callback to - * drm_fb_helper_deferred_io(), delay to 50ms and calls fb_deferred_io_init(). - * It should be called from the &drm_fb_helper_funcs->fb_probe callback. - * drm_fb_helper_fbdev_teardown() cleans up deferred I/O. - * - * NOTE: A copy of &fb_ops is made and assigned to &info->fbops. This is done - * because fb_deferred_io_cleanup() clears &fbops->fb_mmap and would thereby - * affect other instances of that &fb_ops. - * - * Returns: - * 0 on success or a negative error code on failure. - */ -int drm_fb_helper_defio_init(struct drm_fb_helper *fb_helper) -{ -struct fb_info *info = fb_helper->fbdev; -struct fb_deferred_io *fbdefio; -struct fb_ops *fbops; - -fbdefio = kzalloc(sizeof(*fbdefio), GFP_KERNEL); -fbops = kzalloc(sizeof(*fbops), GFP_KERNEL); -if (!fbdefio || !fbops) { -kfree(fbdefio); -kfree(fbops); -return -ENOMEM; -} - -info->fbdefio = fbdefio; -fbdefio->delay = msecs_to_jiffies(50); -fbdefio->deferred_io = drm_fb_helper_deferred_io; - -*fbops = *info->fbops; -info->fbops = fbops; - -fb_deferred_io_init(info); - -return 0; -} -EXPORT_SYMBOL(drm_fb_helper_defio_init); - >
Re: [PATCH 3/3] drm/udl: Switch to SHMEM
Hi Am 05.11.19 um 12:05 schrieb Gerd Hoffmann: > On Mon, Oct 28, 2019 at 09:45:49AM +0100, Thomas Zimmermann wrote: >> Udl's GEM code and the generic SHMEM are almost identical. Replace >> the former with SHMEM. The dmabuf support in udl is being removed >> in favor of the generic GEM PRIME functions. >> >> The main difference is in the caching flags for mmap pages. By >> default, SHMEM always sets (uncached) write combining. In udl's >> memory management code, only imported buffers use write combining. >> Memory pages of locally created buffer objects are mmap'ed with >> caching enabled. To keep the optimization, udl provides its own >> mmap function for GEM objects where it fixes up the mapping flags. > > Hmm, couldn't spot anything wrong, but it's rather hard to see the > actual changes here ... > > Any chance that having a separate "remove all dead code obsoleted by > shmem helpers" patch helps? Let me see what I can do. Best regards Thomas > > cheers, > Gerd > -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer signature.asc Description: OpenPGP digital signature ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 6/9] drm/ast: Add primary plane
Hi Am 05.11.19 um 10:51 schrieb Gerd Hoffmann: >> +static const struct drm_plane_funcs ast_primary_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, >> +.set_property = NULL, >> +.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, >> +.atomic_destroy_state = drm_atomic_helper_plane_destroy_state, >> +.atomic_set_property = NULL, >> +.atomic_get_property = NULL, > > It's not needed to explicitly set optional function pointers to NULL. Sure. These NULL assignments helped me with keeping track of the work during the conversion. I forgot to remove them here and in the other patch. Best regards Thomas > >> static const struct drm_encoder_helper_funcs ast_enc_helper_funcs = { >> .dpms = ast_encoder_dpms, >> .prepare = ast_encoder_prepare, >> @@ -976,10 +1045,33 @@ static void ast_cursor_fini(struct drm_device *dev) >> >> int ast_mode_init(struct drm_device *dev) >> { >> +static const uint32_t primary_plane_formats[] = { >> +DRM_FORMAT_XRGB, >> +DRM_FORMAT_RGB565, >> +DRM_FORMAT_C8, >> +}; > > I'd suggest to move this out of the function. > > cheers, > Gerd > -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer signature.asc Description: OpenPGP digital signature ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 9/9] drm/ast: Enable atomic modesetting
Hi Am 05.11.19 um 11:31 schrieb Daniel Vetter: > On Tue, Nov 05, 2019 at 10:57:11AM +0100, Gerd Hoffmann wrote: >> On Mon, Oct 28, 2019 at 04:49:28PM +0100, Thomas Zimmermann wrote: >>> This commit sets the remaining atomic-modesetting helpers and the flag >>> DRIVER_ATOMIC. Legacy cursor functions are removed in favor of the cursor >>> plane. For power management, atomic helpers replace the indvidual >>> operations that the driver currently runs. >>> >>> Atomic modesetting is enabled with this commit. >>> >>> Signed-off-by: Thomas Zimmermann >>> --- >>> drivers/gpu/drm/ast/ast_drv.c | 24 ++- >>> drivers/gpu/drm/ast/ast_main.c | 5 + >>> drivers/gpu/drm/ast/ast_mode.c | 290 ++--- >>> 3 files changed, 33 insertions(+), 286 deletions(-) >>> >>> diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c >>> index 1f17794b0890..d763da6f0834 100644 >>> --- a/drivers/gpu/drm/ast/ast_drv.c >>> +++ b/drivers/gpu/drm/ast/ast_drv.c >>> @@ -99,14 +99,14 @@ ast_pci_remove(struct pci_dev *pdev) >>> drm_put_dev(dev); >>> } >>> >>> - >>> - >>> static int ast_drm_freeze(struct drm_device *dev) >>> { >>> - drm_kms_helper_poll_disable(dev); >>> - pci_save_state(dev->pdev); >>> - drm_fb_helper_set_suspend_unlocked(dev->fb_helper, true); >>> + int error; >>> >>> + error = drm_mode_config_helper_suspend(dev); >>> + if (error) >>> + return error; >>> + pci_save_state(dev->pdev); >>> return 0; >>> } >>> >>> @@ -114,11 +114,7 @@ static int ast_drm_thaw(struct drm_device *dev) >>> { >>> ast_post_gpu(dev); >>> >>> - drm_mode_config_reset(dev); >>> - drm_helper_resume_force_mode(dev); >>> - drm_fb_helper_set_suspend_unlocked(dev->fb_helper, false); >>> - >>> - return 0; >>> + return drm_mode_config_helper_resume(dev); >>> } >>> >>> static int ast_drm_resume(struct drm_device *dev) >>> @@ -131,8 +127,6 @@ static int ast_drm_resume(struct drm_device *dev) >>> ret = ast_drm_thaw(dev); >>> if (ret) >>> return ret; >>> - >>> - drm_kms_helper_poll_enable(dev); >>> return 0; >>> } >>> >>> @@ -150,6 +144,7 @@ static int ast_pm_suspend(struct device *dev) >>> pci_set_power_state(pdev, PCI_D3hot); >>> return 0; >>> } >>> + >>> static int ast_pm_resume(struct device *dev) >>> { >>> struct pci_dev *pdev = to_pci_dev(dev); >>> @@ -165,7 +160,6 @@ static int ast_pm_freeze(struct device *dev) >>> if (!ddev || !ddev->dev_private) >>> return -ENODEV; >>> return ast_drm_freeze(ddev); >>> - >>> } >>> >>> static int ast_pm_thaw(struct device *dev) >>> @@ -203,7 +197,9 @@ static struct pci_driver ast_pci_driver = { >>> DEFINE_DRM_GEM_FOPS(ast_fops); >>> >>> static struct drm_driver driver = { >>> - .driver_features = DRIVER_MODESET | DRIVER_GEM, >>> + .driver_features = DRIVER_ATOMIC | >>> + DRIVER_GEM | >>> + DRIVER_MODESET, >>> >>> .load = ast_driver_load, >>> .unload = ast_driver_unload, >>> diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c >>> index 48d57ab42955..b79f484e9bd2 100644 >>> --- a/drivers/gpu/drm/ast/ast_main.c >>> +++ b/drivers/gpu/drm/ast/ast_main.c >>> @@ -28,6 +28,7 @@ >>> >>> #include >>> >>> +#include >>> #include >>> #include >>> #include >>> @@ -412,6 +413,8 @@ enum drm_mode_status ast_mode_config_mode_valid(struct >>> drm_device *dev, >>> static const struct drm_mode_config_funcs ast_mode_funcs = { >>> .fb_create = drm_gem_fb_create, >>> .mode_valid = ast_mode_config_mode_valid, >>> + .atomic_check = drm_atomic_helper_check, >>> + .atomic_commit = drm_atomic_helper_commit, >>> }; >>> >>> static u32 ast_get_vram_info(struct drm_device *dev) >>> @@ -529,6 +532,8 @@ int ast_driver_load(struct drm_device *dev, unsigned >>> long flags) >>> if (ret) >>> goto out_free; >>> >>> + drm_mode_config_reset(dev); >>> + >>> ret = drm_fbdev_generic_setup(dev, 32); >>> if (ret) >>> goto out_free; >>> diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c >>> index f5f73200e8e4..5eccb6ae2ede 100644 >>> --- a/drivers/gpu/drm/ast/ast_mode.c >>> +++ b/drivers/gpu/drm/ast/ast_mode.c >>> @@ -45,11 +45,6 @@ >>> >>> static struct ast_i2c_chan *ast_i2c_create(struct drm_device *dev); >>> static void ast_i2c_destroy(struct ast_i2c_chan *i2c); >>> -static int ast_cursor_set(struct drm_crtc *crtc, >>> - struct drm_file *file_priv, >>> - uint32_t handle, >>> - uint32_t width, >>> - uint32_t height); >>> static int ast_cursor_move(struct drm_crtc *crtc, >>>int x, int y); >>> >>> @@ -58,9 +53,6 @@ static u32 copy_cursor_image(u8 *src, u8 *dst, int width, >>> int height); >>> static int ast_cursor_update(void *dst, void *src, unsigned int width, >>> unsigned int heigh
Re: [PATCH 8/9] drm/ast: Add cursor plane
Hi Am 05.11.19 um 10:55 schrieb Daniel Vetter: > On Mon, Oct 28, 2019 at 04:49:27PM +0100, Thomas Zimmermann wrote: >> The cursor plane uses an internal format of ARGB. To userspace, we >> announce ARGB and do the transformation internally. >> >> Signed-off-by: Thomas Zimmermann > > Hm, might be fun to also expose the ARGB directly. Not that anyone > will actually use it :-/ Is that a serious proposal? I thought about ARGB and quickly dismissed it because no one will ever support it anyway. Best regards Thomas > -Daniel > >> --- >> drivers/gpu/drm/ast/ast_drv.h | 1 + >> drivers/gpu/drm/ast/ast_mode.c | 161 - >> 2 files changed, 161 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h >> index 13560622f22a..49557a73390f 100644 >> --- a/drivers/gpu/drm/ast/ast_drv.h >> +++ b/drivers/gpu/drm/ast/ast_drv.h >> @@ -122,6 +122,7 @@ struct ast_private { >> } cursor; >> >> struct drm_plane primary_plane; >> +struct drm_plane cursor_plane; >> >> bool support_wide_screen; >> enum { >> diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c >> index 7667f4502eb9..f5f73200e8e4 100644 >> --- a/drivers/gpu/drm/ast/ast_mode.c >> +++ b/drivers/gpu/drm/ast/ast_mode.c >> @@ -54,6 +54,16 @@ static int ast_cursor_move(struct drm_crtc *crtc, >> int x, int y); >> >> >> +static u32 copy_cursor_image(u8 *src, u8 *dst, int width, int height); >> +static int ast_cursor_update(void *dst, void *src, unsigned int width, >> + unsigned int height); >> +static void ast_cursor_set_base(struct ast_private *ast, u64 address); >> +static int ast_show_cursor(struct drm_crtc *crtc, void *src, >> + unsigned int width, unsigned int height); >> +static void ast_hide_cursor(struct drm_crtc *crtc); >> +static int ast_cursor_move(struct drm_crtc *crtc, >> + int x, int y); >> + >> static inline void ast_load_palette_index(struct ast_private *ast, >> u8 index, u8 red, u8 green, >> u8 blue) >> @@ -594,6 +604,139 @@ static const struct drm_plane_funcs >> ast_primary_plane_funcs = { >> .format_mod_supported = NULL, >> }; >> >> +/* >> + * Cursor plane >> + */ >> + >> +static int >> +ast_cursor_plane_helper_prepare_fb(struct drm_plane *plane, >> + struct drm_plane_state *new_state) >> +{ >> +struct drm_framebuffer *fb = new_state->fb; >> +struct drm_crtc *crtc = new_state->crtc; >> +struct drm_gem_vram_object *gbo; >> +struct ast_private *ast; >> +int ret; >> +void *src, *dst; >> + >> +if (!crtc || !fb) >> +return 0; >> + >> +if (fb->width > AST_MAX_HWC_WIDTH || fb->height > AST_MAX_HWC_HEIGHT) >> +return -EINVAL; >> + >> +ast = crtc->dev->dev_private; >> + >> +gbo = drm_gem_vram_of_gem(fb->obj[0]); >> +src = drm_gem_vram_vmap(gbo); >> +if (IS_ERR(src)) { >> +ret = PTR_ERR(src); >> +goto err_drm_gem_vram_unpin; >> +} >> + >> +dst = drm_gem_vram_vmap(ast->cursor.gbo[ast->cursor.next_index]); >> +if (IS_ERR(dst)) { >> +ret = PTR_ERR(dst); >> +goto err_drm_gem_vram_vunmap_src; >> +} >> + >> +ret = ast_cursor_update(dst, src, fb->width, fb->height); >> +if (ret) >> +goto err_drm_gem_vram_vunmap_dst; >> + >> +/* Always unmap buffers here. Destination buffers are >> + * perma-pinned while the driver is active. We're only >> + * changing ref-counters here. >> + */ >> +drm_gem_vram_vunmap(ast->cursor.gbo[ast->cursor.next_index], dst); >> +drm_gem_vram_vunmap(gbo, src); >> + >> +return 0; >> + >> +err_drm_gem_vram_vunmap_dst: >> +drm_gem_vram_vunmap(ast->cursor.gbo[ast->cursor.next_index], dst); >> +err_drm_gem_vram_vunmap_src: >> +drm_gem_vram_vunmap(gbo, src); >> +err_drm_gem_vram_unpin: >> +drm_gem_vram_unpin(gbo); >> +return ret; >> +} >> + >> +static int ast_cursor_plane_helper_atomic_check(struct drm_plane *plane, >> +struct drm_plane_state *state) >> +{ >> +return 0; >> +} >> + >> +static void >> +ast_cursor_plane_helper_atomic_update(struct drm_plane *plane, >> + struct drm_plane_state *old_state) >> +{ >> +struct drm_plane_state *state = plane->state; >> +struct drm_crtc *crtc = state->crtc; >> +struct drm_framebuffer *fb = state->fb; >> +struct ast_private *ast = plane->dev->dev_private; >> +struct ast_crtc *ast_crtc = to_ast_crtc(crtc); >> +struct drm_gem_vram_object *gbo; >> +s64 off; >> +u8 jreg; >> + >> +ast_crtc->offset_x = AST_MAX_HWC_WIDTH - fb->width; >> +ast_crtc->offset_y = AST_MAX_HWC_WIDTH - fb->height; >> + >> +if (state->fb != old_state->fb) { >> +
[Bug 111481] AMD Navi GPU frequent freezes on both Manjaro/Ubuntu with kernel 5.3 and mesa 19.2 -git/llvm9
https://bugs.freedesktop.org/show_bug.cgi?id=111481 --- Comment #210 from Lazy --- To clarify, first: it's an Asus reference (blower-style) 5700XT I can't use the overclock utilities without a crash coming within the hour on Windows 10 or any of my Linux installs, no fan profiles, no manual control of fans, no setting it to "high performance" on the dynamic clock or it crashes within the hour. No exceptions, no setting then resetting the setting to default to get around it. Generally speaking, it maxes around 75C, but that's mostly due to the default fan profile only ramping up enough to negate further gains at that point (I'm guessing that's to do with trying to keep the card quiet). If I supply cool air, it'll slow the fan, and the heat still comes eventually. Some things that may or may not be relevant: This card crashes mostly around times that the clock rate adjusts more often; If the card goes from, say, max freq to a step below and back, there's a chance of a crash. (maybe coincidence, maybe not, I don't know to be bluntly honest) This is a constant I've noticed on both OSes. Windows 10 tends to keep things relatively stable in that regard, while Manjaro tends to see a lot of spiking and sudden drops. SteamVR definitely instigates that kind of behavior in my experience on my old Vega 56 as well (Which with nodma set on Navi, is actually not much different tbh). Probably explains why ever since the latest set of patches, the majority of the time it crashes is after an hour or two of gameplay in Manjaro. (also no idea why Manjaro switches more often..) To be blunt, though, in both OSes, seemingly random hangs are also a common occurrence for me. I had Win10 just yesterday, hang completely, no recovery, simply animating a minimizing window as SteamVR first opened. Granted, this also coincided with a rapid up-tick in clock speed most likely, as I've observed this massive spike on launching SteamVR via GPU adjusting utilities before I realized they instigate the issue as well. Setting nodma does get rid of some of the more random crashes, but these ones stick around in my experience so far. Maybe 75C is a bit high, but in neither OS can I manage to adjust the fans without the same issue, so.. No idea what to do, here. -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/i915/gvt: fix dropping obj reference twice
On 2019.11.06 15:31:07 +0800, Pan Bian wrote: > The reference count of obj will be decremented twice if error occurs > in dma_buf_fd(). Additionally, attempting to read the reference count of > obj after dropping reference may lead to a use after free bug. Here, we > drop obj's reference until it is not used. > > Signed-off-by: Pan Bian > --- > drivers/gpu/drm/i915/gvt/dmabuf.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c > b/drivers/gpu/drm/i915/gvt/dmabuf.c > index 13044c027f27..4bfaefdf548d 100644 > --- a/drivers/gpu/drm/i915/gvt/dmabuf.c > +++ b/drivers/gpu/drm/i915/gvt/dmabuf.c > @@ -498,8 +498,6 @@ int intel_vgpu_get_dmabuf(struct intel_vgpu *vgpu, > unsigned int dmabuf_id) > goto out_free_gem; > } > > - i915_gem_object_put(obj); > - > ret = dma_buf_fd(dmabuf, DRM_CLOEXEC | DRM_RDWR); > if (ret < 0) { > gvt_vgpu_err("create dma-buf fd failed ret:%d\n", ret); > @@ -524,6 +522,8 @@ int intel_vgpu_get_dmabuf(struct intel_vgpu *vgpu, > unsigned int dmabuf_id) > file_count(dmabuf->file), > kref_read(&obj->base.refcount)); > > + i915_gem_object_put(obj); > + > return dmabuf_fd; > > out_free_dmabuf: Looks fine to me. Thanks! Reviewed-by: Zhenyu Wang -- Open Source Technology Center, Intel ltd. $gpg --keyserver wwwkeys.pgp.net --recv-keys 4D781827 signature.asc Description: PGP signature ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 8/9] drm/ast: Add cursor plane
On Wed, Nov 6, 2019 at 9:31 AM Thomas Zimmermann wrote: > > Hi > > Am 05.11.19 um 10:55 schrieb Daniel Vetter: > > On Mon, Oct 28, 2019 at 04:49:27PM +0100, Thomas Zimmermann wrote: > >> The cursor plane uses an internal format of ARGB. To userspace, we > >> announce ARGB and do the transformation internally. > >> > >> Signed-off-by: Thomas Zimmermann > > > > Hm, might be fun to also expose the ARGB directly. Not that anyone > > will actually use it :-/ > > Is that a serious proposal? I thought about ARGB and quickly > dismissed it because no one will ever support it anyway. For cursor maybe not, but in other cases where we added the RGB->native format hack because userspace, we did make sure that the driver exposes the native formats too. Up to you really. -Daniel > > Best regards > Thomas > > > -Daniel > > > >> --- > >> drivers/gpu/drm/ast/ast_drv.h | 1 + > >> drivers/gpu/drm/ast/ast_mode.c | 161 - > >> 2 files changed, 161 insertions(+), 1 deletion(-) > >> > >> diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h > >> index 13560622f22a..49557a73390f 100644 > >> --- a/drivers/gpu/drm/ast/ast_drv.h > >> +++ b/drivers/gpu/drm/ast/ast_drv.h > >> @@ -122,6 +122,7 @@ struct ast_private { > >> } cursor; > >> > >> struct drm_plane primary_plane; > >> +struct drm_plane cursor_plane; > >> > >> bool support_wide_screen; > >> enum { > >> diff --git a/drivers/gpu/drm/ast/ast_mode.c > >> b/drivers/gpu/drm/ast/ast_mode.c > >> index 7667f4502eb9..f5f73200e8e4 100644 > >> --- a/drivers/gpu/drm/ast/ast_mode.c > >> +++ b/drivers/gpu/drm/ast/ast_mode.c > >> @@ -54,6 +54,16 @@ static int ast_cursor_move(struct drm_crtc *crtc, > >> int x, int y); > >> > >> > >> +static u32 copy_cursor_image(u8 *src, u8 *dst, int width, int height); > >> +static int ast_cursor_update(void *dst, void *src, unsigned int width, > >> + unsigned int height); > >> +static void ast_cursor_set_base(struct ast_private *ast, u64 address); > >> +static int ast_show_cursor(struct drm_crtc *crtc, void *src, > >> + unsigned int width, unsigned int height); > >> +static void ast_hide_cursor(struct drm_crtc *crtc); > >> +static int ast_cursor_move(struct drm_crtc *crtc, > >> + int x, int y); > >> + > >> static inline void ast_load_palette_index(struct ast_private *ast, > >> u8 index, u8 red, u8 green, > >> u8 blue) > >> @@ -594,6 +604,139 @@ static const struct drm_plane_funcs > >> ast_primary_plane_funcs = { > >> .format_mod_supported = NULL, > >> }; > >> > >> +/* > >> + * Cursor plane > >> + */ > >> + > >> +static int > >> +ast_cursor_plane_helper_prepare_fb(struct drm_plane *plane, > >> + struct drm_plane_state *new_state) > >> +{ > >> +struct drm_framebuffer *fb = new_state->fb; > >> +struct drm_crtc *crtc = new_state->crtc; > >> +struct drm_gem_vram_object *gbo; > >> +struct ast_private *ast; > >> +int ret; > >> +void *src, *dst; > >> + > >> +if (!crtc || !fb) > >> +return 0; > >> + > >> +if (fb->width > AST_MAX_HWC_WIDTH || fb->height > AST_MAX_HWC_HEIGHT) > >> +return -EINVAL; > >> + > >> +ast = crtc->dev->dev_private; > >> + > >> +gbo = drm_gem_vram_of_gem(fb->obj[0]); > >> +src = drm_gem_vram_vmap(gbo); > >> +if (IS_ERR(src)) { > >> +ret = PTR_ERR(src); > >> +goto err_drm_gem_vram_unpin; > >> +} > >> + > >> +dst = drm_gem_vram_vmap(ast->cursor.gbo[ast->cursor.next_index]); > >> +if (IS_ERR(dst)) { > >> +ret = PTR_ERR(dst); > >> +goto err_drm_gem_vram_vunmap_src; > >> +} > >> + > >> +ret = ast_cursor_update(dst, src, fb->width, fb->height); > >> +if (ret) > >> +goto err_drm_gem_vram_vunmap_dst; > >> + > >> +/* Always unmap buffers here. Destination buffers are > >> + * perma-pinned while the driver is active. We're only > >> + * changing ref-counters here. > >> + */ > >> +drm_gem_vram_vunmap(ast->cursor.gbo[ast->cursor.next_index], dst); > >> +drm_gem_vram_vunmap(gbo, src); > >> + > >> +return 0; > >> + > >> +err_drm_gem_vram_vunmap_dst: > >> +drm_gem_vram_vunmap(ast->cursor.gbo[ast->cursor.next_index], dst); > >> +err_drm_gem_vram_vunmap_src: > >> +drm_gem_vram_vunmap(gbo, src); > >> +err_drm_gem_vram_unpin: > >> +drm_gem_vram_unpin(gbo); > >> +return ret; > >> +} > >> + > >> +static int ast_cursor_plane_helper_atomic_check(struct drm_plane *plane, > >> +struct drm_plane_state *state) > >> +{ > >> +return 0; > >> +} > >> + > >> +static void > >> +ast_cursor_plane_helper_atomic_update(struct drm_plane *plane, > >> + struct drm_plane_state *old_state) > >> +{ > >> +stru
Re: [PATCH v2 7/7] drm/mediatek: Support 180 degree rotation
Hi, Sean: On Tue, 2019-11-05 at 16:10 -0500, Sean Paul wrote: > From: Sean Paul > > Now that we support both reflections, we can expose 180 degree rotation > and rely on the simplify routine to convert that into REFLECT_X | > REFLECT_Y > Patch 1 ~ 6 of this series looks good to me. For this one, I think the rotation check in mtk_ovl_layer_check() should be modified. Regards, CK > Signed-off-by: Sean Paul > --- > drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c > b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c > index f4c4d3fedc5f..4a55bb6e2213 100644 > --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c > +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c > @@ -143,8 +143,8 @@ static unsigned int mtk_ovl_layer_nr(struct mtk_ddp_comp > *comp) > > static unsigned int mtk_ovl_supported_rotations(struct mtk_ddp_comp *comp) > { > - return DRM_MODE_ROTATE_0 | DRM_MODE_REFLECT_Y | > -DRM_MODE_REFLECT_X; > + return DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 | > +DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y; > } > > static int mtk_ovl_layer_check(struct mtk_ddp_comp *comp, unsigned int idx, ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 5/8] drm/client: Return I/O memory flag from drm_client_buffer_vmap()
With this patch, drm_client_buffer_vmap() forwards the io_mem parameter from the vmap implementation to its caller. By default, is_iomem is assumed to be false. This matches the return type and the old behaviour. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/drm_client.c| 15 --- drivers/gpu/drm/drm_fb_helper.c | 4 ++-- include/drm/drm_client.h| 7 ++- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c index 0ecb588778c5..44af56fc4b4d 100644 --- a/drivers/gpu/drm/drm_client.c +++ b/drivers/gpu/drm/drm_client.c @@ -290,6 +290,8 @@ drm_client_buffer_create(struct drm_client_dev *client, u32 width, u32 height, u /** * drm_client_buffer_vmap - Map DRM client buffer into address space * @buffer: DRM client buffer + * @is_iomem: Returns true if the mapped memory is I/O memory, or false + *otherwise; can be NULL * * This function maps a client buffer into kernel address space. If the * buffer is already mapped, it returns the mapping's address. @@ -302,12 +304,16 @@ drm_client_buffer_create(struct drm_client_dev *client, u32 width, u32 height, u * Returns: * The mapped memory's address */ -void *drm_client_buffer_vmap(struct drm_client_buffer *buffer) +void *drm_client_buffer_vmap(struct drm_client_buffer *buffer, bool *is_iomem) { void *vaddr; + bool vaddr_is_iomem; - if (buffer->vaddr) + if (buffer->vaddr) { + if (is_iomem) + *is_iomem = buffer->vaddr_is_iomem; return buffer->vaddr; + } /* * FIXME: The dependency on GEM here isn't required, we could @@ -317,12 +323,15 @@ void *drm_client_buffer_vmap(struct drm_client_buffer *buffer) * fd_install step out of the driver backend hooks, to make that * final step optional for internal users. */ - vaddr = drm_gem_vmap(buffer->gem, NULL); + vaddr = drm_gem_vmap(buffer->gem, &vaddr_is_iomem); if (IS_ERR(vaddr)) return vaddr; buffer->vaddr = vaddr; + buffer->vaddr_is_iomem = vaddr_is_iomem; + if (is_iomem) + *is_iomem = vaddr_is_iomem; return vaddr; } EXPORT_SYMBOL(drm_client_buffer_vmap); diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 8ebeccdeed23..eff75fad7cab 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -422,7 +422,7 @@ static void drm_fb_helper_dirty_work(struct work_struct *work) /* Generic fbdev uses a shadow buffer */ if (helper->buffer) { - vaddr = drm_client_buffer_vmap(helper->buffer); + vaddr = drm_client_buffer_vmap(helper->buffer, NULL); if (IS_ERR(vaddr)) return; drm_fb_helper_dirty_blit_real(helper, &clip_copy); @@ -2212,7 +2212,7 @@ int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper, fb_deferred_io_init(fbi); } else { /* buffer is mapped for HW framebuffer */ - vaddr = drm_client_buffer_vmap(fb_helper->buffer); + vaddr = drm_client_buffer_vmap(fb_helper->buffer, NULL); if (IS_ERR(vaddr)) return PTR_ERR(vaddr); diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h index 5cf2c5dd8b1e..053d58215be7 100644 --- a/include/drm/drm_client.h +++ b/include/drm/drm_client.h @@ -140,6 +140,11 @@ struct drm_client_buffer { */ void *vaddr; + /** +* @vaddr_is_iomem: True if vaddr points to I/O memory, false otherwise +*/ + bool vaddr_is_iomem; + /** * @fb: DRM framebuffer */ @@ -149,7 +154,7 @@ struct drm_client_buffer { struct drm_client_buffer * drm_client_framebuffer_create(struct drm_client_dev *client, u32 width, u32 height, u32 format); void drm_client_framebuffer_delete(struct drm_client_buffer *buffer); -void *drm_client_buffer_vmap(struct drm_client_buffer *buffer); +void *drm_client_buffer_vmap(struct drm_client_buffer *buffer, bool *is_iomem); void drm_client_buffer_vunmap(struct drm_client_buffer *buffer); int drm_client_modeset_create(struct drm_client_dev *client); -- 2.23.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 4/8] drm/gem: Return I/O-memory flag from drm_gem_vram()
With this patch, drm_gem_vmap() forwards the io_mem parameter from the vmap implementation to its caller. By default, is_iomem is assumed to be false. This matches the return type and the old behaviour. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/drm_client.c | 2 +- drivers/gpu/drm/drm_gem.c | 9 ++--- drivers/gpu/drm/drm_internal.h | 2 +- drivers/gpu/drm/drm_prime.c| 2 +- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c index d9a2e3695525..0ecb588778c5 100644 --- a/drivers/gpu/drm/drm_client.c +++ b/drivers/gpu/drm/drm_client.c @@ -317,7 +317,7 @@ void *drm_client_buffer_vmap(struct drm_client_buffer *buffer) * fd_install step out of the driver backend hooks, to make that * final step optional for internal users. */ - vaddr = drm_gem_vmap(buffer->gem); + vaddr = drm_gem_vmap(buffer->gem, NULL); if (IS_ERR(vaddr)) return vaddr; diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 0acfbd134e04..6b1ae482dfa9 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -1246,14 +1246,17 @@ void drm_gem_unpin(struct drm_gem_object *obj) obj->dev->driver->gem_prime_unpin(obj); } -void *drm_gem_vmap(struct drm_gem_object *obj) +void *drm_gem_vmap(struct drm_gem_object *obj, bool *is_iomem) { void *vaddr; + if (is_iomem) + *is_iomem = false; /* default value matches return type */ + if (obj->funcs && obj->funcs->vmap) - vaddr = obj->funcs->vmap(obj, NULL); + vaddr = obj->funcs->vmap(obj, is_iomem); else if (obj->dev->driver->gem_prime_vmap) - vaddr = obj->dev->driver->gem_prime_vmap(obj, NULL); + vaddr = obj->dev->driver->gem_prime_vmap(obj, is_iomem); else vaddr = ERR_PTR(-EOPNOTSUPP); diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h index 51a2055c8f18..78578e6e1197 100644 --- a/drivers/gpu/drm/drm_internal.h +++ b/drivers/gpu/drm/drm_internal.h @@ -135,7 +135,7 @@ void drm_gem_print_info(struct drm_printer *p, unsigned int indent, int drm_gem_pin(struct drm_gem_object *obj); void drm_gem_unpin(struct drm_gem_object *obj); -void *drm_gem_vmap(struct drm_gem_object *obj); +void *drm_gem_vmap(struct drm_gem_object *obj, bool *is_iomem); void drm_gem_vunmap(struct drm_gem_object *obj, void *vaddr); /* drm_debugfs.c drm_debugfs_crc.c */ diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 0814211b0f3f..68492ca418ec 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -671,7 +671,7 @@ void *drm_gem_dmabuf_vmap(struct dma_buf *dma_buf) struct drm_gem_object *obj = dma_buf->priv; void *vaddr; - vaddr = drm_gem_vmap(obj); + vaddr = drm_gem_vmap(obj, NULL); if (IS_ERR(vaddr)) vaddr = NULL; -- 2.23.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 2/8] drm/qxl: Tell caller if kmap() returned I/O memory
Returning a flag from kmap() whether mapped pages refer to system or I/O memory. This prepares for a respective change to vmap(). Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/qxl/qxl_display.c | 6 +++--- drivers/gpu/drm/qxl/qxl_draw.c| 4 ++-- drivers/gpu/drm/qxl/qxl_drv.h | 2 +- drivers/gpu/drm/qxl/qxl_object.c | 7 +++ drivers/gpu/drm/qxl/qxl_object.h | 2 +- drivers/gpu/drm/qxl/qxl_prime.c | 2 +- 6 files changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index 16d73b22f3f5..83c8df2f9d64 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -606,7 +606,7 @@ static void qxl_cursor_atomic_update(struct drm_plane *plane, user_bo = gem_to_qxl_bo(obj); /* pinning is done in the prepare/cleanup framevbuffer */ - ret = qxl_bo_kmap(user_bo, &user_ptr); + ret = qxl_bo_kmap(user_bo, &user_ptr, NULL); if (ret) goto out_free_release; @@ -624,7 +624,7 @@ static void qxl_cursor_atomic_update(struct drm_plane *plane, if (ret) goto out_unpin; - ret = qxl_bo_kmap(cursor_bo, (void **)&cursor); + ret = qxl_bo_kmap(cursor_bo, (void **)&cursor, NULL); if (ret) goto out_backoff; @@ -1167,7 +1167,7 @@ int qxl_create_monitors_object(struct qxl_device *qdev) if (ret) return ret; - qxl_bo_kmap(qdev->monitors_config_bo, NULL); + qxl_bo_kmap(qdev->monitors_config_bo, NULL, NULL); qdev->monitors_config = qdev->monitors_config_bo->kptr; qdev->ram_header->monitors_config = diff --git a/drivers/gpu/drm/qxl/qxl_draw.c b/drivers/gpu/drm/qxl/qxl_draw.c index 5bebf1ea1c5d..962fc1aa00b7 100644 --- a/drivers/gpu/drm/qxl/qxl_draw.c +++ b/drivers/gpu/drm/qxl/qxl_draw.c @@ -45,7 +45,7 @@ static struct qxl_rect *drawable_set_clipping(struct qxl_device *qdev, struct qxl_clip_rects *dev_clips; int ret; - ret = qxl_bo_kmap(clips_bo, (void **)&dev_clips); + ret = qxl_bo_kmap(clips_bo, (void **)&dev_clips, NULL); if (ret) { return NULL; } @@ -197,7 +197,7 @@ void qxl_draw_dirty_fb(struct qxl_device *qdev, if (ret) goto out_release_backoff; - ret = qxl_bo_kmap(bo, (void **)&surface_base); + ret = qxl_bo_kmap(bo, (void **)&surface_base, NULL); if (ret) goto out_release_backoff; diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h index 27e45a2d6b52..e749c0d0e819 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.h +++ b/drivers/gpu/drm/qxl/qxl_drv.h @@ -342,7 +342,7 @@ int qxl_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_priv); void qxl_gem_object_close(struct drm_gem_object *obj, struct drm_file *file_priv); void qxl_bo_force_delete(struct qxl_device *qdev); -int qxl_bo_kmap(struct qxl_bo *bo, void **ptr); +int qxl_bo_kmap(struct qxl_bo *bo, void **ptr, bool *is_iomem); /* qxl_dumb.c */ int qxl_mode_dumb_create(struct drm_file *file_priv, diff --git a/drivers/gpu/drm/qxl/qxl_object.c b/drivers/gpu/drm/qxl/qxl_object.c index ab72dc3476e9..8507ac2c7d6a 100644 --- a/drivers/gpu/drm/qxl/qxl_object.c +++ b/drivers/gpu/drm/qxl/qxl_object.c @@ -143,9 +143,8 @@ int qxl_bo_create(struct qxl_device *qdev, return 0; } -int qxl_bo_kmap(struct qxl_bo *bo, void **ptr) +int qxl_bo_kmap(struct qxl_bo *bo, void **ptr, bool *is_iomem) { - bool is_iomem; int r; if (bo->kptr) { @@ -157,7 +156,7 @@ int qxl_bo_kmap(struct qxl_bo *bo, void **ptr) r = ttm_bo_kmap(&bo->tbo, 0, bo->tbo.num_pages, &bo->kmap); if (r) return r; - bo->kptr = ttm_kmap_obj_virtual(&bo->kmap, &is_iomem); + bo->kptr = ttm_kmap_obj_virtual(&bo->kmap, is_iomem); if (ptr) *ptr = bo->kptr; bo->map_count = 1; @@ -187,7 +186,7 @@ void *qxl_bo_kmap_atomic_page(struct qxl_device *qdev, return rptr; } - ret = qxl_bo_kmap(bo, &rptr); + ret = qxl_bo_kmap(bo, &rptr, NULL); if (ret) return NULL; diff --git a/drivers/gpu/drm/qxl/qxl_object.h b/drivers/gpu/drm/qxl/qxl_object.h index 8ae54ba7857c..79cb363b3b8b 100644 --- a/drivers/gpu/drm/qxl/qxl_object.h +++ b/drivers/gpu/drm/qxl/qxl_object.h @@ -91,7 +91,7 @@ extern int qxl_bo_create(struct qxl_device *qdev, bool kernel, bool pinned, u32 domain, struct qxl_surface *surf, struct qxl_bo **bo_ptr); -extern int qxl_bo_kmap(struct qxl_bo *bo, void **ptr); +extern int qxl_bo_kmap(struct qxl_bo *bo, void **ptr, bool *is_iomem); extern void qxl_bo_kunmap(struct qxl_bo *bo); void *qxl_bo_kmap_atomic_page(struct qxl_device *qdev
[PATCH 7/8] drm/fb-helper: Select between fb_{sys, cfb}_read() and _write()
Generic fbdev emulation used to access framebuffers as if they were located in system memory. Depending on the whether the framebuffer is in I/O or system memory, the fbdev emulation now calls the correct functions for accessing each. This change allows to support generic fbdev emulation on systems that treat both memory areas differently. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/drm_fb_helper.c | 110 ++-- include/drm/drm_fb_helper.h | 14 2 files changed, 118 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index eff75fad7cab..174e6d97223f 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -771,6 +771,45 @@ void drm_fb_helper_sys_imageblit(struct fb_info *info, } EXPORT_SYMBOL(drm_fb_helper_sys_imageblit); +/** + * drm_fb_helper_cfb_read - wrapper around fb_cfb_read + * @info: fb_info struct pointer + * @buf: userspace buffer to read from framebuffer memory + * @count: number of bytes to read from framebuffer memory + * @ppos: read offset within framebuffer memory + * + * A wrapper around fb_cfb_read implemented by fbdev core + */ +ssize_t drm_fb_helper_cfb_read(struct fb_info *info, char __user *buf, + size_t count, loff_t *ppos) +{ + return fb_cfb_read(info, buf, count, ppos); +} +EXPORT_SYMBOL(drm_fb_helper_cfb_read); + +/** + * drm_fb_helper_cfb_write - wrapper around fb_cfb_write + * @info: fb_info struct pointer + * @buf: userspace buffer to write to framebuffer memory + * @count: number of bytes to write to framebuffer memory + * @ppos: write offset within framebuffer memory + * + * A wrapper around fb_cfb_write implemented by fbdev core + */ +ssize_t drm_fb_helper_cfb_write(struct fb_info *info, const char __user *buf, + size_t count, loff_t *ppos) +{ + ssize_t ret; + + ret = fb_cfb_write(info, buf, count, ppos); + if (ret > 0) + drm_fb_helper_dirty(info, 0, 0, info->var.xres, + info->var.yres); + + return ret; +} +EXPORT_SYMBOL(drm_fb_helper_cfb_write); + /** * drm_fb_helper_cfb_fillrect - wrapper around cfb_fillrect * @info: fbdev registered by the helper @@ -2122,6 +2161,59 @@ static int drm_fbdev_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) return -ENODEV; } +static ssize_t drm_fbdev_fb_read(struct fb_info *info, char __user *buf, +size_t count, loff_t *ppos) +{ + struct drm_fb_helper *fb_helper = info->par; + + if (fb_helper->screen_buffer_is_iomem) + return drm_fb_helper_cfb_read(info, buf, count, ppos); + return drm_fb_helper_sys_read(info, buf, count, ppos); +} + +static ssize_t drm_fbdev_fb_write(struct fb_info *info, const char __user *buf, + size_t count, loff_t *ppos) +{ + struct drm_fb_helper *fb_helper = info->par; + + if (fb_helper->screen_buffer_is_iomem) + return drm_fb_helper_cfb_write(info, buf, count, ppos); + return drm_fb_helper_sys_write(info, buf, count, ppos); +} + +static void drm_fbdev_fb_fillrect(struct fb_info *info, + const struct fb_fillrect *rect) +{ + struct drm_fb_helper *fb_helper = info->par; + + if (fb_helper->screen_buffer_is_iomem) + drm_fb_helper_cfb_fillrect(info, rect); + else + drm_fb_helper_sys_fillrect(info, rect); +} + +static void drm_fbdev_fb_copyarea(struct fb_info *info, + const struct fb_copyarea *region) +{ + struct drm_fb_helper *fb_helper = info->par; + + if (fb_helper->screen_buffer_is_iomem) + drm_fb_helper_cfb_copyarea(info, region); + else + drm_fb_helper_sys_copyarea(info, region); +} + +static void drm_fbdev_fb_imageblit(struct fb_info *info, + const struct fb_image *image) +{ + struct drm_fb_helper *fb_helper = info->par; + + if (fb_helper->screen_buffer_is_iomem) + drm_fb_helper_cfb_imageblit(info, image); + else + drm_fb_helper_sys_imageblit(info, image); +} + static struct fb_ops drm_fbdev_fb_ops = { .owner = THIS_MODULE, DRM_FB_HELPER_DEFAULT_OPS, @@ -2129,11 +2221,11 @@ static struct fb_ops drm_fbdev_fb_ops = { .fb_release = drm_fbdev_fb_release, .fb_destroy = drm_fbdev_fb_destroy, .fb_mmap= drm_fbdev_fb_mmap, - .fb_read= drm_fb_helper_sys_read, - .fb_write = drm_fb_helper_sys_write, - .fb_fillrect= drm_fb_helper_sys_fillrect, - .fb_copyarea= drm_fb_helper_sys_copyarea, - .fb_imageblit = drm_fb_helper_sys_imageblit, + .fb_read= drm_fbdev_fb_read, + .fb_write = drm_fbdev_fb_write, + .fb_fillrect= drm_
[RFC][PATCH 0/8] Support I/O memory in generic fbdev emulation
We recently had a discussion if/how fbdev emulation could support framebuffers in I/O memory on all platform. [1] I typed up a patchset that passes information about the memory area from memory manager to client (e.g., fbdev emulation). The client can take this into consideration when accessing the framebuffer. The alternative proposal is to introduce a separate vmap() call that only returns I/O memorym or NULL if the framebuffer is not in I/O memory. AFAICS the benefit of this idea is the cleaner interface and the ability to modify drivers one by one. The drawback is some additional boilerplate code in drivers and clients. [1] https://lists.freedesktop.org/archives/dri-devel/2019-November/242464.html Thomas Zimmermann (8): drm/vram-helper: Tell caller if vmap() returned I/O memory drm/qxl: Tell caller if kmap() returned I/O memory drm: Add is_iomem return parameter to struct drm_gem_object_funcs.vmap drm/gem: Return I/O-memory flag from drm_gem_vram() drm/client: Return I/O memory flag from drm_client_buffer_vmap() fbdev: Export default read and write operations as fb_cfb_{read,write}() drm/fb-helper: Select between fb_{sys,cfb}_read() and _write() drm/fb-helper: Handle I/O memory correctly when flushing shadow fb drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 6 +- drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.h | 2 +- drivers/gpu/drm/ast/ast_mode.c | 6 +- drivers/gpu/drm/cirrus/cirrus.c | 2 +- drivers/gpu/drm/drm_client.c| 15 ++- drivers/gpu/drm/drm_fb_helper.c | 118 ++-- drivers/gpu/drm/drm_gem.c | 9 +- drivers/gpu/drm/drm_gem_cma_helper.c| 7 +- drivers/gpu/drm/drm_gem_shmem_helper.c | 12 +- drivers/gpu/drm/drm_gem_vram_helper.c | 13 ++- drivers/gpu/drm/drm_internal.h | 2 +- drivers/gpu/drm/drm_prime.c | 2 +- drivers/gpu/drm/etnaviv/etnaviv_drv.h | 2 +- drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c | 4 +- drivers/gpu/drm/mgag200/mgag200_cursor.c| 4 +- drivers/gpu/drm/nouveau/nouveau_gem.h | 2 +- drivers/gpu/drm/nouveau/nouveau_prime.c | 4 +- drivers/gpu/drm/panfrost/panfrost_perfcnt.c | 2 +- drivers/gpu/drm/qxl/qxl_display.c | 6 +- drivers/gpu/drm/qxl/qxl_draw.c | 4 +- drivers/gpu/drm/qxl/qxl_drv.h | 4 +- drivers/gpu/drm/qxl/qxl_object.c| 7 +- drivers/gpu/drm/qxl/qxl_object.h| 2 +- drivers/gpu/drm/qxl/qxl_prime.c | 4 +- drivers/gpu/drm/radeon/radeon_drv.c | 2 +- drivers/gpu/drm/radeon/radeon_prime.c | 4 +- drivers/gpu/drm/tiny/gm12u320.c | 2 +- drivers/gpu/drm/vc4/vc4_bo.c| 4 +- drivers/gpu/drm/vc4/vc4_drv.h | 2 +- drivers/gpu/drm/vgem/vgem_drv.c | 5 +- drivers/gpu/drm/xen/xen_drm_front_gem.c | 6 +- drivers/gpu/drm/xen/xen_drm_front_gem.h | 3 +- drivers/video/fbdev/core/fbmem.c| 53 +++-- include/drm/drm_client.h| 7 +- include/drm/drm_drv.h | 2 +- include/drm/drm_fb_helper.h | 14 +++ include/drm/drm_gem.h | 2 +- include/drm/drm_gem_cma_helper.h| 2 +- include/drm/drm_gem_shmem_helper.h | 2 +- include/drm/drm_gem_vram_helper.h | 2 +- include/linux/fb.h | 5 + 41 files changed, 278 insertions(+), 78 deletions(-) -- 2.23.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 1/8] drm/vram-helper: Tell caller if vmap() returned I/O memory
Returning a flag from kmap() whether mapped pages refer to system or I/O memory. This prepares for a respective change to vmap(). Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/ast/ast_mode.c | 6 +++--- drivers/gpu/drm/drm_gem_vram_helper.c| 8 +--- drivers/gpu/drm/mgag200/mgag200_cursor.c | 4 ++-- include/drm/drm_gem_vram_helper.h| 2 +- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index b13eaa2619ab..bcfab641c3a9 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -1165,7 +1165,7 @@ static int ast_show_cursor(struct drm_crtc *crtc, void *src, u8 jreg; gbo = ast->cursor.gbo[ast->cursor.next_index]; - dst = drm_gem_vram_vmap(gbo); + dst = drm_gem_vram_vmap(gbo, NULL); if (IS_ERR(dst)) return PTR_ERR(dst); off = drm_gem_vram_offset(gbo); @@ -1231,7 +1231,7 @@ static int ast_cursor_set(struct drm_crtc *crtc, return -ENOENT; } gbo = drm_gem_vram_of_gem(obj); - src = drm_gem_vram_vmap(gbo); + src = drm_gem_vram_vmap(gbo, NULL); if (IS_ERR(src)) { ret = PTR_ERR(src); goto err_drm_gem_object_put_unlocked; @@ -1264,7 +1264,7 @@ static int ast_cursor_move(struct drm_crtc *crtc, u8 jreg; gbo = ast->cursor.gbo[ast->cursor.next_index]; - dst = drm_gem_vram_vmap(gbo); + dst = drm_gem_vram_vmap(gbo, NULL); if (IS_ERR(dst)) return PTR_ERR(dst); diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c b/drivers/gpu/drm/drm_gem_vram_helper.c index 666cb4c22bb9..05f63f28814d 100644 --- a/drivers/gpu/drm/drm_gem_vram_helper.c +++ b/drivers/gpu/drm/drm_gem_vram_helper.c @@ -411,6 +411,8 @@ EXPORT_SYMBOL(drm_gem_vram_kunmap); * drm_gem_vram_vmap() - Pins and maps a GEM VRAM object into kernel address * space * @gbo: The GEM VRAM object to map + * @is_iomem: returns true if the mapped memory is I/O memory, or false + * otherwise; can be NULL * * The vmap function pins a GEM VRAM object to its current location, either * system or video memory, and maps its buffer into kernel address space. @@ -425,7 +427,7 @@ EXPORT_SYMBOL(drm_gem_vram_kunmap); * The buffer's virtual address on success, or * an ERR_PTR()-encoded error code otherwise. */ -void *drm_gem_vram_vmap(struct drm_gem_vram_object *gbo) +void *drm_gem_vram_vmap(struct drm_gem_vram_object *gbo, bool *is_iomem) { int ret; void *base; @@ -437,7 +439,7 @@ void *drm_gem_vram_vmap(struct drm_gem_vram_object *gbo) ret = drm_gem_vram_pin_locked(gbo, 0); if (ret) goto err_ttm_bo_unreserve; - base = drm_gem_vram_kmap_locked(gbo, true, NULL); + base = drm_gem_vram_kmap_locked(gbo, true, is_iomem); if (IS_ERR(base)) { ret = PTR_ERR(base); goto err_drm_gem_vram_unpin_locked; @@ -826,7 +828,7 @@ static void *drm_gem_vram_object_vmap(struct drm_gem_object *gem) struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem); void *base; - base = drm_gem_vram_vmap(gbo); + base = drm_gem_vram_vmap(gbo, NULL); if (IS_ERR(base)) return NULL; return base; diff --git a/drivers/gpu/drm/mgag200/mgag200_cursor.c b/drivers/gpu/drm/mgag200/mgag200_cursor.c index 79711dbb5b03..765c59e25f3b 100644 --- a/drivers/gpu/drm/mgag200/mgag200_cursor.c +++ b/drivers/gpu/drm/mgag200/mgag200_cursor.c @@ -131,7 +131,7 @@ static int mgag200_show_cursor(struct mga_device *mdev, void *src, WREG8(MGA_CURPOSXH, 0); return -ENOTSUPP; /* Didn't allocate space for cursors */ } - dst = drm_gem_vram_vmap(gbo); + dst = drm_gem_vram_vmap(gbo, NULL); if (IS_ERR(dst)) { ret = PTR_ERR(dst); dev_err(&dev->pdev->dev, @@ -282,7 +282,7 @@ int mgag200_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, if (!obj) return -ENOENT; gbo = drm_gem_vram_of_gem(obj); - src = drm_gem_vram_vmap(gbo); + src = drm_gem_vram_vmap(gbo, NULL); if (IS_ERR(src)) { ret = PTR_ERR(src); dev_err(&dev->pdev->dev, diff --git a/include/drm/drm_gem_vram_helper.h b/include/drm/drm_gem_vram_helper.h index e040541a105f..ef8f81acff91 100644 --- a/include/drm/drm_gem_vram_helper.h +++ b/include/drm/drm_gem_vram_helper.h @@ -106,7 +106,7 @@ int drm_gem_vram_unpin(struct drm_gem_vram_object *gbo); void *drm_gem_vram_kmap(struct drm_gem_vram_object *gbo, bool map, bool *is_iomem); void drm_gem_vram_kunmap(struct drm_gem_vram_object *gbo); -void *drm_gem_vram_vmap(struct drm_gem_vram_object *gbo); +void *drm_gem_vram_vmap(struct drm_gem_vram_object *gbo, bool *is_iomem); void drm_gem_vram
[PATCH 3/8] drm: Add is_iomem return parameter to struct drm_gem_object_funcs.vmap
The vmap operation can return system or I/O memory, which the caller may have to treat differently. The parameter is_iomem returns 'true' if the returned pointer refers to I/O memory, or 'false' otherwise. In many cases, such as CMA ans SHMEM, the returned value is 'false'. For TTM-based drivers, the correct value is provided by TTM itself. For DMA buffers that are shared among devices, we assume system memory as well. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 6 +- drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.h | 2 +- drivers/gpu/drm/cirrus/cirrus.c | 2 +- drivers/gpu/drm/drm_gem.c | 4 ++-- drivers/gpu/drm/drm_gem_cma_helper.c| 7 ++- drivers/gpu/drm/drm_gem_shmem_helper.c | 12 +--- drivers/gpu/drm/drm_gem_vram_helper.c | 7 +-- drivers/gpu/drm/etnaviv/etnaviv_drv.h | 2 +- drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c | 4 +++- drivers/gpu/drm/nouveau/nouveau_gem.h | 2 +- drivers/gpu/drm/nouveau/nouveau_prime.c | 4 +++- drivers/gpu/drm/panfrost/panfrost_perfcnt.c | 2 +- drivers/gpu/drm/qxl/qxl_drv.h | 2 +- drivers/gpu/drm/qxl/qxl_prime.c | 4 ++-- drivers/gpu/drm/radeon/radeon_drv.c | 2 +- drivers/gpu/drm/radeon/radeon_prime.c | 4 +++- drivers/gpu/drm/tiny/gm12u320.c | 2 +- drivers/gpu/drm/vc4/vc4_bo.c| 4 ++-- drivers/gpu/drm/vc4/vc4_drv.h | 2 +- drivers/gpu/drm/vgem/vgem_drv.c | 5 - drivers/gpu/drm/xen/xen_drm_front_gem.c | 6 +- drivers/gpu/drm/xen/xen_drm_front_gem.h | 3 ++- include/drm/drm_drv.h | 2 +- include/drm/drm_gem.h | 2 +- include/drm/drm_gem_cma_helper.h| 2 +- include/drm/drm_gem_shmem_helper.h | 2 +- 26 files changed, 64 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c index 4917b548b7f2..97b77e7e15dc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c @@ -57,13 +57,15 @@ struct sg_table *amdgpu_gem_prime_get_sg_table(struct drm_gem_object *obj) /** * amdgpu_gem_prime_vmap - &dma_buf_ops.vmap implementation * @obj: GEM BO + * @is_iomem: returns true if the mapped memory is I/O memory, or false + *otherwise; can be NULL * * Sets up an in-kernel virtual mapping of the BO's memory. * * Returns: * The virtual address of the mapping or an error pointer. */ -void *amdgpu_gem_prime_vmap(struct drm_gem_object *obj) +void *amdgpu_gem_prime_vmap(struct drm_gem_object *obj, bool *is_iomem) { struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); int ret; @@ -73,6 +75,8 @@ void *amdgpu_gem_prime_vmap(struct drm_gem_object *obj) if (ret) return ERR_PTR(ret); + if (is_iomem) + return ttm_kmap_obj_virtual(&bo->dma_buf_vmap, is_iomem); return bo->dma_buf_vmap.virtual; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.h index 5012e6ab58f1..910cf2ef345f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.h @@ -34,7 +34,7 @@ struct dma_buf *amdgpu_gem_prime_export(struct drm_gem_object *gobj, int flags); struct drm_gem_object *amdgpu_gem_prime_import(struct drm_device *dev, struct dma_buf *dma_buf); -void *amdgpu_gem_prime_vmap(struct drm_gem_object *obj); +void *amdgpu_gem_prime_vmap(struct drm_gem_object *obj, bool *is_iomem); void amdgpu_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr); int amdgpu_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma); diff --git a/drivers/gpu/drm/cirrus/cirrus.c b/drivers/gpu/drm/cirrus/cirrus.c index 248c9f765c45..6518e5c31eb4 100644 --- a/drivers/gpu/drm/cirrus/cirrus.c +++ b/drivers/gpu/drm/cirrus/cirrus.c @@ -302,7 +302,7 @@ static int cirrus_fb_blit_rect(struct drm_framebuffer *fb, struct cirrus_device *cirrus = fb->dev->dev_private; void *vmap; - vmap = drm_gem_shmem_vmap(fb->obj[0]); + vmap = drm_gem_shmem_vmap(fb->obj[0], NULL); if (!vmap) return -ENOMEM; diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 56f42e0f2584..0acfbd134e04 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -1251,9 +1251,9 @@ void *drm_gem_vmap(struct drm_gem_object *obj) void *vaddr; if (obj->funcs && obj->funcs->vmap) - vaddr = obj->funcs->vmap(obj); + vaddr = obj->funcs->vmap(obj, NULL); else if (obj->dev->driver->gem_prime_vmap) - vaddr = obj->dev->driver->gem_prime_vmap(obj); + vaddr = obj->dev
[PATCH 8/8] drm/fb-helper: Handle I/O memory correctly when flushing shadow fb
The fbdev console's framebuffer can be located in I/O memory, such as video RAM. When flushing the shadow fb, we test for this case and use I/O-based memcpy() instead. The shadow fb is always in system memory. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/drm_fb_helper.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 174e6d97223f..e76c42f8852e 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -393,10 +393,14 @@ static void drm_fb_helper_dirty_blit_real(struct drm_fb_helper *fb_helper, void *src = fb_helper->fbdev->screen_buffer + offset; void *dst = fb_helper->buffer->vaddr + offset; size_t len = (clip->x2 - clip->x1) * cpp; + bool is_iomem = fb_helper->buffer->vaddr_is_iomem; unsigned int y; for (y = clip->y1; y < clip->y2; y++) { - memcpy(dst, src, len); + if (is_iomem) + memcpy_toio((void __iomem *)dst, src, len); + else + memcpy(dst, src, len); src += fb->pitches[0]; dst += fb->pitches[0]; } -- 2.23.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 6/8] fbdev: Export default read and write operations as fb_cfb_{read, write}()
Read and write operations on the fbdev framebuffer can now be called by in-kernel users. This is required by DRM's fbdev helpers. Signed-off-by: Thomas Zimmermann --- drivers/video/fbdev/core/fbmem.c | 53 include/linux/fb.h | 5 +++ 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index 95c32952fa8a..e49cf2988001 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -754,11 +754,10 @@ static struct fb_info *file_fb_info(struct file *file) return info; } -static ssize_t -fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) +ssize_t +fb_cfb_read(struct fb_info *info, char __user *buf, size_t count, loff_t *ppos) { unsigned long p = *ppos; - struct fb_info *info = file_fb_info(file); u8 *buffer, *dst; u8 __iomem *src; int c, cnt = 0, err = 0; @@ -770,9 +769,6 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) if (info->state != FBINFO_STATE_RUNNING) return -EPERM; - if (info->fbops->fb_read) - return info->fbops->fb_read(info, buf, count, ppos); - total_size = info->screen_size; if (total_size == 0) @@ -818,12 +814,13 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) return (err) ? err : cnt; } +EXPORT_SYMBOL(fb_cfb_read); -static ssize_t -fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) +ssize_t +fb_cfb_write(struct fb_info *info, const char __user *buf, size_t count, +loff_t *ppos) { unsigned long p = *ppos; - struct fb_info *info = file_fb_info(file); u8 *buffer, *src; u8 __iomem *dst; int c, cnt = 0, err = 0; @@ -835,9 +832,6 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) if (info->state != FBINFO_STATE_RUNNING) return -EPERM; - if (info->fbops->fb_write) - return info->fbops->fb_write(info, buf, count, ppos); - total_size = info->screen_size; if (total_size == 0) @@ -890,6 +884,41 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) return (cnt) ? cnt : err; } +EXPORT_SYMBOL(fb_cfb_write); + +static ssize_t +fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) +{ + struct fb_info *info = file_fb_info(file); + + if (!info || !info->screen_base) + return -ENODEV; + + if (info->state != FBINFO_STATE_RUNNING) + return -EPERM; + + if (info->fbops->fb_read) + return info->fbops->fb_read(info, buf, count, ppos); + + return fb_cfb_read(info, buf, count, ppos); +} + +static ssize_t +fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) +{ + struct fb_info *info = file_fb_info(file); + + if (!info || !info->screen_base) + return -ENODEV; + + if (info->state != FBINFO_STATE_RUNNING) + return -EPERM; + + if (info->fbops->fb_write) + return info->fbops->fb_write(info, buf, count, ppos); + + return fb_cfb_write(info, buf, count, ppos); +} int fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var) diff --git a/include/linux/fb.h b/include/linux/fb.h index 41e0069eca0a..c69e098e6dc5 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -592,6 +592,11 @@ extern int fb_blank(struct fb_info *info, int blank); extern void cfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect); extern void cfb_copyarea(struct fb_info *info, const struct fb_copyarea *area); extern void cfb_imageblit(struct fb_info *info, const struct fb_image *image); +extern ssize_t fb_cfb_read(struct fb_info *info, char __user *buf, + size_t count, loff_t *ppos); +extern ssize_t fb_cfb_write(struct fb_info *info, const char __user *buf, + size_t count, loff_t *ppos); + /* * Drawing operations where framebuffer is in system RAM */ -- 2.23.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 201539] AMDGPU R9 390 automatic fan speed control in Linux 4.19/4.20/5.0
https://bugzilla.kernel.org/show_bug.cgi?id=201539 --- Comment #26 from MasterCATZ (masterc...@hotmail.com) --- around 12 hrs later lost fan control again -- You are receiving this mail because: You are watching the assignee of the bug. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/amdgpu: fix potential double drop fence reference
Am 06.11.19 um 10:14 schrieb Pan Bian: > The object fence is not set to NULL after its reference is dropped. As a > result, its reference may be dropped again if error occurs after that, > which may lead to a use after free bug. To avoid the issue, fence is > explicitly set to NULL after dropping its reference. > > Signed-off-by: Pan Bian Acked-by: Christian König > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_test.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c > index b66d29d5ffa2..b158230af8db 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c > @@ -138,6 +138,7 @@ static void amdgpu_do_test_moves(struct amdgpu_device > *adev) > } > > dma_fence_put(fence); > + fence = NULL; > > r = amdgpu_bo_kmap(vram_obj, &vram_map); > if (r) { > @@ -183,6 +184,7 @@ static void amdgpu_do_test_moves(struct amdgpu_device > *adev) > } > > dma_fence_put(fence); > + fence = NULL; > > r = amdgpu_bo_kmap(gtt_obj[i], >t_map); > if (r) { ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 111481] AMD Navi GPU frequent freezes on both Manjaro/Ubuntu with kernel 5.3 and mesa 19.2 -git/llvm9
https://bugs.freedesktop.org/show_bug.cgi?id=111481 --- Comment #211 from Marco Liedtke --- Hi folks, i am new to bugreporting, but due to having a new system and this bug, i want to contribute something to this situation. I have almost the same behavior as stated in comment 1. My Xorg freezes every session no matter what i do. I could only get the last dmesg befor i had to hard reboot over ssh, cause this was the only thing working. 2 Examples: [ 1184.577790] [drm:amdgpu_dm_commit_planes.constprop.0 [amdgpu]] *ERROR* Waiting for fences timed out or interrupted! [ 1189.697729] [drm:amdgpu_job_timedout [amdgpu]] *ERROR* ring sdma0 timeout, signaled seq=53043, emitted seq=53045 [ 1189.697797] [drm:amdgpu_job_timedout [amdgpu]] *ERROR* Process information: process Xorg pid 1398 thread Xorg:cs0 pid 1409 [ 1189.697799] [drm] GPU recovery disabled. [ 708.286318] [drm:amdgpu_dm_commit_planes.constprop.0 [amdgpu]] *ERROR* Waiting for fences timed out or interrupted! [ 713.406528] [drm:amdgpu_job_timedout [amdgpu]] *ERROR* ring sdma0 timeout, signaled seq=104848, emitted seq=104850 [ 713.406594] [drm:amdgpu_job_timedout [amdgpu]] *ERROR* Process information: process Xorg pid 1402 thread Xorg:cs0 pid 1414 [ 713.406596] [drm] GPU recovery disabled. I have already set AMD_DEBUG=nodam in /etc/environment and in ~/.profile. Last time i played World of Tanks via Wine and DXVK the same freeze occured, again the same error that xorg pid timed out... It is happenening after 1 Minute logged in or 1 hour. My System specs are: R7 3700x Powercolor R5700XT Red Dragon Silent Bios enabled Gigabyte X570 I Aourus Pro WIFI UBUNTU 18.04.3 LTS with Kernel 5.3.8 and Padoka unstable PPA (Mesa 19.3) I have no NVME SSD and i have no Monitoring applications running. Tests done: -With Kernel 4.15 standrad Ubuntu Kernel and AMDGPU-PRO installed, everything runs fine without a freeze. - With Kernel 4.18 and Mesa 19.0.8 no freezes occured, kernel does not recognize rx5700, so no amdgpu modul is loaded. freezes occured with kernel 5.3.7 and 5.3.8 and in combination with padoka and oibaf ppa (Mesa 19.3). If i can help with further information pls guide me to dig in my system the infos u need. -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 8/9] drm/ast: Add cursor plane
Hi Am 06.11.19 um 10:05 schrieb Daniel Vetter: > On Wed, Nov 6, 2019 at 9:31 AM Thomas Zimmermann wrote: >> >> Hi >> >> Am 05.11.19 um 10:55 schrieb Daniel Vetter: >>> On Mon, Oct 28, 2019 at 04:49:27PM +0100, Thomas Zimmermann wrote: The cursor plane uses an internal format of ARGB. To userspace, we announce ARGB and do the transformation internally. Signed-off-by: Thomas Zimmermann >>> >>> Hm, might be fun to also expose the ARGB directly. Not that anyone >>> will actually use it :-/ >> >> Is that a serious proposal? I thought about ARGB and quickly >> dismissed it because no one will ever support it anyway. > > For cursor maybe not, but in other cases where we added the > RGB->native format hack because userspace, we did make sure that > the driver exposes the native formats too. Up to you really. I see. In that case, I'd like to continue with the patchset as-is, but provide ARGB in a later patch. Best regards Thomas > -Daniel > >> >> Best regards >> Thomas >> >>> -Daniel >>> --- drivers/gpu/drm/ast/ast_drv.h | 1 + drivers/gpu/drm/ast/ast_mode.c | 161 - 2 files changed, 161 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 13560622f22a..49557a73390f 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -122,6 +122,7 @@ struct ast_private { } cursor; struct drm_plane primary_plane; +struct drm_plane cursor_plane; bool support_wide_screen; enum { diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 7667f4502eb9..f5f73200e8e4 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -54,6 +54,16 @@ static int ast_cursor_move(struct drm_crtc *crtc, int x, int y); +static u32 copy_cursor_image(u8 *src, u8 *dst, int width, int height); +static int ast_cursor_update(void *dst, void *src, unsigned int width, + unsigned int height); +static void ast_cursor_set_base(struct ast_private *ast, u64 address); +static int ast_show_cursor(struct drm_crtc *crtc, void *src, + unsigned int width, unsigned int height); +static void ast_hide_cursor(struct drm_crtc *crtc); +static int ast_cursor_move(struct drm_crtc *crtc, + int x, int y); + static inline void ast_load_palette_index(struct ast_private *ast, u8 index, u8 red, u8 green, u8 blue) @@ -594,6 +604,139 @@ static const struct drm_plane_funcs ast_primary_plane_funcs = { .format_mod_supported = NULL, }; +/* + * Cursor plane + */ + +static int +ast_cursor_plane_helper_prepare_fb(struct drm_plane *plane, + struct drm_plane_state *new_state) +{ +struct drm_framebuffer *fb = new_state->fb; +struct drm_crtc *crtc = new_state->crtc; +struct drm_gem_vram_object *gbo; +struct ast_private *ast; +int ret; +void *src, *dst; + +if (!crtc || !fb) +return 0; + +if (fb->width > AST_MAX_HWC_WIDTH || fb->height > AST_MAX_HWC_HEIGHT) +return -EINVAL; + +ast = crtc->dev->dev_private; + +gbo = drm_gem_vram_of_gem(fb->obj[0]); +src = drm_gem_vram_vmap(gbo); +if (IS_ERR(src)) { +ret = PTR_ERR(src); +goto err_drm_gem_vram_unpin; +} + +dst = drm_gem_vram_vmap(ast->cursor.gbo[ast->cursor.next_index]); +if (IS_ERR(dst)) { +ret = PTR_ERR(dst); +goto err_drm_gem_vram_vunmap_src; +} + +ret = ast_cursor_update(dst, src, fb->width, fb->height); +if (ret) +goto err_drm_gem_vram_vunmap_dst; + +/* Always unmap buffers here. Destination buffers are + * perma-pinned while the driver is active. We're only + * changing ref-counters here. + */ +drm_gem_vram_vunmap(ast->cursor.gbo[ast->cursor.next_index], dst); +drm_gem_vram_vunmap(gbo, src); + +return 0; + +err_drm_gem_vram_vunmap_dst: +drm_gem_vram_vunmap(ast->cursor.gbo[ast->cursor.next_index], dst); +err_drm_gem_vram_vunmap_src: +drm_gem_vram_vunmap(gbo, src); +err_drm_gem_vram_unpin: +drm_gem_vram_unpin(gbo); +return ret; +} + +static int ast_cursor_plane_helper_atomic_check(struct drm_plane *plane, +struct drm_plane_state *state) +{ +return
[Bug 109955] amdgpu [RX Vega 64] system freeze while gaming
https://bugs.freedesktop.org/show_bug.cgi?id=109955 --- Comment #127 from har...@gmx.de --- (In reply to Rodney A Morris from comment #126) > If you want someone to apply your changes in bug report no. 110777 to the > kernel for testing, I can so but will not be to it until this weekend. ... thanks for you reply. Yes, that was the idea and would be very nice... Since i thing the proposed fix is more relevant to this very thread, let me repeat the proposed patch here: in 'drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c': static void vega10_notify_smc_display_change(struct pp_hwmgr *hwmgr, bool has_disp) { smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetUclkFastSwitch, has_disp ? 1 : 0); /* proposed fix for crashes because of frequently mclk level 0/1 switching */ smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetUclkDownHyst, 1); } Only module 'amdgpu.ko' needs to be rebuild and copied, like this: $ cd /home/user/linux-5.x.x && make -j8 -C . M=drivers/gpu/drm/amd/amdgpu # cp /home/user/linux-5.x.x/drivers/gpu/drm/amd/amdgpu/amdgpu.ko /lib/modules/5.x.x/kernel/drivers/gpu/drm/amd/amdgpu/amdgpu.ko && update-initramfs -u ... 'user' and 'x.x' have to be adapted, most likely ... -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 2/2] drm/gma500: Add page flip support on psb/cdv
Legacy (non-atomic) page flip support is added to the driver by using the mode_set_base CRTC function, that allows configuring a new framebuffer for display. Since the function requires the primary plane's fb to be set already, this is done prior to calling the function in the page flip helper and reverted if the flip fails. The vblank interrupt handler is also refactored to support passing an event. The PIPE_TE_STATUS bit is also considered to indicate vblank on medfield only, as explained in psb_enable_vblank. It was tested by running weston on both poulsbo and cedartrail. Signed-off-by: Paul Kocialkowski --- drivers/gpu/drm/gma500/cdv_intel_display.c | 1 + drivers/gpu/drm/gma500/gma_display.c | 46 ++ drivers/gpu/drm/gma500/gma_display.h | 6 +++ drivers/gpu/drm/gma500/psb_intel_display.c | 1 + drivers/gpu/drm/gma500/psb_intel_drv.h | 3 ++ drivers/gpu/drm/gma500/psb_irq.c | 18 +++-- 6 files changed, 72 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/gma500/cdv_intel_display.c b/drivers/gpu/drm/gma500/cdv_intel_display.c index 8b784947ed3b..7109d3d19be0 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_display.c +++ b/drivers/gpu/drm/gma500/cdv_intel_display.c @@ -979,6 +979,7 @@ const struct drm_crtc_funcs cdv_intel_crtc_funcs = { .gamma_set = gma_crtc_gamma_set, .set_config = gma_crtc_set_config, .destroy = gma_crtc_destroy, + .page_flip = gma_crtc_page_flip, }; const struct gma_clock_funcs cdv_clock_funcs = { diff --git a/drivers/gpu/drm/gma500/gma_display.c b/drivers/gpu/drm/gma500/gma_display.c index bc07ae2a9a1d..17f136985d21 100644 --- a/drivers/gpu/drm/gma500/gma_display.c +++ b/drivers/gpu/drm/gma500/gma_display.c @@ -503,6 +503,52 @@ void gma_crtc_destroy(struct drm_crtc *crtc) kfree(gma_crtc); } +int gma_crtc_page_flip(struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_pending_vblank_event *event, + uint32_t page_flip_flags, + struct drm_modeset_acquire_ctx *ctx) +{ + struct gma_crtc *gma_crtc = to_gma_crtc(crtc); + struct drm_framebuffer *current_fb = crtc->primary->fb; + struct drm_framebuffer *old_fb = crtc->primary->old_fb; + const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; + struct drm_device *dev = crtc->dev; + unsigned long flags; + int ret; + + if (!crtc_funcs->mode_set_base) + return -EINVAL; + + /* Using mode_set_base requires the new fb to be set already. */ + crtc->primary->fb = fb; + + if (event) { + spin_lock_irqsave(&dev->event_lock, flags); + + WARN_ON(drm_crtc_vblank_get(crtc) != 0); + + gma_crtc->page_flip_event = event; + + /* Call this locked if we want an event at vblank interrupt. */ + ret = crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y, old_fb); + if (ret) { + gma_crtc->page_flip_event = NULL; + drm_crtc_vblank_put(crtc); + } + + spin_unlock_irqrestore(&dev->event_lock, flags); + } else { + ret = crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y, old_fb); + } + + /* Restore previous fb in case of failure. */ + if (ret) + crtc->primary->fb = current_fb; + + return ret; +} + int gma_crtc_set_config(struct drm_mode_set *set, struct drm_modeset_acquire_ctx *ctx) { diff --git a/drivers/gpu/drm/gma500/gma_display.h b/drivers/gpu/drm/gma500/gma_display.h index fdbd7ecaa59c..7bd6c1ee8b21 100644 --- a/drivers/gpu/drm/gma500/gma_display.h +++ b/drivers/gpu/drm/gma500/gma_display.h @@ -11,6 +11,7 @@ #define _GMA_DISPLAY_H_ #include +#include struct drm_encoder; struct drm_mode_set; @@ -71,6 +72,11 @@ extern void gma_crtc_prepare(struct drm_crtc *crtc); extern void gma_crtc_commit(struct drm_crtc *crtc); extern void gma_crtc_disable(struct drm_crtc *crtc); extern void gma_crtc_destroy(struct drm_crtc *crtc); +extern int gma_crtc_page_flip(struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_pending_vblank_event *event, + uint32_t page_flip_flags, + struct drm_modeset_acquire_ctx *ctx); extern int gma_crtc_set_config(struct drm_mode_set *set, struct drm_modeset_acquire_ctx *ctx); diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c index 4256410535f0..fed3b563e62e 100644 --- a/drivers/gpu/drm/gma500/psb_intel_display.c +++ b/drivers/gpu/drm/gma500/psb_intel_display.c @@ -432,6 +432,7 @@ const struct drm_crtc_funcs psb_intel_crtc_funcs = { .gamma_set = gma_crtc_gamma_set, .set_config = gma_crtc_set_co
[PATCH 0/2] drm/gma500: Add page flip support on psb/cdv
This series brings-in the required bits to implement page flip support on poulsbo and cedartrail. Page flip support is required to run weston with the GMA500 driver. This is only legacy page flip support, not a conversion of the driver to atomic DRM. Paul Kocialkowski (2): drm/gma500: Add missing call to allow enabling vblank on psb/cdv drm/gma500: Add page flip support on psb/cdv drivers/gpu/drm/gma500/cdv_intel_display.c | 1 + drivers/gpu/drm/gma500/gma_display.c | 48 ++ drivers/gpu/drm/gma500/gma_display.h | 6 +++ drivers/gpu/drm/gma500/psb_intel_display.c | 1 + drivers/gpu/drm/gma500/psb_intel_drv.h | 3 ++ drivers/gpu/drm/gma500/psb_irq.c | 18 ++-- 6 files changed, 74 insertions(+), 3 deletions(-) -- 2.23.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 1/2] drm/gma500: Add missing call to allow enabling vblank on psb/cdv
This adds a missing call to drm_crtc_vblank_on to the common DPMS helper (used by poulsbo and cedartrail), which is called in the CRTC enable path. With that call, it becomes possible to enable vblank when needed. It is already balanced by a drm_crtc_vblank_off call in the helper. Other platforms (oaktrail and medfield) use a dedicated DPMS helper that does not have the proper vblank on/off hooks. They are not added in this commit due to lack of hardware to test it with. Signed-off-by: Paul Kocialkowski --- drivers/gpu/drm/gma500/gma_display.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/gma500/gma_display.c b/drivers/gpu/drm/gma500/gma_display.c index e20ccb5d10fd..bc07ae2a9a1d 100644 --- a/drivers/gpu/drm/gma500/gma_display.c +++ b/drivers/gpu/drm/gma500/gma_display.c @@ -255,6 +255,8 @@ void gma_crtc_dpms(struct drm_crtc *crtc, int mode) /* Give the overlay scaler a chance to enable * if it's on this pipe */ /* psb_intel_crtc_dpms_video(crtc, true); TODO */ + + drm_crtc_vblank_on(crtc); break; case DRM_MODE_DPMS_OFF: if (!gma_crtc->active) -- 2.23.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/bridge: ti-tfp410: switch to using fwnode_gpiod_get_index()
On Tue, Nov 05, 2019 at 09:53:23PM +0200, Laurent Pinchart wrote: > Hi Daniel, > > On Tue, Nov 05, 2019 at 04:41:41PM +0100, Daniel Vetter wrote: > > On Tue, Nov 5, 2019 at 4:29 PM Linus Walleij wrote: > > > On Tue, Nov 5, 2019 at 1:40 AM Dmitry Torokhov wrote: > > > > On Mon, Oct 14, 2019 at 11:43:20AM -0700, Dmitry Torokhov wrote: > > > > > > > > Instead of fwnode_get_named_gpiod() that I plan to hide away, let's > > > > > use > > > > > the new fwnode_gpiod_get_index() that mimics gpiod_get_index(), but > > > > > works with arbitrary firmware node. > > > > > > > > > > Reviewed-by: Laurent Pinchart > > > > > Signed-off-by: Dmitry Torokhov > > > > > --- > > > > > > > > > > Andrzej, Neil, > > > > > > > > > > This depends on the new code that can be bound in > > > > > ib-fwnode-gpiod-get-index immutable branch of Linus' Walleij tree: > > > > > > > > > > git pull > > > > > git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git > > > > > ib-fwnode-gpiod-get-index > > > > > > > > > > I hope that it would be possible to pull in this immutable branch and > > > > > not wait until after 5.5 merge window, or, alternatively, merge > > > > > through > > > > > Linus Walleij's tree. > > > > > > > > Any chance this could be merged, please? > > > > > > I'm happy to merge it into the GPIO tree if some DRM maintainer can > > > provide an ACK. > > > > Ack. > > > > > Getting ACK from DRM people is problematic and a bit of friction in the > > > community, DVetter usually advice to seek mutual reviews etc, but IMO > > > it would be better if some people felt more compelled to review stuff > > > eventually. (And that has the problem that it doesn't scale.) > > > > This has a review already plus if you merge your implied review. > > That's more than good enough imo, so not seeing the issue here? > > Isn't the issue that the patch should have been picked by someone for > drm-misc ? It requires prep work that isn't in drm-misc I thought? Anyway, Linus has commit rights to drm-misc, could also push it there. Plus you have, except you don't want it. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: Proposal to report GPU private memory allocations with sysfs nodes [plain text version]
On Tue, Nov 05, 2019 at 11:45:28AM -0800, Yiwei Zhang wrote: > Hi Daniel, > > > - The labels are currently free-form, baking them back into your structure > > would mean we'd need to do lots of hot add/remove of sysfs directory > > trees. Which sounds like a real bad idea :-/ > Given the free form of that ioctl, what's the plan of using that and > the reporting of the labeled BOs? > Do you think upstream kernel need to have certain resource category > based tracking for gpu private allocations? There's no plan, we simply didn't consider more standardized buckets when adding that label support. So yeah not sure what to do now, except I don't want 2 different ways for labelling buffers. > > - Buffer objects aren't attached to pids, but files. And files can be > > shared. If we want to list this somewhere outside of debugfs, we need to > > tie this into the files somehow (so proc), except the underlying files > > are all anon inodes, so this gets really tricky I think to make work > > well. > So there isn't any gpu private allocations on the upstream side? > How does upstream deal with duplicate accounting for the shared memory? Atm we don't account gpu memory anywhere at all. There's a lot of discussion going on how to remedy that in the context of a cgroup controller, and how to account allocated buffers against processes is a huge deal. Maybe cgroups is more the kind of control/reporting you're looking for? Of course would mean that android creates a cgroup for each app. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/amdgpu: fix double reference dropping
Am 06.11.19 um 10:53 schrieb Pan Bian: > After dropping the reference of object fence in the loop, it should be > set to NULL to protecting dropping its reference again outside the loop. NAK, the actual bug is that we shouldn't drop the fence outside the loop in the first place. Just move the dma_fence_put(fence); two lines up and drop initializing fence to NULL. Regards, Christian. > > Signed-off-by: Pan Bian > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c > index 649e68c4479b..3174093f35f3 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c > @@ -47,6 +47,7 @@ static int amdgpu_benchmark_do_move(struct amdgpu_device > *adev, unsigned size, > if (r) > goto exit_do_move; > dma_fence_put(fence); > + fence = NULL; > } > end_jiffies = jiffies; > r = jiffies_to_msecs(end_jiffies - start_jiffies); ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 1/1] drm/panel: boe-tv101wum-n16 seperate the panel power control
On Wed, Nov 06, 2019 at 04:17:52PM +0800, Jitao Shi wrote: > Seperate the panel power control from prepare/unprepare. > > Signed-off-by: Jitao Shi Your patch series is all kinds of split up. Can you pls resend, with the entire thing all in one go? Thanks, Daniel > --- > .../gpu/drm/panel/panel-boe-tv101wum-nl6.c| 69 +-- > 1 file changed, 49 insertions(+), 20 deletions(-) > > diff --git a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c > b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c > index e2496a334ab6..5b1b285a2194 100644 > --- a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c > +++ b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c > @@ -50,6 +50,7 @@ struct boe_panel { > struct regulator *avdd; > struct gpio_desc *enable_gpio; > > + bool prepared_power; > bool prepared; > bool enabled; > > @@ -501,12 +502,11 @@ static int boe_panel_disable(struct drm_panel *panel) > return 0; > } > > -static int boe_panel_unprepare(struct drm_panel *panel) > +static int boe_panel_unprepare_power(struct drm_panel *panel) > { > struct boe_panel *boe = to_boe_panel(panel); > - int ret; > > - if (!boe->prepared) > + if (!boe->prepared_power) > return 0; > > if (boe->desc->discharge_on_disable) { > @@ -518,12 +518,6 @@ static int boe_panel_unprepare(struct drm_panel *panel) > usleep_range(5000, 7000); > regulator_disable(boe->pp1800); > } else { > - ret = boe_panel_off(boe); > - if (ret < 0) { > - dev_err(panel->dev, "failed to set panel off: %d\n", > - ret); > - return ret; > - } > msleep(150); > gpiod_set_value(boe->enable_gpio, 0); > usleep_range(500, 1000); > @@ -533,17 +527,39 @@ static int boe_panel_unprepare(struct drm_panel *panel) > regulator_disable(boe->pp1800); > } > > + boe->prepared_power = false; > + > + return 0; > +} > + > +static int boe_panel_unprepare(struct drm_panel *panel) > +{ > + struct boe_panel *boe = to_boe_panel(panel); > + int ret; > + > + if (!boe->prepared) > + return 0; > + > + if (!boe->desc->discharge_on_disable) { > + ret = boe_panel_off(boe); > + if (ret < 0) { > + dev_err(panel->dev, "failed to set panel off: %d\n", > + ret); > + return ret; > + } > + } > + > boe->prepared = false; > > return 0; > } > > -static int boe_panel_prepare(struct drm_panel *panel) > +static int boe_panel_prepare_power(struct drm_panel *panel) > { > struct boe_panel *boe = to_boe_panel(panel); > int ret; > > - if (boe->prepared) > + if (boe->prepared_power) > return 0; > > gpiod_set_value(boe->enable_gpio, 0); > @@ -571,18 +587,10 @@ static int boe_panel_prepare(struct drm_panel *panel) > gpiod_set_value(boe->enable_gpio, 1); > usleep_range(6000, 1); > > - ret = boe_panel_init(boe); > - if (ret < 0) { > - dev_err(panel->dev, "failed to init panel: %d\n", ret); > - goto poweroff; > - } > - > - boe->prepared = true; > + boe->prepared_power = true; > > return 0; > > -poweroff: > - regulator_disable(boe->avee); > poweroffavdd: > regulator_disable(boe->avdd); > poweroff1v8: > @@ -593,6 +601,25 @@ static int boe_panel_prepare(struct drm_panel *panel) > return ret; > } > > +static int boe_panel_prepare(struct drm_panel *panel) > +{ > + struct boe_panel *boe = to_boe_panel(panel); > + int ret; > + > + if (boe->prepared) > + return 0; > + > + ret = boe_panel_init(boe); > + if (ret < 0) { > + dev_err(panel->dev, "failed to init panel: %d\n", ret); > + return ret; > + } > + > + boe->prepared = true; > + > + return 0; > +} > + > static int boe_panel_enable(struct drm_panel *panel) > { > struct boe_panel *boe = to_boe_panel(panel); > @@ -754,7 +781,9 @@ static int boe_panel_get_modes(struct drm_panel *panel) > static const struct drm_panel_funcs boe_panel_funcs = { > .disable = boe_panel_disable, > .unprepare = boe_panel_unprepare, > + .unprepare_power = boe_panel_unprepare_power, > .prepare = boe_panel_prepare, > + .prepare_power = boe_panel_prepare_power, > .enable = boe_panel_enable, > .get_modes = boe_panel_get_modes, > }; > -- > 2.21.0 > -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [GIT PULL FOR v5.5 - 2nd try] R-Car DU CMM support
Hi Dave, (CC'ing Jacopo) On Wed, Nov 06, 2019 at 01:40:13PM +1000, Dave Airlie wrote: > On Wed, 6 Nov 2019 at 05:56, Dave Airlie wrote: > > On Wed, 6 Nov 2019 at 05:49, Laurent Pinchart wrote: > > > > > > Hi Dave, > > > > > > Has this pull request fallen through the cracks ? > > > > It fell down a different crack than usual, it made it from patchwork > > onto my hard drive, but then I didn't execute the pull. > > > > I've pulled it down, thanks for reminder. > > Now it failed as I mentioned on irc. > > I think the new kconfig option needs to be a tristate, otherwise > setting it to Y and having rcar-du as M fails to link Sorry about that :-S Both I and the 0-day bot failed to catch it. Jacopo, could you please have a look ? I'm afraid this likely mean a new version of the series, and thus missing the merge window, as we're already at -rc6. -- Regards, Laurent Pinchart ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [GIT PULL FOR v5.5 - 2nd try] R-Car DU CMM support
This time with Jacopo correctly CC'ed. On Wed, Nov 06, 2019 at 12:00:59PM +0200, Laurent Pinchart wrote: > Hi Dave, > > (CC'ing Jacopo) > > On Wed, Nov 06, 2019 at 01:40:13PM +1000, Dave Airlie wrote: > > On Wed, 6 Nov 2019 at 05:56, Dave Airlie wrote: > > > On Wed, 6 Nov 2019 at 05:49, Laurent Pinchart wrote: > > > > > > > > Hi Dave, > > > > > > > > Has this pull request fallen through the cracks ? > > > > > > It fell down a different crack than usual, it made it from patchwork > > > onto my hard drive, but then I didn't execute the pull. > > > > > > I've pulled it down, thanks for reminder. > > > > Now it failed as I mentioned on irc. > > > > I think the new kconfig option needs to be a tristate, otherwise > > setting it to Y and having rcar-du as M fails to link > > Sorry about that :-S Both I and the 0-day bot failed to catch it. > Jacopo, could you please have a look ? I'm afraid this likely mean a new > version of the series, and thus missing the merge window, as we're > already at -rc6. -- Regards, Laurent Pinchart ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [RFC][PATCH 0/8] Support I/O memory in generic fbdev emulation
On Wed, Nov 06, 2019 at 10:31:13AM +0100, Thomas Zimmermann wrote: > We recently had a discussion if/how fbdev emulation could support > framebuffers in I/O memory on all platform. [1] > > I typed up a patchset that passes information about the memory area > from memory manager to client (e.g., fbdev emulation). The client can > take this into consideration when accessing the framebuffer. > > The alternative proposal is to introduce a separate vmap() call that > only returns I/O memorym or NULL if the framebuffer is not in I/O > memory. AFAICS the benefit of this idea is the cleaner interface and > the ability to modify drivers one by one. The drawback is some additional > boilerplate code in drivers and clients. Imo we need the correct types, to let sparse check this stuff for us. Otherwise this is just going to be whack-a-mole, since on x86 (and I think also on arm) there's not really a difference between iomem and system memory. One idea I had is to do a new opaque pointer struct, and _lots_ of new functions to handle it. Unfortunately that means no more pointer arithmetic on that pointer (this isn't C++): struct opaque_dev_ptr { union { void * __iomem; void * smem; }; bool is_iomem; }; So really it's a _lot_ of work. The other issue is that we also need to fix the dma-buf interfaces. Which is going to be even more work. All that for gain I'm not really sure is worth it - I don't even know which platforms we're fixing with this. -Daniel > > [1] https://lists.freedesktop.org/archives/dri-devel/2019-November/242464.html > > Thomas Zimmermann (8): > drm/vram-helper: Tell caller if vmap() returned I/O memory > drm/qxl: Tell caller if kmap() returned I/O memory > drm: Add is_iomem return parameter to struct drm_gem_object_funcs.vmap > drm/gem: Return I/O-memory flag from drm_gem_vram() > drm/client: Return I/O memory flag from drm_client_buffer_vmap() > fbdev: Export default read and write operations as > fb_cfb_{read,write}() > drm/fb-helper: Select between fb_{sys,cfb}_read() and _write() > drm/fb-helper: Handle I/O memory correctly when flushing shadow fb > > drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 6 +- > drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.h | 2 +- > drivers/gpu/drm/ast/ast_mode.c | 6 +- > drivers/gpu/drm/cirrus/cirrus.c | 2 +- > drivers/gpu/drm/drm_client.c| 15 ++- > drivers/gpu/drm/drm_fb_helper.c | 118 ++-- > drivers/gpu/drm/drm_gem.c | 9 +- > drivers/gpu/drm/drm_gem_cma_helper.c| 7 +- > drivers/gpu/drm/drm_gem_shmem_helper.c | 12 +- > drivers/gpu/drm/drm_gem_vram_helper.c | 13 ++- > drivers/gpu/drm/drm_internal.h | 2 +- > drivers/gpu/drm/drm_prime.c | 2 +- > drivers/gpu/drm/etnaviv/etnaviv_drv.h | 2 +- > drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c | 4 +- > drivers/gpu/drm/mgag200/mgag200_cursor.c| 4 +- > drivers/gpu/drm/nouveau/nouveau_gem.h | 2 +- > drivers/gpu/drm/nouveau/nouveau_prime.c | 4 +- > drivers/gpu/drm/panfrost/panfrost_perfcnt.c | 2 +- > drivers/gpu/drm/qxl/qxl_display.c | 6 +- > drivers/gpu/drm/qxl/qxl_draw.c | 4 +- > drivers/gpu/drm/qxl/qxl_drv.h | 4 +- > drivers/gpu/drm/qxl/qxl_object.c| 7 +- > drivers/gpu/drm/qxl/qxl_object.h| 2 +- > drivers/gpu/drm/qxl/qxl_prime.c | 4 +- > drivers/gpu/drm/radeon/radeon_drv.c | 2 +- > drivers/gpu/drm/radeon/radeon_prime.c | 4 +- > drivers/gpu/drm/tiny/gm12u320.c | 2 +- > drivers/gpu/drm/vc4/vc4_bo.c| 4 +- > drivers/gpu/drm/vc4/vc4_drv.h | 2 +- > drivers/gpu/drm/vgem/vgem_drv.c | 5 +- > drivers/gpu/drm/xen/xen_drm_front_gem.c | 6 +- > drivers/gpu/drm/xen/xen_drm_front_gem.h | 3 +- > drivers/video/fbdev/core/fbmem.c| 53 +++-- > include/drm/drm_client.h| 7 +- > include/drm/drm_drv.h | 2 +- > include/drm/drm_fb_helper.h | 14 +++ > include/drm/drm_gem.h | 2 +- > include/drm/drm_gem_cma_helper.h| 2 +- > include/drm/drm_gem_shmem_helper.h | 2 +- > include/drm/drm_gem_vram_helper.h | 2 +- > include/linux/fb.h | 5 + > 41 files changed, 278 insertions(+), 78 deletions(-) > > -- > 2.23.0 > -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 3/3] drm/prime: Use anon_drm_getfile() for an internal drm struct file
Currently the drm_prime mmap fallback uses a mock struct file to provide the file pointer into the backend mmap routine. Now that we can create fully fledged anonymous struct file around the drm device, put it to use. Signed-off-by: Chris Wilson --- drivers/gpu/drm/drm_prime.c | 26 -- 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 0814211b0f3f..5faa63713ec8 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -709,8 +709,7 @@ EXPORT_SYMBOL(drm_gem_dmabuf_vunmap); */ int drm_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) { - struct drm_file *priv; - struct file *fil; + struct file *file; int ret; if (obj->funcs && obj->funcs->mmap) { @@ -722,30 +721,21 @@ int drm_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) return 0; } - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - fil = kzalloc(sizeof(*fil), GFP_KERNEL); - if (!priv || !fil) { - ret = -ENOMEM; - goto out; - } + file = anon_drm_getfile(obj->dev->primary, O_RDWR); + if (IS_ERR(file)) + return PTR_ERR(file); - /* Used by drm_gem_mmap() to lookup the GEM object */ - priv->minor = obj->dev->primary; - fil->private_data = priv; - - ret = drm_vma_node_allow(&obj->vma_node, priv); + ret = drm_vma_node_allow(&obj->vma_node, file->private_data); if (ret) goto out; vma->vm_pgoff += drm_vma_node_start(&obj->vma_node); - ret = obj->dev->driver->fops->mmap(fil, vma); + ret = file->f_op->mmap(file, vma); - drm_vma_node_revoke(&obj->vma_node, priv); + drm_vma_node_revoke(&obj->vma_node, file->private_data); out: - kfree(priv); - kfree(fil); - + fput(file); return ret; } EXPORT_SYMBOL(drm_gem_prime_mmap); -- 2.24.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 2/3] drm/i915/selftests: Wrap vm_mmap() around GEM objects
Provide a utility function to create a vma corresponding to an mmap() of our device. And use it to exercise the equivalent of userspace performing a GTT mmap of our objects. Signed-off-by: Chris Wilson Cc: Abdiel Janulgue --- drivers/gpu/drm/i915/Makefile | 1 + .../drm/i915/gem/selftests/i915_gem_mman.c| 97 +++ drivers/gpu/drm/i915/selftests/igt_mmap.c | 39 drivers/gpu/drm/i915/selftests/igt_mmap.h | 19 4 files changed, 156 insertions(+) create mode 100644 drivers/gpu/drm/i915/selftests/igt_mmap.c create mode 100644 drivers/gpu/drm/i915/selftests/igt_mmap.h diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 90dcf09f52cc..e0fd10c0cfb8 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -259,6 +259,7 @@ i915-$(CONFIG_DRM_I915_SELFTEST) += \ selftests/i915_selftest.o \ selftests/igt_flush_test.o \ selftests/igt_live_test.o \ + selftests/igt_mmap.o \ selftests/igt_reset.o \ selftests/igt_spinner.o diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c index 29b2077b73d2..11a99d5d2ff8 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c @@ -12,6 +12,7 @@ #include "i915_selftest.h" #include "selftests/i915_random.h" #include "selftests/igt_flush_test.h" +#include "selftests/igt_mmap.h" struct tile { unsigned int width; @@ -694,12 +695,108 @@ static int igt_mmap_offset_exhaustion(void *arg) goto out; } +#define expand32(x) (((x) << 0) | ((x) << 8) | ((x) << 16) | ((x) << 24)) +static int igt_mmap_gtt(void *arg) +{ + struct drm_i915_private *i915 = arg; + struct drm_i915_gem_object *obj; + struct vm_area_struct *area; + unsigned long addr; + void *vaddr; + int err, i; + + obj = i915_gem_object_create_internal(i915, PAGE_SIZE); + if (IS_ERR(obj)) + return PTR_ERR(obj); + + vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB); + if (IS_ERR(vaddr)) { + err = PTR_ERR(vaddr); + goto out; + } + memset(vaddr, POISON_INUSE, PAGE_SIZE); + i915_gem_object_flush_map(obj); + i915_gem_object_unpin_map(obj); + + err = create_mmap_offset(obj); + if (err) + goto out; + + addr = igt_mmap_node(i915, &obj->base.vma_node, +0, PROT_WRITE, MAP_SHARED); + if (IS_ERR_VALUE(addr)) { + err = addr; + goto out; + } + + pr_info("igt_mmap(obj:gtt) @ %lx\n", addr); + + area = find_vma(current->mm, addr); + if (!area) { + pr_err("Did not create a vm_area_struct for the mmap\n"); + err = -EINVAL; + goto out_unmap; + } + + if (area->vm_private_data != obj) { + pr_err("vm_area_struct did not point back to our object!\n"); + err = -EINVAL; + goto out_unmap; + } + + for (i = 0; i < PAGE_SIZE / sizeof(u32); i++) { + u32 __user *ux = u64_to_user_ptr((u64)(addr + i * sizeof*(ux))); + u32 x; + + if (get_user(x, ux)) { + pr_err("Unable to read from GTT mmap, offset:%zd\n", + i * sizeof(x)); + err = -EFAULT; + break; + } + + if (x != expand32(POISON_INUSE)) { + pr_err("Read incorrect value from GTT mmap, offset:%zd, found:%x, expected:%x\n", + i * sizeof(x), x, expand32(POISON_INUSE)); + err = -EINVAL; + break; + } + + x = expand32(POISON_FREE); + if (put_user(x, ux)) { + pr_err("Unable to write to GTT mmap, offset:%zd\n", + i * sizeof(x)); + err = -EFAULT; + break; + } + } + +out_unmap: + vm_munmap(addr, PAGE_SIZE); + + vaddr = i915_gem_object_pin_map(obj, I915_MAP_FORCE_WC); + if (IS_ERR(vaddr)) { + err = PTR_ERR(vaddr); + goto out; + } + if (err == 0 && memchr_inv(vaddr, POISON_FREE, PAGE_SIZE)) { + pr_err("Write via GGTT mmap did not land in backing store\n"); + err = -EINVAL; + } + i915_gem_object_unpin_map(obj); + +out: + i915_gem_object_put(obj); + return err; +} + int i915_gem_mman_live_selftests(struct drm_i915_private *i915) { static const struct i915_subtest tests[] = { SUBTEST(igt_partial_tiling), SUBTEST(igt_smoke_tiling), SUBTEST(igt_mmap_offset_exhaustion), + SUBTEST(igt_mmap_gtt),
[PATCH 1/3] drm: Expose a method for creating anonymous struct file around drm_minor
Sometimes we need to create a struct file to wrap a drm_device, as it the user were to have opened /dev/dri/card0 but to do so anonymously (i.e. for internal use). Provide a utility method to create a struct file with the drm_device->driver.fops, that wrap the drm_device. Signed-off-by: Chris Wilson --- drivers/gpu/drm/drm_file.c | 39 ++ include/drm/drm_file.h | 3 +++ 2 files changed, 42 insertions(+) diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c index ea34bc991858..cc55c0cd5826 100644 --- a/drivers/gpu/drm/drm_file.c +++ b/drivers/gpu/drm/drm_file.c @@ -31,7 +31,9 @@ * OTHER DEALINGS IN THE SOFTWARE. */ +#include #include +#include #include #include #include @@ -754,3 +756,40 @@ void drm_send_event(struct drm_device *dev, struct drm_pending_event *e) spin_unlock_irqrestore(&dev->event_lock, irqflags); } EXPORT_SYMBOL(drm_send_event); + +/** + * anon_drm_getfile - Create a new struct file for the drm device + * @minor: drm minor to wrap (e.g. drm_device->primary) + * @flags: file creation mode (O_RDWR etc) + * + * This create a new struct file that wraps a DRM file context around a + * DRM minor. This mimicks userspace opening e.g. /dev/dri/card0, but without + * invoking userspace. The struct file may be operated on using its f_op + * (the drm_device.driver.fops) to mimick userspace operations, or be supplied + * to userspace facing functions as an internal/anonymous client. + * + * RETURNS: + * Pointer to newly created struct file, ERR_PTR on failure. + */ +struct file *anon_drm_getfile(struct drm_minor *minor, unsigned int flags) +{ + struct drm_device *dev = minor->dev; + struct drm_file *priv; + struct file *file; + + priv = drm_file_alloc(minor); + if (IS_ERR(priv)) + return ERR_CAST(priv); + + file = anon_inode_getfile("drm", dev->driver->fops, priv, flags); + if (IS_ERR(file)) { + drm_file_free(priv); + return file; + } + + drm_dev_get(dev); + priv->filp = file; + + return file; +} +EXPORT_SYMBOL(anon_drm_getfile); diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h index 67af60bb527a..b963535964f7 100644 --- a/include/drm/drm_file.h +++ b/include/drm/drm_file.h @@ -42,6 +42,7 @@ struct dma_fence; struct drm_file; struct drm_device; struct device; +struct file; /* * FIXME: Not sure we want to have drm_minor here in the end, but to avoid @@ -387,4 +388,6 @@ void drm_event_cancel_free(struct drm_device *dev, void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e); void drm_send_event(struct drm_device *dev, struct drm_pending_event *e); +struct file *anon_drm_getfile(struct drm_minor *minor, unsigned int flags); + #endif /* _DRM_FILE_H_ */ -- 2.24.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [Intel-gfx] [PATCH 1/3] drm: Expose a method for creating anonymous struct file around drm_minor
On Wed, Nov 06, 2019 at 10:07:14AM +, Chris Wilson wrote: > Sometimes we need to create a struct file to wrap a drm_device, as it > the user were to have opened /dev/dri/card0 but to do so anonymously > (i.e. for internal use). Provide a utility method to create a struct > file with the drm_device->driver.fops, that wrap the drm_device. > > Signed-off-by: Chris Wilson For proper internal access we already have drm_client_open, so I think this has limited (but good use) in selftests only. So EXPORT_SYMBOL_FOR_TESTS_ONLY plus maybe a clearer name for the intended use like drm_file_mock_open? Aside from this I like. -Daniel > --- > drivers/gpu/drm/drm_file.c | 39 ++ > include/drm/drm_file.h | 3 +++ > 2 files changed, 42 insertions(+) > > diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c > index ea34bc991858..cc55c0cd5826 100644 > --- a/drivers/gpu/drm/drm_file.c > +++ b/drivers/gpu/drm/drm_file.c > @@ -31,7 +31,9 @@ > * OTHER DEALINGS IN THE SOFTWARE. > */ > > +#include > #include > +#include > #include > #include > #include > @@ -754,3 +756,40 @@ void drm_send_event(struct drm_device *dev, struct > drm_pending_event *e) > spin_unlock_irqrestore(&dev->event_lock, irqflags); > } > EXPORT_SYMBOL(drm_send_event); > + > +/** > + * anon_drm_getfile - Create a new struct file for the drm device > + * @minor: drm minor to wrap (e.g. drm_device->primary) > + * @flags: file creation mode (O_RDWR etc) > + * > + * This create a new struct file that wraps a DRM file context around a > + * DRM minor. This mimicks userspace opening e.g. /dev/dri/card0, but without > + * invoking userspace. The struct file may be operated on using its f_op > + * (the drm_device.driver.fops) to mimick userspace operations, or be > supplied > + * to userspace facing functions as an internal/anonymous client. > + * > + * RETURNS: > + * Pointer to newly created struct file, ERR_PTR on failure. > + */ > +struct file *anon_drm_getfile(struct drm_minor *minor, unsigned int flags) > +{ > + struct drm_device *dev = minor->dev; > + struct drm_file *priv; > + struct file *file; > + > + priv = drm_file_alloc(minor); > + if (IS_ERR(priv)) > + return ERR_CAST(priv); > + > + file = anon_inode_getfile("drm", dev->driver->fops, priv, flags); > + if (IS_ERR(file)) { > + drm_file_free(priv); > + return file; > + } > + > + drm_dev_get(dev); > + priv->filp = file; > + > + return file; > +} > +EXPORT_SYMBOL(anon_drm_getfile); > diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h > index 67af60bb527a..b963535964f7 100644 > --- a/include/drm/drm_file.h > +++ b/include/drm/drm_file.h > @@ -42,6 +42,7 @@ struct dma_fence; > struct drm_file; > struct drm_device; > struct device; > +struct file; > > /* > * FIXME: Not sure we want to have drm_minor here in the end, but to avoid > @@ -387,4 +388,6 @@ void drm_event_cancel_free(struct drm_device *dev, > void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event > *e); > void drm_send_event(struct drm_device *dev, struct drm_pending_event *e); > > +struct file *anon_drm_getfile(struct drm_minor *minor, unsigned int flags); > + > #endif /* _DRM_FILE_H_ */ > -- > 2.24.0 > > ___ > Intel-gfx mailing list > intel-...@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 3/3] drm/prime: Use anon_drm_getfile() for an internal drm struct file
On Wed, Nov 06, 2019 at 10:07:16AM +, Chris Wilson wrote: > Currently the drm_prime mmap fallback uses a mock struct file to provide > the file pointer into the backend mmap routine. Now that we can create > fully fledged anonymous struct file around the drm device, put it to > use. > > Signed-off-by: Chris Wilson > --- > drivers/gpu/drm/drm_prime.c | 26 -- > 1 file changed, 8 insertions(+), 18 deletions(-) > > diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c > index 0814211b0f3f..5faa63713ec8 100644 > --- a/drivers/gpu/drm/drm_prime.c > +++ b/drivers/gpu/drm/drm_prime.c > @@ -709,8 +709,7 @@ EXPORT_SYMBOL(drm_gem_dmabuf_vunmap); > */ > int drm_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct > *vma) > { > - struct drm_file *priv; > - struct file *fil; > + struct file *file; > int ret; > > if (obj->funcs && obj->funcs->mmap) { obj->funcs->mmap is the new way of doing this (and hopefully finally something clean), I'd really like to retire the below hack outright. Plus I'm not sure why you need an anon inode here? If a driver needs this for unmap_mapping_range or similar I think it'd be better to try and make something work cleanly for obj->funcs->mmap. -Daniel > @@ -722,30 +721,21 @@ int drm_gem_prime_mmap(struct drm_gem_object *obj, > struct vm_area_struct *vma) > return 0; > } > > - priv = kzalloc(sizeof(*priv), GFP_KERNEL); > - fil = kzalloc(sizeof(*fil), GFP_KERNEL); > - if (!priv || !fil) { > - ret = -ENOMEM; > - goto out; > - } > + file = anon_drm_getfile(obj->dev->primary, O_RDWR); > + if (IS_ERR(file)) > + return PTR_ERR(file); > > - /* Used by drm_gem_mmap() to lookup the GEM object */ > - priv->minor = obj->dev->primary; > - fil->private_data = priv; > - > - ret = drm_vma_node_allow(&obj->vma_node, priv); > + ret = drm_vma_node_allow(&obj->vma_node, file->private_data); > if (ret) > goto out; > > vma->vm_pgoff += drm_vma_node_start(&obj->vma_node); > > - ret = obj->dev->driver->fops->mmap(fil, vma); > + ret = file->f_op->mmap(file, vma); > > - drm_vma_node_revoke(&obj->vma_node, priv); > + drm_vma_node_revoke(&obj->vma_node, file->private_data); > out: > - kfree(priv); > - kfree(fil); > - > + fput(file); > return ret; > } > EXPORT_SYMBOL(drm_gem_prime_mmap); > -- > 2.24.0 > > ___ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 109955] amdgpu [RX Vega 64] system freeze while gaming
https://bugs.freedesktop.org/show_bug.cgi?id=109955 --- Comment #128 from har...@gmx.de --- Created attachment 145901 --> https://bugs.freedesktop.org/attachment.cgi?id=145901&action=edit proposed fix for crashes, caused by frequent mclk level 0/1 switches At least one of the causes for crashes, are more frequently, if vsync is enabled. In this case, memory clock levels are switched usually more frequently. By experiments i found, that especially the transient betweeen level 1 and level 0 is critical. The fact, that disabling memory level 0, helps as a workaround, confirms: this approach points in the right direction. Result of further experiments: By sending a 'PPSMC_MSG_SetUclkDownHyst' message to smc (enabling a hysterese feature ?), the crashes can be avoided, even with enabled mclk level 0 and vsync activated. -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [Intel-gfx] [PATCH] drm/i915: Don't select BROKEN
Quoting Chris Wilson (2019-11-05 23:13:36) > Quoting Daniel Vetter (2019-11-05 20:58:25) > > On Tue, Nov 5, 2019 at 9:38 PM Chris Wilson > > wrote: > > > > > > Quoting Daniel Vetter (2019-11-05 19:38:29) > > > > It's broken. > > > > > > > > Reported-by: Stephen Rothwell > > > > References: > > > > https://lists.freedesktop.org/archives/dri-devel/2019-November/242625.html > > > > Signed-off-by: Daniel Vetter > > > > --- > > > > Note: Probably best to apply this directly onto drm-next to avoid > > > > having drm-next dropped from linux-next until the next pull request. > > > > -Daniel > > > > --- > > > > drivers/gpu/drm/i915/Kconfig.debug | 1 - > > > > 1 file changed, 1 deletion(-) > > > > > > > > diff --git a/drivers/gpu/drm/i915/Kconfig.debug > > > > b/drivers/gpu/drm/i915/Kconfig.debug > > > > index ef123eb29168..d2ba8f7e5e50 100644 > > > > --- a/drivers/gpu/drm/i915/Kconfig.debug > > > > +++ b/drivers/gpu/drm/i915/Kconfig.debug > > > > @@ -44,7 +44,6 @@ config DRM_I915_DEBUG > > > > select DRM_I915_SELFTEST > > > > select DRM_I915_DEBUG_RUNTIME_PM > > > > select DRM_I915_DEBUG_MMIO > > > > - select BROKEN # for prototype uAPI > > > > > > You have to replace it with another secret bool as you cannot otherwise > > > enable CONFIG_BROKEN in .config. > > > > Or this: > > > > diff --git a/init/Kconfig b/init/Kconfig > > index b4daad2bac23..4dbea1b9e6bb 100644 > > --- a/init/Kconfig > > +++ b/init/Kconfig > > @@ -75,6 +75,7 @@ menu "General setup" > > > > config BROKEN > > bool > > + default y > > > > config BROKEN_ON_SMP > > bool > > > > Either way it needs to be in topic/core-for-CI, not in any official > > tree. Because if you allow autobuilders to enable CONFIG_BROKEN, no > > matter how well hidden, they'll all break. You can also just revert my > > patch that Dave pushed to drm-next (to get us back into the linux-next > > club). > > Fwiw, I think the revert in core-for-CI is reasonable, as that gives > devs the ability to toggle on the hidden menus, while at the same time > requiring them to have the minimal debug setup. I've now reverted this in core-for-CI. Regards, Joonas ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 3/3] drm/ttm: remove ttm_bo_wait_unreserved
On Mon, Nov 04, 2019 at 06:38:01PM +0100, Daniel Vetter wrote: > With nouveau fixed all ttm-using drives have the correct nesting of > mmap_sem vs dma_resv, and we can just lock the buffer. > > Assuming I didn't screw up anything with my audit of course. > > v2: > - Dont forget wu_mutex (Christian König) > - Keep the mmap_sem-less wait optimization (Thomas) > - Use _lock_interruptible to be good citizens (Thomas) > > v3: Rebase over fault handler helperification. > > Reviewed-by: Christian König (v2) > Reviewed-by: Thomas Hellström (v2) > Signed-off-by: Daniel Vetter > Cc: Christian Koenig > Cc: Huang Rui > Cc: Gerd Hoffmann > Cc: "VMware Graphics" > Cc: Thomas Hellstrom Entire series merged into drm-misc-next (probably for 5.6) with Dave's irc-ack for the nouveau patch. -Daniel > --- > drivers/gpu/drm/ttm/ttm_bo.c | 36 --- > drivers/gpu/drm/ttm/ttm_bo_util.c | 1 - > drivers/gpu/drm/ttm/ttm_bo_vm.c | 18 +--- > include/drm/ttm/ttm_bo_api.h | 4 > 4 files changed, 5 insertions(+), 54 deletions(-) > > diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c > index 8d91b0428af1..5df596fb0280 100644 > --- a/drivers/gpu/drm/ttm/ttm_bo.c > +++ b/drivers/gpu/drm/ttm/ttm_bo.c > @@ -161,7 +161,6 @@ static void ttm_bo_release_list(struct kref *list_kref) > dma_fence_put(bo->moving); > if (!ttm_bo_uses_embedded_gem_object(bo)) > dma_resv_fini(&bo->base._resv); > - mutex_destroy(&bo->wu_mutex); > bo->destroy(bo); > ttm_mem_global_free(&ttm_mem_glob, acc_size); > } > @@ -1299,7 +1298,6 @@ int ttm_bo_init_reserved(struct ttm_bo_device *bdev, > INIT_LIST_HEAD(&bo->ddestroy); > INIT_LIST_HEAD(&bo->swap); > INIT_LIST_HEAD(&bo->io_reserve_lru); > - mutex_init(&bo->wu_mutex); > bo->bdev = bdev; > bo->type = type; > bo->num_pages = num_pages; > @@ -1903,37 +1901,3 @@ void ttm_bo_swapout_all(struct ttm_bo_device *bdev) > while (ttm_bo_swapout(&ttm_bo_glob, &ctx) == 0); > } > EXPORT_SYMBOL(ttm_bo_swapout_all); > - > -/** > - * ttm_bo_wait_unreserved - interruptible wait for a buffer object to become > - * unreserved > - * > - * @bo: Pointer to buffer > - */ > -int ttm_bo_wait_unreserved(struct ttm_buffer_object *bo) > -{ > - int ret; > - > - /* > - * In the absense of a wait_unlocked API, > - * Use the bo::wu_mutex to avoid triggering livelocks due to > - * concurrent use of this function. Note that this use of > - * bo::wu_mutex can go away if we change locking order to > - * mmap_sem -> bo::reserve. > - */ > - ret = mutex_lock_interruptible(&bo->wu_mutex); > - if (unlikely(ret != 0)) > - return -ERESTARTSYS; > - if (!dma_resv_is_locked(bo->base.resv)) > - goto out_unlock; > - ret = dma_resv_lock_interruptible(bo->base.resv, NULL); > - if (ret == -EINTR) > - ret = -ERESTARTSYS; > - if (unlikely(ret != 0)) > - goto out_unlock; > - dma_resv_unlock(bo->base.resv); > - > -out_unlock: > - mutex_unlock(&bo->wu_mutex); > - return ret; > -} > diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c > b/drivers/gpu/drm/ttm/ttm_bo_util.c > index 6b0883a1776e..2b0e5a088da0 100644 > --- a/drivers/gpu/drm/ttm/ttm_bo_util.c > +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c > @@ -504,7 +504,6 @@ static int ttm_buffer_object_transfer(struct > ttm_buffer_object *bo, > INIT_LIST_HEAD(&fbo->base.lru); > INIT_LIST_HEAD(&fbo->base.swap); > INIT_LIST_HEAD(&fbo->base.io_reserve_lru); > - mutex_init(&fbo->base.wu_mutex); > fbo->base.moving = NULL; > drm_vma_node_reset(&fbo->base.base.vma_node); > > diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c > index 11863fbdd5d6..91466cfb6f16 100644 > --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c > +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c > @@ -128,30 +128,22 @@ static unsigned long ttm_bo_io_mem_pfn(struct > ttm_buffer_object *bo, > vm_fault_t ttm_bo_vm_reserve(struct ttm_buffer_object *bo, >struct vm_fault *vmf) > { > - /* > - * Work around locking order reversal in fault / nopfn > - * between mmap_sem and bo_reserve: Perform a trylock operation > - * for reserve, and if it fails, retry the fault after waiting > - * for the buffer to become unreserved. > - */ > if (unlikely(!dma_resv_trylock(bo->base.resv))) { > if (vmf->flags & FAULT_FLAG_ALLOW_RETRY) { > if (!(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) { > ttm_bo_get(bo); > up_read(&vmf->vma->vm_mm->mmap_sem); > - (void) ttm_bo_wait_unreserved(bo); > + if (!dma_resv_lock_interruptible(bo->base.resv, > + NULL)) > +
Re: [Intel-gfx] [PATCH 1/3] drm: Expose a method for creating anonymous struct file around drm_minor
Quoting Daniel Vetter (2019-11-06 10:19:50) > On Wed, Nov 06, 2019 at 10:07:14AM +, Chris Wilson wrote: > > Sometimes we need to create a struct file to wrap a drm_device, as it > > the user were to have opened /dev/dri/card0 but to do so anonymously > > (i.e. for internal use). Provide a utility method to create a struct > > file with the drm_device->driver.fops, that wrap the drm_device. > > > > Signed-off-by: Chris Wilson > > For proper internal access we already have drm_client_open, so I think > this has limited (but good use) in selftests only. So > EXPORT_SYMBOL_FOR_TESTS_ONLY plus maybe a clearer name for the intended > use like drm_file_mock_open? I found the example in drm_gem_prime_mmap() that was doing the same trick, and the trick of being able to instantiate new struct file and install a fd whenever seems like it will come in handy... Just lacking the third user at the moment to claim generality. -Chris ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCHv2 1/4] drm/arm: Factor out generic afbc helpers
Hi Andrzej, On Tue, Nov 05, 2019 at 11:26:36PM +, Daniel Stone wrote: > Hi Andrzej, > Thanks for taking this on! It's looking better than v1 for sure. A few > things below: > > On Mon, 2019-11-04 at 23:12 +0100, Andrzej Pietrasiewicz wrote: > > +bool drm_afbc_check_offset(struct drm_device *dev, > > + const struct drm_mode_fb_cmd2 *mode_cmd) > > +{ > > + if (mode_cmd->offsets[0] != 0) { > > + DRM_DEBUG_KMS("AFBC buffers' plane offset should be > > 0\n"); > > + return false; > > + } > > + > > + return true; > > +} > > +EXPORT_SYMBOL_GPL(drm_afbc_check_offset); > > Is this actually universally true? If the offset is sufficiently > aligned for (e.g.) DMA transfers to succeed, is there any reason why it > must be zero? > > > +bool drm_afbc_check_size_align(struct drm_device *dev, > > + const struct drm_mode_fb_cmd2 *mode_cmd) > > +{ > > + switch (mode_cmd->modifier[0] & > > AFBC_FORMAT_MOD_BLOCK_SIZE_MASK) { > > + case AFBC_FORMAT_MOD_BLOCK_SIZE_16x16: > > + if ((mode_cmd->width % 16) || (mode_cmd->height % 16)) > > { > > This is a dealbreaker for many resolutions: for example, 1366x768 isn't > cleanly divisible by 16 in width. So this means that we would have to > either use a larger buffer and crop, or scale, or something. > > No userspace is prepared to align fb width/height to tile dimensions > like this, so this check will basically fail everywhere. I agree with Daniel, for AFBC_FORMAT_MOD_BLOCK_SIZE_ you need to check that the allocated framebuffer's width and height are divisible by block size, not what the resolution of the mode is. Best regards, Liviu > > However, overallocation relative to the declared width/height isn't a > problem at all. In order to deal with horizontal alignment, you simply > need to ensure that the stride is a multiple of the tile width; for > vertical arrangement, that the buffer is large enough to contain > sufficient 'lines' to the next tile boundary. > > i.e. rather than checking width/height, you should check: > * fb_stride >= (ALIGN(fb_width, tile_width), bpp) > * buf_size >= fb_stride * ALIGN(fb_height, tile_height) > > This may force us to do some silly cropping games inside the Rockchip > KMS driver, but I feel it beats the alternative of breaking userspace. > > > + DRM_DEBUG_KMS( > > + "AFBC buffer must be aligned to 16 > > pixels\n" > > + ); > > + return false; > > + } > > + break; > > + case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8: > > + /* fall through */ > > It's also incongruous that 32x8 is unsupported here, but has a section > in get_superblk_wh; please harmonise them so this section either does > the checks as above, or that get_superblk_wh doesn't support 32x8 > either. > > > +bool drm_afbc_check_fb_size_ret(u32 pitch, int bpp, > > + u32 w, u32 h, u32 superblk_w, u32 > > superblk_h, > > + size_t size, u32 offset, u32 hdr_align, > > + u32 *payload_off, u32 *total_size) > > +{ > > + int n_superblks = 0; > > + u32 superblk_sz = 0; > > + u32 afbc_size = 0; > > Please don't initialise the above three variables, given that you go on > to immediately change their values. In this case, initialising to zero > can only hide legitimate uninitialised-variable-use warnings. > > > + n_superblks = (w / superblk_w) * (h / superblk_h); > > + superblk_sz = (bpp * superblk_w * superblk_h) / BITS_PER_BYTE; > > + afbc_size = ALIGN(n_superblks * AFBC_HEADER_SIZE, hdr_align); > > + *payload_off = afbc_size; > > + > > + afbc_size += n_superblks * ALIGN(superblk_sz, > > AFBC_SUPERBLK_ALIGNMENT); > > + *total_size = afbc_size + offset; > > Generally these are referred to as 'tiles' rather than 'superblocks', > given that I would only expect one superblock per buffer, but if that's > the terminology AFBC uses then it might be better to stick with it. > > > + if ((w * bpp) != (pitch * BITS_PER_BYTE)) { > > + DRM_DEBUG_KMS("Invalid value of (pitch * BITS_PER_BYTE) > > (=%u) should be same as width (=%u) * bpp (=%u)\n", > > + pitch * BITS_PER_BYTE, w, bpp > > + ); > > + return false; > > + } > > Having a too-small pitch is obviously a problem and we should reject > it. But is having a too-large pitch really a problem; does it need to > be an exact match, or can we support the case where the pitch is too > large but also tile-aligned? If we can, it would be very good to > support that. > > Cheers, > Daniel > -- | I would like to | | fix the world, | | but they're not | | giving me the | \ source code! / --- ¯\_(ツ)_/¯ ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-deve
Re: [Intel-gfx] [PATCH 1/3] drm: Expose a method for creating anonymous struct file around drm_minor
Quoting Chris Wilson (2019-11-06 10:26:48) > Quoting Daniel Vetter (2019-11-06 10:19:50) > > On Wed, Nov 06, 2019 at 10:07:14AM +, Chris Wilson wrote: > > > Sometimes we need to create a struct file to wrap a drm_device, as it > > > the user were to have opened /dev/dri/card0 but to do so anonymously > > > (i.e. for internal use). Provide a utility method to create a struct > > > file with the drm_device->driver.fops, that wrap the drm_device. > > > > > > Signed-off-by: Chris Wilson > > > > For proper internal access we already have drm_client_open, so I think > > this has limited (but good use) in selftests only. So > > EXPORT_SYMBOL_FOR_TESTS_ONLY plus maybe a clearer name for the intended > > use like drm_file_mock_open? > > I found the example in drm_gem_prime_mmap() that was doing the same trick, > and the trick of being able to instantiate new struct file and install a > fd whenever seems like it will come in handy... Just lacking the third > user at the moment to claim generality. The closest example I found in the spirit of creating a new drm_device struct file and installing it is drm_mode_create_lease_ioctl() that uses file_clone_open() for this purpose. The argument there would be whether cloning the (file->f_path, file->f_flags, file->f_cred) is appropriate versus an anonymous inode. I think cloning the credentials seems correct for leasing. -Chris ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [GIT PULL FOR v5.5 - 2nd try] R-Car DU CMM support
Hi Laurent, Dave, On Wed, Nov 06, 2019 at 12:02:05PM +0200, Laurent Pinchart wrote: > This time with Jacopo correctly CC'ed. > > On Wed, Nov 06, 2019 at 12:00:59PM +0200, Laurent Pinchart wrote: > > Hi Dave, > > > > (CC'ing Jacopo) > > > > On Wed, Nov 06, 2019 at 01:40:13PM +1000, Dave Airlie wrote: > > > On Wed, 6 Nov 2019 at 05:56, Dave Airlie wrote: > > > > On Wed, 6 Nov 2019 at 05:49, Laurent Pinchart wrote: > > > > > > > > > > Hi Dave, > > > > > > > > > > Has this pull request fallen through the cracks ? > > > > > > > > It fell down a different crack than usual, it made it from patchwork > > > > onto my hard drive, but then I didn't execute the pull. > > > > > > > > I've pulled it down, thanks for reminder. > > > > > > Now it failed as I mentioned on irc. > > > > > > I think the new kconfig option needs to be a tristate, otherwise > > > setting it to Y and having rcar-du as M fails to link > > > > Sorry about that :-S Both I and the 0-day bot failed to catch it. > > Jacopo, could you please have a look ? I'm afraid this likely mean a new > > version of the series, and thus missing the merge window, as we're > > already at -rc6. I managed to reproduce it by setting DRM=m. RCAR_CMM stays indeed =y as it's a bool. Simply setting it to tristate is enough to have it set to =m when DRM=m. Could this be changed when applying the series ? diff --git a/drivers/gpu/drm/rcar-du/Kconfig b/drivers/gpu/drm/rcar-du/Kconfig index 539d232790d1..e6607b5c8bb3 100644 --- a/drivers/gpu/drm/rcar-du/Kconfig +++ b/drivers/gpu/drm/rcar-du/Kconfig @@ -14,7 +14,7 @@ config DRM_RCAR_DU If M is selected the module will be called rcar-du-drm. config DRM_RCAR_CMM - bool "R-Car DU Color Management Module (CMM) Support" + tristate "R-Car DU Color Management Module (CMM) Support" depends on DRM && OF depends on DRM_RCAR_DU help Thanks j > > -- > Regards, > > Laurent Pinchart signature.asc Description: PGP signature ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 3/3] drm/prime: Use anon_drm_getfile() for an internal drm struct file
Quoting Daniel Vetter (2019-11-06 10:21:57) > On Wed, Nov 06, 2019 at 10:07:16AM +, Chris Wilson wrote: > > Currently the drm_prime mmap fallback uses a mock struct file to provide > > the file pointer into the backend mmap routine. Now that we can create > > fully fledged anonymous struct file around the drm device, put it to > > use. > > > > Signed-off-by: Chris Wilson > > --- > > drivers/gpu/drm/drm_prime.c | 26 -- > > 1 file changed, 8 insertions(+), 18 deletions(-) > > > > diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c > > index 0814211b0f3f..5faa63713ec8 100644 > > --- a/drivers/gpu/drm/drm_prime.c > > +++ b/drivers/gpu/drm/drm_prime.c > > @@ -709,8 +709,7 @@ EXPORT_SYMBOL(drm_gem_dmabuf_vunmap); > > */ > > int drm_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct > > *vma) > > { > > - struct drm_file *priv; > > - struct file *fil; > > + struct file *file; > > int ret; > > > > if (obj->funcs && obj->funcs->mmap) { > > obj->funcs->mmap is the new way of doing this (and hopefully finally > something clean), I'd really like to retire the below hack outright. > > Plus I'm not sure why you need an anon inode here? If a driver needs this > for unmap_mapping_range or similar I think it'd be better to try and make > something work cleanly for obj->funcs->mmap. It's faking one currently. If the fake is not good enough, you are playing whack-a-mole until you finally do create a fully fledged file. If you are going to the trouble of having to create a struct file to provide to the fallback routines, might as well avoid stinky code :) -Chris ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 2/4] drm/udl: Allocate GEM object via struct drm_driver.gem_create_object
In preparation of a switch to SHMEM, udl now allocates its GEM objects via struct drm_driver.gem_create_object. No functional changes are made. For SHMEM GEM objects, udl will require the use of a special mmap function, which we set though the create-object function. Signed-off-by: Thomas Zimmermann Acked-by: Gerd Hoffmann --- drivers/gpu/drm/udl/udl_drv.c | 1 + drivers/gpu/drm/udl/udl_drv.h | 2 ++ drivers/gpu/drm/udl/udl_gem.c | 25 + 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 8426669433e4..778a0b652f64 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -64,6 +64,7 @@ static struct drm_driver driver = { /* gem hooks */ .gem_free_object_unlocked = udl_gem_free_object, + .gem_create_object = udl_driver_gem_create_object, .gem_vm_ops = &udl_gem_vm_ops, .dumb_create = udl_dumb_create, diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h index e1306a51903c..fc312e791d18 100644 --- a/drivers/gpu/drm/udl/udl_drv.h +++ b/drivers/gpu/drm/udl/udl_drv.h @@ -125,6 +125,8 @@ int udl_dumb_create(struct drm_file *file_priv, int udl_gem_mmap(struct drm_file *file_priv, struct drm_device *dev, uint32_t handle, uint64_t *offset); +struct drm_gem_object *udl_driver_gem_create_object(struct drm_device *dev, + size_t size); void udl_gem_free_object(struct drm_gem_object *gem_obj); struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, size_t size); diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c index 7d3c1b73ea02..628749cc1143 100644 --- a/drivers/gpu/drm/udl/udl_gem.c +++ b/drivers/gpu/drm/udl/udl_gem.c @@ -6,26 +6,43 @@ #include #include +#include #include #include #include "udl_drv.h" -struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, - size_t size) +/* + * Helpers for struct drm_driver + */ + +struct drm_gem_object *udl_driver_gem_create_object(struct drm_device *dev, + size_t size) { struct udl_gem_object *obj; obj = kzalloc(sizeof(*obj), GFP_KERNEL); + if (!obj) + return NULL; + + return &obj->base; +} + +struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, + size_t size) +{ + struct drm_gem_object *obj; + + obj = dev->driver->gem_create_object(dev, size); if (obj == NULL) return NULL; - if (drm_gem_object_init(dev, &obj->base, size) != 0) { + if (drm_gem_object_init(dev, obj, size) != 0) { kfree(obj); return NULL; } - return obj; + return to_udl_bo(obj); } static int -- 2.23.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 3/4] drm/udl: Switch to SHMEM
Udl's GEM code and the generic SHMEM are almost identical. Replace the former with SHMEM. The dmabuf support in udl is being replaced with generic GEM PRIME functions. The main difference is in the caching flags for mmap pages. By default, SHMEM always sets (uncached) write combining. In udl's memory management code, only imported buffers use write combining. Memory pages of locally created buffer objects are mmap'ed with caching enabled. To keep the optimization, udl provides its own mmap function for GEM objects where it fixes up the mapping flags. v2: - remove obsolete code in a separate patch Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/udl/Kconfig | 1 + drivers/gpu/drm/udl/udl_drv.c | 29 ++- drivers/gpu/drm/udl/udl_drv.h | 1 + drivers/gpu/drm/udl/udl_fb.c | 66 +++ drivers/gpu/drm/udl/udl_gem.c | 61 +--- 5 files changed, 98 insertions(+), 60 deletions(-) diff --git a/drivers/gpu/drm/udl/Kconfig b/drivers/gpu/drm/udl/Kconfig index b4d179b87f01..145b2a95ce58 100644 --- a/drivers/gpu/drm/udl/Kconfig +++ b/drivers/gpu/drm/udl/Kconfig @@ -5,6 +5,7 @@ config DRM_UDL depends on USB_SUPPORT depends on USB_ARCH_HAS_HCD select USB + select DRM_GEM_SHMEM_HELPER select DRM_KMS_HELPER help This is a KMS driver for the USB displaylink video adapters. diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 778a0b652f64..563cc5809e56 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -32,23 +33,7 @@ static int udl_usb_resume(struct usb_interface *interface) return 0; } -static const struct vm_operations_struct udl_gem_vm_ops = { - .fault = udl_gem_fault, - .open = drm_gem_vm_open, - .close = drm_gem_vm_close, -}; - -static const struct file_operations udl_driver_fops = { - .owner = THIS_MODULE, - .open = drm_open, - .mmap = udl_drm_gem_mmap, - .poll = drm_poll, - .read = drm_read, - .unlocked_ioctl = drm_ioctl, - .release = drm_release, - .compat_ioctl = drm_compat_ioctl, - .llseek = noop_llseek, -}; +DEFINE_DRM_GEM_FOPS(udl_driver_fops); static void udl_driver_release(struct drm_device *dev) { @@ -63,18 +48,10 @@ static struct drm_driver driver = { .release = udl_driver_release, /* gem hooks */ - .gem_free_object_unlocked = udl_gem_free_object, .gem_create_object = udl_driver_gem_create_object, - .gem_vm_ops = &udl_gem_vm_ops, - .dumb_create = udl_dumb_create, - .dumb_map_offset = udl_gem_mmap, .fops = &udl_driver_fops, - - .prime_handle_to_fd = drm_gem_prime_handle_to_fd, - .prime_fd_to_handle = drm_gem_prime_fd_to_handle, - .gem_prime_export = udl_gem_prime_export, - .gem_prime_import = udl_gem_prime_import, + DRM_GEM_SHMEM_DRIVER_OPS, .name = DRIVER_NAME, .desc = DRIVER_DESC, diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h index fc312e791d18..630e64abc986 100644 --- a/drivers/gpu/drm/udl/udl_drv.h +++ b/drivers/gpu/drm/udl/udl_drv.h @@ -85,6 +85,7 @@ struct udl_gem_object { struct udl_framebuffer { struct drm_framebuffer base; struct udl_gem_object *obj; + struct drm_gem_shmem_object *shmem; bool active_16; /* active on the 16-bit channel */ }; diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c index ef3504d06343..f8153b726343 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include "udl_drv.h" @@ -94,16 +95,14 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y, if (!fb->active_16) return 0; - if (!fb->obj->vmapping) { - ret = udl_gem_vmap(fb->obj); - if (ret == -ENOMEM) { + if (!fb->shmem->vaddr) { + void *vaddr; + + vaddr = drm_gem_shmem_vmap(&fb->shmem->base); + if (IS_ERR(vaddr)) { DRM_ERROR("failed to vmap fb\n"); return 0; } - if (!fb->obj->vmapping) { - DRM_ERROR("failed to vmapping\n"); - return 0; - } } aligned_x = DL_ALIGN_DOWN(x, sizeof(unsigned long)); @@ -127,7 +126,7 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y, const int byte_offset = line_offset + (x << log_bpp); const int dev_byte_offset = (fb->base.width * i + x) << log_bpp; if (udl_render_hline(dev, log_bpp, &urb, -(char *) fb->obj->vmapping, +(char *) fb
[PATCH v2 4/4] drm/udl: Remove struct udl_gem_object and functions
Simply removes all the obsolete GEM code from udl. No functional changes. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/udl/Makefile | 2 +- drivers/gpu/drm/udl/udl_dmabuf.c | 254 --- drivers/gpu/drm/udl/udl_drv.h| 29 drivers/gpu/drm/udl/udl_gem.c| 206 - 4 files changed, 1 insertion(+), 490 deletions(-) delete mode 100644 drivers/gpu/drm/udl/udl_dmabuf.c diff --git a/drivers/gpu/drm/udl/Makefile b/drivers/gpu/drm/udl/Makefile index e5bb6f757e11..9c42820ae33d 100644 --- a/drivers/gpu/drm/udl/Makefile +++ b/drivers/gpu/drm/udl/Makefile @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only -udl-y := udl_drv.o udl_modeset.o udl_connector.o udl_encoder.o udl_main.o udl_fb.o udl_transfer.o udl_gem.o udl_dmabuf.o +udl-y := udl_drv.o udl_modeset.o udl_connector.o udl_encoder.o udl_main.o udl_fb.o udl_transfer.o udl_gem.o obj-$(CONFIG_DRM_UDL) := udl.o diff --git a/drivers/gpu/drm/udl/udl_dmabuf.c b/drivers/gpu/drm/udl/udl_dmabuf.c deleted file mode 100644 index b1c1ee64de59.. --- a/drivers/gpu/drm/udl/udl_dmabuf.c +++ /dev/null @@ -1,254 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * udl_dmabuf.c - * - * Copyright (c) 2014 The Chromium OS Authors - */ - -#include -#include - -#include - -#include "udl_drv.h" - -struct udl_drm_dmabuf_attachment { - struct sg_table sgt; - enum dma_data_direction dir; - bool is_mapped; -}; - -static int udl_attach_dma_buf(struct dma_buf *dmabuf, - struct dma_buf_attachment *attach) -{ - struct udl_drm_dmabuf_attachment *udl_attach; - - DRM_DEBUG_PRIME("[DEV:%s] size:%zd\n", dev_name(attach->dev), - attach->dmabuf->size); - - udl_attach = kzalloc(sizeof(*udl_attach), GFP_KERNEL); - if (!udl_attach) - return -ENOMEM; - - udl_attach->dir = DMA_NONE; - attach->priv = udl_attach; - - return 0; -} - -static void udl_detach_dma_buf(struct dma_buf *dmabuf, - struct dma_buf_attachment *attach) -{ - struct udl_drm_dmabuf_attachment *udl_attach = attach->priv; - struct sg_table *sgt; - - if (!udl_attach) - return; - - DRM_DEBUG_PRIME("[DEV:%s] size:%zd\n", dev_name(attach->dev), - attach->dmabuf->size); - - sgt = &udl_attach->sgt; - - if (udl_attach->dir != DMA_NONE) - dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, - udl_attach->dir); - - sg_free_table(sgt); - kfree(udl_attach); - attach->priv = NULL; -} - -static struct sg_table *udl_map_dma_buf(struct dma_buf_attachment *attach, - enum dma_data_direction dir) -{ - struct udl_drm_dmabuf_attachment *udl_attach = attach->priv; - struct udl_gem_object *obj = to_udl_bo(attach->dmabuf->priv); - struct drm_device *dev = obj->base.dev; - struct udl_device *udl = dev->dev_private; - struct scatterlist *rd, *wr; - struct sg_table *sgt = NULL; - unsigned int i; - int page_count; - int nents, ret; - - DRM_DEBUG_PRIME("[DEV:%s] size:%zd dir=%d\n", dev_name(attach->dev), - attach->dmabuf->size, dir); - - /* just return current sgt if already requested. */ - if (udl_attach->dir == dir && udl_attach->is_mapped) - return &udl_attach->sgt; - - if (!obj->pages) { - ret = udl_gem_get_pages(obj); - if (ret) { - DRM_ERROR("failed to map pages.\n"); - return ERR_PTR(ret); - } - } - - page_count = obj->base.size / PAGE_SIZE; - obj->sg = drm_prime_pages_to_sg(obj->pages, page_count); - if (IS_ERR(obj->sg)) { - DRM_ERROR("failed to allocate sgt.\n"); - return ERR_CAST(obj->sg); - } - - sgt = &udl_attach->sgt; - - ret = sg_alloc_table(sgt, obj->sg->orig_nents, GFP_KERNEL); - if (ret) { - DRM_ERROR("failed to alloc sgt.\n"); - return ERR_PTR(-ENOMEM); - } - - mutex_lock(&udl->gem_lock); - - rd = obj->sg->sgl; - wr = sgt->sgl; - for (i = 0; i < sgt->orig_nents; ++i) { - sg_set_page(wr, sg_page(rd), rd->length, rd->offset); - rd = sg_next(rd); - wr = sg_next(wr); - } - - if (dir != DMA_NONE) { - nents = dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir); - if (!nents) { - DRM_ERROR("failed to map sgl with iommu.\n"); - sg_free_table(sgt); - sgt = ERR_PTR(-EIO); - goto err_unlock; - } - } - - udl_attach->is_mapped = true; - udl_attach->dir = dir; - attach->priv = udl_attach; - -err_unlock: -
[PATCH v2 1/4] drm/udl: Remove flags field from struct udl_gem_object
The flags field in struct udl_gem controls mapping parameters: cached access for local buffers, write-combined access for imported buffers. We can drop the field and distinguish both cases by testing whether struct drm_gem_object.import_attach is NULL. Signed-off-by: Thomas Zimmermann Acked-by: Gerd Hoffmann --- drivers/gpu/drm/udl/udl_dmabuf.c | 1 - drivers/gpu/drm/udl/udl_drv.h| 4 drivers/gpu/drm/udl/udl_gem.c| 27 +++ 3 files changed, 7 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/udl/udl_dmabuf.c b/drivers/gpu/drm/udl/udl_dmabuf.c index 3108e9a9234b..b1c1ee64de59 100644 --- a/drivers/gpu/drm/udl/udl_dmabuf.c +++ b/drivers/gpu/drm/udl/udl_dmabuf.c @@ -241,7 +241,6 @@ struct drm_gem_object *udl_gem_prime_import(struct drm_device *dev, goto fail_unmap; uobj->base.import_attach = attach; - uobj->flags = UDL_BO_WC; return &uobj->base; diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h index 12a970fd9a87..e1306a51903c 100644 --- a/drivers/gpu/drm/udl/udl_drv.h +++ b/drivers/gpu/drm/udl/udl_drv.h @@ -29,9 +29,6 @@ struct drm_mode_create_dumb; #define DRIVER_MINOR 0 #define DRIVER_PATCHLEVEL 1 -#define UDL_BO_CACHEABLE (1 << 0) -#define UDL_BO_WC (1 << 1) - struct udl_device; struct urb_node { @@ -81,7 +78,6 @@ struct udl_gem_object { struct page **pages; void *vmapping; struct sg_table *sg; - unsigned int flags; }; #define to_udl_bo(x) container_of(x, struct udl_gem_object, base) diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c index b23a5c2fcd80..7d3c1b73ea02 100644 --- a/drivers/gpu/drm/udl/udl_gem.c +++ b/drivers/gpu/drm/udl/udl_gem.c @@ -25,7 +25,6 @@ struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, return NULL; } - obj->flags = UDL_BO_CACHEABLE; return obj; } @@ -57,23 +56,6 @@ udl_gem_create(struct drm_file *file, return 0; } -static void update_vm_cache_attr(struct udl_gem_object *obj, -struct vm_area_struct *vma) -{ - DRM_DEBUG_KMS("flags = 0x%x\n", obj->flags); - - /* non-cacheable as default. */ - if (obj->flags & UDL_BO_CACHEABLE) { - vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); - } else if (obj->flags & UDL_BO_WC) { - vma->vm_page_prot = - pgprot_writecombine(vm_get_page_prot(vma->vm_flags)); - } else { - vma->vm_page_prot = - pgprot_noncached(vm_get_page_prot(vma->vm_flags)); - } -} - int udl_dumb_create(struct drm_file *file, struct drm_device *dev, struct drm_mode_create_dumb *args) @@ -86,16 +68,21 @@ int udl_dumb_create(struct drm_file *file, int udl_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) { + struct drm_gem_object *obj; int ret; ret = drm_gem_mmap(filp, vma); if (ret) return ret; + obj = vma->vm_private_data; + vma->vm_flags &= ~VM_PFNMAP; vma->vm_flags |= VM_MIXEDMAP; - update_vm_cache_attr(to_udl_bo(vma->vm_private_data), vma); + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); + if (obj->import_attach) + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); return ret; } @@ -155,7 +142,7 @@ int udl_gem_vmap(struct udl_gem_object *obj) return -ENOMEM; return 0; } - + ret = udl_gem_get_pages(obj); if (ret) return ret; -- 2.23.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 0/4] drm/udl: Convert to SHMEM
Udl's GEM implementation is mostly SHMEM and we should attempt to replace it with the latter. Patches #1 and #2 update udl to simplify the conversion. In patch #3 the udl code is being replaced by SHMEM. The GEM object's mmap() and free_object() functions are wrappers around their SHMEM counterparts. For mmap() we fix-up the page-caching flags to distinguish between write-combined and cached access. For free(), we have to unmap the buffer's mapping that has been established by udl's fbdev code. Patch #4 removes the obsolete udl code. The patchset has been tested by running the fbdev console, X11 and Weston on a DisplayLink adapter. v2: * remove obsolete udl code in a separate patch Thomas Zimmermann (4): drm/udl: Remove flags field from struct udl_gem_object drm/udl: Allocate GEM object via struct drm_driver.gem_create_object drm/udl: Switch to SHMEM drm/udl: Remove struct udl_gem_object and functions drivers/gpu/drm/udl/Kconfig | 1 + drivers/gpu/drm/udl/Makefile | 2 +- drivers/gpu/drm/udl/udl_dmabuf.c | 255 --- drivers/gpu/drm/udl/udl_drv.c| 30 +--- drivers/gpu/drm/udl/udl_drv.h| 36 + drivers/gpu/drm/udl/udl_fb.c | 66 drivers/gpu/drm/udl/udl_gem.c| 245 ++--- 7 files changed, 93 insertions(+), 542 deletions(-) delete mode 100644 drivers/gpu/drm/udl/udl_dmabuf.c -- 2.23.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH V9 3/6] mdev: introduce device specific ops
On Wed, 6 Nov 2019 15:05:45 +0800 Jason Wang wrote: > Currently, except for the create and remove, the rest of > mdev_parent_ops is designed for vfio-mdev driver only and may not help > for kernel mdev driver. With the help of class id, this patch > introduces device specific callbacks inside mdev_device > structure. This allows different set of callback to be used by > vfio-mdev and virtio-mdev. > > Reviewed-by: Parav Pandit > Signed-off-by: Jason Wang > --- > .../driver-api/vfio-mediated-device.rst | 35 + > MAINTAINERS | 1 + > drivers/gpu/drm/i915/gvt/kvmgt.c | 18 --- > drivers/s390/cio/vfio_ccw_ops.c | 18 --- > drivers/s390/crypto/vfio_ap_ops.c | 14 +++-- > drivers/vfio/mdev/mdev_core.c | 24 - > drivers/vfio/mdev/mdev_private.h | 5 ++ > drivers/vfio/mdev/vfio_mdev.c | 37 ++--- > include/linux/mdev.h | 43 --- > include/linux/mdev_vfio_ops.h | 52 +++ > samples/vfio-mdev/mbochs.c| 20 --- > samples/vfio-mdev/mdpy.c | 20 --- > samples/vfio-mdev/mtty.c | 18 --- > 13 files changed, 206 insertions(+), 99 deletions(-) > create mode 100644 include/linux/mdev_vfio_ops.h Reviewed-by: Cornelia Huck ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH V9 4/6] mdev: introduce virtio device and its device ops
On Wed, 6 Nov 2019 15:05:46 +0800 Jason Wang wrote: > This patch implements basic support for mdev driver that supports > virtio transport for kernel virtio driver. > > Signed-off-by: Jason Wang > --- > MAINTAINERS | 1 + > drivers/vfio/mdev/mdev_core.c| 21 + > drivers/vfio/mdev/mdev_private.h | 2 + > include/linux/mdev.h | 6 ++ > include/linux/mdev_virtio_ops.h | 147 +++ > 5 files changed, 177 insertions(+) > create mode 100644 include/linux/mdev_virtio_ops.h Reviewed-by: Cornelia Huck ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH V9 5/6] virtio: introduce a mdev based transport
On Wed, 6 Nov 2019 15:05:47 +0800 Jason Wang wrote: > This patch introduces a new mdev transport for virtio. This is used to > use kernel virtio driver to drive the mediated device that is capable > of populating virtqueue directly. > > A new virtio-mdev driver will be registered to the mdev bus, when a > new virtio-mdev device is probed, it will register the device with > mdev based config ops. This means it is a software transport between > mdev driver and mdev device. The transport was implemented through > device specific ops which is a part of mdev_parent_ops now. > > Signed-off-by: Jason Wang > --- > drivers/virtio/Kconfig | 13 ++ > drivers/virtio/Makefile | 1 + > drivers/virtio/virtio_mdev.c | 406 +++ > 3 files changed, 420 insertions(+) > create mode 100644 drivers/virtio/virtio_mdev.c > > diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig > index 078615cf2afc..558ac607d107 100644 > --- a/drivers/virtio/Kconfig > +++ b/drivers/virtio/Kconfig > @@ -43,6 +43,19 @@ config VIRTIO_PCI_LEGACY > > If unsure, say Y. > > +config VIRTIO_MDEV > + tristate "MDEV driver for virtio devices" > + depends on VFIO_MDEV && VIRTIO > + default n > + help > + This driver provides support for virtio based paravirtual > + device driver over MDEV bus. This requires your environemnt > + has appropriate virtio mdev device implementation which may > + operate on the physical device that the datapath of virtio > + could be offloaded to hardware. That sentence is a bit confusing to me... what about "For this to be useful, you need an appropriate virtio mdev device implementation that operates on a physical device to allow the datapath of virtio to be offloaded to hardware." ? > + > + If unsure, say M Building this as a module should not hurt (but please add a trailing '.' here :) > + > config VIRTIO_PMEM > tristate "Support for virtio pmem driver" > depends on VIRTIO With the changes above, Reviewed-by: Cornelia Huck ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCHv2 2/4] drm/malidp: use afbc helpers
Hi Andrzej, On Mon, Nov 04, 2019 at 11:12:26PM +0100, Andrzej Pietrasiewicz wrote: > There are afbc helpers available. > > Signed-off-by: Andrzej Pietrasiewicz > --- > drivers/gpu/drm/arm/malidp_drv.c | 66 ++-- > 1 file changed, 12 insertions(+), 54 deletions(-) > > diff --git a/drivers/gpu/drm/arm/malidp_drv.c > b/drivers/gpu/drm/arm/malidp_drv.c > index 37d92a06318e..ab93588cc8eb 100644 > --- a/drivers/gpu/drm/arm/malidp_drv.c > +++ b/drivers/gpu/drm/arm/malidp_drv.c > @@ -15,6 +15,7 @@ > #include > #include > > +#include > #include > #include > #include > @@ -35,8 +36,6 @@ > #include "malidp_hw.h" > > #define MALIDP_CONF_VALID_TIMEOUT250 > -#define AFBC_HEADER_SIZE 16 > -#define AFBC_SUPERBLK_ALIGNMENT 128 > > static void malidp_write_gamma_table(struct malidp_hw_device *hwdev, >u32 data[MALIDP_COEFFTAB_NUM_COEFFS]) > @@ -277,24 +276,8 @@ malidp_verify_afbc_framebuffer_caps(struct drm_device > *dev, > mode_cmd->modifier[0]) == false) > return false; > > - if (mode_cmd->offsets[0] != 0) { > - DRM_DEBUG_KMS("AFBC buffers' plane offset should be 0\n"); > - return false; > - } > - > - switch (mode_cmd->modifier[0] & AFBC_SIZE_MASK) { > - case AFBC_SIZE_16X16: > - if ((mode_cmd->width % 16) || (mode_cmd->height % 16)) { > - DRM_DEBUG_KMS("AFBC buffers must be aligned to 16 > pixels\n"); > - return false; > - } > - break; > - default: > - DRM_DEBUG_KMS("Unsupported AFBC block size\n"); > - return false; > - } > - > - return true; > + return drm_afbc_check_offset(dev, mode_cmd) && > +drm_afbc_check_size_align(dev, mode_cmd); > } Given that the content of this function gets copied pretty much verbatim into the new drm_afbc.c file, I suggest you make the change in the 1/4 patch and also update the copyright statement in that file to show that the code originated from here. Best regards, Liviu > > static bool > @@ -302,54 +285,29 @@ malidp_verify_afbc_framebuffer_size(struct drm_device > *dev, > struct drm_file *file, > const struct drm_mode_fb_cmd2 *mode_cmd) > { > - int n_superblocks = 0; > const struct drm_format_info *info; > struct drm_gem_object *objs = NULL; > - u32 afbc_superblock_size = 0, afbc_superblock_height = 0; > - u32 afbc_superblock_width = 0, afbc_size = 0; > int bpp = 0; > - > - switch (mode_cmd->modifier[0] & AFBC_SIZE_MASK) { > - case AFBC_SIZE_16X16: > - afbc_superblock_height = 16; > - afbc_superblock_width = 16; > - break; > - default: > - DRM_DEBUG_KMS("AFBC superblock size is not supported\n"); > - return false; > - } > + u32 w, h; > > info = drm_get_format_info(dev, mode_cmd); > - > - n_superblocks = (mode_cmd->width / afbc_superblock_width) * > - (mode_cmd->height / afbc_superblock_height); > - > bpp = malidp_format_get_bpp(info->format); > > - afbc_superblock_size = (bpp * afbc_superblock_width * > afbc_superblock_height) > - / BITS_PER_BYTE; > - > - afbc_size = ALIGN(n_superblocks * AFBC_HEADER_SIZE, > AFBC_SUPERBLK_ALIGNMENT); > - afbc_size += n_superblocks * ALIGN(afbc_superblock_size, > AFBC_SUPERBLK_ALIGNMENT); > - > - if ((mode_cmd->width * bpp) != (mode_cmd->pitches[0] * BITS_PER_BYTE)) { > - DRM_DEBUG_KMS("Invalid value of (pitch * BITS_PER_BYTE) (=%u) " > - "should be same as width (=%u) * bpp (=%u)\n", > - (mode_cmd->pitches[0] * BITS_PER_BYTE), > - mode_cmd->width, bpp); > - return false; > - } > - > objs = drm_gem_object_lookup(file, mode_cmd->handles[0]); > if (!objs) { > DRM_DEBUG_KMS("Failed to lookup GEM object\n"); > return false; > } > > - if (objs->size < afbc_size) { > - DRM_DEBUG_KMS("buffer size (%zu) too small for AFBC buffer size > = %u\n", > - objs->size, afbc_size); > + if (!drm_afbc_get_superblk_wh(mode_cmd->modifier[0], &w, &h)) > + return false; > + > + if (!drm_afbc_check_fb_size(mode_cmd->pitches[0], bpp, > + mode_cmd->width, mode_cmd->height, w, h, > + objs->size, mode_cmd->offsets[0], > + AFBC_SUPERBLK_ALIGNMENT)) { > drm_gem_object_put_unlocked(objs); > + > return false; > } > > -- > 2.17.1 > -- | I would like to | | fix the world, | | but they're not | | giving me the | \ source
Re: [PATCH] drm/bridge: tc358767: fix max_tu_symbol value
On 10/10/2019 12:25, Tomi Valkeinen wrote: Hi Andrzej, On 10/10/2019 12:19, Andrzej Hajda wrote: On 24.09.2019 15:17, Tomi Valkeinen wrote: max_tu_symbol was programmed to TU_SIZE_RECOMMENDED - 1, which is not what the spec says. The spec says: roundup ((input active video bandwidth in bytes/output active video bandwidth in bytes) * tu_size) It is not quite clear what the above means, but calculating max_tu_symbol = (input Bps / output Bps) * tu_size seems to work and fixes the issues seen. This fixes artifacts in some videomodes (e.g. 1024x768@60 on 2-lanes & 1.62Gbps was pretty bad for me). Signed-off-by: Tomi Valkeinen Queued to fixes. If you didn't push this yet, can you drop it for now? This works for all the video modes I have tested, but as I mention above, the calculation is really not quite clear to me. I've sent queries to Toshiba about how to calculate this, and I'm hoping to get a reply soon. If you did push it already, that's fine too, as it does improve things. Just for the record, got a reply from Toshiba, and the patch is correct. Tomi -- Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [Intel-gfx] [PATCH] drm/fbdev: Fallback to non tiled mode if all tiles not present
Hi, On Wed, 6 Nov 2019 at 02:47, Dave Airlie wrote: > Otherwise I think this seems fine, though it does beg the question in > my mind of what happens if I get 2 8K monitors, and plug the first > tile of one in, and the second tile of the other in. Honestly in that case I think 'you get to literally keep both pieces' is a reasonable answer. Cheers, Daniel ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 205093] [amdgpu] resume of IP block failed -110 (GPU crash into black screen)
https://bugzilla.kernel.org/show_bug.cgi?id=205093 Marcin P (kat.zygf...@gmail.com) changed: What|Removed |Added Kernel Version|5.2.13 |5.3.6 -- You are receiving this mail because: You are watching the assignee of the bug. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 4/4] drm/udl: Remove struct udl_gem_object and functions
Den 06.11.2019 11.47, skrev Thomas Zimmermann: > Simply removes all the obsolete GEM code from udl. No functional > changes. > > Signed-off-by: Thomas Zimmermann > --- > drivers/gpu/drm/udl/Makefile | 2 +- > drivers/gpu/drm/udl/udl_dmabuf.c | 254 --- > drivers/gpu/drm/udl/udl_drv.h| 29 > drivers/gpu/drm/udl/udl_gem.c| 206 - > 4 files changed, 1 insertion(+), 490 deletions(-) > delete mode 100644 drivers/gpu/drm/udl/udl_dmabuf.c > > -int udl_gem_vmap(struct udl_gem_object *obj) > -{ > - int page_count = obj->base.size / PAGE_SIZE; > - int ret; > - > - if (obj->base.import_attach) { > - obj->vmapping = dma_buf_vmap(obj->base.import_attach->dmabuf); > - if (!obj->vmapping) > - return -ENOMEM; > - return 0; > - } > - > - ret = udl_gem_get_pages(obj); > - if (ret) > - return ret; > - > - obj->vmapping = vmap(obj->pages, page_count, 0, PAGE_KERNEL); This differs from the shmem helper vmap: shmem->vaddr = vmap(shmem->pages, obj->size >> PAGE_SHIFT, VM_MAP, pgprot_writecombine(PAGE_KERNEL)); Boris added the WC in be7d9f05c53e: drm/gem_shmem: Use a writecombine mapping for ->vaddr Right now, the BO is mapped as a cached region when ->vmap() is called and the underlying object is not a dmabuf. Doing that makes cache management a bit more complicated (you'd need to call dma_map/unmap_sg() on the ->sgt field everytime the BO is about to be passed to the GPU/CPU), so let's map the BO with writecombine attributes instead (as done in most drivers). I don't know what the implications of this are, just pointing out a difference. Noralf. > - if (!obj->vmapping) > - return -ENOMEM; > - return 0; > -} ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] drm: msm: a6xx: fix debug bus register configuration
Fix the cx debugbus related register configuration, to collect accurate bus data during gpu snapshot. This helps with complete snapshot dump and also complete proper GPU recovery. Signed-off-by: Sharat Masetty --- drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c | 24 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c index 483e100..c5764b4 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c @@ -353,26 +353,26 @@ static void a6xx_get_debugbus(struct msm_gpu *gpu, cxdbg = ioremap(res->start, resource_size(res)); if (cxdbg) { - cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_CNTLT, + cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_CNTLT, A6XX_DBGC_CFG_DBGBUS_CNTLT_SEGT(0xf)); - cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_CNTLM, + cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_CNTLM, A6XX_DBGC_CFG_DBGBUS_CNTLM_ENABLE(0xf)); - cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_IVTL_0, 0); - cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_IVTL_1, 0); - cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_IVTL_2, 0); - cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_IVTL_3, 0); + cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_IVTL_0, 0); + cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_IVTL_1, 0); + cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_IVTL_2, 0); + cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_IVTL_3, 0); - cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_BYTEL_0, + cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_BYTEL_0, 0x76543210); - cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_BYTEL_1, + cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_BYTEL_1, 0xFEDCBA98); - cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_MASKL_0, 0); - cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_MASKL_1, 0); - cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_MASKL_2, 0); - cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_MASKL_3, 0); + cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_MASKL_0, 0); + cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_MASKL_1, 0); + cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_MASKL_2, 0); + cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_MASKL_3, 0); } nr_debugbus_blocks = ARRAY_SIZE(a6xx_debugbus_blocks) + -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 4/4] drm/udl: Remove struct udl_gem_object and functions
Hi Am 06.11.19 um 12:48 schrieb Noralf Trønnes: > > > Den 06.11.2019 11.47, skrev Thomas Zimmermann: >> Simply removes all the obsolete GEM code from udl. No functional >> changes. >> >> Signed-off-by: Thomas Zimmermann >> --- >> drivers/gpu/drm/udl/Makefile | 2 +- >> drivers/gpu/drm/udl/udl_dmabuf.c | 254 --- >> drivers/gpu/drm/udl/udl_drv.h| 29 >> drivers/gpu/drm/udl/udl_gem.c| 206 - >> 4 files changed, 1 insertion(+), 490 deletions(-) >> delete mode 100644 drivers/gpu/drm/udl/udl_dmabuf.c >> > > > >> -int udl_gem_vmap(struct udl_gem_object *obj) >> -{ >> -int page_count = obj->base.size / PAGE_SIZE; >> -int ret; >> - >> -if (obj->base.import_attach) { >> -obj->vmapping = dma_buf_vmap(obj->base.import_attach->dmabuf); >> -if (!obj->vmapping) >> -return -ENOMEM; >> -return 0; >> -} >> - >> -ret = udl_gem_get_pages(obj); >> -if (ret) >> -return ret; >> - >> -obj->vmapping = vmap(obj->pages, page_count, 0, PAGE_KERNEL); > > This differs from the shmem helper vmap: > > shmem->vaddr = vmap(shmem->pages, obj->size >> PAGE_SHIFT, > VM_MAP, pgprot_writecombine(PAGE_KERNEL)); > > Boris added the WC in be7d9f05c53e: > > drm/gem_shmem: Use a writecombine mapping for ->vaddr > > Right now, the BO is mapped as a cached region when ->vmap() is called > and the underlying object is not a dmabuf. > Doing that makes cache management a bit more complicated (you'd need > to call dma_map/unmap_sg() on the ->sgt field everytime the BO is about > to be passed to the GPU/CPU), so let's map the BO with writecombine > attributes instead (as done in most drivers). > > I don't know what the implications of this are, just pointing out a > difference. Thanks! Switching to SHMEM disables caching on these pages. The logic around dma_map/unmap_sg() is the same in udl and generic prime functions from what I can tell. Actually, I've never seen any difference in display performance when modifying these settings. (DisplayLink is always slow.) I'd like to throw away the caching optimization and rather tell userspace to allocate a shadow buffer if necessary. Best regards Thomas > Noralf. > >> -if (!obj->vmapping) >> -return -ENOMEM; >> -return 0; >> -} > > ___ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel > -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer signature.asc Description: OpenPGP digital signature ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCHv2 1/4] drm/arm: Factor out generic afbc helpers
Hi Daniel, Thank you for review, W dniu 05.11.2019 o 10:22, Daniel Vetter pisze: On Mon, Nov 04, 2019 at 11:12:25PM +0100, Andrzej Pietrasiewicz wrote: These are useful for other users of afbc, e.g. rockchip. + +bool drm_afbc_check_fb_size_ret(u32 pitch, int bpp, + u32 w, u32 h, u32 superblk_w, u32 superblk_h, + size_t size, u32 offset, u32 hdr_align, + u32 *payload_off, u32 *total_size) +{ + int n_superblks = 0; + u32 superblk_sz = 0; + u32 afbc_size = 0; + + n_superblks = (w / superblk_w) * (h / superblk_h); + superblk_sz = (bpp * superblk_w * superblk_h) / BITS_PER_BYTE; + afbc_size = ALIGN(n_superblks * AFBC_HEADER_SIZE, hdr_align); + *payload_off = afbc_size; + + afbc_size += n_superblks * ALIGN(superblk_sz, AFBC_SUPERBLK_ALIGNMENT); + *total_size = afbc_size + offset; + + if ((w * bpp) != (pitch * BITS_PER_BYTE)) { + DRM_DEBUG_KMS("Invalid value of (pitch * BITS_PER_BYTE) (=%u) should be same as width (=%u) * bpp (=%u)\n", + pitch * BITS_PER_BYTE, w, bpp + ); + return false; + } + + if (size < afbc_size) { + DRM_DEBUG_KMS("buffer size (%zu) too small for AFBC buffer size = %u\n", + size, afbc_size + ); + + return false; + } + + return true; +} +EXPORT_SYMBOL(drm_afbc_check_fb_size_ret); + +bool drm_afbc_check_fb_size(u32 pitch, int bpp, + u32 w, u32 h, u32 superblk_w, u32 superblk_h, + size_t size, u32 offset, u32 hdr_align) +{ + u32 payload_offset, total_size; + + return drm_afbc_check_fb_size_ret(pitch, bpp, w, h, + superblk_w, superblk_h, + size, offset, hdr_align, + &payload_offset, &total_size); +} +EXPORT_SYMBOL(drm_afbc_check_fb_size); Why don't we have one overall "check afbc parameters against buffer" function? I noticed that different drivers have different needs (malidp and rockchip are kind of similar, but komeda is a bit different). That is why the helpers are only building blocks out of which each driver builds its own checking logic. In particular komeda wants some by-products of the check stored in its internal data structures, hence drm_afbc_check_fb_size_ret() and its wrapper drm_afbc_check_fb_size() which ignores the "out" parameters. If I wanted to create one overall "check afbc parameters" I'd have to come up with a way to pass driver-specific requirements to it and then inside the function have some logic to decide what to check against what. Do you think it is worth it? Andrzej ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 1/2] drm/todo: Convert drivers to generic fbdev emulation
This replaces the original TODO item for drm_fb_helper_fbdev_setup() and _teardown(), which are deprecated. v2: * remove driver-specific comments * list some basic requirements * keep a TODO item on drm_fb_helper_init() Signed-off-by: Thomas Zimmermann --- Documentation/gpu/todo.rst | 23 +++ 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index b3c0d517db93..3ec509381fc5 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -171,21 +171,12 @@ Contact: Maintainer of the driver you plan to convert Level: Intermediate -Convert drivers to use drm_fb_helper_fbdev_setup/teardown() +Convert drivers to use drm_fbdev_generic_setup() + -Most drivers can use drm_fb_helper_fbdev_setup() except maybe: - -- amdgpu which has special logic to decide whether to call - drm_helper_disable_unused_functions() - -- armada which isn't atomic and doesn't call - drm_helper_disable_unused_functions() - -- i915 which calls drm_fb_helper_initial_config() in a worker - -Drivers that use drm_framebuffer_remove() to clean up the fbdev framebuffer can -probably use drm_fb_helper_fbdev_teardown(). +Most drivers can use drm_fbdev_generic_setup(). Driver have to implement +atomic modesetting and GEM vmap support. Current generic fbdev emulation +expects the framebuffer in system memory (or system-like memory). Contact: Maintainer of the driver you plan to convert @@ -328,8 +319,8 @@ drm_fb_helper tasks these igt tests need to be fixed: kms_fbcon_fbt@psr and kms_fbcon_fbt@psr-suspend. -- The max connector argument for drm_fb_helper_init() and - drm_fb_helper_fbdev_setup() isn't used anymore and can be removed. +- The max connector argument for drm_fb_helper_init() isn't used anymore and + can be removed. - The helper doesn't keep an array of connectors anymore so these can be removed: drm_fb_helper_single_add_all_connectors(), -- 2.23.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 2/2] drm/fb-helper: Remove drm_fb_helper_fbdev_{setup, teardown}()
Both functions are unused and can be removed. Drivers should use drm_fbdev_generic_setup() instead. Signed-off-by: Thomas Zimmermann Reviewed-by: Noralf Trønnes --- drivers/gpu/drm/drm_fb_helper.c | 109 +--- include/drm/drm_fb_helper.h | 25 2 files changed, 1 insertion(+), 133 deletions(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 8ebeccdeed23..1038a2f0639e 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -95,10 +95,6 @@ static DEFINE_MUTEX(kernel_fb_helper_lock); * It will automatically set up deferred I/O if the driver requires a shadow * buffer. * - * For other drivers, setup fbdev emulation by calling - * drm_fb_helper_fbdev_setup() and tear it down by calling - * drm_fb_helper_fbdev_teardown(). - * * At runtime drivers should restore the fbdev console by using * drm_fb_helper_lastclose() as their &drm_driver.lastclose callback. * They should also notify the fb helper code from updates to the output @@ -1919,108 +1915,6 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) } EXPORT_SYMBOL(drm_fb_helper_hotplug_event); -/** - * drm_fb_helper_fbdev_setup() - Setup fbdev emulation - * @dev: DRM device - * @fb_helper: fbdev helper structure to set up - * @funcs: fbdev helper functions - * @preferred_bpp: Preferred bits per pixel for the device. - * @dev->mode_config.preferred_depth is used if this is zero. - * @max_conn_count: Maximum number of connectors (not used) - * - * This function sets up fbdev emulation and registers fbdev for access by - * userspace. If all connectors are disconnected, setup is deferred to the next - * time drm_fb_helper_hotplug_event() is called. - * The caller must to provide a &drm_fb_helper_funcs->fb_probe callback - * function. - * - * Use drm_fb_helper_fbdev_teardown() to destroy the fbdev. - * - * See also: drm_fb_helper_initial_config(), drm_fbdev_generic_setup(). - * - * Returns: - * Zero on success or negative error code on failure. - */ -int drm_fb_helper_fbdev_setup(struct drm_device *dev, - struct drm_fb_helper *fb_helper, - const struct drm_fb_helper_funcs *funcs, - unsigned int preferred_bpp, - unsigned int max_conn_count) -{ - int ret; - - if (!preferred_bpp) - preferred_bpp = dev->mode_config.preferred_depth; - if (!preferred_bpp) - preferred_bpp = 32; - - drm_fb_helper_prepare(dev, fb_helper, funcs); - - ret = drm_fb_helper_init(dev, fb_helper, 0); - if (ret < 0) { - DRM_DEV_ERROR(dev->dev, "fbdev: Failed to initialize (ret=%d)\n", ret); - return ret; - } - - if (!drm_drv_uses_atomic_modeset(dev)) - drm_helper_disable_unused_functions(dev); - - ret = drm_fb_helper_initial_config(fb_helper, preferred_bpp); - if (ret < 0) { - DRM_DEV_ERROR(dev->dev, "fbdev: Failed to set configuration (ret=%d)\n", ret); - goto err_drm_fb_helper_fini; - } - - return 0; - -err_drm_fb_helper_fini: - drm_fb_helper_fbdev_teardown(dev); - - return ret; -} -EXPORT_SYMBOL(drm_fb_helper_fbdev_setup); - -/** - * drm_fb_helper_fbdev_teardown - Tear down fbdev emulation - * @dev: DRM device - * - * This function unregisters fbdev if not already done and cleans up the - * associated resources including the &drm_framebuffer. - * The driver is responsible for freeing the &drm_fb_helper structure which is - * stored in &drm_device->fb_helper. Do note that this pointer has been cleared - * when this function returns. - * - * In order to support device removal/unplug while file handles are still open, - * drm_fb_helper_unregister_fbi() should be called on device removal and - * drm_fb_helper_fbdev_teardown() in the &drm_driver->release callback when - * file handles are closed. - */ -void drm_fb_helper_fbdev_teardown(struct drm_device *dev) -{ - struct drm_fb_helper *fb_helper = dev->fb_helper; - struct fb_ops *fbops = NULL; - - if (!fb_helper) - return; - - /* Unregister if it hasn't been done already */ - if (fb_helper->fbdev && fb_helper->fbdev->dev) - drm_fb_helper_unregister_fbi(fb_helper); - - if (fb_helper->fbdev && fb_helper->fbdev->fbdefio) { - fb_deferred_io_cleanup(fb_helper->fbdev); - kfree(fb_helper->fbdev->fbdefio); - fbops = fb_helper->fbdev->fbops; - } - - drm_fb_helper_fini(fb_helper); - kfree(fbops); - - if (fb_helper->fb) - drm_framebuffer_remove(fb_helper->fb); -} -EXPORT_SYMBOL(drm_fb_helper_fbdev_teardown); - /** * drm_fb_helper_lastclose - DRM driver lastclose helper for fbdev emulation * @dev: DRM device @@ -2309,8 +2203,7 @@ static const struct drm_client_funcs drm
[PATCH v2 0/2] Remove drm_fb_helper_fbdev_{setup,teardown}()
Both functions are unused. Update TODO item and remove them. v2: * reword the whole TODO item * keep a TODO item on drm_fb_helper_init() Thomas Zimmermann (2): drm/todo: Convert drivers to generic fbdev emulation drm/fb-helper: Remove drm_fb_helper_fbdev_{setup,teardown}() Documentation/gpu/todo.rst | 23 ++- drivers/gpu/drm/drm_fb_helper.c | 109 +--- include/drm/drm_fb_helper.h | 25 3 files changed, 8 insertions(+), 149 deletions(-) -- 2.23.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2] drm/amdgpu: fix double reference dropping
Am 06.11.19 um 12:35 schrieb Pan Bian: > The reference to object fence is dropped at the end of the loop. > However, it is dropped again outside the loop. The reference can be > dropped immediately after calling dma_fence_wait() in the loop and > thus the dropping operation outside the loop can be removed. > > Signed-off-by: Pan Bian Reviewed-by: Christian König > --- > v2: fix the bug in a more concise way > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c | 6 ++ > 1 file changed, 2 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c > index 649e68c4479b..d1495e1c9289 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c > @@ -33,7 +33,7 @@ static int amdgpu_benchmark_do_move(struct amdgpu_device > *adev, unsigned size, > { > unsigned long start_jiffies; > unsigned long end_jiffies; > - struct dma_fence *fence = NULL; > + struct dma_fence *fence; > int i, r; > > start_jiffies = jiffies; > @@ -44,16 +44,14 @@ static int amdgpu_benchmark_do_move(struct amdgpu_device > *adev, unsigned size, > if (r) > goto exit_do_move; > r = dma_fence_wait(fence, false); > + dma_fence_put(fence); > if (r) > goto exit_do_move; > - dma_fence_put(fence); > } > end_jiffies = jiffies; > r = jiffies_to_msecs(end_jiffies - start_jiffies); > > exit_do_move: > - if (fence) > - dma_fence_put(fence); > return r; > } > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [GIT PULL FOR v5.5 - 2nd try] R-Car DU CMM support
Hello, On Wed, Nov 06, 2019 at 11:46:28AM +0100, Jacopo Mondi wrote: > On Wed, Nov 06, 2019 at 12:02:05PM +0200, Laurent Pinchart wrote: > > On Wed, Nov 06, 2019 at 12:00:59PM +0200, Laurent Pinchart wrote: > > > On Wed, Nov 06, 2019 at 01:40:13PM +1000, Dave Airlie wrote: > > > > On Wed, 6 Nov 2019 at 05:56, Dave Airlie wrote: > > > > > On Wed, 6 Nov 2019 at 05:49, Laurent Pinchart wrote: > > > > > > > > > > > > Hi Dave, > > > > > > > > > > > > Has this pull request fallen through the cracks ? > > > > > > > > > > It fell down a different crack than usual, it made it from patchwork > > > > > onto my hard drive, but then I didn't execute the pull. > > > > > > > > > > I've pulled it down, thanks for reminder. > > > > > > > > Now it failed as I mentioned on irc. > > > > > > > > I think the new kconfig option needs to be a tristate, otherwise > > > > setting it to Y and having rcar-du as M fails to link > > > > > > Sorry about that :-S Both I and the 0-day bot failed to catch it. > > > Jacopo, could you please have a look ? I'm afraid this likely mean a new > > > version of the series, and thus missing the merge window, as we're > > > already at -rc6. > > I managed to reproduce it by setting DRM=m. > RCAR_CMM stays indeed =y as it's a bool. Simply setting it to tristate > is enough to have it set to =m when DRM=m. > > Could this be changed when applying the series ? > > diff --git a/drivers/gpu/drm/rcar-du/Kconfig b/drivers/gpu/drm/rcar-du/Kconfig > index 539d232790d1..e6607b5c8bb3 100644 > --- a/drivers/gpu/drm/rcar-du/Kconfig > +++ b/drivers/gpu/drm/rcar-du/Kconfig > @@ -14,7 +14,7 @@ config DRM_RCAR_DU > If M is selected the module will be called rcar-du-drm. > > config DRM_RCAR_CMM > - bool "R-Car DU Color Management Module (CMM) Support" > + tristate "R-Car DU Color Management Module (CMM) Support" > depends on DRM && OF > depends on DRM_RCAR_DU > help This looks reasonable to me. I'll let Dave decide if he wants to apply this change himself, or if I should send a new pull request for v5.6. -- Regards, Laurent Pinchart ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 3/4] drm/udl: Switch to SHMEM
On Wed, Nov 06, 2019 at 11:47:21AM +0100, Thomas Zimmermann wrote: > Udl's GEM code and the generic SHMEM are almost identical. Replace > the former with SHMEM. The dmabuf support in udl is being replaced > with generic GEM PRIME functions. > > The main difference is in the caching flags for mmap pages. By > default, SHMEM always sets (uncached) write combining. In udl's > memory management code, only imported buffers use write combining. > Memory pages of locally created buffer objects are mmap'ed with > caching enabled. To keep the optimization, udl provides its own > mmap function for GEM objects where it fixes up the mapping flags. > > v2: > - remove obsolete code in a separate patch That indeed makes the patch more readable as the context stays intact this way. > > Signed-off-by: Thomas Zimmermann Acked-by: Gerd Hoffmann > --- > drivers/gpu/drm/udl/Kconfig | 1 + > drivers/gpu/drm/udl/udl_drv.c | 29 ++- > drivers/gpu/drm/udl/udl_drv.h | 1 + > drivers/gpu/drm/udl/udl_fb.c | 66 +++ > drivers/gpu/drm/udl/udl_gem.c | 61 +--- > 5 files changed, 98 insertions(+), 60 deletions(-) > > diff --git a/drivers/gpu/drm/udl/Kconfig b/drivers/gpu/drm/udl/Kconfig > index b4d179b87f01..145b2a95ce58 100644 > --- a/drivers/gpu/drm/udl/Kconfig > +++ b/drivers/gpu/drm/udl/Kconfig > @@ -5,6 +5,7 @@ config DRM_UDL > depends on USB_SUPPORT > depends on USB_ARCH_HAS_HCD > select USB > + select DRM_GEM_SHMEM_HELPER > select DRM_KMS_HELPER > help > This is a KMS driver for the USB displaylink video adapters. > diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c > index 778a0b652f64..563cc5809e56 100644 > --- a/drivers/gpu/drm/udl/udl_drv.c > +++ b/drivers/gpu/drm/udl/udl_drv.c > @@ -8,6 +8,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -32,23 +33,7 @@ static int udl_usb_resume(struct usb_interface *interface) > return 0; > } > > -static const struct vm_operations_struct udl_gem_vm_ops = { > - .fault = udl_gem_fault, > - .open = drm_gem_vm_open, > - .close = drm_gem_vm_close, > -}; > - > -static const struct file_operations udl_driver_fops = { > - .owner = THIS_MODULE, > - .open = drm_open, > - .mmap = udl_drm_gem_mmap, > - .poll = drm_poll, > - .read = drm_read, > - .unlocked_ioctl = drm_ioctl, > - .release = drm_release, > - .compat_ioctl = drm_compat_ioctl, > - .llseek = noop_llseek, > -}; > +DEFINE_DRM_GEM_FOPS(udl_driver_fops); > > static void udl_driver_release(struct drm_device *dev) > { > @@ -63,18 +48,10 @@ static struct drm_driver driver = { > .release = udl_driver_release, > > /* gem hooks */ > - .gem_free_object_unlocked = udl_gem_free_object, > .gem_create_object = udl_driver_gem_create_object, > - .gem_vm_ops = &udl_gem_vm_ops, > > - .dumb_create = udl_dumb_create, > - .dumb_map_offset = udl_gem_mmap, > .fops = &udl_driver_fops, > - > - .prime_handle_to_fd = drm_gem_prime_handle_to_fd, > - .prime_fd_to_handle = drm_gem_prime_fd_to_handle, > - .gem_prime_export = udl_gem_prime_export, > - .gem_prime_import = udl_gem_prime_import, > + DRM_GEM_SHMEM_DRIVER_OPS, > > .name = DRIVER_NAME, > .desc = DRIVER_DESC, > diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h > index fc312e791d18..630e64abc986 100644 > --- a/drivers/gpu/drm/udl/udl_drv.h > +++ b/drivers/gpu/drm/udl/udl_drv.h > @@ -85,6 +85,7 @@ struct udl_gem_object { > struct udl_framebuffer { > struct drm_framebuffer base; > struct udl_gem_object *obj; > + struct drm_gem_shmem_object *shmem; > bool active_16; /* active on the 16-bit channel */ > }; > > diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c > index ef3504d06343..f8153b726343 100644 > --- a/drivers/gpu/drm/udl/udl_fb.c > +++ b/drivers/gpu/drm/udl/udl_fb.c > @@ -15,6 +15,7 @@ > #include > #include > #include > +#include > #include > > #include "udl_drv.h" > @@ -94,16 +95,14 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, > int y, > if (!fb->active_16) > return 0; > > - if (!fb->obj->vmapping) { > - ret = udl_gem_vmap(fb->obj); > - if (ret == -ENOMEM) { > + if (!fb->shmem->vaddr) { > + void *vaddr; > + > + vaddr = drm_gem_shmem_vmap(&fb->shmem->base); > + if (IS_ERR(vaddr)) { > DRM_ERROR("failed to vmap fb\n"); > return 0; > } > - if (!fb->obj->vmapping) { > - DRM_ERROR("failed to vmapping\n"); > - return 0; > - } > } > > aligned_x = DL_ALIGN_DOWN(x, sizeof(unsigned long)); > @@ -127,7 +126,7 @@ int udl_handle_damage(struct udl_framebuffer *
Re: [PATCH v2 4/4] drm/udl: Remove struct udl_gem_object and functions
On Wed, Nov 06, 2019 at 11:47:22AM +0100, Thomas Zimmermann wrote: > Simply removes all the obsolete GEM code from udl. No functional > changes. > > Signed-off-by: Thomas Zimmermann Acked-by: Gerd Hoffmann > --- > drivers/gpu/drm/udl/Makefile | 2 +- > drivers/gpu/drm/udl/udl_dmabuf.c | 254 --- > drivers/gpu/drm/udl/udl_drv.h| 29 > drivers/gpu/drm/udl/udl_gem.c| 206 - > 4 files changed, 1 insertion(+), 490 deletions(-) > delete mode 100644 drivers/gpu/drm/udl/udl_dmabuf.c > > diff --git a/drivers/gpu/drm/udl/Makefile b/drivers/gpu/drm/udl/Makefile > index e5bb6f757e11..9c42820ae33d 100644 > --- a/drivers/gpu/drm/udl/Makefile > +++ b/drivers/gpu/drm/udl/Makefile > @@ -1,4 +1,4 @@ > # SPDX-License-Identifier: GPL-2.0-only > -udl-y := udl_drv.o udl_modeset.o udl_connector.o udl_encoder.o udl_main.o > udl_fb.o udl_transfer.o udl_gem.o udl_dmabuf.o > +udl-y := udl_drv.o udl_modeset.o udl_connector.o udl_encoder.o udl_main.o > udl_fb.o udl_transfer.o udl_gem.o > > obj-$(CONFIG_DRM_UDL) := udl.o > diff --git a/drivers/gpu/drm/udl/udl_dmabuf.c > b/drivers/gpu/drm/udl/udl_dmabuf.c > deleted file mode 100644 > index b1c1ee64de59.. > --- a/drivers/gpu/drm/udl/udl_dmabuf.c > +++ /dev/null > @@ -1,254 +0,0 @@ > -// SPDX-License-Identifier: GPL-2.0-or-later > -/* > - * udl_dmabuf.c > - * > - * Copyright (c) 2014 The Chromium OS Authors > - */ > - > -#include > -#include > - > -#include > - > -#include "udl_drv.h" > - > -struct udl_drm_dmabuf_attachment { > - struct sg_table sgt; > - enum dma_data_direction dir; > - bool is_mapped; > -}; > - > -static int udl_attach_dma_buf(struct dma_buf *dmabuf, > - struct dma_buf_attachment *attach) > -{ > - struct udl_drm_dmabuf_attachment *udl_attach; > - > - DRM_DEBUG_PRIME("[DEV:%s] size:%zd\n", dev_name(attach->dev), > - attach->dmabuf->size); > - > - udl_attach = kzalloc(sizeof(*udl_attach), GFP_KERNEL); > - if (!udl_attach) > - return -ENOMEM; > - > - udl_attach->dir = DMA_NONE; > - attach->priv = udl_attach; > - > - return 0; > -} > - > -static void udl_detach_dma_buf(struct dma_buf *dmabuf, > -struct dma_buf_attachment *attach) > -{ > - struct udl_drm_dmabuf_attachment *udl_attach = attach->priv; > - struct sg_table *sgt; > - > - if (!udl_attach) > - return; > - > - DRM_DEBUG_PRIME("[DEV:%s] size:%zd\n", dev_name(attach->dev), > - attach->dmabuf->size); > - > - sgt = &udl_attach->sgt; > - > - if (udl_attach->dir != DMA_NONE) > - dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, > - udl_attach->dir); > - > - sg_free_table(sgt); > - kfree(udl_attach); > - attach->priv = NULL; > -} > - > -static struct sg_table *udl_map_dma_buf(struct dma_buf_attachment *attach, > - enum dma_data_direction dir) > -{ > - struct udl_drm_dmabuf_attachment *udl_attach = attach->priv; > - struct udl_gem_object *obj = to_udl_bo(attach->dmabuf->priv); > - struct drm_device *dev = obj->base.dev; > - struct udl_device *udl = dev->dev_private; > - struct scatterlist *rd, *wr; > - struct sg_table *sgt = NULL; > - unsigned int i; > - int page_count; > - int nents, ret; > - > - DRM_DEBUG_PRIME("[DEV:%s] size:%zd dir=%d\n", dev_name(attach->dev), > - attach->dmabuf->size, dir); > - > - /* just return current sgt if already requested. */ > - if (udl_attach->dir == dir && udl_attach->is_mapped) > - return &udl_attach->sgt; > - > - if (!obj->pages) { > - ret = udl_gem_get_pages(obj); > - if (ret) { > - DRM_ERROR("failed to map pages.\n"); > - return ERR_PTR(ret); > - } > - } > - > - page_count = obj->base.size / PAGE_SIZE; > - obj->sg = drm_prime_pages_to_sg(obj->pages, page_count); > - if (IS_ERR(obj->sg)) { > - DRM_ERROR("failed to allocate sgt.\n"); > - return ERR_CAST(obj->sg); > - } > - > - sgt = &udl_attach->sgt; > - > - ret = sg_alloc_table(sgt, obj->sg->orig_nents, GFP_KERNEL); > - if (ret) { > - DRM_ERROR("failed to alloc sgt.\n"); > - return ERR_PTR(-ENOMEM); > - } > - > - mutex_lock(&udl->gem_lock); > - > - rd = obj->sg->sgl; > - wr = sgt->sgl; > - for (i = 0; i < sgt->orig_nents; ++i) { > - sg_set_page(wr, sg_page(rd), rd->length, rd->offset); > - rd = sg_next(rd); > - wr = sg_next(wr); > - } > - > - if (dir != DMA_NONE) { > - nents = dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir); > - if (!nents) { > - DRM_ERROR("failed to map sgl with iommu.\n"); > - sg_free_tabl
Re: [GIT PULL FOR v5.5 - 2nd try] R-Car DU CMM support
Hi Jacopo, On Wed, Nov 06, 2019 at 02:52:25PM +0200, Laurent Pinchart wrote: > On Wed, Nov 06, 2019 at 11:46:28AM +0100, Jacopo Mondi wrote: > > On Wed, Nov 06, 2019 at 12:02:05PM +0200, Laurent Pinchart wrote: > > > On Wed, Nov 06, 2019 at 12:00:59PM +0200, Laurent Pinchart wrote: > > > > On Wed, Nov 06, 2019 at 01:40:13PM +1000, Dave Airlie wrote: > > > > > On Wed, 6 Nov 2019 at 05:56, Dave Airlie wrote: > > > > > > On Wed, 6 Nov 2019 at 05:49, Laurent Pinchart wrote: > > > > > > > > > > > > > > Hi Dave, > > > > > > > > > > > > > > Has this pull request fallen through the cracks ? > > > > > > > > > > > > It fell down a different crack than usual, it made it from patchwork > > > > > > onto my hard drive, but then I didn't execute the pull. > > > > > > > > > > > > I've pulled it down, thanks for reminder. > > > > > > > > > > Now it failed as I mentioned on irc. > > > > > > > > > > I think the new kconfig option needs to be a tristate, otherwise > > > > > setting it to Y and having rcar-du as M fails to link > > > > > > > > Sorry about that :-S Both I and the 0-day bot failed to catch it. > > > > Jacopo, could you please have a look ? I'm afraid this likely mean a new > > > > version of the series, and thus missing the merge window, as we're > > > > already at -rc6. > > > > I managed to reproduce it by setting DRM=m. > > RCAR_CMM stays indeed =y as it's a bool. Simply setting it to tristate > > is enough to have it set to =m when DRM=m. > > > > Could this be changed when applying the series ? > > > > diff --git a/drivers/gpu/drm/rcar-du/Kconfig > > b/drivers/gpu/drm/rcar-du/Kconfig > > index 539d232790d1..e6607b5c8bb3 100644 > > --- a/drivers/gpu/drm/rcar-du/Kconfig > > +++ b/drivers/gpu/drm/rcar-du/Kconfig > > @@ -14,7 +14,7 @@ config DRM_RCAR_DU > > If M is selected the module will be called rcar-du-drm. > > > > config DRM_RCAR_CMM > > - bool "R-Car DU Color Management Module (CMM) Support" > > + tristate "R-Car DU Color Management Module (CMM) Support" > > depends on DRM && OF > > depends on DRM_RCAR_DU > > help > > This looks reasonable to me. I'll let Dave decide if he wants to apply > this change himself, or if I should send a new pull request for v5.6. Actually this won't work. With DRM_RCAR_DU=y and DRM_RCAR_CMM=m you'll have a link failure. Let's fix this properly for v5.6. Could you please propose a fix that will work with all combinations of DRM, DRM_RCAR_DU and DRM_RCAR_CMM ? -- Regards, Laurent Pinchart ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 2/3] drm/rockchip: add ability to handle external dphys in mipi-dsi
Hi Heiko, Thank you for the patch. On Wed, Nov 06, 2019 at 12:26:49PM +0100, Heiko Stuebner wrote: > While the common case is that the dsi controller uses an internal dphy, > accessed through the phy registers inside the dsi controller, there is > also the possibility to use a separate dphy from a different vendor. > > One such case is the Rockchip px30 that uses a Innosilicon Mipi dphy, > so add the support for handling such a constellation, including the pll > also getting generated inside that external phy. > > Signed-off-by: Heiko Stuebner > --- > .../display/rockchip/dw_mipi_dsi_rockchip.txt | 7 ++- > .../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 54 ++- > 2 files changed, 57 insertions(+), 4 deletions(-) > > diff --git > a/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt > b/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt > index ce4c1fc9116c..8b25156a9dcf 100644 > --- > a/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt > +++ > b/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt > @@ -8,8 +8,9 @@ Required properties: > "rockchip,rk3399-mipi-dsi", "snps,dw-mipi-dsi". > - reg: Represent the physical address range of the controller. > - interrupts: Represent the controller's interrupt to the CPU(s). > -- clocks, clock-names: Phandles to the controller's pll reference > - clock(ref) and APB clock(pclk). For RK3399, a phy config clock > +- clocks, clock-names: Phandles to the controller's and APB clock(pclk) > + and either a pll reference clock(ref) (internal dphy) or pll clock(pll) > + (when connected to an external phy). For RK3399, a phy config clock Why does external PHY clock need to be specified here ? Shouldn't it be handled by the PHY instead ? >(phy_cfg) and a grf clock(grf) are required. As described in [1]. > - rockchip,grf: this soc should set GRF regs to mux vopl/vopb. > - ports: contain a port node with endpoint definitions as defined in [2]. > @@ -18,6 +19,8 @@ Required properties: > - video port 1 for either a panel or subsequent encoder > > Optional properties: > +- phys: from general PHY binding: the phandle for the PHY device. > +- phy-names: Should be "dphy" if phys references an external phy. > - power-domains: a phandle to mipi dsi power domain node. > - resets: list of phandle + reset specifier pairs, as described in [3]. > - reset-names: string reset name, must be "apb". > diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c > b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c > index bc073ec5c183..99ec625e0448 100644 > --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c > +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c > @@ -12,6 +12,7 @@ > #include > #include > #include > +#include > #include > #include > > @@ -223,6 +224,9 @@ struct dw_mipi_dsi_rockchip { > bool is_slave; > struct dw_mipi_dsi_rockchip *slave; > > + /* optional external dphy */ > + struct phy *phy; > + > unsigned int lane_mbps; /* per lane */ > u16 input_div; > u16 feedback_div; > @@ -359,6 +363,9 @@ static int dw_mipi_dsi_phy_init(void *priv_data) > struct dw_mipi_dsi_rockchip *dsi = priv_data; > int ret, i, vco; > > + if (dsi->phy) > + return 0; > + > /* >* Get vco from frequency(lane_mbps) >* vco frequency table > @@ -467,6 +474,27 @@ static int dw_mipi_dsi_phy_init(void *priv_data) > return ret; > } > > +static void dw_mipi_dsi_phy_power_on(void *priv_data) > +{ > + struct dw_mipi_dsi_rockchip *dsi = priv_data; > + int ret; > + > + ret = phy_set_mode(dsi->phy, PHY_MODE_MIPI_DPHY); > + if (ret) { > + DRM_DEV_ERROR(dsi->dev, "failed to set phy mode: %d\n", ret); > + return; > + } > + > + phy_power_on(dsi->phy); > +} > + > +static void dw_mipi_dsi_phy_power_off(void *priv_data) > +{ > + struct dw_mipi_dsi_rockchip *dsi = priv_data; > + > + phy_power_off(dsi->phy); > +} > + > static int > dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode > *mode, > unsigned long mode_flags, u32 lanes, u32 format, > @@ -504,9 +532,21 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct > drm_display_mode *mode, > "DPHY clock frequency is out of range\n"); > } > > - fin = clk_get_rate(dsi->pllref_clk); > fout = target_mbps * USEC_PER_SEC; > > + /* an external phy does have a controllable pll clk */ > + if (dsi->phy) { > + fout = clk_round_rate(dsi->pllref_clk, fout); > + clk_set_rate(dsi->pllref_clk, fout); > + > + dsi->lane_mbps = target_mbps; > + *lane_mbps = dsi->lane_mbps; > + > + return 0; > + } > + > + fin = clk_get_rate(dsi->pllref_clk); > + > /* constraint: 5Mhz <= Fref / N <= 40M
Re: [PATCH 3/3] drm/prime: Use anon_drm_getfile() for an internal drm struct file
On Wed, Nov 6, 2019 at 11:45 AM Chris Wilson wrote: > > Quoting Daniel Vetter (2019-11-06 10:21:57) > > On Wed, Nov 06, 2019 at 10:07:16AM +, Chris Wilson wrote: > > > Currently the drm_prime mmap fallback uses a mock struct file to provide > > > the file pointer into the backend mmap routine. Now that we can create > > > fully fledged anonymous struct file around the drm device, put it to > > > use. > > > > > > Signed-off-by: Chris Wilson > > > --- > > > drivers/gpu/drm/drm_prime.c | 26 -- > > > 1 file changed, 8 insertions(+), 18 deletions(-) > > > > > > diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c > > > index 0814211b0f3f..5faa63713ec8 100644 > > > --- a/drivers/gpu/drm/drm_prime.c > > > +++ b/drivers/gpu/drm/drm_prime.c > > > @@ -709,8 +709,7 @@ EXPORT_SYMBOL(drm_gem_dmabuf_vunmap); > > > */ > > > int drm_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct > > > *vma) > > > { > > > - struct drm_file *priv; > > > - struct file *fil; > > > + struct file *file; > > > int ret; > > > > > > if (obj->funcs && obj->funcs->mmap) { > > > > obj->funcs->mmap is the new way of doing this (and hopefully finally > > something clean), I'd really like to retire the below hack outright. > > > > Plus I'm not sure why you need an anon inode here? If a driver needs this > > for unmap_mapping_range or similar I think it'd be better to try and make > > something work cleanly for obj->funcs->mmap. > > It's faking one currently. If the fake is not good enough, you are > playing whack-a-mole until you finally do create a fully fledged file. > > If you are going to the trouble of having to create a struct file to > provide to the fallback routines, might as well avoid stinky code :) We're currently not faking the inode at all, we're just using the one that comes with the dma-buf. So distinct from the drm_device file, and hence unmap_mapping_range won't work (or at least doing that on the drm_device inode wont shoot down the ptes for redirected dma-buf mmaps). obj->funcs->mmap has the same issue. But since all current users of this don't expect unmap_mapping_range to work correctly, it's not an real issue. If that changes then imo we should fix up the obj->funcs->mmap path to have the correct inode, not the deprecated path you're updating here. But since there's no patch 4 in this series to start using this for i915 or someone else, I'm not seeing the point. Or am I blind? At least slightly confused, -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [Intel-gfx] [PATCH 1/3] drm: Expose a method for creating anonymous struct file around drm_minor
On Wed, Nov 6, 2019 at 11:43 AM Chris Wilson wrote: > > Quoting Chris Wilson (2019-11-06 10:26:48) > > Quoting Daniel Vetter (2019-11-06 10:19:50) > > > On Wed, Nov 06, 2019 at 10:07:14AM +, Chris Wilson wrote: > > > > Sometimes we need to create a struct file to wrap a drm_device, as it > > > > the user were to have opened /dev/dri/card0 but to do so anonymously > > > > (i.e. for internal use). Provide a utility method to create a struct > > > > file with the drm_device->driver.fops, that wrap the drm_device. > > > > > > > > Signed-off-by: Chris Wilson > > > > > > For proper internal access we already have drm_client_open, so I think > > > this has limited (but good use) in selftests only. So > > > EXPORT_SYMBOL_FOR_TESTS_ONLY plus maybe a clearer name for the intended > > > use like drm_file_mock_open? > > > > I found the example in drm_gem_prime_mmap() that was doing the same trick, > > and the trick of being able to instantiate new struct file and install a > > fd whenever seems like it will come in handy... Just lacking the third > > user at the moment to claim generality. > > The closest example I found in the spirit of creating a new drm_device > struct file and installing it is drm_mode_create_lease_ioctl() that uses > file_clone_open() for this purpose. The argument there would be whether > cloning the (file->f_path, file->f_flags, file->f_cred) is appropriate > versus an anonymous inode. I think cloning the credentials seems correct > for leasing. Hm ... I think we want the clone for this one here too. Otherwise we get the wrong inode, and then unmap_mapping_range wont work correctly, and we cant use this for selftests. That's the only case where I think we do actually need the file/inode to be functional. For anything else the drm_client internal api gets away without the file/inode stuff. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH V9 5/6] virtio: introduce a mdev based transport
On 2019/11/6 下午7:00, Cornelia Huck wrote: On Wed, 6 Nov 2019 15:05:47 +0800 Jason Wang wrote: This patch introduces a new mdev transport for virtio. This is used to use kernel virtio driver to drive the mediated device that is capable of populating virtqueue directly. A new virtio-mdev driver will be registered to the mdev bus, when a new virtio-mdev device is probed, it will register the device with mdev based config ops. This means it is a software transport between mdev driver and mdev device. The transport was implemented through device specific ops which is a part of mdev_parent_ops now. Signed-off-by: Jason Wang --- drivers/virtio/Kconfig | 13 ++ drivers/virtio/Makefile | 1 + drivers/virtio/virtio_mdev.c | 406 +++ 3 files changed, 420 insertions(+) create mode 100644 drivers/virtio/virtio_mdev.c diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig index 078615cf2afc..558ac607d107 100644 --- a/drivers/virtio/Kconfig +++ b/drivers/virtio/Kconfig @@ -43,6 +43,19 @@ config VIRTIO_PCI_LEGACY If unsure, say Y. +config VIRTIO_MDEV + tristate "MDEV driver for virtio devices" + depends on VFIO_MDEV && VIRTIO + default n + help + This driver provides support for virtio based paravirtual + device driver over MDEV bus. This requires your environemnt + has appropriate virtio mdev device implementation which may + operate on the physical device that the datapath of virtio + could be offloaded to hardware. That sentence is a bit confusing to me... what about "For this to be useful, you need an appropriate virtio mdev device implementation that operates on a physical device to allow the datapath of virtio to be offloaded to hardware." ? + + If unsure, say M Building this as a module should not hurt (but please add a trailing '.' here :) + config VIRTIO_PMEM tristate "Support for virtio pmem driver" depends on VIRTIO With the changes above, Reviewed-by: Cornelia Huck Will post V10. Thanks ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 3/3] drm/prime: Use anon_drm_getfile() for an internal drm struct file
Quoting Daniel Vetter (2019-11-06 13:06:26) > On Wed, Nov 6, 2019 at 11:45 AM Chris Wilson wrote: > > > > Quoting Daniel Vetter (2019-11-06 10:21:57) > > > On Wed, Nov 06, 2019 at 10:07:16AM +, Chris Wilson wrote: > > > > Currently the drm_prime mmap fallback uses a mock struct file to provide > > > > the file pointer into the backend mmap routine. Now that we can create > > > > fully fledged anonymous struct file around the drm device, put it to > > > > use. > > > > > > > > Signed-off-by: Chris Wilson > > > > --- > > > > drivers/gpu/drm/drm_prime.c | 26 -- > > > > 1 file changed, 8 insertions(+), 18 deletions(-) > > > > > > > > diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c > > > > index 0814211b0f3f..5faa63713ec8 100644 > > > > --- a/drivers/gpu/drm/drm_prime.c > > > > +++ b/drivers/gpu/drm/drm_prime.c > > > > @@ -709,8 +709,7 @@ EXPORT_SYMBOL(drm_gem_dmabuf_vunmap); > > > > */ > > > > int drm_gem_prime_mmap(struct drm_gem_object *obj, struct > > > > vm_area_struct *vma) > > > > { > > > > - struct drm_file *priv; > > > > - struct file *fil; > > > > + struct file *file; > > > > int ret; > > > > > > > > if (obj->funcs && obj->funcs->mmap) { > > > > > > obj->funcs->mmap is the new way of doing this (and hopefully finally > > > something clean), I'd really like to retire the below hack outright. > > > > > > Plus I'm not sure why you need an anon inode here? If a driver needs this > > > for unmap_mapping_range or similar I think it'd be better to try and make > > > something work cleanly for obj->funcs->mmap. > > > > It's faking one currently. If the fake is not good enough, you are > > playing whack-a-mole until you finally do create a fully fledged file. > > > > If you are going to the trouble of having to create a struct file to > > provide to the fallback routines, might as well avoid stinky code :) > > We're currently not faking the inode at all, we're just using the one > that comes with the dma-buf. So distinct from the drm_device file, and > hence unmap_mapping_range won't work (or at least doing that on the > drm_device inode wont shoot down the ptes for redirected dma-buf > mmaps). obj->funcs->mmap has the same issue. > > But since all current users of this don't expect unmap_mapping_range > to work correctly, it's not an real issue. If that changes then imo we > should fix up the obj->funcs->mmap path to have the correct inode, not > the deprecated path you're updating here. But since there's no patch 4 > in this series to start using this for i915 or someone else, I'm not > seeing the point. There's a bug in anon_drm_inode() in that it requires an extra: + /* Everyone shares a single global address space */ + file->f_mapping = dev->anon_inode->i_mapping; I'm up to 5 patches now, but only i915/selftests & this here fallback as direct users. -Chris ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 9/9] drm/ast: Enable atomic modesetting
Hi Am 05.11.19 um 10:57 schrieb Gerd Hoffmann: > On Mon, Oct 28, 2019 at 04:49:28PM +0100, Thomas Zimmermann wrote: >> This commit sets the remaining atomic-modesetting helpers and the flag >> DRIVER_ATOMIC. Legacy cursor functions are removed in favor of the cursor >> plane. For power management, atomic helpers replace the indvidual >> operations that the driver currently runs. >> >> Atomic modesetting is enabled with this commit. >> >> Signed-off-by: Thomas Zimmermann >> --- >> drivers/gpu/drm/ast/ast_drv.c | 24 ++- >> drivers/gpu/drm/ast/ast_main.c | 5 + >> drivers/gpu/drm/ast/ast_mode.c | 290 ++--- >> 3 files changed, 33 insertions(+), 286 deletions(-) >> >> diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c >> index 1f17794b0890..d763da6f0834 100644 >> --- a/drivers/gpu/drm/ast/ast_drv.c >> +++ b/drivers/gpu/drm/ast/ast_drv.c >> @@ -99,14 +99,14 @@ ast_pci_remove(struct pci_dev *pdev) >> drm_put_dev(dev); >> } >> >> - >> - >> static int ast_drm_freeze(struct drm_device *dev) >> { >> -drm_kms_helper_poll_disable(dev); >> -pci_save_state(dev->pdev); >> -drm_fb_helper_set_suspend_unlocked(dev->fb_helper, true); >> +int error; >> >> +error = drm_mode_config_helper_suspend(dev); >> +if (error) >> +return error; >> +pci_save_state(dev->pdev); >> return 0; >> } >> >> @@ -114,11 +114,7 @@ static int ast_drm_thaw(struct drm_device *dev) >> { >> ast_post_gpu(dev); >> >> -drm_mode_config_reset(dev); >> -drm_helper_resume_force_mode(dev); >> -drm_fb_helper_set_suspend_unlocked(dev->fb_helper, false); >> - >> -return 0; >> +return drm_mode_config_helper_resume(dev); >> } >> >> static int ast_drm_resume(struct drm_device *dev) >> @@ -131,8 +127,6 @@ static int ast_drm_resume(struct drm_device *dev) >> ret = ast_drm_thaw(dev); >> if (ret) >> return ret; >> - >> -drm_kms_helper_poll_enable(dev); >> return 0; >> } >> >> @@ -150,6 +144,7 @@ static int ast_pm_suspend(struct device *dev) >> pci_set_power_state(pdev, PCI_D3hot); >> return 0; >> } >> + >> static int ast_pm_resume(struct device *dev) >> { >> struct pci_dev *pdev = to_pci_dev(dev); >> @@ -165,7 +160,6 @@ static int ast_pm_freeze(struct device *dev) >> if (!ddev || !ddev->dev_private) >> return -ENODEV; >> return ast_drm_freeze(ddev); >> - >> } >> >> static int ast_pm_thaw(struct device *dev) >> @@ -203,7 +197,9 @@ static struct pci_driver ast_pci_driver = { >> DEFINE_DRM_GEM_FOPS(ast_fops); >> >> static struct drm_driver driver = { >> -.driver_features = DRIVER_MODESET | DRIVER_GEM, >> +.driver_features = DRIVER_ATOMIC | >> + DRIVER_GEM | >> + DRIVER_MODESET, >> >> .load = ast_driver_load, >> .unload = ast_driver_unload, >> diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c >> index 48d57ab42955..b79f484e9bd2 100644 >> --- a/drivers/gpu/drm/ast/ast_main.c >> +++ b/drivers/gpu/drm/ast/ast_main.c >> @@ -28,6 +28,7 @@ >> >> #include >> >> +#include >> #include >> #include >> #include >> @@ -412,6 +413,8 @@ enum drm_mode_status ast_mode_config_mode_valid(struct >> drm_device *dev, >> static const struct drm_mode_config_funcs ast_mode_funcs = { >> .fb_create = drm_gem_fb_create, >> .mode_valid = ast_mode_config_mode_valid, >> +.atomic_check = drm_atomic_helper_check, >> +.atomic_commit = drm_atomic_helper_commit, >> }; >> >> static u32 ast_get_vram_info(struct drm_device *dev) >> @@ -529,6 +532,8 @@ int ast_driver_load(struct drm_device *dev, unsigned >> long flags) >> if (ret) >> goto out_free; >> >> +drm_mode_config_reset(dev); >> + >> ret = drm_fbdev_generic_setup(dev, 32); >> if (ret) >> goto out_free; >> diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c >> index f5f73200e8e4..5eccb6ae2ede 100644 >> --- a/drivers/gpu/drm/ast/ast_mode.c >> +++ b/drivers/gpu/drm/ast/ast_mode.c >> @@ -45,11 +45,6 @@ >> >> static struct ast_i2c_chan *ast_i2c_create(struct drm_device *dev); >> static void ast_i2c_destroy(struct ast_i2c_chan *i2c); >> -static int ast_cursor_set(struct drm_crtc *crtc, >> - struct drm_file *file_priv, >> - uint32_t handle, >> - uint32_t width, >> - uint32_t height); >> static int ast_cursor_move(struct drm_crtc *crtc, >> int x, int y); >> >> @@ -58,9 +53,6 @@ static u32 copy_cursor_image(u8 *src, u8 *dst, int width, >> int height); >> static int ast_cursor_update(void *dst, void *src, unsigned int width, >> unsigned int height); >> static void ast_cursor_set_base(struct ast_private *ast, u64 address); >> -static int ast_show_cursor(struct drm_crtc *crtc, void *src, >> -
[PATCH V10 0/6] mdev based hardware virtio offloading support
Hi all: There are hardwares that can do virtio datapath offloading while having its own control path. This path tries to implement a mdev based unified API to support using kernel virtio driver to drive those devices. This is done by introducing a new mdev transport for virtio (virtio_mdev) and register itself as a new kind of mdev driver. Then it provides a unified way for kernel virtio driver to talk with mdev device implementation. Though the series only contains kernel driver support, the goal is to make the transport generic enough to support userspace drivers. This means vhost-mdev[1] could be built on top as well by resuing the transport. A sample driver is also implemented which simulate a virito-net loopback ethernet device on top of vringh + workqueue. This could be used as a reference implementation for real hardware driver. Also a real IFC VF driver was also posted here[2] which is a good reference for vendors who is interested in their own virtio datapath offloading product. Consider mdev framework only support VFIO device and driver right now, this series also extend it to support other types. This is done through introducing class id to the device and pairing it with id_talbe claimed by the driver. On top, this seris also decouple device specific ops out of the common ones for implementing class specific operations over mdev bus. Pktgen test was done with virito-net + mvnet loop back device. Please review. [1] https://lkml.org/lkml/2019/11/5/424 [2] https://lkml.org/lkml/2019/11/5/227 Changes from V9: - Tweak the help text for virito-mdev kconfig Changes from V8: - try silent checkpatch, some are still there becuase they were inherited from virtio_config_ops which needs to be resolved in an independent series - tweak on the comment and doc - remove VIRTIO_MDEV_F_VERSION_1 completely - rename CONFIG_VIRTIO_MDEV_DEVICE to CONFIG_VIRTIO_MDEV Changes from V7: - drop {set|get}_mdev_features for virtio - typo and comment style fixes Changes from V6: - rename ops files and compile guard Changes from V5: - use dev_warn() instead of WARN(1) when class id is not set - validate id_table before trying to do matching between device and driver - add wildcard for modpost script - use unique name for id_table - move get_mdev_features() to be the first member of virtio_device_ops and more comments for it - typo fixes for the comments above virtio_mdev_ops Changes from V4: - keep mdev_set_class() for the device that doesn't use device ops - use union for device ops pointer in mdev_device - introduce class specific helper for getting is device ops - use WARN_ON instead of BUG_ON in mdev_set_virtio_ops - explain details of get_mdev_features() and get_vendor_id() - distinguish the optional virito device ops from mandatory ones and make get_generation() optional - rename vfio_mdev.h to vfio_mdev_ops.h, rename virito_mdev.h to virtio_mdev_ops.h - don't abuse version fileds in virtio_mdev structure, use features instead - fix warning during device remove - style & docs tweaks and typo fixes Changes from V3: - document that class id (device ops) must be specified in create() - add WARN() when trying to set class_id when it has already set - add WARN() when class_id is not specified in create() and correctly return an error in this case - correct the prototype of mdev_set_class() in the doc - add documention of mdev_set_class() - remove the unnecessary "class_id_fail" label when class id is not specified in create() - convert id_table in vfio_mdev to const - move mdev_set_class and its friends after mdev_uuid() - suqash the patch of bus uevent into patch of introducing class id - tweak the words in the docs per Cornelia suggestion - tie class_id and device ops through class specific initialization routine like mdev_set_vfio_ops() - typos fixes in the docs of virtio-mdev callbacks - document the usage of virtqueues in struct virtio_mdev_device - remove the useless vqs array in struct virtio_mdev_device - rename MDEV_ID_XXX to MDEV_CLASS_ID_XXX Changes from V2: - fail when class_id is not specified - drop the vringh patch - match the doc to the code - tweak the commit log - move device_ops from parent to mdev device - remove the unused MDEV_ID_VHOST Changes from V1: - move virtio_mdev.c to drivers/virtio - store class_id in mdev_device instead of mdev_parent - store device_ops in mdev_device instead of mdev_parent - reorder the patch, vringh fix comes first - really silent compiling warnings - really switch to use u16 for class_id - uevent and modpost support for mdev class_id - vraious tweaks per comments from Parav Changes from RFC-V2: - silent compile warnings on some specific configuration - use u16 instead u8 for class id - reseve MDEV_ID_VHOST for future vhost-mdev work - introduce "virtio" type for mvnet and make "vhost" type for future work - add entries in MAINTAINER - tweak and typos fixes in commit log Changes from RFC-V1: - rename device id to class id - add docs for c
[PATCH V10 1/6] mdev: class id support
Mdev bus only supports vfio driver right now, so it doesn't implement match method. But in the future, we may add drivers other than vfio, the first driver could be virtio-mdev. This means we need to add device class id support in bus match method to pair the mdev device and mdev driver correctly. So this patch adds id_table to mdev_driver and class_id for mdev device with the match method for mdev bus. Reviewed-by: Parav Pandit Reviewed-by: Cornelia Huck Signed-off-by: Jason Wang --- .../driver-api/vfio-mediated-device.rst | 5 drivers/gpu/drm/i915/gvt/kvmgt.c | 1 + drivers/s390/cio/vfio_ccw_ops.c | 1 + drivers/s390/crypto/vfio_ap_ops.c | 1 + drivers/vfio/mdev/mdev_core.c | 17 + drivers/vfio/mdev/mdev_driver.c | 25 +++ drivers/vfio/mdev/mdev_private.h | 1 + drivers/vfio/mdev/vfio_mdev.c | 6 + include/linux/mdev.h | 8 ++ include/linux/mod_devicetable.h | 8 ++ samples/vfio-mdev/mbochs.c| 1 + samples/vfio-mdev/mdpy.c | 1 + samples/vfio-mdev/mtty.c | 1 + 13 files changed, 76 insertions(+) diff --git a/Documentation/driver-api/vfio-mediated-device.rst b/Documentation/driver-api/vfio-mediated-device.rst index 25eb7d5b834b..6709413bee29 100644 --- a/Documentation/driver-api/vfio-mediated-device.rst +++ b/Documentation/driver-api/vfio-mediated-device.rst @@ -102,12 +102,14 @@ structure to represent a mediated device's driver:: * @probe: called when new device created * @remove: called when device removed * @driver: device driver structure + * @id_table: the ids serviced by this driver */ struct mdev_driver { const char *name; int (*probe) (struct device *dev); void (*remove) (struct device *dev); struct device_driverdriver; +const struct mdev_class_id *id_table; }; A mediated bus driver for mdev should use this structure in the function calls @@ -170,6 +172,9 @@ that a driver should use to unregister itself with the mdev core driver:: extern void mdev_unregister_device(struct device *dev); +It is also required to specify the class_id in create() callback through:: + + int mdev_set_class(struct mdev_device *mdev, u16 id); Mediated Device Management Interface Through sysfs == diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index 343d79c1cb7e..6420f0dbd31b 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c @@ -678,6 +678,7 @@ static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev) dev_name(mdev_dev(mdev))); ret = 0; + mdev_set_class(mdev, MDEV_CLASS_ID_VFIO); out: return ret; } diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c index f0d71ab77c50..cf2c013ae32f 100644 --- a/drivers/s390/cio/vfio_ccw_ops.c +++ b/drivers/s390/cio/vfio_ccw_ops.c @@ -129,6 +129,7 @@ static int vfio_ccw_mdev_create(struct kobject *kobj, struct mdev_device *mdev) private->sch->schid.ssid, private->sch->schid.sch_no); + mdev_set_class(mdev, MDEV_CLASS_ID_VFIO); return 0; } diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c index 5c0f53c6dde7..07c31070afeb 100644 --- a/drivers/s390/crypto/vfio_ap_ops.c +++ b/drivers/s390/crypto/vfio_ap_ops.c @@ -343,6 +343,7 @@ static int vfio_ap_mdev_create(struct kobject *kobj, struct mdev_device *mdev) list_add(&matrix_mdev->node, &matrix_dev->mdev_list); mutex_unlock(&matrix_dev->lock); + mdev_set_class(mdev, MDEV_CLASS_ID_VFIO); return 0; } diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c index b558d4cfd082..7bfa2e46e829 100644 --- a/drivers/vfio/mdev/mdev_core.c +++ b/drivers/vfio/mdev/mdev_core.c @@ -45,6 +45,17 @@ void mdev_set_drvdata(struct mdev_device *mdev, void *data) } EXPORT_SYMBOL(mdev_set_drvdata); +/* + * Specify the class for the mdev device, this must be called during + * create() callback. + */ +void mdev_set_class(struct mdev_device *mdev, u16 id) +{ + WARN_ON(mdev->class_id); + mdev->class_id = id; +} +EXPORT_SYMBOL(mdev_set_class); + struct device *mdev_dev(struct mdev_device *mdev) { return &mdev->dev; @@ -324,6 +335,12 @@ int mdev_device_create(struct kobject *kobj, if (ret) goto ops_create_fail; + if (!mdev->class_id) { + ret = -EINVAL; + dev_warn(dev, "mdev vendor driver failed to specify device class\n"); + goto add_fail; + } + ret = device_add(&mdev->dev); if (ret)
[PATCH V10 2/6] modpost: add support for mdev class id
Add support to parse mdev class id table. Reviewed-by: Parav Pandit Reviewed-by: Cornelia Huck Signed-off-by: Jason Wang --- drivers/vfio/mdev/vfio_mdev.c | 2 ++ scripts/mod/devicetable-offsets.c | 3 +++ scripts/mod/file2alias.c | 11 +++ 3 files changed, 16 insertions(+) diff --git a/drivers/vfio/mdev/vfio_mdev.c b/drivers/vfio/mdev/vfio_mdev.c index 38431e9ef7f5..a6641cd8b5a3 100644 --- a/drivers/vfio/mdev/vfio_mdev.c +++ b/drivers/vfio/mdev/vfio_mdev.c @@ -125,6 +125,8 @@ static const struct mdev_class_id vfio_id_table[] = { { 0 }, }; +MODULE_DEVICE_TABLE(mdev, vfio_id_table); + static struct mdev_driver vfio_mdev_driver = { .name = "vfio_mdev", .probe = vfio_mdev_probe, diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c index 054405b90ba4..6cbb1062488a 100644 --- a/scripts/mod/devicetable-offsets.c +++ b/scripts/mod/devicetable-offsets.c @@ -231,5 +231,8 @@ int main(void) DEVID(wmi_device_id); DEVID_FIELD(wmi_device_id, guid_string); + DEVID(mdev_class_id); + DEVID_FIELD(mdev_class_id, id); + return 0; } diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index c91eba751804..45f1c22f49be 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -1335,6 +1335,16 @@ static int do_wmi_entry(const char *filename, void *symval, char *alias) return 1; } +/* looks like: "mdev:cN" */ +static int do_mdev_entry(const char *filename, void *symval, char *alias) +{ + DEF_FIELD(symval, mdev_class_id, id); + + sprintf(alias, "mdev:c%02X", id); + add_wildcard(alias); + return 1; +} + /* Does namelen bytes of name exactly match the symbol? */ static bool sym_is(const char *name, unsigned namelen, const char *symbol) { @@ -1407,6 +1417,7 @@ static const struct devtable devtable[] = { {"typec", SIZE_typec_device_id, do_typec_entry}, {"tee", SIZE_tee_client_device_id, do_tee_entry}, {"wmi", SIZE_wmi_device_id, do_wmi_entry}, + {"mdev", SIZE_mdev_class_id, do_mdev_entry}, }; /* Create MODULE_ALIAS() statements. -- 2.19.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH V10 4/6] mdev: introduce virtio device and its device ops
This patch implements basic support for mdev driver that supports virtio transport for kernel virtio driver. Reviewed-by: Cornelia Huck Signed-off-by: Jason Wang --- MAINTAINERS | 1 + drivers/vfio/mdev/mdev_core.c| 21 + drivers/vfio/mdev/mdev_private.h | 2 + include/linux/mdev.h | 6 ++ include/linux/mdev_virtio_ops.h | 147 +++ 5 files changed, 177 insertions(+) create mode 100644 include/linux/mdev_virtio_ops.h diff --git a/MAINTAINERS b/MAINTAINERS index f661d13344d6..4997957443df 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -17248,6 +17248,7 @@ F: include/linux/virtio*.h F: include/uapi/linux/virtio_*.h F: drivers/crypto/virtio/ F: mm/balloon_compaction.c +F: include/linux/mdev_virtio_ops.h VIRTIO BLOCK AND SCSI DRIVERS M: "Michael S. Tsirkin" diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c index 4e70f19ac145..c58253404ed5 100644 --- a/drivers/vfio/mdev/mdev_core.c +++ b/drivers/vfio/mdev/mdev_core.c @@ -78,6 +78,27 @@ const struct mdev_vfio_device_ops *mdev_get_vfio_ops(struct mdev_device *mdev) } EXPORT_SYMBOL(mdev_get_vfio_ops); +/* + * Specify the virtio device ops for the mdev device, this + * must be called during create() callback for virtio mdev device. + */ +void mdev_set_virtio_ops(struct mdev_device *mdev, +const struct mdev_virtio_device_ops *virtio_ops) +{ + mdev_set_class(mdev, MDEV_CLASS_ID_VIRTIO); + mdev->virtio_ops = virtio_ops; +} +EXPORT_SYMBOL(mdev_set_virtio_ops); + +/* Get the virtio device ops for the mdev device. */ +const struct mdev_virtio_device_ops * +mdev_get_virtio_ops(struct mdev_device *mdev) +{ + WARN_ON(mdev->class_id != MDEV_CLASS_ID_VIRTIO); + return mdev->virtio_ops; +} +EXPORT_SYMBOL(mdev_get_virtio_ops); + struct device *mdev_dev(struct mdev_device *mdev) { return &mdev->dev; diff --git a/drivers/vfio/mdev/mdev_private.h b/drivers/vfio/mdev/mdev_private.h index 411227373625..2c74dd032409 100644 --- a/drivers/vfio/mdev/mdev_private.h +++ b/drivers/vfio/mdev/mdev_private.h @@ -11,6 +11,7 @@ #define MDEV_PRIVATE_H #include +#include int mdev_bus_register(void); void mdev_bus_unregister(void); @@ -38,6 +39,7 @@ struct mdev_device { u16 class_id; union { const struct mdev_vfio_device_ops *vfio_ops; + const struct mdev_virtio_device_ops *virtio_ops; }; }; diff --git a/include/linux/mdev.h b/include/linux/mdev.h index 9e37506d1987..f3d75a60c2b5 100644 --- a/include/linux/mdev.h +++ b/include/linux/mdev.h @@ -17,6 +17,7 @@ struct mdev_device; struct mdev_vfio_device_ops; +struct mdev_virtio_device_ops; /* * Called by the parent device driver to set the device which represents @@ -112,6 +113,10 @@ void mdev_set_class(struct mdev_device *mdev, u16 id); void mdev_set_vfio_ops(struct mdev_device *mdev, const struct mdev_vfio_device_ops *vfio_ops); const struct mdev_vfio_device_ops *mdev_get_vfio_ops(struct mdev_device *mdev); +void mdev_set_virtio_ops(struct mdev_device *mdev, +const struct mdev_virtio_device_ops *virtio_ops); +const struct mdev_virtio_device_ops * +mdev_get_virtio_ops(struct mdev_device *mdev); extern struct bus_type mdev_bus_type; @@ -127,6 +132,7 @@ struct mdev_device *mdev_from_dev(struct device *dev); enum { MDEV_CLASS_ID_VFIO = 1, + MDEV_CLASS_ID_VIRTIO = 2, /* New entries must be added here */ }; diff --git a/include/linux/mdev_virtio_ops.h b/include/linux/mdev_virtio_ops.h new file mode 100644 index ..8951331c6629 --- /dev/null +++ b/include/linux/mdev_virtio_ops.h @@ -0,0 +1,147 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Virtio mediated device driver + * + * Copyright 2019, Red Hat Corp. + * Author: Jason Wang + */ +#ifndef MDEV_VIRTIO_OPS_H +#define MDEV_VIRTIO_OPS_H + +#include +#include +#include + +#define VIRTIO_MDEV_DEVICE_API_STRING "virtio-mdev" + +struct virtio_mdev_callback { + irqreturn_t (*callback)(void *data); + void *private; +}; + +/** + * struct mdev_virtio_device_ops - Structure to be registered for each + * mdev device to register the device for virtio/vhost drivers. + * + * The callbacks are mandatory unless explicitly mentioned. + * + * @set_vq_address:Set the address of virtqueue + * @mdev: mediated device + * @idx: virtqueue index + * @desc_area: address of desc area + * @driver_area: address of driver area + * @device_area: address of device area + * Returns integer: success (0) or error (< 0) + * @set_vq_num:Set the size of virtqueue + * @mdev: mediated device + *
[PATCH V10 3/6] mdev: introduce device specific ops
Currently, except for the create and remove, the rest of mdev_parent_ops is designed for vfio-mdev driver only and may not help for kernel mdev driver. With the help of class id, this patch introduces device specific callbacks inside mdev_device structure. This allows different set of callback to be used by vfio-mdev and virtio-mdev. Reviewed-by: Parav Pandit Signed-off-by: Jason Wang --- .../driver-api/vfio-mediated-device.rst | 35 + MAINTAINERS | 1 + drivers/gpu/drm/i915/gvt/kvmgt.c | 18 --- drivers/s390/cio/vfio_ccw_ops.c | 18 --- drivers/s390/crypto/vfio_ap_ops.c | 14 +++-- drivers/vfio/mdev/mdev_core.c | 24 - drivers/vfio/mdev/mdev_private.h | 5 ++ drivers/vfio/mdev/vfio_mdev.c | 37 ++--- include/linux/mdev.h | 43 --- include/linux/mdev_vfio_ops.h | 52 +++ samples/vfio-mdev/mbochs.c| 20 --- samples/vfio-mdev/mdpy.c | 20 --- samples/vfio-mdev/mtty.c | 18 --- 13 files changed, 206 insertions(+), 99 deletions(-) create mode 100644 include/linux/mdev_vfio_ops.h diff --git a/Documentation/driver-api/vfio-mediated-device.rst b/Documentation/driver-api/vfio-mediated-device.rst index 6709413bee29..04d56884c357 100644 --- a/Documentation/driver-api/vfio-mediated-device.rst +++ b/Documentation/driver-api/vfio-mediated-device.rst @@ -152,15 +152,6 @@ callbacks per mdev parent device, per mdev type, or any other categorization. Vendor drivers are expected to be fully asynchronous in this respect or provide their own internal resource protection.) -The callbacks in the mdev_parent_ops structure are as follows: - -* open: open callback of mediated device -* close: close callback of mediated device -* ioctl: ioctl callback of mediated device -* read : read emulation callback -* write: write emulation callback -* mmap: mmap emulation callback - A driver should use the mdev_parent_ops structure in the function call to register itself with the mdev core driver:: @@ -172,10 +163,34 @@ that a driver should use to unregister itself with the mdev core driver:: extern void mdev_unregister_device(struct device *dev); -It is also required to specify the class_id in create() callback through:: +As multiple types of mediated devices may be supported, class id needs +to be specified in the create() callback. This could be done +explicitly for the device that interacts with the mdev device directly +through:: int mdev_set_class(struct mdev_device *mdev, u16 id); +For the device that uses the mdev bus for its operation, the class +should provide helper function to set class id and device specific +ops. E.g for vfio-mdev devices, the function to be called is:: + + int mdev_set_vfio_ops(struct mdev_device *mdev, + const struct mdev_vfio_device_ops *vfio_ops); + +The class id (set by this function to MDEV_CLASS_ID_VFIO) is used to +match a device with an mdev driver via its id table. The device +specific callbacks (specified in *vfio_ops) are obtainable via +mdev_get_vfio_ops() (for use by the mdev bus driver). A vfio-mdev +device (class id MDEV_CLASS_ID_VFIO) uses the following +device-specific ops: + +* open: open callback of vfio mediated device +* close: close callback of vfio mediated device +* ioctl: ioctl callback of vfio mediated device +* read : read emulation callback +* write: write emulation callback +* mmap: mmap emulation callback + Mediated Device Management Interface Through sysfs == diff --git a/MAINTAINERS b/MAINTAINERS index cba1095547fd..f661d13344d6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -17121,6 +17121,7 @@ S: Maintained F: Documentation/driver-api/vfio-mediated-device.rst F: drivers/vfio/mdev/ F: include/linux/mdev.h +F: include/linux/mdev_vfio_ops.h F: samples/vfio-mdev/ VFIO PLATFORM DRIVER diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index 6420f0dbd31b..662f3a672372 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -643,6 +644,8 @@ static void kvmgt_put_vfio_device(void *vgpu) vfio_device_put(((struct intel_vgpu *)vgpu)->vdev.vfio_device); } +static const struct mdev_vfio_device_ops intel_vfio_vgpu_dev_ops; + static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev) { struct intel_vgpu *vgpu = NULL; @@ -678,7 +681,7 @@ static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev) dev_name(mdev_dev(mdev))); ret = 0; - mdev_set_class(mdev, MDEV_CLASS_ID_VFIO); + mdev_set_vfio_ops(
[PATCH V10 5/6] virtio: introduce a mdev based transport
This patch introduces a new mdev transport for virtio. This is used to use kernel virtio driver to drive the mediated device that is capable of populating virtqueue directly. A new virtio-mdev driver will be registered to the mdev bus, when a new virtio-mdev device is probed, it will register the device with mdev based config ops. This means it is a software transport between mdev driver and mdev device. The transport was implemented through virtio device specific ops. Reviewed-by: Cornelia Huck Signed-off-by: Jason Wang --- drivers/virtio/Kconfig | 13 ++ drivers/virtio/Makefile | 1 + drivers/virtio/virtio_mdev.c | 406 +++ 3 files changed, 420 insertions(+) create mode 100644 drivers/virtio/virtio_mdev.c diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig index 078615cf2afc..bf526ce0facc 100644 --- a/drivers/virtio/Kconfig +++ b/drivers/virtio/Kconfig @@ -43,6 +43,19 @@ config VIRTIO_PCI_LEGACY If unsure, say Y. +config VIRTIO_MDEV + tristate "MDEV driver for virtio devices" + depends on VFIO_MDEV && VIRTIO + default n + help + This driver provides support for virtio based paravirtual + device driver over MDEV bus. For this to be useful, you need + an appropriate virtio mdev device implementation that + operates on a physical device to allow the datapath of virtio + to be offloaded to hardware. + + If unsure, say M. + config VIRTIO_PMEM tristate "Support for virtio pmem driver" depends on VIRTIO diff --git a/drivers/virtio/Makefile b/drivers/virtio/Makefile index 3a2b5c5dcf46..f2997b6c812f 100644 --- a/drivers/virtio/Makefile +++ b/drivers/virtio/Makefile @@ -6,3 +6,4 @@ virtio_pci-y := virtio_pci_modern.o virtio_pci_common.o virtio_pci-$(CONFIG_VIRTIO_PCI_LEGACY) += virtio_pci_legacy.o obj-$(CONFIG_VIRTIO_BALLOON) += virtio_balloon.o obj-$(CONFIG_VIRTIO_INPUT) += virtio_input.o +obj-$(CONFIG_VIRTIO_MDEV) += virtio_mdev.o diff --git a/drivers/virtio/virtio_mdev.c b/drivers/virtio/virtio_mdev.c new file mode 100644 index ..9e12ef240493 --- /dev/null +++ b/drivers/virtio/virtio_mdev.c @@ -0,0 +1,406 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * VIRTIO based driver for Mediated device + * + * Copyright (c) 2019, Red Hat. All rights reserved. + * Author: Jason Wang + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_VERSION "0.1" +#define DRIVER_AUTHOR "Red Hat Corporation" +#define DRIVER_DESC "VIRTIO based driver for Mediated device" + +#define to_virtio_mdev_device(dev) \ + container_of(dev, struct virtio_mdev_device, vdev) + +struct virtio_mdev_device { + struct virtio_device vdev; + struct mdev_device *mdev; + u64 features; + + /* The lock to protect virtqueue list */ + spinlock_t lock; + /* List of virtio_mdev_vq_info */ + struct list_head virtqueues; +}; + +struct virtio_mdev_vq_info { + /* the actual virtqueue */ + struct virtqueue *vq; + + /* the list node for the virtqueues list */ + struct list_head node; +}; + +static struct mdev_device *vm_get_mdev(struct virtio_device *vdev) +{ + struct virtio_mdev_device *vm_dev = to_virtio_mdev_device(vdev); + struct mdev_device *mdev = vm_dev->mdev; + + return mdev; +} + +static void virtio_mdev_get(struct virtio_device *vdev, unsigned offset, + void *buf, unsigned len) +{ + struct mdev_device *mdev = vm_get_mdev(vdev); + const struct mdev_virtio_device_ops *ops = mdev_get_virtio_ops(mdev); + + ops->get_config(mdev, offset, buf, len); +} + +static void virtio_mdev_set(struct virtio_device *vdev, unsigned offset, + const void *buf, unsigned len) +{ + struct mdev_device *mdev = vm_get_mdev(vdev); + const struct mdev_virtio_device_ops *ops = mdev_get_virtio_ops(mdev); + + ops->set_config(mdev, offset, buf, len); +} + +static u32 virtio_mdev_generation(struct virtio_device *vdev) +{ + struct mdev_device *mdev = vm_get_mdev(vdev); + const struct mdev_virtio_device_ops *ops = mdev_get_virtio_ops(mdev); + + if (ops->get_generation) + return ops->get_generation(mdev); + + return 0; +} + +static u8 virtio_mdev_get_status(struct virtio_device *vdev) +{ + struct mdev_device *mdev = vm_get_mdev(vdev); + const struct mdev_virtio_device_ops *ops = mdev_get_virtio_ops(mdev); + + return ops->get_status(mdev); +} + +static void virtio_mdev_set_status(struct virtio_device *vdev, u8 status) +{ + struct mdev_device *mdev = vm_get_mdev(vdev); + const struct mdev_virtio_device_ops *ops = mdev_get_virtio_ops(mdev); + + return ops->set_status(mdev, status); +} + +static void virtio_mdev_reset(struct virtio_device *vdev) +{ + struct mdev
[PATCH V10 6/6] docs: sample driver to demonstrate how to implement virtio-mdev framework
This sample driver creates mdev device that simulate virtio net device over virtio mdev transport. The device is implemented through vringh and workqueue. A device specific dma ops is to make sure HVA is used directly as the IOVA. This should be sufficient for kernel virtio driver to work. Only 'virtio' type is supported right now. I plan to add 'vhost' type on top which requires some virtual IOMMU implemented in this sample driver. Acked-by: Cornelia Huck Signed-off-by: Jason Wang --- MAINTAINERS| 1 + samples/Kconfig| 10 + samples/vfio-mdev/Makefile | 1 + samples/vfio-mdev/mvnet.c | 686 + 4 files changed, 698 insertions(+) create mode 100644 samples/vfio-mdev/mvnet.c diff --git a/MAINTAINERS b/MAINTAINERS index 4997957443df..6e9ad105a28f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -17249,6 +17249,7 @@ F: include/uapi/linux/virtio_*.h F: drivers/crypto/virtio/ F: mm/balloon_compaction.c F: include/linux/mdev_virtio_ops.h +F: samples/vfio-mdev/mvnet.c VIRTIO BLOCK AND SCSI DRIVERS M: "Michael S. Tsirkin" diff --git a/samples/Kconfig b/samples/Kconfig index c8dacb4dda80..13a2443e18e0 100644 --- a/samples/Kconfig +++ b/samples/Kconfig @@ -131,6 +131,16 @@ config SAMPLE_VFIO_MDEV_MDPY mediated device. It is a simple framebuffer and supports the region display interface (VFIO_GFX_PLANE_TYPE_REGION). +config SAMPLE_VIRTIO_MDEV_NET + tristate "Build VIRTIO net example mediated device sample code -- loadable modules only" + depends on VIRTIO_MDEV && VHOST_RING && m + help + Build a networking sample device for use as a virtio + mediated device. The device coopreates with virtio-mdev bus + driver to present an virtio ethernet driver for + kernel. It simply loopbacks all packets from its TX + virtqueue to its RX virtqueue. + config SAMPLE_VFIO_MDEV_MDPY_FB tristate "Build VFIO mdpy example guest fbdev driver -- loadable module only" depends on FB && m diff --git a/samples/vfio-mdev/Makefile b/samples/vfio-mdev/Makefile index 10d179c4fdeb..f34af90ed0a0 100644 --- a/samples/vfio-mdev/Makefile +++ b/samples/vfio-mdev/Makefile @@ -3,3 +3,4 @@ obj-$(CONFIG_SAMPLE_VFIO_MDEV_MTTY) += mtty.o obj-$(CONFIG_SAMPLE_VFIO_MDEV_MDPY) += mdpy.o obj-$(CONFIG_SAMPLE_VFIO_MDEV_MDPY_FB) += mdpy-fb.o obj-$(CONFIG_SAMPLE_VFIO_MDEV_MBOCHS) += mbochs.o +obj-$(CONFIG_SAMPLE_VIRTIO_MDEV_NET) += mvnet.o diff --git a/samples/vfio-mdev/mvnet.c b/samples/vfio-mdev/mvnet.c new file mode 100644 index ..a89aecfab68a --- /dev/null +++ b/samples/vfio-mdev/mvnet.c @@ -0,0 +1,686 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Mediated virtual virtio-net device driver. + * + * Copyright (c) 2019, Red Hat Inc. All rights reserved. + * Author: Jason Wang + * + * Sample driver that creates mdev device that simulates ethernet loopback + * device. + * + * Usage: + * + * # modprobe virtio_mdev + * # modprobe mvnet + * # cd /sys/devices/virtual/mvnet/mvnet/mdev_supported_types/mvnet-virtio + * # echo "83b8f4f2-509f-382f-3c1e-e6bfe0fa1001" > ./create + * # cd devices/83b8f4f2-509f-382f-3c1e-e6bfe0fa1001 + * # ls -d virtio0 + * virtio0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define VERSION_STRING "0.1" +#define DRIVER_AUTHOR "Red Hat Corporation" + +#define MVNET_CLASS_NAME "mvnet" +#define MVNET_NAME "mvnet" + +/* + * Global Structures + */ + +static struct mvnet_dev { + struct class*vd_class; + struct idr vd_idr; + struct device dev; +} mvnet_dev; + +struct mvnet_virtqueue { + struct vringh vring; + struct vringh_kiov iov; + unsigned short head; + bool ready; + u64 desc_addr; + u64 device_addr; + u64 driver_addr; + u32 num; + void *private; + irqreturn_t (*cb)(void *data); +}; + +#define MVNET_QUEUE_ALIGN PAGE_SIZE +#define MVNET_QUEUE_MAX 256 +#define MVNET_DEVICE_ID 0x1 +#define MVNET_VENDOR_ID 0 + +u64 mvnet_features = (1ULL << VIRTIO_F_ANY_LAYOUT) | +(1ULL << VIRTIO_F_VERSION_1) | +(1ULL << VIRTIO_F_IOMMU_PLATFORM); + +/* State of each mdev device */ +struct mvnet_state { + struct mvnet_virtqueue vqs[2]; + struct work_struct work; + /* spinlock to synchronize virtqueue state */ + spinlock_t lock; + struct mdev_device *mdev; + struct virtio_net_config config; + void *buffer; + u32 status; + u32 generation; + u64 features; + struct list_head next; +}; + +static struct mutex mdev_list_lock; +static struct list_head mdev_devices_list; + +static void mvnet_queue_ready(struct mvnet_state *mvnet, unsigned int idx) +{ + struct mvnet_virtqueue *
[Bug 111481] AMD Navi GPU frequent freezes on both Manjaro/Ubuntu with kernel 5.3 and mesa 19.2 -git/llvm9
https://bugs.freedesktop.org/show_bug.cgi?id=111481 --- Comment #212 from wychuchol --- (In reply to Marco Liedtke from comment #211) > > I have already set AMD_DEBUG=nodam in /etc/environment and in ~/.profile. > Last time i played World of Tanks via Wine and DXVK the same freeze occured, > again the same error that xorg pid timed out... Don't know if you made a typo here but do you have AMD_DEBUG="nongg,nodma" line in /etc/environment ? Bugs still occur for me but they're far less frequent. Also since you're running ryzen 3000 try to get kernel 5.4. It won't solve your problems but there's a massive performance buff for zen2 in 5.4. -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v15 1/5] dma-buf: Add dma-buf heaps framework
On 11/5/19 11:22 PM, John Stultz wrote: > From: "Andrew F. Davis" > > This framework allows a unified userspace interface for dma-buf > exporters, allowing userland to allocate specific types of memory > for use in dma-buf sharing. > > Each heap is given its own device node, which a user can allocate > a dma-buf fd from using the DMA_HEAP_IOC_ALLOC. > > This code is an evoluiton of the Android ION implementation, > and a big thanks is due to its authors/maintainers over time > for their effort: > Rebecca Schultz Zavin, Colin Cross, Benjamin Gaignard, > Laura Abbott, and many other contributors! > > Cc: Laura Abbott > Cc: Benjamin Gaignard > Cc: Sumit Semwal > Cc: Liam Mark > Cc: Pratik Patel > Cc: Brian Starkey > Cc: Vincent Donnefort > Cc: Sudipto Paul > Cc: Andrew F. Davis > Cc: Christoph Hellwig > Cc: Chenbo Feng > Cc: Alistair Strachan > Cc: Hridya Valsaraju > Cc: Sandeep Patil > Cc: Hillf Danton > Cc: Dave Airlie > Cc: dri-devel@lists.freedesktop.org > Reviewed-by: Brian Starkey > Acked-by: Sandeep Patil > Signed-off-by: Andrew F. Davis > Signed-off-by: John Stultz > --- > v2: > * Folded down fixes I had previously shared in implementing > heaps > * Make flags a u64 (Suggested by Laura) > * Add PAGE_ALIGN() fix to the core alloc funciton > * IOCTL fixups suggested by Brian > * Added fixes suggested by Benjamin > * Removed core stats mgmt, as that should be implemented by > per-heap code > * Changed alloc to return a dma-buf fd, rather than a buffer > (as it simplifies error handling) > v3: > * Removed scare-quotes in MAINTAINERS email address > * Get rid of .release function as it didn't do anything (from > Christoph) > * Renamed filp to file (suggested by Christoph) > * Split out ioctl handling to separate function (suggested by > Christoph) > * Add comment documenting PAGE_ALIGN usage (suggested by Brian) > * Switch from idr to Xarray (suggested by Brian) > * Fixup cdev creation (suggested by Brian) > * Avoid EXPORT_SYMBOL until we finalize modules (suggested by > Brian) > * Make struct dma_heap internal only (folded in from Andrew) > * Small cleanups suggested by GregKH > * Provide class->devnode callback to get consistent /dev/ > subdirectory naming (Suggested by Bjorn) > v4: > * Folded down dma-heap.h change that was in a following patch > * Added fd_flags entry to allocation structure and pass it > through to heap code for use on dma-buf fd creation (suggested > by Benjamin) > v5: > * Minor cleanups > v6: > * Improved error path handling, minor whitespace fixes, both > suggested by Brian > v7: > * Longer Kconfig description to quiet checkpatch warnings > * Re-add compat_ioctl bits (Hridya noticed 32bit userland wasn't > working) > v8: > * Make struct dma_heap_ops consts (Suggested by Christoph) > * Checkpatch whitespace fixups > v9: > * Minor cleanups suggested by Brian Starkey > * Rename dma_heap_get_data->dma_heap_get_drvdata suggested > by Hilf Danton > v11: > * Kconfig text improvements suggested by Randy Dunlap > v12: > * Add logic to prevent duplicately named heaps being added > * Add symbol exports for heaps as modules > v13: > * Re-remove symbol exports per discussion w/ Brian. Will > resubmit in a separte patch for review > v14: > * Reworked ioctl handler to zero fill any difference in > structure size, similar to what the DRM core does, as > suggested by Dave Airlie > * Removed now unnecessary reserved bits in allocate_data > * Added get_features ioctl as suggested by Dave Airlie > * Removed pr_warn_once messages as requested by Dave > Airlie > v15: > * Dropped the get_features ioctl as suggested by Brian > Starkey and Daniel Vetter > * Add listhead comment suggested by Sandeep Patil > * Dropped minor value in struct dma_heap as suggested by > Sandeep Patil > * Fix grammar typo from Brian Starkey > --- > MAINTAINERS | 18 +++ > drivers/dma-buf/Kconfig | 9 ++ > drivers/dma-buf/Makefile | 1 + > drivers/dma-buf/dma-heap.c| 297 ++ > include/linux/dma-heap.h | 59 +++ > include/uapi/linux/dma-heap.h | 53 ++ > 6 files changed, 437 insertions(+) > create mode 100644 drivers/dma-buf/dma-heap.c > create mode 100644 include/linux/dma-heap.h > create mode 100644 include/uapi/linux/dma-heap.h > > diff --git a/MAINTAINERS b/MAINTAINERS > index cba1095547fd..568f94172905 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -4940,6 +4940,24 @@ F: include/linux/*fence.h > F: Documentation/driver-api/dma-buf.rst > T: git git://anongit.freedesktop.org/drm/drm-misc > > +DMA-BUF HEAPS FRAMEWORK > +M: Sumit Semwal > +R: Andrew F. Davis > +R: Benjamin Gaignard > +R: Liam Mark > +R: Laura Abbott > +R: Brian Starkey > +R: John Stultz > +S: Maintained > +L: linux-me...@vger.kernel.org > +L: dri-devel@lists.freedesktop.org > +L: linaro-mm-...@lists.linaro.org (moderated for non-subscribers) > +F: include/uapi/linu
Re: [PATCH v6 8/9] drm: Add macro to export functions only when CONFIG_DRM_DEBUG_SELFTEST is enabled
Quoting Alexandru-Cosmin Gheorghe (2018-10-29 17:14:43) > If we want to be able to write drmselftests for non-static core > functions that are not intended to be used by drivers we need this > functions to be exported. > > This adds a macro that is tied of CONFIG_DRM_DEBUG_SELFTEST, and uses > that to export drm_internal_framebuffer_create, in order for > subsequent patches to be able to test it. > > Signed-off-by: Alexandru Gheorghe > --- > drivers/gpu/drm/drm_framebuffer.c | 1 + > include/drm/drmP.h| 6 ++ > 2 files changed, 7 insertions(+) > > diff --git a/drivers/gpu/drm/drm_framebuffer.c > b/drivers/gpu/drm/drm_framebuffer.c > index 167c1c4544af..fcaea8f50513 100644 > --- a/drivers/gpu/drm/drm_framebuffer.c > +++ b/drivers/gpu/drm/drm_framebuffer.c > @@ -323,6 +323,7 @@ drm_internal_framebuffer_create(struct drm_device *dev, > > return fb; > } > +EXPORT_SYMBOL_FOR_TESTS_ONLY(drm_internal_framebuffer_create); > > /** > * drm_mode_addfb2 - add an FB to the graphics configuration > diff --git a/include/drm/drmP.h b/include/drm/drmP.h > index 05350424a4d3..514beb2d483a 100644 > --- a/include/drm/drmP.h > +++ b/include/drm/drmP.h > @@ -110,4 +110,10 @@ static inline bool drm_can_sleep(void) > return true; > } > > +#if defined(CONFIG_DRM_DEBUG_SELFTEST_MODULE) > +#define EXPORT_SYMBOL_FOR_TESTS_ONLY(x) EXPORT_SYMBOL(x) > +#else > +#define EXPORT_SYMBOL_FOR_TESTS_ONLY(x) > +#endif There's no Kconfig stanza for this symbol. -Chris ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 2/4] drm/i915/selftests: Replace mock_file hackery with drm's true fake
As drm now exports a method to create an anonymous struct file around a drm_device for internal use, make use of it to avoid our horrible hacks. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/Kconfig.debug| 2 + .../gpu/drm/i915/gem/selftests/huge_pages.c | 2 +- .../drm/i915/gem/selftests/i915_gem_context.c | 12 ++--- .../i915/gem/selftests/i915_gem_object_blt.c | 4 +- drivers/gpu/drm/i915/gt/selftest_context.c| 4 +- drivers/gpu/drm/i915/gt/selftest_hangcheck.c | 8 +-- .../gpu/drm/i915/gt/selftest_workarounds.c| 2 +- drivers/gpu/drm/i915/selftests/i915_gem.c | 4 +- .../gpu/drm/i915/selftests/i915_gem_evict.c | 2 +- drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 4 +- drivers/gpu/drm/i915/selftests/i915_request.c | 2 +- .../drm/i915/selftests/intel_memory_region.c | 2 +- drivers/gpu/drm/i915/selftests/mock_drm.c | 49 +++ drivers/gpu/drm/i915/selftests/mock_drm.h | 8 ++- 14 files changed, 39 insertions(+), 66 deletions(-) diff --git a/drivers/gpu/drm/i915/Kconfig.debug b/drivers/gpu/drm/i915/Kconfig.debug index ef123eb29168..bcf710f66168 100644 --- a/drivers/gpu/drm/i915/Kconfig.debug +++ b/drivers/gpu/drm/i915/Kconfig.debug @@ -38,6 +38,7 @@ config DRM_I915_DEBUG select DRM_VGEM # used by igt/prime_vgem (dmabuf interop checks) select DRM_DEBUG_MM if DRM=y select DRM_DEBUG_SELFTEST + select DRM_DEBUG_SELFTEST_MODULE select DMABUF_SELFTESTS select SW_SYNC # signaling validation framework (igt/syncobj*) select DRM_I915_SW_FENCE_DEBUG_OBJECTS @@ -160,6 +161,7 @@ config DRM_I915_SELFTEST bool "Enable selftests upon driver load" depends on DRM_I915 default n + select DRM_DEBUG_SELFTEST_MODULE select FAULT_INJECTION select PRIME_NUMBERS help diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c index 688c49a24f32..06dad7b0db82 100644 --- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c +++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c @@ -1944,6 +1944,6 @@ int i915_gem_huge_page_live_selftests(struct drm_i915_private *i915) err = i915_subtests(tests, ctx); out_file: - mock_file_free(i915, file); + mock_file_put(file); return err; } diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c index 62fabc023a83..47890c92534c 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c @@ -149,7 +149,7 @@ static int live_nop_switch(void *arg) } out_file: - mock_file_free(i915, file); + mock_file_put(file); return err; } @@ -377,7 +377,7 @@ static int live_parallel_switch(void *arg) } kfree(data); out_file: - mock_file_free(i915, file); + mock_file_put(file); return err; } @@ -716,7 +716,7 @@ static int igt_ctx_exec(void *arg) if (igt_live_test_end(&t)) err = -EIO; - mock_file_free(i915, file); + mock_file_put(file); if (err) return err; @@ -854,7 +854,7 @@ static int igt_shared_ctx_exec(void *arg) if (igt_live_test_end(&t)) err = -EIO; out_file: - mock_file_free(i915, file); + mock_file_put(file); return err; } @@ -1426,7 +1426,7 @@ static int igt_ctx_readonly(void *arg) if (igt_live_test_end(&t)) err = -EIO; - mock_file_free(i915, file); + mock_file_put(file); return err; } @@ -1750,7 +1750,7 @@ static int igt_vm_isolation(void *arg) out_file: if (igt_live_test_end(&t)) err = -EIO; - mock_file_free(i915, file); + mock_file_put(file); return err; } diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_object_blt.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_object_blt.c index e8132aca0bb6..d9fdfddb7091 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_object_blt.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_object_blt.c @@ -301,7 +301,7 @@ static int igt_fill_blt_thread(void *arg) intel_context_put(ce); out_file: - mock_file_free(i915, file); + mock_file_put(file); return err; } @@ -432,7 +432,7 @@ static int igt_copy_blt_thread(void *arg) intel_context_put(ce); out_file: - mock_file_free(i915, file); + mock_file_put(file); return err; } diff --git a/drivers/gpu/drm/i915/gt/selftest_context.c b/drivers/gpu/drm/i915/gt/selftest_context.c index bc720defc6b8..a5688f7d9073 100644 --- a/drivers/gpu/drm/i915/gt/selftest_context.c +++ b/drivers/gpu/drm/i915/gt/selftest_context.c @@ -313,7 +313,7 @@ static int live_active_context(void *arg) } out_file: - mock_file_free(gt->i915, f
[PATCH v2 1/4] drm: Expose a method for creating anonymous struct file around drm_minor
Sometimes we need to create a struct file to wrap a drm_device, as it the user were to have opened /dev/dri/card0 but to do so anonymously (i.e. for internal use). Provide a utility method to create a struct file with the drm_device->driver.fops, that wrap the drm_device. v2: Restrict usage to selftests Signed-off-by: Chris Wilson Cc: Daniel Vetter --- drivers/gpu/drm/Kconfig| 4 drivers/gpu/drm/drm_file.c | 42 ++ include/drm/drm_file.h | 3 +++ 3 files changed, 49 insertions(+) diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 617d9c3a86c3..589d5d693855 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -70,6 +70,10 @@ config DRM_DEBUG_SELFTEST If in doubt, say "N". +config DRM_DEBUG_SELFTEST_MODULE + bool + depends on DRM_DEBUG_SELFTEST + config DRM_KMS_HELPER tristate depends on DRM diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c index ea34bc991858..4d9385d1bf2d 100644 --- a/drivers/gpu/drm/drm_file.c +++ b/drivers/gpu/drm/drm_file.c @@ -31,7 +31,9 @@ * OTHER DEALINGS IN THE SOFTWARE. */ +#include #include +#include #include #include #include @@ -754,3 +756,43 @@ void drm_send_event(struct drm_device *dev, struct drm_pending_event *e) spin_unlock_irqrestore(&dev->event_lock, irqflags); } EXPORT_SYMBOL(drm_send_event); + +/** + * mock_drm_getfile - Create a new struct file for the drm device + * @minor: drm minor to wrap (e.g. #drm_device.primary) + * @flags: file creation mode (O_RDWR etc) + * + * This create a new struct file that wraps a DRM file context around a + * DRM minor. This mimicks userspace opening e.g. /dev/dri/card0, but without + * invoking userspace. The struct file may be operated on using its f_op + * (the drm_device.driver.fops) to mimick userspace operations, or be supplied + * to userspace facing functions as an internal/anonymous client. + * + * RETURNS: + * Pointer to newly created struct file, ERR_PTR on failure. + */ +struct file *mock_drm_getfile(struct drm_minor *minor, unsigned int flags) +{ + struct drm_device *dev = minor->dev; + struct drm_file *priv; + struct file *file; + + priv = drm_file_alloc(minor); + if (IS_ERR(priv)) + return ERR_CAST(priv); + + file = anon_inode_getfile("drm", dev->driver->fops, priv, flags); + if (IS_ERR(file)) { + drm_file_free(priv); + return file; + } + + /* Everyone shares a single global address space */ + file->f_mapping = dev->anon_inode->i_mapping; + + drm_dev_get(dev); + priv->filp = file; + + return file; +} +EXPORT_SYMBOL_FOR_TESTS_ONLY(mock_drm_getfile); diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h index 67af60bb527a..8b099b347817 100644 --- a/include/drm/drm_file.h +++ b/include/drm/drm_file.h @@ -42,6 +42,7 @@ struct dma_fence; struct drm_file; struct drm_device; struct device; +struct file; /* * FIXME: Not sure we want to have drm_minor here in the end, but to avoid @@ -387,4 +388,6 @@ void drm_event_cancel_free(struct drm_device *dev, void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e); void drm_send_event(struct drm_device *dev, struct drm_pending_event *e); +struct file *mock_drm_getfile(struct drm_minor *minor, unsigned int flags); + #endif /* _DRM_FILE_H_ */ -- 2.24.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 4/4] drm/i915/selftests: Verify mmap_gtt revocation on unbinding
Whenever, we unbind (or change fence registers) on an object, we must revoke any and all mmap_gtt using the previous bindings. Those user PTEs point at the GGTT which know points into a new object, the wrong object. Ergo, those PTEs must be cleared so that any user access provokes a new page fault. Signed-off-by: Chris Wilson Cc: Abdiel Janulgue --- .../drm/i915/gem/selftests/i915_gem_mman.c| 107 ++ 1 file changed, 107 insertions(+) diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c index 3c8f2297be86..687750388cd5 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c @@ -790,6 +790,112 @@ static int igt_mmap_gtt(void *arg) return err; } +static int check_present_pte(pte_t *pte, unsigned long addr, void *data) +{ + if (!pte_present(*pte) || pte_none(*pte)) { + pr_err("missing PTE:%lx\n", + (addr - (unsigned long)data) >> PAGE_SHIFT); + return -EINVAL; + } + + return 0; +} + +static int check_absent_pte(pte_t *pte, unsigned long addr, void *data) +{ + if (pte_present(*pte) && !pte_none(*pte)) { + pr_err("present PTE:%lx; expected to be revoked\n", + (addr - (unsigned long)data) >> PAGE_SHIFT); + return -EINVAL; + } + + return 0; +} + +static int check_present(unsigned long addr, unsigned long len) +{ + return apply_to_page_range(current->mm, addr, len, + check_present_pte, (void *)addr); +} + +static int check_absent(unsigned long addr, unsigned long len) +{ + return apply_to_page_range(current->mm, addr, len, + check_absent_pte, (void *)addr); +} + +static int prefault_range(u64 start, u64 len) +{ + const char __user *addr, *end; + char __maybe_unused c; + + addr = u64_to_user_ptr(start); + end = addr + len; + + for (; addr < end; addr += PAGE_SIZE) { + int err = __get_user(c, addr); + if (err) + return err; + } + + return __get_user(c, end - 1); +} + +static int igt_mmap_gtt_revoke(void *arg) +{ + struct drm_i915_private *i915 = arg; + struct drm_i915_gem_object *obj; + unsigned long addr; + int err; + + obj = i915_gem_object_create_internal(i915, SZ_4M); + if (IS_ERR(obj)) + return PTR_ERR(obj); + + err = create_mmap_offset(obj); + if (err) + goto out; + + addr = igt_mmap_node(i915, &obj->base.vma_node, +0, PROT_WRITE, MAP_SHARED); + if (IS_ERR_VALUE(addr)) { + err = addr; + goto out; + } + + err = prefault_range(addr, obj->base.size); + if (err) + goto out_unmap; + + GEM_BUG_ON(!atomic_read(&obj->bind_count)); + + err = check_present(addr, obj->base.size); + if (err) + goto out_unmap; + + /* +* After unbinding the object from the GGTT, its address may be reused +* for other objects. Ergo we have to revoke the previous mmap PTE +* access as it no longer points to the same object. +*/ + err = i915_gem_object_unbind(obj, I915_GEM_OBJECT_UNBIND_ACTIVE); + if (err) { + pr_err("Failed to unbind object!\n"); + goto out_unmap; + } + GEM_BUG_ON(atomic_read(&obj->bind_count)); + + err = check_absent(addr, obj->base.size); + if (err) + goto out_unmap; + +out_unmap: + vm_munmap(addr, obj->base.size); +out: + i915_gem_object_put(obj); + return err; +} + int i915_gem_mman_live_selftests(struct drm_i915_private *i915) { static const struct i915_subtest tests[] = { @@ -797,6 +903,7 @@ int i915_gem_mman_live_selftests(struct drm_i915_private *i915) SUBTEST(igt_smoke_tiling), SUBTEST(igt_mmap_offset_exhaustion), SUBTEST(igt_mmap_gtt), + SUBTEST(igt_mmap_gtt_revoke), }; return i915_subtests(tests, i915); -- 2.24.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 3/4] drm/i915/selftests: Wrap vm_mmap() around GEM objects
Provide a utility function to create a vma corresponding to an mmap() of our device. And use it to exercise the equivalent of userspace performing a GTT mmap of our objects. Signed-off-by: Chris Wilson Cc: Abdiel Janulgue --- drivers/gpu/drm/i915/Makefile | 1 + .../drm/i915/gem/selftests/i915_gem_mman.c| 97 +++ drivers/gpu/drm/i915/selftests/igt_mmap.c | 39 drivers/gpu/drm/i915/selftests/igt_mmap.h | 19 4 files changed, 156 insertions(+) create mode 100644 drivers/gpu/drm/i915/selftests/igt_mmap.c create mode 100644 drivers/gpu/drm/i915/selftests/igt_mmap.h diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 90dcf09f52cc..e0fd10c0cfb8 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -259,6 +259,7 @@ i915-$(CONFIG_DRM_I915_SELFTEST) += \ selftests/i915_selftest.o \ selftests/igt_flush_test.o \ selftests/igt_live_test.o \ + selftests/igt_mmap.o \ selftests/igt_reset.o \ selftests/igt_spinner.o diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c index 29b2077b73d2..3c8f2297be86 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c @@ -12,6 +12,7 @@ #include "i915_selftest.h" #include "selftests/i915_random.h" #include "selftests/igt_flush_test.h" +#include "selftests/igt_mmap.h" struct tile { unsigned int width; @@ -694,12 +695,108 @@ static int igt_mmap_offset_exhaustion(void *arg) goto out; } +#define expand32(x) (((x) << 0) | ((x) << 8) | ((x) << 16) | ((x) << 24)) +static int igt_mmap_gtt(void *arg) +{ + struct drm_i915_private *i915 = arg; + struct drm_i915_gem_object *obj; + struct vm_area_struct *area; + unsigned long addr; + void *vaddr; + int err, i; + + obj = i915_gem_object_create_internal(i915, PAGE_SIZE); + if (IS_ERR(obj)) + return PTR_ERR(obj); + + vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB); + if (IS_ERR(vaddr)) { + err = PTR_ERR(vaddr); + goto out; + } + memset(vaddr, POISON_INUSE, PAGE_SIZE); + i915_gem_object_flush_map(obj); + i915_gem_object_unpin_map(obj); + + err = create_mmap_offset(obj); + if (err) + goto out; + + addr = igt_mmap_node(i915, &obj->base.vma_node, +0, PROT_WRITE, MAP_SHARED); + if (IS_ERR_VALUE(addr)) { + err = addr; + goto out; + } + + pr_debug("igt_mmap(obj:gtt) @ %lx\n", addr); + + area = find_vma(current->mm, addr); + if (!area) { + pr_err("Did not create a vm_area_struct for the mmap\n"); + err = -EINVAL; + goto out_unmap; + } + + if (area->vm_private_data != obj) { + pr_err("vm_area_struct did not point back to our object!\n"); + err = -EINVAL; + goto out_unmap; + } + + for (i = 0; i < PAGE_SIZE / sizeof(u32); i++) { + u32 __user *ux = u64_to_user_ptr((u64)(addr + i * sizeof*(ux))); + u32 x; + + if (get_user(x, ux)) { + pr_err("Unable to read from GTT mmap, offset:%zd\n", + i * sizeof(x)); + err = -EFAULT; + break; + } + + if (x != expand32(POISON_INUSE)) { + pr_err("Read incorrect value from GTT mmap, offset:%zd, found:%x, expected:%x\n", + i * sizeof(x), x, expand32(POISON_INUSE)); + err = -EINVAL; + break; + } + + x = expand32(POISON_FREE); + if (put_user(x, ux)) { + pr_err("Unable to write to GTT mmap, offset:%zd\n", + i * sizeof(x)); + err = -EFAULT; + break; + } + } + +out_unmap: + vm_munmap(addr, PAGE_SIZE); + + vaddr = i915_gem_object_pin_map(obj, I915_MAP_FORCE_WC); + if (IS_ERR(vaddr)) { + err = PTR_ERR(vaddr); + goto out; + } + if (err == 0 && memchr_inv(vaddr, POISON_FREE, PAGE_SIZE)) { + pr_err("Write via GGTT mmap did not land in backing store\n"); + err = -EINVAL; + } + i915_gem_object_unpin_map(obj); + +out: + i915_gem_object_put(obj); + return err; +} + int i915_gem_mman_live_selftests(struct drm_i915_private *i915) { static const struct i915_subtest tests[] = { SUBTEST(igt_partial_tiling), SUBTEST(igt_smoke_tiling), SUBTEST(igt_mmap_offset_exhaustion), + SUBTEST(igt_mmap_gtt),
Re: [PATCH V10 0/6] mdev based hardware virtio offloading support
On Wed, 6 Nov 2019 21:35:25 +0800 Jason Wang wrote: > Hi all: > > There are hardwares that can do virtio datapath offloading while > having its own control path. This path tries to implement a mdev based > unified API to support using kernel virtio driver to drive those > devices. This is done by introducing a new mdev transport for virtio > (virtio_mdev) and register itself as a new kind of mdev driver. Then > it provides a unified way for kernel virtio driver to talk with mdev > device implementation. > > Though the series only contains kernel driver support, the goal is to > make the transport generic enough to support userspace drivers. This > means vhost-mdev[1] could be built on top as well by resuing the > transport. > > A sample driver is also implemented which simulate a virito-net > loopback ethernet device on top of vringh + workqueue. This could be > used as a reference implementation for real hardware driver. > > Also a real IFC VF driver was also posted here[2] which is a good > reference for vendors who is interested in their own virtio datapath > offloading product. > > Consider mdev framework only support VFIO device and driver right now, > this series also extend it to support other types. This is done > through introducing class id to the device and pairing it with > id_talbe claimed by the driver. On top, this seris also decouple > device specific ops out of the common ones for implementing class > specific operations over mdev bus. > > Pktgen test was done with virito-net + mvnet loop back device. > > Please review. All looking good to me now. > > [1] https://lkml.org/lkml/2019/11/5/424 > [2] https://lkml.org/lkml/2019/11/5/227 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 1/2] drm/todo: Convert drivers to generic fbdev emulation
Den 06.11.2019 13.47, skrev Thomas Zimmermann: > This replaces the original TODO item for drm_fb_helper_fbdev_setup() > and _teardown(), which are deprecated. > > v2: > * remove driver-specific comments > * list some basic requirements > * keep a TODO item on drm_fb_helper_init() > > Signed-off-by: Thomas Zimmermann > --- Reviewed-by: Noralf Trønnes ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 1/4] drm: Expose a method for creating anonymous struct file around drm_minor
On Wed, Nov 06, 2019 at 01:57:36PM +, Chris Wilson wrote: > Sometimes we need to create a struct file to wrap a drm_device, as it > the user were to have opened /dev/dri/card0 but to do so anonymously > (i.e. for internal use). Provide a utility method to create a struct > file with the drm_device->driver.fops, that wrap the drm_device. > > v2: Restrict usage to selftests > > Signed-off-by: Chris Wilson > Cc: Daniel Vetter Not fully sold on the name, but then fget/fput/get_file and friends are all supremely confusing naming already, so meh. And on 2nd reading the f_mapping is the only thing we need for unmap_mapping_range, so should be all fine too. Reviewed-by: Daniel Vetter > --- > drivers/gpu/drm/Kconfig| 4 > drivers/gpu/drm/drm_file.c | 42 ++ > include/drm/drm_file.h | 3 +++ > 3 files changed, 49 insertions(+) > > diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig > index 617d9c3a86c3..589d5d693855 100644 > --- a/drivers/gpu/drm/Kconfig > +++ b/drivers/gpu/drm/Kconfig > @@ -70,6 +70,10 @@ config DRM_DEBUG_SELFTEST > > If in doubt, say "N". > > +config DRM_DEBUG_SELFTEST_MODULE > + bool > + depends on DRM_DEBUG_SELFTEST > + > config DRM_KMS_HELPER > tristate > depends on DRM > diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c > index ea34bc991858..4d9385d1bf2d 100644 > --- a/drivers/gpu/drm/drm_file.c > +++ b/drivers/gpu/drm/drm_file.c > @@ -31,7 +31,9 @@ > * OTHER DEALINGS IN THE SOFTWARE. > */ > > +#include > #include > +#include > #include > #include > #include > @@ -754,3 +756,43 @@ void drm_send_event(struct drm_device *dev, struct > drm_pending_event *e) > spin_unlock_irqrestore(&dev->event_lock, irqflags); > } > EXPORT_SYMBOL(drm_send_event); > + > +/** > + * mock_drm_getfile - Create a new struct file for the drm device > + * @minor: drm minor to wrap (e.g. #drm_device.primary) > + * @flags: file creation mode (O_RDWR etc) > + * > + * This create a new struct file that wraps a DRM file context around a > + * DRM minor. This mimicks userspace opening e.g. /dev/dri/card0, but without > + * invoking userspace. The struct file may be operated on using its f_op > + * (the drm_device.driver.fops) to mimick userspace operations, or be > supplied > + * to userspace facing functions as an internal/anonymous client. > + * > + * RETURNS: > + * Pointer to newly created struct file, ERR_PTR on failure. > + */ > +struct file *mock_drm_getfile(struct drm_minor *minor, unsigned int flags) > +{ > + struct drm_device *dev = minor->dev; > + struct drm_file *priv; > + struct file *file; > + > + priv = drm_file_alloc(minor); > + if (IS_ERR(priv)) > + return ERR_CAST(priv); > + > + file = anon_inode_getfile("drm", dev->driver->fops, priv, flags); > + if (IS_ERR(file)) { > + drm_file_free(priv); > + return file; > + } > + > + /* Everyone shares a single global address space */ > + file->f_mapping = dev->anon_inode->i_mapping; > + > + drm_dev_get(dev); > + priv->filp = file; > + > + return file; > +} > +EXPORT_SYMBOL_FOR_TESTS_ONLY(mock_drm_getfile); > diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h > index 67af60bb527a..8b099b347817 100644 > --- a/include/drm/drm_file.h > +++ b/include/drm/drm_file.h > @@ -42,6 +42,7 @@ struct dma_fence; > struct drm_file; > struct drm_device; > struct device; > +struct file; > > /* > * FIXME: Not sure we want to have drm_minor here in the end, but to avoid > @@ -387,4 +388,6 @@ void drm_event_cancel_free(struct drm_device *dev, > void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event > *e); > void drm_send_event(struct drm_device *dev, struct drm_pending_event *e); > > +struct file *mock_drm_getfile(struct drm_minor *minor, unsigned int flags); > + > #endif /* _DRM_FILE_H_ */ > -- > 2.24.0 > -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 1/5] drm: Move EXPORT_SYMBOL_FOR_TESTS_ONLY under a separate Kconfig
Currently, we only export symbols for drm-selftests which are either compiled as modules or into the main drm builtin. However, if we want to export symbols from drm.ko for the drivers' selftests, we require a means of controlling that export separately. So we add a new Kconfig to determine whether or not the EXPORT_SYMBOL_FOR_TESTS_ONLY() takes effect. Signed-off-by: Chris Wilson Cc: Daniel Vetter --- drivers/gpu/drm/Kconfig | 4 include/drm/drm_util.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 617d9c3a86c3..d3560afe34d3 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -54,6 +54,9 @@ config DRM_DEBUG_MM If in doubt, say "N". +config DRM_EXPORT_FOR_TESTS + bool + config DRM_DEBUG_SELFTEST tristate "kselftests for DRM" depends on DRM @@ -61,6 +64,7 @@ config DRM_DEBUG_SELFTEST select PRIME_NUMBERS select DRM_LIB_RANDOM select DRM_KMS_HELPER + select DRM_EXPORT_FOR_TESTS if m default n help This option provides kernel modules that can be used to run diff --git a/include/drm/drm_util.h b/include/drm/drm_util.h index 07b8e9f04599..79952d8c4bba 100644 --- a/include/drm/drm_util.h +++ b/include/drm/drm_util.h @@ -41,7 +41,7 @@ * Use EXPORT_SYMBOL_FOR_TESTS_ONLY() for functions that shall * only be visible for drmselftests. */ -#if defined(CONFIG_DRM_DEBUG_SELFTEST_MODULE) +#if defined(CONFIG_DRM_EXPORT_FOR_TESTS) #define EXPORT_SYMBOL_FOR_TESTS_ONLY(x) EXPORT_SYMBOL(x) #else #define EXPORT_SYMBOL_FOR_TESTS_ONLY(x) -- 2.24.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 2/5] drm: Expose a method for creating anonymous struct file around drm_minor
Sometimes we need to create a struct file to wrap a drm_device, as it the user were to have opened /dev/dri/card0 but to do so anonymously (i.e. for internal use). Provide a utility method to create a struct file with the drm_device->driver.fops, that wrap the drm_device. v2: Restrict usage to selftests Signed-off-by: Chris Wilson Cc: Daniel Vetter --- drivers/gpu/drm/drm_file.c | 42 ++ include/drm/drm_file.h | 3 +++ 2 files changed, 45 insertions(+) diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c index ea34bc991858..4d9385d1bf2d 100644 --- a/drivers/gpu/drm/drm_file.c +++ b/drivers/gpu/drm/drm_file.c @@ -31,7 +31,9 @@ * OTHER DEALINGS IN THE SOFTWARE. */ +#include #include +#include #include #include #include @@ -754,3 +756,43 @@ void drm_send_event(struct drm_device *dev, struct drm_pending_event *e) spin_unlock_irqrestore(&dev->event_lock, irqflags); } EXPORT_SYMBOL(drm_send_event); + +/** + * mock_drm_getfile - Create a new struct file for the drm device + * @minor: drm minor to wrap (e.g. #drm_device.primary) + * @flags: file creation mode (O_RDWR etc) + * + * This create a new struct file that wraps a DRM file context around a + * DRM minor. This mimicks userspace opening e.g. /dev/dri/card0, but without + * invoking userspace. The struct file may be operated on using its f_op + * (the drm_device.driver.fops) to mimick userspace operations, or be supplied + * to userspace facing functions as an internal/anonymous client. + * + * RETURNS: + * Pointer to newly created struct file, ERR_PTR on failure. + */ +struct file *mock_drm_getfile(struct drm_minor *minor, unsigned int flags) +{ + struct drm_device *dev = minor->dev; + struct drm_file *priv; + struct file *file; + + priv = drm_file_alloc(minor); + if (IS_ERR(priv)) + return ERR_CAST(priv); + + file = anon_inode_getfile("drm", dev->driver->fops, priv, flags); + if (IS_ERR(file)) { + drm_file_free(priv); + return file; + } + + /* Everyone shares a single global address space */ + file->f_mapping = dev->anon_inode->i_mapping; + + drm_dev_get(dev); + priv->filp = file; + + return file; +} +EXPORT_SYMBOL_FOR_TESTS_ONLY(mock_drm_getfile); diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h index 67af60bb527a..8b099b347817 100644 --- a/include/drm/drm_file.h +++ b/include/drm/drm_file.h @@ -42,6 +42,7 @@ struct dma_fence; struct drm_file; struct drm_device; struct device; +struct file; /* * FIXME: Not sure we want to have drm_minor here in the end, but to avoid @@ -387,4 +388,6 @@ void drm_event_cancel_free(struct drm_device *dev, void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e); void drm_send_event(struct drm_device *dev, struct drm_pending_event *e); +struct file *mock_drm_getfile(struct drm_minor *minor, unsigned int flags); + #endif /* _DRM_FILE_H_ */ -- 2.24.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 3/5] drm/i915/selftests: Replace mock_file hackery with drm's true fake
As drm now exports a method to create an anonymous struct file around a drm_device for internal use, make use of it to avoid our horrible hacks. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/Kconfig.debug| 2 + .../gpu/drm/i915/gem/selftests/huge_pages.c | 2 +- .../drm/i915/gem/selftests/i915_gem_context.c | 12 ++--- .../i915/gem/selftests/i915_gem_object_blt.c | 4 +- drivers/gpu/drm/i915/gt/selftest_context.c| 4 +- drivers/gpu/drm/i915/gt/selftest_hangcheck.c | 8 +-- .../gpu/drm/i915/gt/selftest_workarounds.c| 2 +- drivers/gpu/drm/i915/selftests/i915_gem.c | 4 +- .../gpu/drm/i915/selftests/i915_gem_evict.c | 2 +- drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 4 +- drivers/gpu/drm/i915/selftests/i915_request.c | 2 +- .../drm/i915/selftests/intel_memory_region.c | 2 +- drivers/gpu/drm/i915/selftests/mock_drm.c | 49 +++ drivers/gpu/drm/i915/selftests/mock_drm.h | 8 ++- 14 files changed, 39 insertions(+), 66 deletions(-) diff --git a/drivers/gpu/drm/i915/Kconfig.debug b/drivers/gpu/drm/i915/Kconfig.debug index ef123eb29168..1140525da75a 100644 --- a/drivers/gpu/drm/i915/Kconfig.debug +++ b/drivers/gpu/drm/i915/Kconfig.debug @@ -37,6 +37,7 @@ config DRM_I915_DEBUG select X86_MSR # used by igt/pm_rpm select DRM_VGEM # used by igt/prime_vgem (dmabuf interop checks) select DRM_DEBUG_MM if DRM=y + select DRM_EXPORT_FOR_TESTS if m select DRM_DEBUG_SELFTEST select DMABUF_SELFTESTS select SW_SYNC # signaling validation framework (igt/syncobj*) @@ -160,6 +161,7 @@ config DRM_I915_SELFTEST bool "Enable selftests upon driver load" depends on DRM_I915 default n + select DRM_EXPORT_FOR_TESTS if m select FAULT_INJECTION select PRIME_NUMBERS help diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c index 688c49a24f32..06dad7b0db82 100644 --- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c +++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c @@ -1944,6 +1944,6 @@ int i915_gem_huge_page_live_selftests(struct drm_i915_private *i915) err = i915_subtests(tests, ctx); out_file: - mock_file_free(i915, file); + mock_file_put(file); return err; } diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c index 62fabc023a83..47890c92534c 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c @@ -149,7 +149,7 @@ static int live_nop_switch(void *arg) } out_file: - mock_file_free(i915, file); + mock_file_put(file); return err; } @@ -377,7 +377,7 @@ static int live_parallel_switch(void *arg) } kfree(data); out_file: - mock_file_free(i915, file); + mock_file_put(file); return err; } @@ -716,7 +716,7 @@ static int igt_ctx_exec(void *arg) if (igt_live_test_end(&t)) err = -EIO; - mock_file_free(i915, file); + mock_file_put(file); if (err) return err; @@ -854,7 +854,7 @@ static int igt_shared_ctx_exec(void *arg) if (igt_live_test_end(&t)) err = -EIO; out_file: - mock_file_free(i915, file); + mock_file_put(file); return err; } @@ -1426,7 +1426,7 @@ static int igt_ctx_readonly(void *arg) if (igt_live_test_end(&t)) err = -EIO; - mock_file_free(i915, file); + mock_file_put(file); return err; } @@ -1750,7 +1750,7 @@ static int igt_vm_isolation(void *arg) out_file: if (igt_live_test_end(&t)) err = -EIO; - mock_file_free(i915, file); + mock_file_put(file); return err; } diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_object_blt.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_object_blt.c index e8132aca0bb6..d9fdfddb7091 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_object_blt.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_object_blt.c @@ -301,7 +301,7 @@ static int igt_fill_blt_thread(void *arg) intel_context_put(ce); out_file: - mock_file_free(i915, file); + mock_file_put(file); return err; } @@ -432,7 +432,7 @@ static int igt_copy_blt_thread(void *arg) intel_context_put(ce); out_file: - mock_file_free(i915, file); + mock_file_put(file); return err; } diff --git a/drivers/gpu/drm/i915/gt/selftest_context.c b/drivers/gpu/drm/i915/gt/selftest_context.c index bc720defc6b8..a5688f7d9073 100644 --- a/drivers/gpu/drm/i915/gt/selftest_context.c +++ b/drivers/gpu/drm/i915/gt/selftest_context.c @@ -313,7 +313,7 @@ static int live_active_context(void *arg) } out_file: - mock_file_free(gt->i915, file