intel/display: enable panel self refresh support

Fixes #5339
This commit is contained in:
Alexander Boettcher 2024-09-02 14:03:36 +02:00 committed by Norman Feske
parent 3ba8ddc85c
commit 0414e4929f
4 changed files with 62 additions and 11 deletions

View File

@ -26,10 +26,6 @@ if {$use_fb_controller} {
set apply_on_hotplug "yes" set apply_on_hotplug "yes"
} }
if {$use_usb} {
import_from_depot [depot_user]/src/pc_usb_host
}
import_from_depot [depot_user]/src/fs_rom \ import_from_depot [depot_user]/src/fs_rom \
[depot_user]/src/vfs \ [depot_user]/src/vfs \
[depot_user]/src/vfs_import \ [depot_user]/src/vfs_import \
@ -44,6 +40,7 @@ set build_components {
test/framebuffer test/framebuffer
} }
append_if $use_usb build_components { driver/usb_host }
append_if $use_gpu build_components { driver/gpu/intel } append_if $use_gpu build_components { driver/gpu/intel }
append_if $use_top build_components { app/top } append_if $use_top build_components { app/top }

View File

@ -105,9 +105,6 @@ int intel_root_gt_init_early(struct drm_i915_private * i915)
intel_uc_init_early(&gt->uc); intel_uc_init_early(&gt->uc);
/* disable panel self refresh (required for FUJITSU S937/S938) */
i915->params.enable_psr = 0;
/* /*
* Tells driver that IOMMU, e.g. VT-d, is on, so that scratch page * Tells driver that IOMMU, e.g. VT-d, is on, so that scratch page
* workaround is applied by Intel display driver: * workaround is applied by Intel display driver:

View File

@ -28,6 +28,7 @@
enum { MAX_BRIGHTNESS = 100, INVALID_BRIGHTNESS = MAX_BRIGHTNESS + 1 }; enum { MAX_BRIGHTNESS = 100, INVALID_BRIGHTNESS = MAX_BRIGHTNESS + 1 };
struct task_struct * lx_update_task = NULL;
struct task_struct * lx_user_task = NULL; struct task_struct * lx_user_task = NULL;
static struct drm_client_dev * dev_client = NULL; static struct drm_client_dev * dev_client = NULL;
@ -473,11 +474,53 @@ static int configure_connectors(void * data)
} }
void framebuffer_dirty(void)
{
struct drm_framebuffer *fb = NULL;
struct drm_clip_rect *clips = NULL;
struct drm_mode_fb_dirty_cmd r = { };
unsigned flags = 0;
int num_clips = 0;
int ret = 0;
if (!dev_client || !dumb_fb.fb_id)
return;
fb = drm_framebuffer_lookup(dev_client->dev, dev_client->file,
dumb_fb.fb_id);
if (!fb || !fb->funcs || !fb->funcs->dirty)
return;
ret = fb->funcs->dirty(fb, dev_client->file, flags, r.color, clips,
num_clips);
if (ret)
printk("%s failed %d\n", __func__, ret);
}
static int update_content(void *)
{
while (true) {
framebuffer_dirty();
lx_emul_task_schedule(true /* block task */);
}
return 0;
}
void lx_user_init(void) void lx_user_init(void)
{ {
int pid = kernel_thread(configure_connectors, NULL, "lx_user", int pid = kernel_thread(configure_connectors, NULL, "lx_user",
CLONE_FS | CLONE_FILES); CLONE_FS | CLONE_FILES);
lx_user_task = find_task_by_pid_ns(pid, NULL);; int pid2 = kernel_thread(update_content, NULL, "lx_update",
CLONE_FS | CLONE_FILES);
lx_user_task = find_task_by_pid_ns(pid, NULL);;
lx_update_task = find_task_by_pid_ns(pid2, NULL);;
} }
@ -598,11 +641,18 @@ static int fb_client_hotplug(struct drm_client_dev *client)
* commit the change. * commit the change.
*/ */
if (fb) { if (fb) {
bool mode_too_large = false;
mutex_lock(&client->modeset_mutex); mutex_lock(&client->modeset_mutex);
drm_client_for_each_modeset(modeset, client) { drm_client_for_each_modeset(modeset, client) {
if (!modeset || !modeset->num_connectors) if (!modeset || !modeset->num_connectors)
continue; continue;
if (!mode_too_large && modeset->mode &&
(modeset->mode->hdisplay > fb->width ||
modeset->mode->vdisplay > fb->height))
mode_too_large = true;
modeset->fb = fb; modeset->fb = fb;
} }
mutex_unlock(&client->modeset_mutex); mutex_unlock(&client->modeset_mutex);
@ -610,7 +660,7 @@ static int fb_client_hotplug(struct drm_client_dev *client)
/* triggers disablement of encoders attached to disconnected ports */ /* triggers disablement of encoders attached to disconnected ports */
result = drm_client_modeset_commit(client); result = drm_client_modeset_commit(client);
if (result) { if (result && !(mode_too_large && result == -ENOSPC)) {
printk("%s: error on modeset commit %d%s\n", __func__, result, printk("%s: error on modeset commit %d%s\n", __func__, result,
(result == -ENOSPC) ? " - ENOSPC" : " - unknown error"); (result == -ENOSPC) ? " - ENOSPC" : " - unknown error");
} }

View File

@ -33,6 +33,7 @@ extern "C" {
extern struct task_struct * lx_user_task; extern struct task_struct * lx_user_task;
extern struct task_struct * lx_update_task;
namespace Framebuffer { namespace Framebuffer {
@ -88,6 +89,12 @@ struct Framebuffer::Driver
using Pixel = Capture::Pixel; using Pixel = Capture::Pixel;
Surface<Pixel> surface((Pixel*)_base, _size_phys); Surface<Pixel> surface((Pixel*)_base, _size_phys);
_captured_screen.apply_to_surface(surface); _captured_screen.apply_to_surface(surface);
if (!lx_update_task)
return;
lx_emul_task_unblock(lx_update_task);
Lx_kit::env().scheduler.execute();
} }
Fb(Env & env, void * base, Capture::Area size, Fb(Env & env, void * base, Capture::Area size,