dde_linux: update intel_fb to 4.16.3

Fixes #2736
This commit is contained in:
Alexander Boettcher
2018-04-09 23:33:34 +02:00
committed by Christian Helmuth
parent 80104f5192
commit eb62d9cc04
25 changed files with 3582 additions and 1493 deletions

View File

@ -18,7 +18,7 @@ Each of the connector can be configured explicitly in terms of resolution and
whether it should be enabled or not. This looks like the following:
! <config>
! <connector name="LVDS-11" width="1280" height="800" enabled="true"/>
! <connector name="LVDS-11" width="1280" height="800" hz="60" brightness="75" enabled="true"/>
! </config>
When the configuration changes during run-time, the driver will adapt to it. In
@ -26,6 +26,9 @@ this case it will also change the current virtual resolution to the maximum of
the configured resolutions in width and height, and it will inform its client
about the change in resolution.
The brightness value is in percentage and takes effect only if supported by
the hardware.
If you experience problems like hotplugging of connectors does not work, you
can force the driver to poll frequently for hotplug events by defining a period
in milliseconds like this:
@ -46,10 +49,13 @@ configured too, like in the following:
The exported report has the following format:
! <connectors>
! <connector name="LVDS-11" connected="1">
! <connector name="LVDS-11" connected="1" brightness="50">
! <mode width="1280" height="800" hz="60"/>
! ...
! </connector>
! ...
! <connector name="HDMI-A-1" connected="false"/>
! <connector name="DP-1" connected="false"/>
! </connectors>
The brightness attribute is soley reported if the hardware supports it.

File diff suppressed because it is too large Load Diff

View File

@ -12,37 +12,40 @@
*/
#include <../drivers/gpu/drm/i915/i915_drv.h>
struct i915_params i915 = {
struct i915_params i915_modparams = {
.vbt_firmware = NULL,
.modeset = -1,
.panel_ignore_lid = 1,
.semaphores = -1,
.lvds_channel_mode = 0,
.panel_use_ssc = -1,
.vbt_sdvo_panel_type = -1,
.enable_rc6 = -1,
.enable_dc = -1,
.enable_fbc = -1,
.enable_execlists = -1,
.enable_hangcheck = false,
.enable_ppgtt = -1,
.enable_ppgtt = 0,
.enable_psr = 0,
.preliminary_hw_support = true,
.disable_power_well = -1,
.enable_ips = 1,
.fastboot = 0,
.prefault_disable = 0,
.load_detect_test = 0,
.reset = true,
.enable_ips = true,
.invert_brightness = 0,
.disable_display = 0,
.enable_cmd_parser = 1,
.disable_vtd_wa = 0,
.use_mmio_flip = 0,
.mmio_debug = 0,
.verbose_state_checks = 1,
.nuclear_pageflip = 0,
.edp_vswing = 0,
.enable_guc_submission = false,
.guc_log_level = -1,
.guc_firmware_path = NULL,
.huc_firmware_path = NULL,
.mmio_debug = 0,
.edp_vswing = 0,
.enable_guc = 0,
.reset = 0,
.inject_load_failure = 0,
.alpha_support = IS_ENABLED(CONFIG_DRM_I915_ALPHA_SUPPORT),
.enable_cmd_parser = true,
.enable_hangcheck = false,
.fastboot = false,
.prefault_disable = false,
.load_detect_test = false,
.force_reset_modeset_test = false,
.error_capture = true,
.disable_display = false,
.verbose_state_checks = true,
.nuclear_pageflip = false,
.enable_dp_mst = false,
.enable_dpcd_backlight = false,
.enable_gvt = false
};

View File

@ -53,7 +53,10 @@ class Framebuffer::Driver
Genode::Signal_handler<Driver> _poll_handler;
unsigned long _poll_ms = 0;
drm_display_mode * _preferred_mode(drm_connector *connector);
Genode::Signal_context_capability _config_sigh;
drm_display_mode * _preferred_mode(drm_connector *connector,
unsigned &brightness);
void _poll();
@ -74,6 +77,29 @@ class Framebuffer::Driver
void set_polling(unsigned long poll);
void update_mode();
void generate_report();
/**
* Register signal handler used for config updates
*
* The signal handler is artificially triggered as a side effect
* of connector changes.
*/
void config_sigh(Genode::Signal_context_capability sigh)
{
_config_sigh = sigh;
}
void trigger_reconfiguration()
{
/*
* Trigger the reprocessing of the configuration following the
* same ontrol flow as used for external config changes.
*/
if (_config_sigh.valid())
Genode::Signal_transmitter(_config_sigh).submit();
else
Genode::warning("config signal handler unexpectedly undefined");
}
};

File diff suppressed because it is too large Load Diff

View File

@ -54,6 +54,8 @@ void lx_c_set_mode(struct drm_device *, struct drm_connector *,
struct drm_framebuffer *, struct drm_display_mode *);
void lx_c_set_driver(struct drm_device *, void *);
void * lx_c_get_driver(struct drm_device *);
void lx_c_set_brightness(struct drm_connector *, unsigned, unsigned);
unsigned lx_c_get_brightness(struct drm_connector * const, unsigned);
#include <lx_emul/extern_c_end.h>

File diff suppressed because it is too large Load Diff

View File

@ -17,23 +17,14 @@
#include <../drivers/gpu/drm/i915/intel_drv.h>
#include <drm/drm_atomic_helper.h>
extern struct drm_framebuffer *
lx_c_intel_framebuffer_create(struct drm_device *dev,
struct drm_mode_fb_cmd2 *mode_cmd,
struct drm_i915_gem_object *obj);
int intel_sanitize_enable_execlists(struct drm_device *dev,
int enable_execlists)
{
if (INTEL_INFO(dev)->gen >= 9)
return 1;
return 0;
}
void lx_c_allocate_framebuffer(struct drm_device * dev,
struct lx_c_fb_config *c)
struct lx_c_fb_config *c)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_mode_fb_cmd2 * r;
@ -44,10 +35,12 @@ void lx_c_allocate_framebuffer(struct drm_device * dev,
/* for linear buffers the pitch needs to be 64 byte aligned */
c->pitch = roundup(c->width * c->bpp, 64);
c->size = roundup(c->pitch * c->height, PAGE_SIZE);
if (c->size * 2 < dev_priv->gtt.stolen_usable_size)
obj = i915_gem_object_create_stolen(dev, c->size);
obj = i915_gem_object_create_stolen(dev_priv, c->size);
if (obj == NULL)
obj = i915_gem_alloc_object(dev, c->size);
obj = i915_gem_object_create(dev_priv, c->size);
if (obj == NULL) goto out2;
r = (struct drm_mode_fb_cmd2*) kzalloc(sizeof(struct drm_mode_fb_cmd2), 0);
@ -56,37 +49,41 @@ void lx_c_allocate_framebuffer(struct drm_device * dev,
r->height = c->height;
r->pixel_format = DRM_FORMAT_RGB565;
r->pitches[0] = c->pitch;
c->lx_fb = lx_c_intel_framebuffer_create(dev, r, obj);
c->lx_fb = intel_framebuffer_create(obj, r);
if (IS_ERR(c->lx_fb)) goto err2;
if (intel_pin_and_fence_fb_obj(NULL, c->lx_fb, NULL, NULL, NULL))
/* XXX rotation info missing */
struct i915_vma * vma = intel_pin_and_fence_fb_obj(c->lx_fb, DRM_MODE_ROTATE_0);
if (IS_ERR(vma))
goto err1;
c->addr = ioremap_wc(dev_priv->gtt.mappable_base
+ i915_gem_obj_ggtt_offset(obj), c->size);
c->addr = ioremap_wc(dev_priv->ggtt.gmadr.start + i915_ggtt_offset(vma),
c->size);
memset_io(c->addr, 0, c->size);
/* intel_framebuffer_create inc ref, so dec since obj ptr is dropped now */
i915_gem_object_put(obj);
goto out1;
err1:
DRM_ERROR("could not allocate framebuffer %ld", (long)vma);
drm_framebuffer_remove(c->lx_fb);
err2:
c->lx_fb = NULL;
drm_gem_object_unreference(&obj->base);
i915_gem_object_put(obj);
out1:
kfree(r);
out2:
mutex_unlock(&dev->struct_mutex);
}
void lx_c_set_mode(struct drm_device * dev, struct drm_connector * connector,
struct drm_framebuffer *fb, struct drm_display_mode *mode)
struct drm_framebuffer *fb, struct drm_display_mode *mode)
{
struct drm_crtc *crtc = NULL;
struct drm_encoder *encoder = connector->encoder;
if (!mode) return;
struct drm_crtc * crtc = NULL;
struct drm_encoder * encoder = connector->encoder;
if (!encoder) {
struct drm_encoder *enc;
@ -109,28 +106,36 @@ void lx_c_set_mode(struct drm_device * dev, struct drm_connector * connector,
}
if (!encoder) {
DRM_DEBUG("Found no encoder for the connector %s\n", connector->name);
lx_printf("Found no encoder for the connector %s\n", connector->name);
return;
}
unsigned used_crtc = 0;
crtc = encoder->crtc;
if (!crtc) {
unsigned i = 0;
struct drm_crtc *c;
list_for_each_entry(c, &dev->mode_config.crtc_list, head) {
if (!(encoder->possible_crtcs & (1 << i))) continue;
if (c->state->enable) continue;
if (c->state->enable) {
used_crtc ++;
continue;
}
crtc = c;
break;
}
}
if (!crtc) {
DRM_DEBUG("Found no crtc for the connector %s\n", connector->name);
if (mode)
lx_printf("Found no crtc for the connector %s used/max %u+1/%u\n",
connector->name, used_crtc, dev->mode_config.num_crtc);
return;
}
DRM_DEBUG("set mode %s for connector %s\n", mode->name, connector->name);
DRM_DEBUG("%s%s for connector %s\n", mode ? "set mode " : "no mode",
mode ? mode->name : "", connector->name);
struct drm_mode_set set;
set.crtc = crtc;
@ -138,11 +143,15 @@ void lx_c_set_mode(struct drm_device * dev, struct drm_connector * connector,
set.y = 0;
set.mode = mode;
set.connectors = &connector;
set.num_connectors = 1;
set.fb = fb;
drm_atomic_helper_set_config(&set);
}
set.num_connectors = mode ? 1 : 0;
set.fb = mode ? fb : 0;
uint32_t const ref_cnt_before = drm_framebuffer_read_refcount(fb);
int ret = drm_atomic_helper_set_config(&set, dev->mode_config.acquire_ctx);
if (ret)
lx_printf("Error: set config failed ret=%d refcnt before=%u after=%u\n",
ret, ref_cnt_before, drm_framebuffer_read_refcount(fb));
}
void lx_c_set_driver(struct drm_device * dev, void * driver)
{
@ -157,3 +166,33 @@ void* lx_c_get_driver(struct drm_device * dev)
struct drm_i915_private *dev_priv = dev->dev_private;
return (void*) dev_priv->audio_component;
}
void lx_c_set_brightness(struct drm_connector * const connector,
unsigned const bn_set, unsigned const bn_max)
{
struct intel_connector * const c = to_intel_connector(connector);
intel_panel_set_backlight_acpi(c->base.state, bn_set, bn_max);
}
unsigned lx_c_get_brightness(struct drm_connector * const connector, unsigned error)
{
if (!connector)
return error;
struct intel_connector * const intel_c = to_intel_connector(connector);
if (!intel_c)
return error;
struct intel_panel *panel = &intel_c->panel;
if (!panel || !panel->backlight.device || !panel->backlight.device->ops ||
!panel->backlight.device->ops->get_brightness)
return error;
panel->backlight.device->connector = intel_c;
unsigned ret = panel->backlight.device->ops->get_brightness(panel->backlight.device);
panel->backlight.device->connector = NULL;
return ret;
}

View File

@ -33,8 +33,10 @@
#include <lx_kit/work.h>
/* Linux module functions */
extern "C" int postcore_i2c_init(); /* i2c-core.c */
extern "C" void postcore_i2c_init(void); /* i2c-core-base.c */
extern "C" int module_i915_init(); /* i915_drv.c */
extern "C" void radix_tree_init(); /* called by start_kernel(void) normally */
extern "C" void drm_connector_ida_init(); /* called by drm_core_init(void) normally */
static void run_linux(void * m);
@ -89,16 +91,25 @@ struct Main
struct Policy_agent
{
Main &main;
Genode::Signal_handler<Policy_agent> sd;
Genode::Signal_handler<Policy_agent> handler;
bool _pending = false;
void handle()
{
_pending = true;
main.linux_task().unblock();
Lx::scheduler().schedule();
}
bool pending()
{
bool ret = _pending;
_pending = false;
return ret;
}
Policy_agent(Main &m)
: main(m), sd(main.ep, *this, &Policy_agent::handle) {}
: main(m), handler(main.ep, *this, &Policy_agent::handle) {}
};
@ -106,17 +117,23 @@ static void run_linux(void * m)
{
Main * main = reinterpret_cast<Main*>(m);
system_wq = alloc_workqueue("system_wq", 0, 0);
radix_tree_init();
drm_connector_ida_init();
postcore_i2c_init();
module_i915_init();
main->root.session.driver().finish_initialization();
main->announce();
static Policy_agent pa(*main);
main->config.sigh(pa.sd);
Policy_agent pa(*main);
main->root.session.driver().config_sigh(pa.handler);
main->config.sigh(pa.handler);
while (1) {
Lx::scheduler().current()->block_and_schedule();
main->root.session.config_changed();
while (pa.pending())
main->root.session.config_changed();
}
}

View File

@ -22,3 +22,4 @@ vpath %.cc $(PRG_DIR)
vpath %.cc $(REP_DIR)/src/lx_kit
CC_CXX_WARN_STRICT =
CC_OPT += -Wno-narrowing

View File

@ -26,12 +26,15 @@ extern unsigned long jiffies;
enum {
JIFFIES_TICK_MS = 1000/HZ,
JIFFIES_TICK_US = 1000*1000/HZ,
JIFFIES_TICK_NS = 1000ULL*1000*1000/HZ,
};
static inline unsigned long msecs_to_jiffies(const unsigned int m) { return m / JIFFIES_TICK_MS; }
static inline unsigned int jiffies_to_msecs(const unsigned long j) { return j * JIFFIES_TICK_MS; }
static inline unsigned long usecs_to_jiffies(const unsigned int u) { return u / JIFFIES_TICK_US; }
static inline unsigned int jiffies_to_msecs(const unsigned long j) { return j * JIFFIES_TICK_MS; }
static inline u64 jiffies_to_nsecs(const unsigned long j) { return (u64)j * JIFFIES_TICK_NS; }
clock_t jiffies_to_clock_t(unsigned long x);
static inline clock_t jiffies_delta_to_clock_t(long delta)
{

View File

@ -20,6 +20,7 @@
#include <base/attached_rom_dataspace.h>
#include <util/xml_generator.h>
#include <util/xml_node.h>
#include <timer_session/connection.h>
using namespace Genode;
@ -31,19 +32,32 @@ struct Framebuffer_controller
Heap heap;
Allocator_avl fs_alloc;
File_system::Connection fs;
Timer::Connection timer;
Signal_handler<Framebuffer_controller> timer_handler;
void update_connector_config(Xml_generator & xml, Xml_node & node);
void update_fb_config(Xml_node & report);
void report_changed();
void handle_timer();
Framebuffer_controller(Env &env)
: rom(env, "connectors"),
rom_sigh(env.ep(), *this, &Framebuffer_controller::report_changed),
heap(env.ram(), env.rm()),
fs_alloc(&heap),
fs(env, fs_alloc, "", "/", true, 128*1024)
fs(env, fs_alloc, "", "/", true, 128*1024),
timer(env),
timer_handler(env.ep(), *this, &Framebuffer_controller::handle_timer)
{
Attached_rom_dataspace config(env, "config");
unsigned long const period_ms = config.xml().attribute_value("artifical_update_ms", 0UL);
rom.sigh(rom_sigh);
if (period_ms) {
timer.sigh(timer_handler);
timer.trigger_periodic(period_ms * 1000 /* in us */);
}
}
};
@ -59,20 +73,25 @@ void Framebuffer_controller::update_connector_config(Xml_generator & xml,
bool connected = node.attribute_value("connected", false);
xml.attribute("enabled", connected ? "true" : "false");
unsigned long width = 0, height = 0;
unsigned long width = 0, height = 0, hz = 0;
node.for_each_sub_node("mode", [&] (Xml_node &mode) {
unsigned long w, h;
unsigned long w, h, z;
w = mode.attribute_value<unsigned long>("width", 0);
h = mode.attribute_value<unsigned long>("height", 0);
if (w > width) {
z = mode.attribute_value<unsigned long>("hz", 0);
if (w >= width) {
width = w;
height = h;
if (z > hz)
hz = z;
}
});
if (width && height) {
xml.attribute("width", width);
xml.attribute("height", height);
xml.attribute("hz", hz);
xml.attribute("brightness", 73);
}
});
}
@ -84,6 +103,7 @@ void Framebuffer_controller::update_fb_config(Xml_node & report)
static char buf[4096];
Xml_generator xml(buf, sizeof(buf), "config", [&] {
// xml.attribute("poll", "5000");
xml.node("report", [&] {
xml.attribute("connectors", "yes");
});
@ -115,6 +135,17 @@ void Framebuffer_controller::report_changed()
}
void Framebuffer_controller::handle_timer()
{
if (!rom.is_valid())
return;
/* artificial update */
Xml_node report(rom.local_addr<char>(), rom.size());
update_fb_config(report);
}
void Component::construct(Genode::Env &env)
{
log("--- Framebuffer controller ---\n");