The double-buffered cursor image is currently stored in video memory by creating two BOs and pinning them to VRAM. The exact location is chosen by VRAM helpers. Since the driver has no control over BO placement, pinned cursor BOs can conflict with framebuffer BOs and prevent the primary plane from displaying its framebuffer. As a first step to solving this problem, we reserve dedicated space at the high end of the video memory for the cursor images. As the amount of video memory now differs from the amount of available framebuffer memory, size tests are performed against the VRAM helper's framebuffer limits. Signed-off-by: Thomas Zimmermann <tzimmermann@xxxxxxx> --- drivers/gpu/drm/mgag200/mgag200_main.c | 2 +- drivers/gpu/drm/mgag200/mgag200_mode.c | 2 +- drivers/gpu/drm/mgag200/mgag200_ttm.c | 15 ++++++++++++++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c index 2b59280777a5..4b8686e9a276 100644 --- a/drivers/gpu/drm/mgag200/mgag200_main.c +++ b/drivers/gpu/drm/mgag200/mgag200_main.c @@ -159,7 +159,7 @@ int mgag200_driver_load(struct drm_device *dev, unsigned long flags) drm_mode_config_init(dev); dev->mode_config.funcs = (void *)&mga_mode_funcs; - if (IS_G200_SE(mdev) && mdev->mc.vram_size < (2048*1024)) + if (IS_G200_SE(mdev) && dev->vram_mm->vram_size < (2048*1024)) dev->mode_config.preferred_depth = 16; else dev->mode_config.preferred_depth = 32; diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index 0cf5608c3644..2ac66a2270bb 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -1629,7 +1629,7 @@ static enum drm_mode_status mga_vga_mode_valid(struct drm_connector *connector, bpp = connector->cmdline_mode.bpp; } - if ((mode->hdisplay * mode->vdisplay * (bpp/8)) > mdev->mc.vram_size) { + if ((mode->hdisplay * mode->vdisplay * (bpp/8)) > dev->vram_mm->vram_size) { if (connector->cmdline_mode.specified) connector->cmdline_mode.specified = false; return MODE_BAD; diff --git a/drivers/gpu/drm/mgag200/mgag200_ttm.c b/drivers/gpu/drm/mgag200/mgag200_ttm.c index 69c81ebf3745..1df8504c6cab 100644 --- a/drivers/gpu/drm/mgag200/mgag200_ttm.c +++ b/drivers/gpu/drm/mgag200/mgag200_ttm.c @@ -32,12 +32,25 @@ int mgag200_mm_init(struct mga_device *mdev) { + unsigned long cursor_framesize, cursor_nframes, cursor_size; + unsigned long framebuffer_size; struct drm_vram_mm *vmm; int ret; struct drm_device *dev = mdev->dev; + /* At the high end of video memory, we reserve space for + * two cursor images. The cursor plane uses this memory to + * store a double-buffered image of the current cursor. + */ + + cursor_framesize = roundup(64 * 48, 1024); + cursor_nframes = 2; + cursor_size = roundup(cursor_framesize * cursor_nframes, PAGE_SIZE); + + framebuffer_size = (mdev->mc.vram_size - cursor_size) & PAGE_MASK; + vmm = drm_vram_helper_alloc_mm(dev, pci_resource_start(dev->pdev, 0), - mdev->mc.vram_size); + framebuffer_size); if (IS_ERR(vmm)) { ret = PTR_ERR(vmm); DRM_ERROR("Error initializing VRAM MM; %d\n", ret); -- 2.23.0