mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-27 17:18:53 +00:00
parent
eab92f8d6f
commit
6b1f1794c4
@ -912,11 +912,10 @@ struct Igd::Device
|
||||
|
||||
void _device_reset_and_init()
|
||||
{
|
||||
_mmio.reset();
|
||||
_mmio.reset(_info.generation);
|
||||
_mmio.clear_errors();
|
||||
_mmio.init();
|
||||
_mmio.enable_intr();
|
||||
_mmio.forcewake_enable();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -976,14 +975,14 @@ struct Igd::Device
|
||||
|
||||
_clock_gating();
|
||||
|
||||
_mmio->dump();
|
||||
_mmio->context_status_pointer_dump();
|
||||
_mmio.dump();
|
||||
_mmio.context_status_pointer_dump();
|
||||
|
||||
/* read out slice, subslice, EUs information depending on platform */
|
||||
if (_info.platform == Device_info::Platform::BROADWELL) {
|
||||
enum { SUBSLICE_MAX = 3 };
|
||||
_subslice_mask.value = (1u << SUBSLICE_MAX) - 1;
|
||||
_subslice_mask.value &= ~_mmio->read<Igd::Mmio::FUSE2::Gt_subslice_disable_fuse_gen8>();
|
||||
_subslice_mask.value &= ~_mmio.read<Igd::Mmio::FUSE2::Gt_subslice_disable_fuse_gen8>();
|
||||
|
||||
for (unsigned i=0; i < SUBSLICE_MAX; i++)
|
||||
if (_subslice_mask.value & (1u << i))
|
||||
@ -995,7 +994,7 @@ struct Igd::Device
|
||||
if (_info.generation == 9) {
|
||||
enum { SUBSLICE_MAX = 4 };
|
||||
_subslice_mask.value = (1u << SUBSLICE_MAX) - 1;
|
||||
_subslice_mask.value &= ~_mmio->read<Igd::Mmio::FUSE2::Gt_subslice_disable_fuse_gen9>();
|
||||
_subslice_mask.value &= ~_mmio.read<Igd::Mmio::FUSE2::Gt_subslice_disable_fuse_gen9>();
|
||||
|
||||
for (unsigned i=0; i < SUBSLICE_MAX; i++)
|
||||
if (_subslice_mask.value & (1u << i))
|
||||
@ -1005,13 +1004,13 @@ struct Igd::Device
|
||||
} else
|
||||
Genode::error("unsupported platform ", (int)_info.platform);
|
||||
|
||||
_timer.sigh(_watchdog_timeout_sigh);
|
||||
_resources.timer().sigh(_watchdog_timeout_sigh);
|
||||
}
|
||||
|
||||
void _clock_gating()
|
||||
{
|
||||
if (_info.platform == Device_info::Platform::KABYLAKE) {
|
||||
_mmio->kbl_clock_gating();
|
||||
_mmio.kbl_clock_gating();
|
||||
} else
|
||||
Genode::warning("no clock gating");
|
||||
}
|
||||
@ -1024,7 +1023,7 @@ struct Igd::Device
|
||||
Genode::error("wrong eu_total calculation");
|
||||
}
|
||||
|
||||
_slice_mask.value = _mmio->read<Igd::Mmio::FUSE2::Gt_slice_enable_fuse>();
|
||||
_slice_mask.value = _mmio.read<Igd::Mmio::FUSE2::Gt_slice_enable_fuse>();
|
||||
|
||||
unsigned eu_total = 0;
|
||||
|
||||
@ -1043,7 +1042,7 @@ struct Igd::Device
|
||||
if (!(_slice_mask.value & (1u << slice)))
|
||||
continue;
|
||||
|
||||
auto const disabled = _mmio->read<Igd::Mmio::EU_DISABLE>(disable_byte);
|
||||
auto const disabled = _mmio.read<Igd::Mmio::EU_DISABLE>(disable_byte);
|
||||
|
||||
for (unsigned b = 0; b < 8; b++) {
|
||||
if (disabled & (1u << b))
|
||||
|
@ -698,6 +698,47 @@ class Igd::Mmio : public Genode::Mmio
|
||||
struct ELEM_DESCRIPTOR1 : Register<0x4400, 32> { };
|
||||
struct ELEM_DESCRIPTOR2 : Register<0x4404, 32> { };
|
||||
|
||||
/**
|
||||
* Forcewake for GEN9 & GEN10, lx 5.13
|
||||
*/
|
||||
struct FORCEWAKE_GT_GEN9 : Register<0x0a188, 32> {
|
||||
struct Fallback_kernel_mask : Bitfield<31, 1> { };
|
||||
struct Kernel_mask : Bitfield<16, 1> { };
|
||||
struct Fallback_kernel : Bitfield<15, 1> { };
|
||||
struct Kernel : Bitfield< 0, 1> { };
|
||||
};
|
||||
struct FORCEWAKE_MEDIA_GEN9 : Register<0x0a270, 32> {
|
||||
struct Fallback_kernel_mask : Bitfield<31, 1> { };
|
||||
struct Kernel_mask : Bitfield<16, 1> { };
|
||||
struct Fallback_kernel : Bitfield<15, 1> { };
|
||||
struct Kernel : Bitfield< 0, 1> { };
|
||||
};
|
||||
struct FORCEWAKE_RENDER_GEN9 : Register<0x0a278, 32> {
|
||||
struct Fallback_kernel_mask : Bitfield<31, 1> { };
|
||||
struct Kernel_mask : Bitfield<16, 1> { };
|
||||
struct Fallback_kernel : Bitfield<15, 1> { };
|
||||
struct Kernel : Bitfield< 0, 1> { };
|
||||
};
|
||||
|
||||
struct FORCEWAKE_GEN9_RENDER_ACK : Register<0x000D84, 32> {
|
||||
struct Fallback_kernel_mask : Bitfield<31, 1> { };
|
||||
struct Kernel_mask : Bitfield<16, 1> { };
|
||||
struct Fallback_kernel : Bitfield<15, 1> { };
|
||||
struct Kernel : Bitfield< 0, 1> { };
|
||||
};
|
||||
struct FORCEWAKE_GEN9_MEDIA_ACK : Register<0x000D88, 32> {
|
||||
struct Fallback_kernel_mask : Bitfield<31, 1> { };
|
||||
struct Kernel_mask : Bitfield<16, 1> { };
|
||||
struct Fallback_kernel : Bitfield<15, 1> { };
|
||||
struct Kernel : Bitfield< 0, 1> { };
|
||||
};
|
||||
struct FORCEWAKE_GEN9_GT_ACK : Register<0x130044, 32> {
|
||||
struct Fallback_kernel_mask : Bitfield<31, 1> { };
|
||||
struct Kernel_mask : Bitfield<16, 1> { };
|
||||
struct Fallback_kernel : Bitfield<15, 1> { };
|
||||
struct Kernel : Bitfield< 0, 1> { };
|
||||
};
|
||||
|
||||
/*
|
||||
* IHD-OS-BDW-Vol 2c-11.15 p. 703
|
||||
*
|
||||
@ -722,20 +763,32 @@ class Igd::Mmio : public Genode::Mmio
|
||||
{
|
||||
using B = Register<BASE + 0xD0, 32>;
|
||||
|
||||
struct Mask_bits : B::template Bitfield<16, 15> { };
|
||||
struct Mask_bits : B::template Bitfield<16, 16> { };
|
||||
struct Ready_for_reset : B::template Bitfield< 1, 1> { };
|
||||
struct Request_reset : B::template Bitfield< 0, 1> { };
|
||||
};
|
||||
|
||||
template <unsigned long BASE>
|
||||
struct MI_MODE_CTRL_BASE : Register<BASE + 0x9c, 32>
|
||||
{
|
||||
using F = Register<BASE + 0x9c, 32>;
|
||||
|
||||
struct Rings_idle : F::template Bitfield< 9, 1> { };
|
||||
struct Stop_rings_mask : F::template Bitfield<16 + 8, 1> { };
|
||||
struct Stop_rings : F::template Bitfield< 8, 1> { };
|
||||
};
|
||||
|
||||
/*
|
||||
* IHD-OS-BDW-Vol 2c-11.15 p. 288
|
||||
*/
|
||||
struct CS_RESET_CTRL : RESET_CTRL_BASE<0x02000> { };
|
||||
struct CS_RESET_CTRL : RESET_CTRL_BASE <0x02000> { };
|
||||
struct CS_MI_MODE_CTRL : MI_MODE_CTRL_BASE<0x02000> { };
|
||||
|
||||
/*
|
||||
* IHD-OS-BDW-Vol 2c-11.15 p. 165
|
||||
*/
|
||||
struct BCS_RESET_CTRL : RESET_CTRL_BASE<0x22000> { };
|
||||
struct BCS_RESET_CTRL : RESET_CTRL_BASE <0x22000> { };
|
||||
struct BCS_MI_MODE_CTRL : MI_MODE_CTRL_BASE<0x22000> { };
|
||||
|
||||
/*
|
||||
* IHD-OS-BDW-Vol 2c-11.15 p. 609 ff.
|
||||
@ -885,7 +938,7 @@ class Igd::Mmio : public Genode::Mmio
|
||||
|
||||
Mmio::Delayer &_delayer;
|
||||
|
||||
void _fw_reset()
|
||||
void _fw_reset_gen8()
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
@ -941,6 +994,107 @@ class Igd::Mmio : public Genode::Mmio
|
||||
}
|
||||
}
|
||||
|
||||
void _fw_reset_gen9()
|
||||
{
|
||||
write_post<FORCEWAKE_MEDIA_GEN9>(FORCEWAKE_MT::RESET);
|
||||
write_post<FORCEWAKE_RENDER_GEN9>(FORCEWAKE_MT::RESET);
|
||||
write_post<FORCEWAKE_GT_GEN9>(FORCEWAKE_MT::RESET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set forcewake state, i.e., prevent from powering down
|
||||
*/
|
||||
void _fw_enable_media() {
|
||||
_fw_enable<FORCEWAKE_MEDIA_GEN9, FORCEWAKE_GEN9_MEDIA_ACK>(); }
|
||||
|
||||
void _fw_enable_gt() {
|
||||
_fw_enable<FORCEWAKE_GT_GEN9, FORCEWAKE_GEN9_GT_ACK>(); }
|
||||
|
||||
void _fw_enable_render() {
|
||||
_fw_enable<FORCEWAKE_RENDER_GEN9, FORCEWAKE_GEN9_RENDER_ACK>(); }
|
||||
|
||||
template <typename REG, typename REG_ACK>
|
||||
void _fw_enable()
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
while (read<typename REG_ACK::Kernel>()) {
|
||||
log(__func__, " ", __LINE__, " wait ", Hex(read<REG_ACK>()));
|
||||
_delayer.usleep(500 * 1000);
|
||||
|
||||
_fw_enable_wa<REG, REG_ACK>();
|
||||
}
|
||||
|
||||
typename REG::access_t v = 0;
|
||||
REG::Kernel_mask::set(v, 1);
|
||||
REG::Kernel ::set(v, 1);
|
||||
write<REG>(v);
|
||||
|
||||
try {
|
||||
wait_for(Attempts(50), Microseconds(1000), _delayer,
|
||||
typename REG_ACK::Equal(1));
|
||||
} catch (Polling_timeout) {
|
||||
error(__func__, " could not enable force-wake");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename REG, typename REG_ACK>
|
||||
void _fw_enable_wa()
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
while (read<typename REG_ACK::Fallback_kernel>()) {
|
||||
log(__func__, " ", __LINE__, " wait ", Hex(read<REG_ACK>()));
|
||||
_delayer.usleep(500 * 1000);
|
||||
}
|
||||
|
||||
typename REG::access_t v_set = 0;
|
||||
REG::Fallback_kernel_mask::set(v_set, 1);
|
||||
REG::Fallback_kernel ::set(v_set, 1);
|
||||
write<REG>(v_set);
|
||||
|
||||
_delayer.usleep(100 * 1000);
|
||||
|
||||
log(__func__, " ", __LINE__, " ",
|
||||
Genode::Hex(read<REG>()), " ",
|
||||
Genode::Hex(read<REG_ACK>()));
|
||||
|
||||
while (!(read<typename REG_ACK::Fallback_kernel>())) {
|
||||
log(__func__, " ", __LINE__, " wait ", Hex(read<REG_ACK>()));
|
||||
_delayer.usleep(500 * 1000);
|
||||
}
|
||||
|
||||
typename REG::access_t v_clear = 0;
|
||||
REG::Fallback_kernel_mask::set(v_clear, 1);
|
||||
REG::Fallback_kernel ::set(v_clear, 0);
|
||||
write<REG>(v_clear);
|
||||
}
|
||||
|
||||
void _fw_disable_media() {
|
||||
_fw_disable<FORCEWAKE_MEDIA_GEN9, FORCEWAKE_GEN9_MEDIA_ACK>(); }
|
||||
|
||||
void _fw_disable_gt() {
|
||||
_fw_enable<FORCEWAKE_GT_GEN9, FORCEWAKE_GEN9_GT_ACK>(); }
|
||||
|
||||
void _fw_disable_render() {
|
||||
_fw_disable<FORCEWAKE_RENDER_GEN9, FORCEWAKE_GEN9_RENDER_ACK>(); }
|
||||
|
||||
template <typename REG, typename REG_ACK>
|
||||
void _fw_disable()
|
||||
{
|
||||
typename REG::access_t v = 0;
|
||||
REG::Kernel_mask::set(v, 1);
|
||||
REG::Kernel ::set(v, 0);
|
||||
write<REG>(v);
|
||||
|
||||
while (read<typename REG_ACK::Kernel>()) {
|
||||
Genode::log(__func__, " ", __LINE__, " wait ",
|
||||
Genode::Hex(read<REG_ACK>()));
|
||||
_delayer.usleep(500 * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reset interrupts
|
||||
*/
|
||||
@ -1139,12 +1293,45 @@ class Igd::Mmio : public Genode::Mmio
|
||||
write<PAT_INDEX_H>(v >> 32);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop engine
|
||||
*/
|
||||
template <typename REG, typename REG_MI_MODE>
|
||||
bool _stop_engine()
|
||||
{
|
||||
auto mi_mode = read<REG_MI_MODE>();
|
||||
|
||||
unsigned loop = 0;
|
||||
|
||||
while (loop < 10 && !(REG_MI_MODE::Rings_idle::get(mi_mode))) {
|
||||
REG_MI_MODE::Stop_rings_mask::set(mi_mode, 1);
|
||||
REG_MI_MODE::Stop_rings::set(mi_mode, 1);
|
||||
write_post<REG_MI_MODE>(mi_mode);
|
||||
|
||||
_delayer.usleep(10 * loop);
|
||||
|
||||
mi_mode = read<REG_MI_MODE>();
|
||||
|
||||
loop ++;
|
||||
}
|
||||
|
||||
if (!(REG_MI_MODE::Rings_idle::get(mi_mode))) {
|
||||
Genode::error("could not stop engine");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset engine
|
||||
*/
|
||||
template <typename REG>
|
||||
template <typename REG, typename REG_MI_MODE>
|
||||
bool _reset_engine()
|
||||
{
|
||||
if (!_stop_engine<REG, REG_MI_MODE>())
|
||||
return false;
|
||||
|
||||
typename REG::access_t v = 0;
|
||||
REG::Mask_bits::set(v, 1);
|
||||
REG::Request_reset::set(v, 1);
|
||||
@ -1156,6 +1343,7 @@ class Igd::Mmio : public Genode::Mmio
|
||||
Genode::error("could not reset engine");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1167,18 +1355,23 @@ class Igd::Mmio : public Genode::Mmio
|
||||
bool _reset_engine(unsigned id)
|
||||
{
|
||||
switch (id) {
|
||||
case RCS_ID: return _reset_engine<CS_RESET_CTRL>();
|
||||
case BCS_ID: return _reset_engine<BCS_RESET_CTRL>();
|
||||
case RCS_ID: return _reset_engine<CS_RESET_CTRL, CS_MI_MODE_CTRL>();
|
||||
case BCS_ID: return _reset_engine<BCS_RESET_CTRL, BCS_MI_MODE_CTRL>();
|
||||
default: return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool _reset_engines()
|
||||
{
|
||||
bool reset_failed = false;
|
||||
|
||||
for (int i = 0; i < NUM_ENGINES; i++) {
|
||||
if (!_reset_engine(i)) { return false; }
|
||||
if (!_reset_engine(i)) {
|
||||
reset_failed = true;
|
||||
Genode::warning("engine ", i, " reset failed");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return !reset_failed;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1186,8 +1379,6 @@ class Igd::Mmio : public Genode::Mmio
|
||||
*/
|
||||
void _reset_device()
|
||||
{
|
||||
_fw_enable(FORCEWAKE_ID_RENDER);
|
||||
|
||||
bool res = _reset_engines();
|
||||
if (!res) {
|
||||
Genode::warning("cannot reset device, engines not ready");
|
||||
@ -1201,8 +1392,6 @@ class Igd::Mmio : public Genode::Mmio
|
||||
} catch (Mmio::Polling_timeout) {
|
||||
Genode::error("resetting device failed");
|
||||
}
|
||||
|
||||
_fw_disable(FORCEWAKE_ID_RENDER);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1240,18 +1429,86 @@ class Igd::Mmio : public Genode::Mmio
|
||||
(void)read<T>();
|
||||
}
|
||||
|
||||
void forcewake_enable() { _fw_enable(FORCEWAKE_ID_RENDER); }
|
||||
void forcewake_disable() { _fw_disable(FORCEWAKE_ID_RENDER); }
|
||||
void forcewake_gen8_enable() { _fw_enable(FORCEWAKE_ID_RENDER); }
|
||||
void forcewake_gen8_disable() { _fw_disable(FORCEWAKE_ID_RENDER); }
|
||||
|
||||
void reset()
|
||||
void forcewake_gen9_enable()
|
||||
{
|
||||
_fw_enable_gt();
|
||||
_fw_enable_render();
|
||||
_fw_enable_media();
|
||||
}
|
||||
|
||||
void forcewake_gen9_disable()
|
||||
{
|
||||
_fw_disable_media();
|
||||
_fw_disable_render();
|
||||
_fw_disable_gt();
|
||||
}
|
||||
|
||||
void forcewake_enable(unsigned const generation)
|
||||
{
|
||||
switch (generation) {
|
||||
case 8:
|
||||
forcewake_gen8_enable();
|
||||
return;
|
||||
case 9:
|
||||
forcewake_gen9_enable();
|
||||
return;
|
||||
default:
|
||||
Genode::error(__func__, " unsupported generation ", generation);
|
||||
}
|
||||
}
|
||||
|
||||
void forcewake_disable(unsigned const generation)
|
||||
{
|
||||
switch (generation) {
|
||||
case 8:
|
||||
forcewake_gen8_disable();
|
||||
return;
|
||||
case 9:
|
||||
forcewake_gen9_disable();
|
||||
return;
|
||||
default:
|
||||
Genode::error(__func__, " unsupported generation ", generation);
|
||||
}
|
||||
}
|
||||
|
||||
void reset(unsigned const generation)
|
||||
{
|
||||
switch (generation) {
|
||||
case 8:
|
||||
reset_gen8();
|
||||
return;
|
||||
case 9:
|
||||
reset_gen9();
|
||||
return;
|
||||
default:
|
||||
Genode::error(__func__, " unsupported generation ", generation);
|
||||
}
|
||||
}
|
||||
|
||||
void reset_gen8()
|
||||
{
|
||||
_intr_reset();
|
||||
_fw_reset_gen8();
|
||||
forcewake_gen8_enable();
|
||||
_reset_device();
|
||||
_fw_reset();
|
||||
_reset_fences();
|
||||
|
||||
_disable_nde_handshake();
|
||||
_set_page_attributes();
|
||||
}
|
||||
|
||||
void reset_gen9()
|
||||
{
|
||||
_intr_reset();
|
||||
_fw_reset_gen9();
|
||||
forcewake_gen9_enable();
|
||||
_reset_device();
|
||||
_reset_fences();
|
||||
|
||||
_disable_nde_handshake();
|
||||
_set_page_attributes();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user