mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-21 02:01:38 +00:00
intel/display: support force_* and configured mode
Up to now, when using force_*, all other configured modes of a connector got overwritten and the force_* got enforced. With the commit, the connector mode is considered (if below max_*) and the resulting framebuffer may be larger then the dimension of force_*.
This commit is contained in:
parent
ab91750869
commit
9b312054f5
@ -304,7 +304,7 @@ append_if $use_top boot_modules { top }
|
||||
build_boot_image $boot_modules
|
||||
|
||||
if { [get_cmd_switch --autopilot] } {
|
||||
run_genode_until {\[init -\> init_dynamic -\> intel_fb_drv\] HDMI-A-2: enable.*} 30
|
||||
run_genode_until {\[init -\> init_dynamic -\> intel_fb_drv\] HDMI-A-2: enable.*} 30
|
||||
} else {
|
||||
run_genode_until forever
|
||||
}
|
||||
|
@ -17,6 +17,8 @@
|
||||
struct genode_mode {
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
unsigned force_width;
|
||||
unsigned force_height;
|
||||
unsigned max_width;
|
||||
unsigned max_height;
|
||||
unsigned hz;
|
||||
|
@ -59,14 +59,22 @@ static inline bool mode_larger(struct drm_display_mode const * const x,
|
||||
}
|
||||
|
||||
|
||||
static inline bool conf_smaller_mode(struct genode_mode const * const g,
|
||||
struct drm_display_mode const * const p)
|
||||
static inline bool conf_smaller_max_mode(struct genode_mode const * const g,
|
||||
struct drm_display_mode const * const p)
|
||||
{
|
||||
return (uint64_t)g->max_width * (uint64_t)g->max_height <
|
||||
(uint64_t)p->hdisplay * (uint64_t)p->vdisplay;
|
||||
}
|
||||
|
||||
|
||||
static inline bool conf_larger_mode(struct genode_mode const * const g,
|
||||
struct drm_display_mode const * const p)
|
||||
{
|
||||
return (uint64_t)g->width * (uint64_t)g->height >
|
||||
(uint64_t)p->hdisplay * (uint64_t)p->vdisplay;
|
||||
}
|
||||
|
||||
|
||||
static inline bool fb_smaller_mode(struct fb_info const * const info,
|
||||
struct drm_display_mode const * const mode)
|
||||
{
|
||||
@ -135,18 +143,34 @@ static void preferred_mode(struct drm_device const * const dev,
|
||||
if (mode_id && mode_larger(&smallest, min_mode))
|
||||
*min_mode = smallest;
|
||||
|
||||
if (conf_mode.force_width && conf_mode.force_height) {
|
||||
/*
|
||||
* Even so the force_* mode is selected, a configured mode for
|
||||
* a connector is considered, effectively the framebuffer content
|
||||
* will be shown smaller in the upper corner of the monitor
|
||||
*/
|
||||
if (conf_larger_mode(&conf_mode, min_mode)) {
|
||||
min_mode->hdisplay = conf_mode.width;
|
||||
min_mode->vdisplay = conf_mode.height;
|
||||
}
|
||||
|
||||
/* enforce the force mode */
|
||||
conf_mode.width = conf_mode.force_width;
|
||||
conf_mode.height = conf_mode.force_height;
|
||||
}
|
||||
|
||||
/* maximal resolution enforcement */
|
||||
if (conf_mode.max_width && conf_mode.max_height) {
|
||||
max_enforcement.hdisplay = conf_mode.max_width;
|
||||
max_enforcement.vdisplay = conf_mode.max_height;
|
||||
if (conf_smaller_mode(&conf_mode, prefer))
|
||||
if (conf_smaller_max_mode(&conf_mode, prefer))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!conf_mode.width || !conf_mode.height)
|
||||
continue;
|
||||
|
||||
if (!conf_smaller_mode(&conf_mode, prefer)) {
|
||||
if (conf_larger_mode(&conf_mode, prefer)) {
|
||||
prefer->hdisplay = conf_mode.width;
|
||||
prefer->vdisplay = conf_mode.height;
|
||||
}
|
||||
@ -232,7 +256,7 @@ static bool reconfigure(struct drm_client_dev * const dev)
|
||||
|
||||
struct drm_display_mode mode_preferred = {};
|
||||
struct drm_display_mode mode_minimum = {};
|
||||
struct drm_display_mode mode_real = {};
|
||||
struct drm_display_mode framebuffer = {};
|
||||
struct drm_mode_modeinfo user_mode = {};
|
||||
struct drm_display_mode *mode = NULL;
|
||||
struct drm_mode_set *mode_set = NULL;
|
||||
@ -256,22 +280,21 @@ static bool reconfigure(struct drm_client_dev * const dev)
|
||||
mode_preferred = mode_minimum;
|
||||
}
|
||||
|
||||
|
||||
if (mode_larger(&mode_preferred, &mode_minimum))
|
||||
mode_real = mode_preferred;
|
||||
framebuffer = mode_preferred;
|
||||
else
|
||||
mode_real = mode_minimum;
|
||||
framebuffer = mode_minimum;
|
||||
|
||||
{
|
||||
int const err = check_resize_fb(dev,
|
||||
&gem_dumb,
|
||||
&dumb_fb,
|
||||
mode_real.hdisplay,
|
||||
mode_real.vdisplay);
|
||||
framebuffer.hdisplay,
|
||||
framebuffer.vdisplay);
|
||||
|
||||
if (err) {
|
||||
printk("setting up framebuffer of %ux%u failed - error=%d\n",
|
||||
mode_real.hdisplay, mode_real.vdisplay, err);
|
||||
framebuffer.hdisplay, framebuffer.vdisplay, err);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -282,8 +305,8 @@ static bool reconfigure(struct drm_client_dev * const dev)
|
||||
return retry;
|
||||
|
||||
/* prepare fb info for register_framebuffer() evaluated by Genode side */
|
||||
report_fb_info.var.xres = mode_real.hdisplay;
|
||||
report_fb_info.var.yres = mode_real.vdisplay;
|
||||
report_fb_info.var.xres = framebuffer.hdisplay;
|
||||
report_fb_info.var.yres = framebuffer.vdisplay;
|
||||
report_fb_info.var.xres_virtual = mode_preferred.hdisplay;
|
||||
report_fb_info.var.yres_virtual = mode_preferred.vdisplay;
|
||||
|
||||
@ -397,12 +420,14 @@ static bool reconfigure(struct drm_client_dev * const dev)
|
||||
}
|
||||
|
||||
/* diagnostics */
|
||||
printk("%s: %s name='%s' id=%u %ux%u@%u%s",
|
||||
printk("%10s: %s name='%9s' id=%u%s mode=%4ux%4u@%u%s fb=%4ux%4u%s",
|
||||
connector->name ? connector->name : "unnamed",
|
||||
conf_mode.enabled ? " enable" : "disable",
|
||||
mode->name ? mode->name : "noname",
|
||||
mode_id, mode->hdisplay,
|
||||
mode_id, mode_id < 10 ? " " : "", mode->hdisplay,
|
||||
mode->vdisplay, drm_mode_vrefresh(mode),
|
||||
drm_mode_vrefresh(mode) < 100 ? " ": "",
|
||||
framebuffer.hdisplay, framebuffer.vdisplay,
|
||||
(err || no_match) ? "" : "\n");
|
||||
|
||||
if (no_match)
|
||||
@ -512,7 +537,7 @@ void lx_emul_i915_iterate_modes(void * lx_data, void * genode_data)
|
||||
.preferred = mode->type & (DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DEFAULT),
|
||||
.hz = drm_mode_vrefresh(mode),
|
||||
.id = mode_id,
|
||||
.enabled = !max_mode || !conf_smaller_mode(&conf_max_mode, mode)
|
||||
.enabled = !max_mode || !conf_smaller_max_mode(&conf_max_mode, mode)
|
||||
};
|
||||
|
||||
static_assert(sizeof(conf_mode.name) == DRM_DISPLAY_MODE_LEN);
|
||||
|
@ -256,12 +256,9 @@ void Framebuffer::Driver::lookup_config(char const * const name,
|
||||
mode.id = node.attribute_value("mode_id", 0U);
|
||||
});
|
||||
|
||||
mode.preferred = false;
|
||||
with_force([&](unsigned const width, unsigned const height) {
|
||||
mode.preferred = true;
|
||||
mode.width = width;
|
||||
mode.height = height;
|
||||
mode.id = 0;
|
||||
mode.force_width = width;
|
||||
mode.force_height = height;
|
||||
});
|
||||
|
||||
with_max_enforcement([&](unsigned const width, unsigned const height) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user