diff --git a/repos/os/src/drivers/gpu/intel/main.cc b/repos/os/src/drivers/gpu/intel/main.cc index aa38d1b86e..1d6a5c8465 100644 --- a/repos/os/src/drivers/gpu/intel/main.cc +++ b/repos/os/src/drivers/gpu/intel/main.cc @@ -568,9 +568,14 @@ struct Igd::Device Ring_buffer::Index advance = 0; + bool dc_flush_wa = _device.match(Device_info::Platform::KABYLAKE, + Device_info::Stepping::A0, + Device_info::Stepping::B0); + size_t const need = 4 /* batchbuffer cmd */ + 6 /* prolog */ + ((_device.generation().value == 9) ? 6 : 0) - + ((_device.generation().value == 8) ? 20 : 22); /* epilog + w/a */ + + ((_device.generation().value == 8) ? 20 : 22) /* epilog + w/a */ + + (dc_flush_wa ? 12 : 0); if (!el.ring_avail(need)) { el.ring_reset_and_fill_zero(); } /* save old tail */ @@ -597,6 +602,18 @@ struct Igd::Device } } + if (dc_flush_wa) { + enum { CMD_NUM = 6 }; + Genode::uint32_t cmd[CMD_NUM] = {}; + Igd::Pipe_control pc(CMD_NUM); + cmd[0] = pc.value; + cmd[1] = Igd::Pipe_control::DC_FLUSH_ENABLE; + + for (size_t i = 0; i < CMD_NUM; i++) { + advance += el.ring_append(cmd[i]); + } + } + /* prolog */ if (1) { @@ -630,6 +647,18 @@ struct Igd::Device } } + if (dc_flush_wa) { + enum { CMD_NUM = 6 }; + Genode::uint32_t cmd[CMD_NUM] = {}; + Igd::Pipe_control pc(CMD_NUM); + cmd[0] = pc.value; + cmd[1] = Igd::Pipe_control::CS_STALL; + + for (size_t i = 0; i < CMD_NUM; i++) { + advance += el.ring_append(cmd[i]); + } + } + #define MI_INSTR(opcode, flags) (((opcode) << 23) | (flags)) #define MI_NOOP MI_INSTR(0u, 0) #define MI_ARB_ON_OFF MI_INSTR(0x08u, 0)