diff --git a/repos/base/run/platform_drv.inc b/repos/base/run/platform_drv.inc index c442dff71d..3da9f74d87 100644 --- a/repos/base/run/platform_drv.inc +++ b/repos/base/run/platform_drv.inc @@ -188,6 +188,7 @@ proc platform_drv_config {} { + } diff --git a/repos/pc/run/intel_fb.run b/repos/pc/run/intel_fb.run index 0ae21947d4..7265214d59 100644 --- a/repos/pc/run/intel_fb.run +++ b/repos/pc/run/intel_fb.run @@ -68,6 +68,9 @@ append config { + + + diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/lx_emul.c b/repos/pc/src/drivers/framebuffer/intel/pc/lx_emul.c index afb1f8ec99..2c0c20a3b3 100644 --- a/repos/pc/src/drivers/framebuffer/intel/pc/lx_emul.c +++ b/repos/pc/src/drivers/framebuffer/intel/pc/lx_emul.c @@ -215,6 +215,9 @@ void intel_gt_init_early(struct intel_gt * gt, struct drm_i915_private * i915) init_llist_head(>->watchdog.list); lx_emul_trace(__func__); + + /* disable panel self refresh (required for FUJITSU S937/S938) */ + i915->params.enable_psr = 0; } @@ -242,7 +245,7 @@ void * memremap(resource_size_t offset, size_t size, unsigned long flags) { lx_emul_trace(__func__); - return NULL; + return intel_io_mem_map(offset, size); } diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/lx_emul.h b/repos/pc/src/drivers/framebuffer/intel/pc/lx_emul.h index b6444c51c0..7dc6902aa1 100644 --- a/repos/pc/src/drivers/framebuffer/intel/pc/lx_emul.h +++ b/repos/pc/src/drivers/framebuffer/intel/pc/lx_emul.h @@ -39,6 +39,7 @@ unsigned int lx_emul_io_port_inl(unsigned short port); void *emul_alloc_shmem_file_buffer(unsigned long); +void * intel_io_mem_map(unsigned long offset, unsigned long size); #include "lx_i915.h" diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/opregion_io_mem.cc b/repos/pc/src/drivers/framebuffer/intel/pc/opregion_io_mem.cc new file mode 100644 index 0000000000..b97e7d56d5 --- /dev/null +++ b/repos/pc/src/drivers/framebuffer/intel/pc/opregion_io_mem.cc @@ -0,0 +1,70 @@ +/* + * \brief Linux emulation environment specific to this driver - Intel opregion + * \author Alexander Boettcher + * \date 2022-01-21 + */ + +/* + * Copyright (C) 2022 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + + +#include +#include +#include +#include + +#include +#include +#include + + +extern "C" void * intel_io_mem_map(unsigned long const phys, + unsigned long const size) +{ + using namespace Genode; + + static Constructible rom_opregion { }; + static addr_t opregion_start = 0; + static addr_t opregion_size = 0; + + if (!rom_opregion.constructed()) { + try { + rom_opregion.construct(Lx_kit::env().env, "intel_opregion"); + + Dataspace_client ds_client(rom_opregion->cap()); + + auto mem_local = rom_opregion->local_addr(); + opregion_start = *(addr_t*)(mem_local + ds_client.size() - sizeof(addr_t) * 2); + opregion_size = *(addr_t*)(mem_local + ds_client.size() - sizeof(addr_t)); + + if (opregion_size > ds_client.size()) + opregion_size = ds_client.size(); + } catch (...) { + error("Intel opregion ROM lookup failed"); + if (rom_opregion.constructed()) + rom_opregion.destruct(); + return nullptr; + } + } + + if ((opregion_start <= phys) && + (phys + size <= opregion_start + opregion_size)) { + + try { + auto ptr = ((addr_t)rom_opregion->local_addr()) + + (phys - opregion_start) + (phys & 0xffful); + return (void *)ptr; + } catch (...) { + error("Intel opregion lookup failed"); + return nullptr; + } + } + + warning("Unknown memremap range ", Hex_range(phys, size)); + + return nullptr; +} diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/target.inc b/repos/pc/src/drivers/framebuffer/intel/pc/target.inc index ef119180c2..235ce2e1b5 100644 --- a/repos/pc/src/drivers/framebuffer/intel/pc/target.inc +++ b/repos/pc/src/drivers/framebuffer/intel/pc/target.inc @@ -11,6 +11,7 @@ INC_DIR += $(REL_PRG_DIR)/shadow SRC_CC += main.cc SRC_CC += misc.cc SRC_CC += emul.cc +SRC_CC += opregion_io_mem.cc SRC_C += dummies.c SRC_C += lx_emul.c SRC_C += $(notdir $(wildcard $(REL_PRG_DIR)/generated_dummies.c))