intel/display: support larger resolutions

- fix detection to re-allocate framebuffer
- free up resources on framebuffer switching

Thanks Peter for reporting and fixing.
This commit is contained in:
Alexander Boettcher 2024-01-08 15:58:14 +01:00 committed by Christian Helmuth
parent 25c7204b2a
commit 27c9825bf0
3 changed files with 50 additions and 38 deletions

View File

@ -5,7 +5,7 @@
*/ */
/* /*
* Copyright (C) 2021-2022 Genode Labs GmbH * Copyright (C) 2021-2024 Genode Labs GmbH
* *
* This file is distributed under the terms of the GNU General Public License * This file is distributed under the terms of the GNU General Public License
* version 2. * version 2.
@ -820,3 +820,27 @@ void devm_pinctrl_put(struct pinctrl * p)
{ {
lx_emul_trace(__func__); lx_emul_trace(__func__);
} }
void check_move_unevictable_pages(struct pagevec * pvec)
{
lx_emul_trace(__func__);
}
void intel_gt_flush_ggtt_writes(struct intel_gt * gt)
{
lx_emul_trace(__func__);
}
void intel_gt_invalidate_tlb(struct intel_gt * gt,u32 seqno)
{
lx_emul_trace(__func__);
}
void mark_page_accessed(struct page * page)
{
lx_emul_trace(__func__);
}

View File

@ -236,14 +236,6 @@ void bust_spinlocks(int yes)
} }
#include <linux/swap.h>
void check_move_unevictable_pages(struct pagevec * pvec)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/pagemap.h> #include <linux/pagemap.h>
bool clear_page_dirty_for_io(struct page * page) bool clear_page_dirty_for_io(struct page * page)
@ -1224,20 +1216,6 @@ void intel_gt_driver_unregister(struct intel_gt * gt)
} }
extern void intel_gt_flush_ggtt_writes(struct intel_gt * gt);
void intel_gt_flush_ggtt_writes(struct intel_gt * gt)
{
lx_emul_trace_and_stop(__func__);
}
extern void intel_gt_invalidate_tlb(struct intel_gt * gt,u32 seqno);
void intel_gt_invalidate_tlb(struct intel_gt * gt,u32 seqno)
{
lx_emul_trace_and_stop(__func__);
}
extern u32 intel_gt_mcr_read_any(struct intel_gt * gt,i915_reg_t reg); extern u32 intel_gt_mcr_read_any(struct intel_gt * gt,i915_reg_t reg);
u32 intel_gt_mcr_read_any(struct intel_gt * gt,i915_reg_t reg) u32 intel_gt_mcr_read_any(struct intel_gt * gt,i915_reg_t reg)
{ {
@ -1586,14 +1564,6 @@ void kmsg_dump(enum kmsg_dump_reason reason)
} }
#include <linux/swap.h>
void mark_page_accessed(struct page * page)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/io.h> #include <linux/io.h>
void memunmap(void * addr) void memunmap(void * addr)

View File

@ -5,7 +5,7 @@
*/ */
/* /*
* Copyright (C) 2022-2023 Genode Labs GmbH * Copyright (C) 2022-2024 Genode Labs GmbH
* *
* This file is distributed under the terms of the GNU General Public License * This file is distributed under the terms of the GNU General Public License
* version 2. * version 2.
@ -602,13 +602,16 @@ static int fb_client_hotplug(struct drm_client_dev *client)
if (result) { if (result) {
printk("%s: error on modeset commit %d%s\n", __func__, result, printk("%s: error on modeset commit %d%s\n", __func__, result,
(result == -ENOSPC) ? " - insufficient amount of RAM for framebuffer" : ""); (result == -ENOSPC) ? " - ENOSPC" : " - unknown error");
} }
} }
/* notify Genode side */ /* notify Genode side */
lx_emul_i915_hotplug_connector(client); lx_emul_i915_hotplug_connector(client);
if (fb)
drm_framebuffer_put(fb);
return result; return result;
} }
@ -694,8 +697,8 @@ static int user_register_fb(struct drm_client_dev const * const dev,
int result = -EINVAL; int result = -EINVAL;
struct i915_gtt_view const view = { .type = I915_GTT_VIEW_NORMAL }; struct i915_gtt_view const view = { .type = I915_GTT_VIEW_NORMAL };
unsigned long flags = 0; static struct i915_vma *vma = NULL;
struct i915_vma *vma = NULL; static unsigned long flags = 0;
void __iomem *vaddr = NULL; void __iomem *vaddr = NULL;
struct drm_i915_private *dev_priv = to_i915(dev->dev); struct drm_i915_private *dev_priv = to_i915(dev->dev);
struct drm_framebuffer *fb = drm_framebuffer_lookup(dev->dev, struct drm_framebuffer *fb = drm_framebuffer_lookup(dev->dev,
@ -709,6 +712,13 @@ static int user_register_fb(struct drm_client_dev const * const dev,
wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm); wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
if (vma) {
intel_unpin_fb_vma(vma, flags);
vma = NULL;
flags = 0;
}
/* Pin the GGTT vma for our access via info->screen_base. /* Pin the GGTT vma for our access via info->screen_base.
* This also validates that any existing fb inherited from the * This also validates that any existing fb inherited from the
* BIOS is suitable for own access. * BIOS is suitable for own access.
@ -744,6 +754,9 @@ static int user_register_fb(struct drm_client_dev const * const dev,
register_framebuffer(info); register_framebuffer(info);
if (fb)
drm_framebuffer_put(fb);
return 0; return 0;
} }
@ -762,13 +775,18 @@ static int check_resize_fb(struct drm_client_dev * const dev,
/* if requested size is smaller, free up current dumb buffer */ /* if requested size is smaller, free up current dumb buffer */
if (gem_dumb->width && gem_dumb->height && if (gem_dumb->width && gem_dumb->height &&
gem_dumb->width * gem_dumb->height < width * height) { (gem_dumb->width < width || gem_dumb->height < height)) {
result = drm_mode_rmfb(dev->dev, dumb_fb->fb_id, dev->file);
if (result) {
drm_err(dev->dev, "%s: failed to remove framebufer %d\n",
__func__, result);
}
result = drm_mode_destroy_dumb(dev->dev, gem_dumb->handle, dev->file); result = drm_mode_destroy_dumb(dev->dev, gem_dumb->handle, dev->file);
if (result) { if (result) {
drm_err(dev->dev, "%s: failed to destroy framebuffer %d\n", drm_err(dev->dev, "%s: failed to destroy framebuffer %d\n",
__func__, result); __func__, result);
return result;
} }
memset(gem_dumb, 0, sizeof(*gem_dumb)); memset(gem_dumb, 0, sizeof(*gem_dumb));
@ -792,7 +810,7 @@ static int check_resize_fb(struct drm_client_dev * const dev,
} }
} }
/* bind framwbuffer(GEM object) to drm client */ /* bind framebuffer(GEM object) to drm client */
if (!dumb_fb->width && !dumb_fb->height) { if (!dumb_fb->width && !dumb_fb->height) {
/* .fb_id <- written by kernel */ /* .fb_id <- written by kernel */
dumb_fb->width = gem_dumb->width, dumb_fb->width = gem_dumb->width,