From 101d052ddb798201a9cf764068a6b7fee55fee8f Mon Sep 17 00:00:00 2001 From: Stefan Kalkowski Date: Fri, 17 Jun 2016 14:48:41 +0200 Subject: [PATCH] intel_fb_drv: consider aligned pitch value * Align pitch value to 64 byte (thanks to cnuke for investigation) * Get rid of extra dataspace retrival and attachment, now that we always buffer * Consistently name all lx_emul helpers: lx_* (get rid of dde*) * Add missing file headers Fix #1997 --- .../patches/intel_fb_export_api.patch | 4 +- repos/dde_linux/ports/dde_linux.hash | 2 +- .../src/drivers/framebuffer/intel/dummies.c | 2 +- .../drivers/framebuffer/intel/i915_params.c | 13 ++++ .../framebuffer/intel/include/component.h | 57 +++++++---------- .../framebuffer/intel/include/lx_emul_c.h | 60 ++++++++++++++++++ .../src/drivers/framebuffer/intel/lx_emul.cc | 60 ++++++++---------- .../src/drivers/framebuffer/intel/lx_emul_c.c | 63 +++++++++++-------- .../framebuffer/intel/lx_emul_private.h | 37 ----------- 9 files changed, 165 insertions(+), 133 deletions(-) create mode 100644 repos/dde_linux/src/drivers/framebuffer/intel/include/lx_emul_c.h delete mode 100644 repos/dde_linux/src/drivers/framebuffer/intel/lx_emul_private.h diff --git a/repos/dde_linux/patches/intel_fb_export_api.patch b/repos/dde_linux/patches/intel_fb_export_api.patch index 4b5fc0fd1..87e062608 100644 --- a/repos/dde_linux/patches/intel_fb_export_api.patch +++ b/repos/dde_linux/patches/intel_fb_export_api.patch @@ -8,9 +8,9 @@ index 32cf973..ec1d558 100644 } + +struct drm_framebuffer * -+dde_c_intel_framebuffer_create(struct drm_device *dev, ++lx_c_intel_framebuffer_create(struct drm_device *dev, + struct drm_mode_fb_cmd2 *mode_cmd, + struct drm_i915_gem_object *obj) { + return intel_framebuffer_create(dev, mode_cmd, obj); +} -+EXPORT_SYMBOL(dde_c_intel_framebuffer_create); ++EXPORT_SYMBOL(lx_c_intel_framebuffer_create); diff --git a/repos/dde_linux/ports/dde_linux.hash b/repos/dde_linux/ports/dde_linux.hash index c75bdb3fc..f8e3b5c36 100644 --- a/repos/dde_linux/ports/dde_linux.hash +++ b/repos/dde_linux/ports/dde_linux.hash @@ -1 +1 @@ -a226766f99897d980fa70f8bf24e09ad0c1d39ee +ccb3b82a7cc54d0beab20dcb4dcdc5edd0cb0385 diff --git a/repos/dde_linux/src/drivers/framebuffer/intel/dummies.c b/repos/dde_linux/src/drivers/framebuffer/intel/dummies.c index 76f056e04..2713fc214 100644 --- a/repos/dde_linux/src/drivers/framebuffer/intel/dummies.c +++ b/repos/dde_linux/src/drivers/framebuffer/intel/dummies.c @@ -1,5 +1,5 @@ -#include "lx_emul_private.h" #include +#include #include #include #include diff --git a/repos/dde_linux/src/drivers/framebuffer/intel/i915_params.c b/repos/dde_linux/src/drivers/framebuffer/intel/i915_params.c index 9ed3945c2..cfde3e88a 100644 --- a/repos/dde_linux/src/drivers/framebuffer/intel/i915_params.c +++ b/repos/dde_linux/src/drivers/framebuffer/intel/i915_params.c @@ -1,3 +1,16 @@ +/* + * \brief Linux emulation Intel i915 parameter struct definition + * \author Stefan Kalkowski + * \date 2016-03-22 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + #include <../drivers/gpu/drm/i915/i915_drv.h> struct i915_params i915 = { diff --git a/repos/dde_linux/src/drivers/framebuffer/intel/include/component.h b/repos/dde_linux/src/drivers/framebuffer/intel/include/component.h index 5c0bb2fd6..5dddfc0c2 100644 --- a/repos/dde_linux/src/drivers/framebuffer/intel/include/component.h +++ b/repos/dde_linux/src/drivers/framebuffer/intel/include/component.h @@ -27,9 +27,7 @@ #include #include -struct drm_display_mode; -struct drm_connector; -struct drm_framebuffer; +#include namespace Framebuffer { class Driver; @@ -42,14 +40,10 @@ class Framebuffer::Driver { private: - struct Configuration { - int height = 16; - int width = 64; - unsigned bpp = 2; - Genode::Dataspace_capability cap; - void * addr = nullptr; - Genode::size_t size = 0; - drm_framebuffer * lx_obj = nullptr; + struct Configuration + { + struct lx_c_fb_config _lx = { 16, 64, 64, 2, + nullptr, 0, nullptr }; } _config; Session_component &_session; @@ -67,11 +61,11 @@ class Framebuffer::Driver : _session(session), _timer(env), _poll_handler(env.ep(), *this, &Driver::_poll) {} - int width() const { return _config.width; } - int height() const { return _config.height; } - int bpp() const { return _config.bpp; } - Genode::Dataspace_capability dataspace() const { - return _config.cap; } + int width() const { return _config._lx.width; } + int height() const { return _config._lx.height; } + int bpp() const { return _config._lx.bpp; } + void * fb_addr() const { return _config._lx.addr; } + unsigned pitch() const { return _config._lx.pitch; } void finish_initialization(); void set_polling(unsigned long poll); @@ -90,9 +84,8 @@ class Framebuffer::Session_component : public Genode::Rpc_object Genode::Attached_rom_dataspace &_config; Genode::Signal_context_capability _mode_sigh; Timer::Connection _timer; - Lazy _fb_ds; Genode::Ram_session &_ram; - Genode::Attached_ram_dataspace _bb_ds; + Genode::Attached_ram_dataspace _ds; bool _in_mode_change = true; unsigned long _polling_from_config() { @@ -103,7 +96,7 @@ class Framebuffer::Session_component : public Genode::Rpc_object Session_component(Genode::Env &env, Genode::Attached_rom_dataspace &config) : _driver(env, *this), _config(config), _timer(env), - _ram(env.ram()), _bb_ds(env.ram(), env.rm(), 0) {} + _ram(env.ram()), _ds(env.ram(), env.rm(), 0) {} Driver & driver() { return _driver; } @@ -118,11 +111,6 @@ class Framebuffer::Session_component : public Genode::Rpc_object _driver.update_mode(); - if (_driver.dataspace().valid()) - _fb_ds.construct(_driver.dataspace()); - else - _fb_ds.destruct(); - if (_mode_sigh.valid()) Genode::Signal_transmitter(_mode_sigh).submit(); } @@ -136,9 +124,9 @@ class Framebuffer::Session_component : public Genode::Rpc_object Genode::Dataspace_capability dataspace() override { - _bb_ds.realloc(&_ram, _driver.width()*_driver.height()*_driver.bpp()); + _ds.realloc(&_ram, _driver.width()*_driver.height()*_driver.bpp()); _in_mode_change = false; - return _bb_ds.cap(); + return _ds.cap(); } Mode mode() const override { @@ -157,13 +145,14 @@ class Framebuffer::Session_component : public Genode::Rpc_object { using namespace Genode; - if (!_fb_ds.constructed() || - !_bb_ds.local_addr() || + if (!_driver.fb_addr() || + !_ds.local_addr() || _in_mode_change) return; - int width = _driver.width(); - int height = _driver.height(); - unsigned bpp = _driver.bpp(); + int width = _driver.width(); + int height = _driver.height(); + unsigned bpp = _driver.bpp(); + unsigned pitch = _driver.pitch(); /* clip specified coordinates against screen boundaries */ int x2 = min(x + w - 1, width - 1), @@ -173,10 +162,10 @@ class Framebuffer::Session_component : public Genode::Rpc_object if (x1 > x2 || y1 > y2) return; /* copy pixels from back buffer to physical frame buffer */ - char *src = _bb_ds.local_addr() + bpp*(width*y1 + x1), - *dst = _fb_ds->local_addr() + bpp*(width*y1 + x1); + char *src = _ds.local_addr() + bpp*(width*y1 + x1), + *dst = (char*)_driver.fb_addr() + pitch*y1 + bpp*x1; - blit(src, bpp*width, dst, bpp*width, + blit(src, bpp*width, dst, pitch, bpp*(x2 - x1 + 1), y2 - y1 + 1); } }; diff --git a/repos/dde_linux/src/drivers/framebuffer/intel/include/lx_emul_c.h b/repos/dde_linux/src/drivers/framebuffer/intel/include/lx_emul_c.h new file mode 100644 index 000000000..f54596e07 --- /dev/null +++ b/repos/dde_linux/src/drivers/framebuffer/intel/include/lx_emul_c.h @@ -0,0 +1,60 @@ +/* + * \brief C-declarations needed for device driver environment + * \author Stefan Kalkowski + * \author Norman Feske + * \date 2016-06-17 + */ + +#ifndef _LX_EMUL_C_H_ +#define _LX_EMUL_C_H_ + +#if 0 +#define TRACE \ + do { \ + lx_printf("%s not implemented\n", __func__); \ + } while (0) +#else +#define TRACE do { ; } while (0) +#endif + +#define TRACE_AND_STOP \ + do { \ + lx_printf("%s not implemented\n", __func__); \ + BUG(); \ + } while (0) + +#define ASSERT(x) \ + do { \ + if (!(x)) { \ + lx_printf("%s:%u assertion failed\n", __func__, __LINE__); \ + BUG(); \ + } \ + } while (0) + +#include + +struct drm_device; +struct drm_framebuffer; +struct drm_display_mode; +struct drm_connector; + +struct lx_c_fb_config { + int height; + int width; + unsigned pitch; + unsigned bpp; + void * addr; + unsigned long size; + struct drm_framebuffer * lx_fb; +}; + +void lx_c_allocate_framebuffer(struct drm_device *, + struct lx_c_fb_config *); +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 *); + +#include + +#endif /* _LX_EMUL_C_H_ */ diff --git a/repos/dde_linux/src/drivers/framebuffer/intel/lx_emul.cc b/repos/dde_linux/src/drivers/framebuffer/intel/lx_emul.cc index a723b2609..676ed02a6 100644 --- a/repos/dde_linux/src/drivers/framebuffer/intel/lx_emul.cc +++ b/repos/dde_linux/src/drivers/framebuffer/intel/lx_emul.cc @@ -5,6 +5,13 @@ * \date 2015-08-19 */ +/* + * Copyright (C) 2015-2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + /* Genode includes */ #include #include @@ -16,8 +23,8 @@ /* DRM-specific includes */ #include +#include #include -#include "lx_emul_private.h" #include #include #include @@ -36,16 +43,7 @@ #include #include -static struct drm_device * dde_drm_device = nullptr; - -extern "C" struct drm_framebuffer* -dde_c_allocate_framebuffer(int width, int height, void ** base, - uint64_t * size, struct drm_device * dev); -extern "C" void -dde_c_set_mode(struct drm_device * dev, struct drm_connector * connector, - struct drm_framebuffer *fb, struct drm_display_mode *mode); -extern "C" void dde_c_set_driver(struct drm_device * dev, void * driver); -extern "C" void* dde_c_get_driver(struct drm_device * dev); +static struct drm_device * lx_drm_device = nullptr; struct Drm_guard @@ -73,7 +71,7 @@ struct Drm_guard template -static inline void dde_for_each_connector(drm_device * dev, FUNCTOR f) +static inline void lx_for_each_connector(drm_device * dev, FUNCTOR f) { struct drm_connector *connector; list_for_each_entry(connector, &dev->mode_config.connector_list, head) @@ -135,7 +133,7 @@ Framebuffer::Driver::_preferred_mode(drm_connector *connector) void Framebuffer::Driver::finish_initialization() { - dde_c_set_driver(dde_drm_device, (void*)this); + lx_c_set_driver(lx_drm_device, (void*)this); generate_report(); _session.config_changed(); } @@ -145,7 +143,7 @@ void Framebuffer::Driver::finish_initialization() void Framebuffer::Driver::_poll() { - Lx::Pci_dev * pci_dev = (Lx::Pci_dev*) dde_drm_device->pdev->bus; + Lx::Pci_dev * pci_dev = (Lx::Pci_dev*) lx_drm_device->pdev->bus; Lx::Irq::irq().inject_irq(pci_dev->client()); } @@ -172,39 +170,35 @@ void Framebuffer::Driver::update_mode() Configuration old = _config; _config = Configuration(); - dde_for_each_connector(dde_drm_device, [&] (drm_connector *c) { + lx_for_each_connector(lx_drm_device, [&] (drm_connector *c) { drm_display_mode * mode = _preferred_mode(c); if (!mode) return; - if (mode->hdisplay > _config.width) _config.width = mode->hdisplay; - if (mode->vdisplay > _config.height) _config.height = mode->vdisplay; + if (mode->hdisplay > _config._lx.width) _config._lx.width = mode->hdisplay; + if (mode->vdisplay > _config._lx.height) _config._lx.height = mode->vdisplay; }); - _config.lx_obj = - dde_c_allocate_framebuffer(_config.width, _config.height, &_config.addr, - (uint64_t*)&_config.size, dde_drm_device); - _config.cap = _config.addr ? Lx::ioremap_lookup((addr_t)_config.addr, _config.size) - : Genode::Dataspace_capability(); + lx_c_allocate_framebuffer(lx_drm_device, &_config._lx); { - Drm_guard guard(dde_drm_device); - dde_for_each_connector(dde_drm_device, [&] (drm_connector *c) { - dde_c_set_mode(dde_drm_device, c, _config.lx_obj, + Drm_guard guard(lx_drm_device); + lx_for_each_connector(lx_drm_device, [&] (drm_connector *c) { + lx_c_set_mode(lx_drm_device, c, _config._lx.lx_fb, _preferred_mode(c)); }); } - if (old.addr) Lx::iounmap(old.addr); - if (old.lx_obj) old.lx_obj->funcs->destroy(old.lx_obj); + if (old._lx.addr) Lx::iounmap(old._lx.addr); + if (old._lx.lx_fb) old._lx.lx_fb->funcs->destroy(old._lx.lx_fb); } void Framebuffer::Driver::generate_report() { - Drm_guard guard(dde_drm_device); + Drm_guard guard(lx_drm_device); /* detect mode information per connector */ { struct drm_connector *c; - list_for_each_entry(c, &dde_drm_device->mode_config.connector_list, + list_for_each_entry(c, &lx_drm_device->mode_config.connector_list, head) if (list_empty(&c->modes)) c->funcs->fill_modes(c, 0, 0); } @@ -224,7 +218,7 @@ void Framebuffer::Driver::generate_report() Genode::Reporter::Xml_generator xml(reporter, [&] () { struct drm_connector *c; - list_for_each_entry(c, &dde_drm_device->mode_config.connector_list, + list_for_each_entry(c, &lx_drm_device->mode_config.connector_list, head) { xml.node("connector", [&] () { @@ -871,8 +865,8 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags) { drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY); - ASSERT(!dde_drm_device); - dde_drm_device = dev; + ASSERT(!lx_drm_device); + lx_drm_device = dev; return dev->driver->load(dev, flags); } @@ -1546,7 +1540,7 @@ void local_irq_enable() void drm_sysfs_hotplug_event(struct drm_device *dev) { Framebuffer::Driver * driver = (Framebuffer::Driver*) - dde_c_get_driver(dde_drm_device); + lx_c_get_driver(lx_drm_device); if (driver) { DRM_DEBUG("generating hotplug event\n"); diff --git a/repos/dde_linux/src/drivers/framebuffer/intel/lx_emul_c.c b/repos/dde_linux/src/drivers/framebuffer/intel/lx_emul_c.c index 4878b0896..217ac32b3 100644 --- a/repos/dde_linux/src/drivers/framebuffer/intel/lx_emul_c.c +++ b/repos/dde_linux/src/drivers/framebuffer/intel/lx_emul_c.c @@ -1,10 +1,24 @@ -#include "lx_emul_private.h" +/* + * \brief Linux emulation C helper functions + * \author Stefan Kalkowski + * \date 2016-03-22 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +/* Genode includes */ +#include #include <../drivers/gpu/drm/i915/i915_drv.h> #include <../drivers/gpu/drm/i915/intel_drv.h> #include extern struct drm_framebuffer * -dde_c_intel_framebuffer_create(struct drm_device *dev, +lx_c_intel_framebuffer_create(struct drm_device *dev, struct drm_mode_fb_cmd2 *mode_cmd, struct drm_i915_gem_object *obj); @@ -18,56 +32,55 @@ int intel_sanitize_enable_execlists(struct drm_device *dev, } -struct drm_framebuffer* -dde_c_allocate_framebuffer(int width, int height, void ** base, - uint64_t * size, struct drm_device * dev) +void lx_c_allocate_framebuffer(struct drm_device * dev, + struct lx_c_fb_config *c) { struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_framebuffer * fb = NULL; struct drm_mode_fb_cmd2 * r; struct drm_i915_gem_object * obj = NULL; mutex_lock(&dev->struct_mutex); - *size = roundup(width * height * 2, PAGE_SIZE); - if (*size * 2 < dev_priv->gtt.stolen_usable_size) - obj = i915_gem_object_create_stolen(dev, *size); + /* 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); if (obj == NULL) - obj = i915_gem_alloc_object(dev, *size); + obj = i915_gem_alloc_object(dev, c->size); if (obj == NULL) goto out2; r = (struct drm_mode_fb_cmd2*) kzalloc(sizeof(struct drm_mode_fb_cmd2), 0); if (!r) goto err2; - r->width = width; - r->height = height; + r->width = c->width; + r->height = c->height; r->pixel_format = DRM_FORMAT_RGB565; - r->pitches[0] = width * 2; - fb = dde_c_intel_framebuffer_create(dev, r, obj); - if (IS_ERR(fb)) goto err2; + r->pitches[0] = c->pitch; + c->lx_fb = lx_c_intel_framebuffer_create(dev, r, obj); + if (IS_ERR(c->lx_fb)) goto err2; - if (intel_pin_and_fence_fb_obj(NULL, fb, NULL, NULL, NULL)) + if (intel_pin_and_fence_fb_obj(NULL, c->lx_fb, NULL, NULL, NULL)) goto err1; - *base = ioremap_wc(dev_priv->gtt.mappable_base - + i915_gem_obj_ggtt_offset(obj), *size); + c->addr = ioremap_wc(dev_priv->gtt.mappable_base + + i915_gem_obj_ggtt_offset(obj), c->size); - memset_io(*base, 0, *size); + memset_io(c->addr, 0, c->size); goto out1; err1: - drm_framebuffer_remove(fb); + drm_framebuffer_remove(c->lx_fb); err2: - fb = NULL; + c->lx_fb = NULL; drm_gem_object_unreference(&obj->base); out1: kfree(r); out2: mutex_unlock(&dev->struct_mutex); - return fb; } -void dde_c_set_mode(struct drm_device * dev, struct drm_connector * connector, +void lx_c_set_mode(struct drm_device * dev, struct drm_connector * connector, struct drm_framebuffer *fb, struct drm_display_mode *mode) { struct drm_crtc *crtc = NULL; @@ -131,7 +144,7 @@ void dde_c_set_mode(struct drm_device * dev, struct drm_connector * connector, } -void dde_c_set_driver(struct drm_device * dev, void * driver) +void lx_c_set_driver(struct drm_device * dev, void * driver) { struct drm_i915_private *dev_priv = dev->dev_private; ASSERT(!dev_priv->audio_component); @@ -139,7 +152,7 @@ void dde_c_set_driver(struct drm_device * dev, void * driver) } -void* dde_c_get_driver(struct drm_device * dev) +void* lx_c_get_driver(struct drm_device * dev) { struct drm_i915_private *dev_priv = dev->dev_private; return (void*) dev_priv->audio_component; diff --git a/repos/dde_linux/src/drivers/framebuffer/intel/lx_emul_private.h b/repos/dde_linux/src/drivers/framebuffer/intel/lx_emul_private.h deleted file mode 100644 index 748174d5e..000000000 --- a/repos/dde_linux/src/drivers/framebuffer/intel/lx_emul_private.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * \brief Local definitions of the Linux kernel API implementation - * \author Norman Feske - * \date 2015-08-24 - */ - -#ifndef _LX_EMUL_PRIVATE_H_ -#define _LX_EMUL_PRIVATE_H_ - -/* Linux kernel API */ -#include -#include - -#if 0 -#define TRACE \ - do { \ - lx_printf("%s not implemented\n", __func__); \ - } while (0) -#else -#define TRACE do { ; } while (0) -#endif - -#define TRACE_AND_STOP \ - do { \ - lx_printf("%s not implemented\n", __func__); \ - BUG(); \ - } while (0) - -#define ASSERT(x) \ - do { \ - if (!(x)) { \ - lx_printf("%s:%u assertion failed\n", __func__, __LINE__); \ - BUG(); \ - } \ - } while (0) - -#endif /* _LX_EMUL_PRIVATE_H_ */