diff --git a/repos/os/src/drivers/gpu/intel/commands.h b/repos/os/src/drivers/gpu/intel/commands.h index e0e13c02a2..ecc4118972 100644 --- a/repos/os/src/drivers/gpu/intel/commands.h +++ b/repos/os/src/drivers/gpu/intel/commands.h @@ -25,7 +25,10 @@ namespace Igd { struct Cmd_header; + struct Mi_cmd; struct Mi_noop; + struct Mi_arb_check; + struct Mi_arb_on_off; struct Mi_user_interrupt; struct Mi_batch_buffer_start; struct Pipe_control; @@ -57,11 +60,12 @@ struct Igd::Cmd_header : Genode::Register<32> */ struct Mi_cmd_opcode : Bitfield<23, 6> { - enum { + enum Opcode { MI_NOOP = 0x00, MI_USER_INTERRUPT = 0x02, MI_WAIT_FOR_EVENT = 0x03, MI_FLUSH = 0x04, + MI_ARB_CHECK = 0x05, MI_REPORT_HEAD = 0x07, MI_ARB_ON_OFF = 0x08, MI_BATCH_BUFFER_END = 0x0A, @@ -94,33 +98,65 @@ struct Igd::Cmd_header : Genode::Register<32> }; +struct Igd::Mi_cmd : Cmd_header +{ + Mi_cmd(Mi_cmd_opcode::Opcode opcode) + { + Cmd_type::set(value, Cmd_type::MI_COMMAND); + Mi_cmd_opcode::set(value, opcode); + }; +}; + + /* * IHD-OS-BDW-Vol 2a-11.15 p. 870 */ -struct Igd::Mi_noop : Cmd_header +struct Igd::Mi_noop : Mi_cmd { Mi_noop() - { - Cmd_header::Cmd_type::set(Cmd_header::value, - Cmd_header::Cmd_type::MI_COMMAND); - Cmd_header::Mi_cmd_opcode::set(Cmd_header::value, - Cmd_header::Mi_cmd_opcode::MI_NOOP); - } + : + Mi_cmd(Mi_cmd_opcode::MI_NOOP) + { } }; /* * IHD-OS-BDW-Vol 2a-11.15 p. 948 ff. */ -struct Igd::Mi_user_interrupt : Cmd_header +struct Igd::Mi_user_interrupt : Mi_cmd { Mi_user_interrupt() + : + Mi_cmd(Mi_cmd_opcode::MI_USER_INTERRUPT) + { } +}; + + +/* + * IHD-OS-BDW-Vol 2a-11.15 p. 777 ff. + */ +struct Igd::Mi_arb_check : Mi_cmd +{ + Mi_arb_check() + : + Mi_cmd(Mi_cmd_opcode::MI_ARB_CHECK) + { } +}; + + +/* + * IHD-OS-BDW-Vol 2a-11.15 p. 781 ff. + */ +struct Igd::Mi_arb_on_off : Mi_cmd +{ + struct Enable : Bitfield<0, 1> { }; + + Mi_arb_on_off(bool enable) + : + Mi_cmd(Mi_cmd_opcode::MI_ARB_ON_OFF) { - Cmd_header::Cmd_type::set(Cmd_header::value, - Cmd_header::Cmd_type::MI_COMMAND); - Cmd_header::Mi_cmd_opcode::set(Cmd_header::value, - Cmd_header::Mi_cmd_opcode::MI_USER_INTERRUPT); + Enable::set(value, enable ? 1 : 0); } }; @@ -128,7 +164,7 @@ struct Igd::Mi_user_interrupt : Cmd_header /* * IHD-OS-BDW-Vol 2a-11.15 p. 793 ff. */ -struct Igd::Mi_batch_buffer_start : Cmd_header +struct Igd::Mi_batch_buffer_start : Mi_cmd { struct Address_space_indicator : Bitfield<8, 1> { @@ -138,11 +174,9 @@ struct Igd::Mi_batch_buffer_start : Cmd_header struct Dword_length : Bitfield<0, 8> { }; Mi_batch_buffer_start() + : + Mi_cmd(Mi_cmd_opcode::MI_BATCH_BUFFER_START) { - Cmd_header::Cmd_type::set(Cmd_header::value, - Cmd_header::Cmd_type::MI_COMMAND); - Cmd_header::Mi_cmd_opcode::set(Cmd_header::value, - Cmd_header::Mi_cmd_opcode::MI_BATCH_BUFFER_START); Address_space_indicator::set(Cmd_header::value, Address_space_indicator::PPGTT); Dword_length::set(Cmd_header::value, 1); diff --git a/repos/os/src/drivers/gpu/intel/context.h b/repos/os/src/drivers/gpu/intel/context.h index 4ecb7caa1f..33518ba013 100644 --- a/repos/os/src/drivers/gpu/intel/context.h +++ b/repos/os/src/drivers/gpu/intel/context.h @@ -32,6 +32,7 @@ namespace Igd { struct Generation; struct Hardware_status_page; + class Pphardware_status_page; template class Execlist_context; template class Ppgtt_context; class Engine_context; @@ -92,7 +93,7 @@ struct Igd::Common_context_regs : public Genode::Mmio struct Common_register_array : Register_array { }; template - struct Common_register_array_64 : Register_array { }; + struct Common_register_array_64 : Register_array { }; addr_t _base; @@ -397,7 +398,7 @@ class Igd::Execlist_context : public Igd::Common_context_regs { typename Ring_buffer_control_value::access_t v = read(); /* length is given in number of pages */ - Ring_buffer_control_value::Buffer_length::set(v, ring_buffer_length / PAGE_SIZE); + Ring_buffer_control_value::Buffer_length::set(v, (ring_buffer_length / PAGE_SIZE) - 1); /* according to the PRM it should be disable b/c of the amount of reports generated */ Ring_buffer_control_value::Arhp::set(v, Ring_buffer_control_value::Arhp::MI_AUTOREPORT_OFF); Ring_buffer_control_value::Ring_buffer_enable::set(v, 1); @@ -702,6 +703,72 @@ class Igd::Hardware_status_page : public Igd::Common_context_regs Hardware_status_page(addr_t base) : Common_context_regs(base) { } + + void dump(bool raw = false) + { + using namespace Genode; + + if (raw) { + uint32_t const *p = (uint32_t const *)base(); + for (uint32_t i = 0; i < PAGE_SIZE / sizeof(uint32_t); i += 8) { + log(Hex(i, Hex::PREFIX, Hex::PAD), " ", + Hex(p[i ], Hex::PREFIX, Hex::PAD), " ", + Hex(p[i+1], Hex::PREFIX, Hex::PAD), " ", + Hex(p[i+2], Hex::PREFIX, Hex::PAD), " ", + Hex(p[i+3], Hex::PREFIX, Hex::PAD), " ", + Hex(p[i+4], Hex::PREFIX, Hex::PAD), " ", + Hex(p[i+5], Hex::PREFIX, Hex::PAD), " ", + Hex(p[i+6], Hex::PREFIX, Hex::PAD), " ", + Hex(p[i+7], Hex::PREFIX, Hex::PAD)); + } + } else { + log("Hardware_status_page"); + log(" Interrupt_status_register_storage: ", + Hex(read(), + Hex::PREFIX, Hex::PAD)); + log(" Ring_head_ptr_storage: ", + Hex(read(), + Hex::PREFIX, Hex::PAD)); + + auto const cs_last = read(); + + log(" Last_written_status_offset: ", + Hex(cs_last, Hex::PREFIX, Hex::PAD)); + + for (unsigned i = 0; i < CONTEXT_STATUS_REGISTERS; i++) { + using C = Igd::Context_status_qword; + C::access_t v = read(i); + log(" Context_status ", i); + log(" Context_id: ", C::Context_id::get(v)); + log(" Lite_restore: ", C::Lite_restore::get(v)); + log(" Display_plane: ", C::Display_plane::get(v)); + log(" Semaphore_wait_mode: ", C::Semaphore_wait_mode::get(v)); + log(" Wait_on_scanline: ", C::Wait_on_scanline::get(v)); + log(" Wait_on_semaphore: ", C::Wait_on_semaphore::get(v)); + log(" Wait_on_v_blank: ", C::Wait_on_v_blank::get(v)); + log(" Wait_on_sync_flip: ", C::Wait_on_sync_flip::get(v)); + log(" Context_complete: ", C::Context_complete::get(v)); + log(" Active_to_idle: ", C::Active_to_idle::get(v)); + log(" Element_switch: ", C::Element_switch::get(v)); + log(" Preempted: ", C::Preempted::get(v)); + log(" Idle_to_active: ", C::Idle_to_active::get(v)); + } + } + } +}; + + +/* + * IHD-OS-BDW-Vol 2d-11.15 p. 303 + */ +class Igd::Pphardware_status_page : public Igd::Common_context_regs +{ + public: + + struct Ring_head_ptr_storage : Common_register<4> { }; + + Pphardware_status_page(addr_t base) + : Common_context_regs(base) { } }; @@ -713,7 +780,7 @@ class Igd::Rcs_context enum { HW_ID = 0, - CONTEXT_PAGES = 20 /* ctx */ + 1 /* GuC */, + CONTEXT_PAGES = 22 /* ctx */ + 1 /* GuC */, RING_PAGES = 4, RCS_RING_BASE = 0x2000, @@ -731,7 +798,8 @@ class Igd::Rcs_context PPGTT_CTX_START = EXECLIST_CTX_END, PPGTT_CTX_END = 0x0050, PPGTT_CTX_SIZE = (PPGTT_CTX_END - PPGTT_CTX_START) * sizeof(uint32_t), - PPGTT_CTX_IH = 0x11000001, + PPGTT_CTX_IH = 0x11001011, + PPGTT_CTX_IH_2 = 0x11000001, ENGINE_CTX_START = PPGTT_CTX_END, ENGINE_CTX_END = 0x0EC0, @@ -748,7 +816,7 @@ class Igd::Rcs_context private: - Hardware_status_page _hw_status_page; + Pphardware_status_page _hw_status_page; Execlist_context _execlist_context; Ppgtt_context _ppgtt_context; Engine_context _engine_context; @@ -808,7 +876,8 @@ class Igd::Rcs_context using P = Ppgtt_context; - _ppgtt_context.write(PPGTT_CTX_IH); + _ppgtt_context.write(PPGTT_CTX_IH); + _ppgtt_context.write(PPGTT_CTX_IH_2); } size_t head_offset() @@ -850,58 +919,6 @@ class Igd::Rcs_context _ppgtt_context.dump(); } - void dump_hw_status_page(bool raw = false) - { - using namespace Genode; - - if (raw) { - uint32_t const *p = (uint32_t const *)_hw_status_page.base(); - for (uint32_t i = 0; i < HW_STATUS_PAGE_SIZE / sizeof(uint32_t); i += 8) { - log(Hex(i, Hex::PREFIX, Hex::PAD), " ", - Hex(p[i ], Hex::PREFIX, Hex::PAD), " ", - Hex(p[i+1], Hex::PREFIX, Hex::PAD), " ", - Hex(p[i+2], Hex::PREFIX, Hex::PAD), " ", - Hex(p[i+3], Hex::PREFIX, Hex::PAD), " ", - Hex(p[i+4], Hex::PREFIX, Hex::PAD), " ", - Hex(p[i+5], Hex::PREFIX, Hex::PAD), " ", - Hex(p[i+6], Hex::PREFIX, Hex::PAD), " ", - Hex(p[i+7], Hex::PREFIX, Hex::PAD)); - } - } else { - using H = Hardware_status_page; - log("Hardware_status_page"); - log(" Interrupt_status_register_storage: ", - Hex(_hw_status_page.read(), - Hex::PREFIX, Hex::PAD)); - log(" Ring_head_ptr_storage: ", - Hex(_hw_status_page.read(), - Hex::PREFIX, Hex::PAD)); - - auto const cs_last = _hw_status_page.read(); - - log(" Last_written_status_offset: ", - Hex(cs_last, Hex::PREFIX, Hex::PAD)); - - for (unsigned i = 0; i < H::CONTEXT_STATUS_REGISTERS; i++) { - Igd::Context_status_qword::access_t v = _hw_status_page.read(i); - log(" Context_status ", i); - log(" Context_id: ", Igd::Context_status_qword::Context_id::get(v)); - log(" Lite_restore: ", Igd::Context_status_qword::Lite_restore::get(v)); - log(" Display_plane: ", Igd::Context_status_qword::Display_plane::get(v)); - log(" Semaphore_wait_mode: ", Igd::Context_status_qword::Semaphore_wait_mode::get(v)); - log(" Wait_on_scanline: ", Igd::Context_status_qword::Wait_on_scanline::get(v)); - log(" Wait_on_semaphore: ", Igd::Context_status_qword::Wait_on_semaphore::get(v)); - log(" Wait_on_v_blank: ", Igd::Context_status_qword::Wait_on_v_blank::get(v)); - log(" Wait_on_sync_flip: ", Igd::Context_status_qword::Wait_on_sync_flip::get(v)); - log(" Context_complete: ", Igd::Context_status_qword::Context_complete::get(v)); - log(" Active_to_idle: ", Igd::Context_status_qword::Active_to_idle::get(v)); - log(" Element_switch: ", Igd::Context_status_qword::Element_switch::get(v)); - log(" Preempted: ", Igd::Context_status_qword::Preempted::get(v)); - log(" Idle_to_active: ", Igd::Context_status_qword::Idle_to_active::get(v)); - } - } - } - void dump_execlist_context() { using namespace Genode; diff --git a/repos/os/src/drivers/gpu/intel/main.cc b/repos/os/src/drivers/gpu/intel/main.cc index 1d6a5c8465..891c93fc0d 100644 --- a/repos/os/src/drivers/gpu/intel/main.cc +++ b/repos/os/src/drivers/gpu/intel/main.cc @@ -43,6 +43,7 @@ #include #include #include +#include using namespace Genode; @@ -467,9 +468,6 @@ struct Igd::Device addr_t hw_status_page() const { return ctx.gmaddr(); } - uint64_t seqno() const { - Utils::clflush((uint32_t*)(ctx.vaddr() + 0xc0)); - return *(uint32_t*)(ctx.vaddr() + 0xc0); } private: @@ -504,11 +502,15 @@ struct Igd::Device uint32_t _vgpu_avail { 0 }; + /* global hardware-status page */ + Constructible _hw_status_ctx { }; + Constructible _hw_status_page { }; + struct Vgpu : Genode::Fifo::Element { enum { APERTURE_SIZE = 32u << 20, - MAX_FENCES = 4, + MAX_FENCES = 16, }; Device &_device; @@ -556,11 +558,10 @@ struct Igd::Device void user_complete() { /* remember last completed seqno for info object */ - _completed_seqno = rcs.seqno(); + _completed_seqno = _device.seqno(); } - bool setup_ring_buffer(Genode::addr_t const buffer_addr, - Genode::addr_t const scratch_addr) + bool setup_ring_buffer(Genode::addr_t const buffer_addr) { _current_seqno++; @@ -632,15 +633,12 @@ struct Igd::Device tmp |= Igd::Pipe_control::QW_WRITE; tmp |= Igd::Pipe_control::STORE_DATA_INDEX; -/* - tmp |= Igd::Pipe_control::GLOBAL_GTT_IVB; - tmp |= Igd::Pipe_control::DC_FLUSH_ENABLE; - tmp |= Igd::Pipe_control::INDIRECT_STATE_DISABLE; - tmp |= Igd::Pipe_control::MEDIA_STATE_CLEAR; -*/ - cmd[1] = tmp; - cmd[2] = scratch_addr; + /* + * PP-Hardware status page (base GLOBAL_GTT_IVB is disabled) + * offset (dword 52) because STORE_DATA_INDEX is enabled. + */ + cmd[2] = 0x34 * 4; for (size_t i = 0; i < CMD_NUM; i++) { advance += el.ring_append(cmd[i]); @@ -659,13 +657,6 @@ struct Igd::Device } } - #define MI_INSTR(opcode, flags) (((opcode) << 23) | (flags)) - #define MI_NOOP MI_INSTR(0u, 0) - #define MI_ARB_ON_OFF MI_INSTR(0x08u, 0) - #define MI_ARB_ENABLE (1u<<0) - #define MI_ARB_DISABLE (0u<<0) - #define MI_ARB_CHECK MI_INSTR(0x05u, 0) - /* * gen8_emit_bb_start_noarb, gen8 and render engine * @@ -677,7 +668,7 @@ struct Igd::Device Genode::uint32_t cmd[CMD_NUM] = {}; Igd::Mi_batch_buffer_start mi; - cmd[0] = MI_ARB_ON_OFF | MI_ARB_DISABLE; + cmd[0] = Mi_arb_on_off(false).value; cmd[1] = mi.value; cmd[2] = buffer_addr & 0xffffffff; cmd[3] = (buffer_addr >> 32) & 0xffff; @@ -698,12 +689,12 @@ struct Igd::Device Genode::uint32_t cmd[CMD_NUM] = {}; Igd::Mi_batch_buffer_start mi; - cmd[0] = MI_ARB_ON_OFF | MI_ARB_ENABLE; + cmd[0] = Mi_arb_on_off(true).value; cmd[1] = mi.value; cmd[2] = buffer_addr & 0xffffffff; cmd[3] = (buffer_addr >> 32) & 0xffff; - cmd[4] = MI_ARB_ON_OFF | MI_ARB_DISABLE; - cmd[5] = MI_NOOP; + cmd[4] = Mi_arb_on_off(false).value; + cmd[5] = Mi_noop().value; for (size_t i = 0; i < CMD_NUM; i++) { advance += el.ring_append(cmd[i]); @@ -721,7 +712,6 @@ struct Igd::Device tmp |= Igd::Pipe_control::RENDER_TARGET_CACHE_FLUSH; tmp |= Igd::Pipe_control::DEPTH_CACHE_FLUSH; tmp |= Igd::Pipe_control::DC_FLUSH_ENABLE; - cmd[1] = tmp; for (size_t i = 0; i < CMD_NUM; i++) { @@ -741,9 +731,10 @@ struct Igd::Device tmp |= Igd::Pipe_control::FLUSH_ENABLE; tmp |= Igd::Pipe_control::GLOBAL_GTT_IVB; tmp |= Igd::Pipe_control::QW_WRITE; + tmp |= Igd::Pipe_control::STORE_DATA_INDEX; cmd[1] = tmp; - cmd[2] = (rcs.hw_status_page() + HWS_DATA) & 0xffffffff; + cmd[2] = HWS_DATA; cmd[3] = 0; /* upper addr 0 */ cmd[4] = _current_seqno & 0xffffffff; cmd[5] = _current_seqno >> 32; @@ -767,7 +758,7 @@ struct Igd::Device Genode::uint32_t cmd[2] = {}; Igd::Mi_user_interrupt ui; cmd[0] = ui.value; - cmd[1] = MI_ARB_ON_OFF | MI_ARB_ENABLE; + cmd[1] = Mi_arb_on_off(true).value; for (size_t i = 0; i < CMD_NUM; i++) { advance += el.ring_append(cmd[i]); @@ -779,9 +770,8 @@ struct Igd::Device /* gen8_emit_fini_breadcrumb_tail -> gen8_emit_wa_tail */ enum { CMD_NUM = 2 }; Genode::uint32_t cmd[2] = {}; - Igd::Mi_user_interrupt ui; - cmd[0] = MI_ARB_CHECK; - cmd[1] = MI_NOOP; + cmd[0] = Mi_arb_check().value; + cmd[1] = Mi_noop().value; for (size_t i = 0; i < CMD_NUM; i++) { advance += el.ring_append(cmd[i]); @@ -841,6 +831,11 @@ struct Igd::Device int const port = _mmio.read(); + if (_mmio.read() || + _mmio.read()) + return; + + el.schedule(port); uint32_t desc[4]; @@ -883,13 +878,6 @@ struct Igd::Device _mmio.flush_gfx_tlb(); - /* - * XXX check if HWSP is shared across contexts and if not when - * we actually need to write the register - */ - Mmio::HWS_PGA_RCSUNIT::access_t const addr = rcs.hw_status_page(); - _mmio.write_post(addr); - _submit_execlist(rcs); _active_vgpu = gpu; @@ -970,7 +958,7 @@ struct Igd::Device _mmio.execlist_status_dump(); _active_vgpu->rcs.context->dump(); - _active_vgpu->rcs.context->dump_hw_status_page(); + _hw_status_page->dump(); Execlist &el = *_active_vgpu->rcs.execlist; el.ring_update_head(_active_vgpu->rcs.context->head_offset()); el.ring_dump(4096, _active_vgpu->rcs.context->tail_offset() * 2, @@ -1055,8 +1043,12 @@ struct Igd::Device _clock_gating(); - _mmio.dump(); - _mmio.context_status_pointer_dump(); + /* setup global hardware status page */ + _hw_status_ctx.construct(env.rm(), alloc, *this, 1, 0); + _hw_status_page.construct(_hw_status_ctx->vaddr()); + + Mmio::HWS_PGA_RCSUNIT::access_t const addr = _hw_status_ctx->gmaddr(); + _mmio.write_post(addr); /* read out slice, subslice, EUs information depending on platform */ if (_info.platform == Device_info::Platform::BROADWELL) { @@ -1084,6 +1076,9 @@ struct Igd::Device } else Genode::error("unsupported platform ", (int)_info.platform); + /* apply generation specific workarounds */ + apply_workarounds(_mmio, _info.generation); + _resources.timer().sigh(_watchdog_timeout_sigh); } @@ -1192,6 +1187,20 @@ struct Igd::Device return stepping_start <= stepping && stepping <= stepping_end; } + + /************************** + ** Hardware status page ** + **************************/ + + addr_t hw_status_page() const { return _hw_status_ctx->gmaddr(); } + + uint64_t seqno() const + { + Utils::clflush((uint32_t*)(_hw_status_ctx->vaddr() + 0xc0)); + return *(uint32_t*)(_hw_status_ctx->vaddr() + 0xc0); + } + + /******************* ** Vgpu handling ** *******************/ @@ -1324,7 +1333,7 @@ struct Igd::Device uint32_t set_tiling(Ggtt::Offset const start, size_t const size, uint32_t const mode) { - uint32_t const id = _mmio.find_free_fence(); + uint32_t const id = _get_free_fence(); if (id == INVALID_FENCE) { Genode::warning("could not find free FENCE"); return id; @@ -1360,7 +1369,6 @@ struct Igd::Device Mmio::GT_0_INTERRUPT_IIR::access_t const v = _mmio.read(); bool const ctx_switch = Mmio::GT_0_INTERRUPT_IIR::Cs_ctx_switch_interrupt::get(v); - (void)ctx_switch; bool const user_complete = Mmio::GT_0_INTERRUPT_IIR::Cs_mi_user_interrupt::get(v); if (v) { _clear_rcs_iir(v); } @@ -1375,15 +1383,17 @@ struct Igd::Device bool const fault_valid = _mmio.fault_regs_valid(); if (fault_valid) { Genode::error("FAULT_REG valid"); } - _mmio.update_context_status_pointer(); + if (ctx_switch) + _mmio.update_context_status_pointer(); if (user_complete) { _unschedule_current_vgpu(); _active_vgpu = nullptr; if (notify_gpu) { - if (!_notify_complete(notify_gpu)) + if (!_notify_complete(notify_gpu)) { _vgpu_list.enqueue(*notify_gpu); + } } /* keep the ball rolling... */ @@ -1540,7 +1550,7 @@ class Gpu::Session_component : public Genode::Session_object throw Gpu::Session::Invalid_state(); } - found = _vgpu.setup_ring_buffer(buffer.ppgtt_va, _device._ggtt->scratch_page()); + found = _vgpu.setup_ring_buffer(buffer.ppgtt_va); }); if (!found) @@ -1751,6 +1761,9 @@ class Gpu::Session_component : public Genode::Session_object return false; } + //XXX: support change of already fenced bo's fencing mode + if (b->fenced) return true; + Igd::size_t const size = Genode::Dataspace_client(b->cap).size(); Genode::uint32_t const fenced = _device.set_tiling(b->map.offset, size, mode); @@ -1910,7 +1923,16 @@ struct Main }; -void Component::construct(Genode::Env &env) { static Main main(env); } +void Component::construct(Genode::Env &env) +{ + static Constructible
main; + try { + main.construct(env); + } catch (Igd::Resources::Initialization_failed) { + Genode::warning("Intel GPU resources not found."); + env.parent().exit(0); + } +} Genode::size_t Component::stack_size() { return 32UL*1024*sizeof(long); } diff --git a/repos/os/src/drivers/gpu/intel/mmio.h b/repos/os/src/drivers/gpu/intel/mmio.h index 92204da02b..313a745322 100644 --- a/repos/os/src/drivers/gpu/intel/mmio.h +++ b/repos/os/src/drivers/gpu/intel/mmio.h @@ -1698,6 +1698,10 @@ class Igd::Mmio : public Genode::Mmio } } + struct Arbiter_control : Register<0xb004, 32> { + struct Gaps_tsv_enable : Bitfield<7, 1> {}; + }; + /********************* ** DEBUG interface ** *********************/ diff --git a/repos/os/src/drivers/gpu/intel/mmio_dump.cc b/repos/os/src/drivers/gpu/intel/mmio_dump.cc index 67c482f252..f27825d3db 100644 --- a/repos/os/src/drivers/gpu/intel/mmio_dump.cc +++ b/repos/os/src/drivers/gpu/intel/mmio_dump.cc @@ -36,7 +36,7 @@ void Igd::Mmio::dump() log("0x2064 - IPEIR: ", Hex(read())); log("0x2068 - IPEHR: ", Hex(read())); log("0x206C - RCS_INSTDONE: ", Hex(read())); - log("0x207C - RCS_ACTHD: ", Hex(read())); + log("0x2074 - RCS_ACTHD: ", Hex(read())); log("0x2078 - DMA_FADD_PREF: ", Hex(read())); log("0x207C - RCS_INSTDONE_1: ", Hex(read())); log("0x2094 - NOP_ID: ", Hex(read())); diff --git a/repos/os/src/drivers/gpu/intel/workarounds.h b/repos/os/src/drivers/gpu/intel/workarounds.h new file mode 100644 index 0000000000..fbb0165f05 --- /dev/null +++ b/repos/os/src/drivers/gpu/intel/workarounds.h @@ -0,0 +1,30 @@ +/* + * \brief Generation specific workarounds + * \author Sebastian Sumpf + * \data 2021-09-21 + */ + +/* + * Copyright (C) 2021 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ +#include + +namespace Igd { + void apply_workarounds(Mmio &mmio, unsigned generation); +} + +void Igd::apply_workarounds(Mmio &mmio, unsigned generation) +{ + /* + * WaEnableGapsTsvCreditFix + * + * Sets the "GAPS TSV Credit fix ENABLE" of the RC arbiter bit that should be + * set by BIOS for GEN9+. If this bit is not set, GPU will hang arbitrary + * during batch buffer execution + */ + if (generation >= 9) + mmio.write(1); +}