drm/i915/skl: Read the pipe WM HW state
This patch provides the implementation for reading the pipe wm HW state. v2: Incorporated Damien's review comments and also made modifications to incorporate the plane/cursor split. v3: No need to ident a line that was fitting 80 chars Return early instead of indenting the remaining of a function (Damien) v4: Rebase on top of nightly (minor conflict in intel_drv.h) v5: Rebase on top of nightly (minor conflict in intel_drv.h) v6: Rebase on top of nightly (minor conflict in intel_drv.h) Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
Родитель
8211bd5bdf
Коммит
3078999f2a
|
@ -13266,7 +13266,9 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
|
|||
pll->on = false;
|
||||
}
|
||||
|
||||
if (HAS_PCH_SPLIT(dev))
|
||||
if (IS_GEN9(dev))
|
||||
skl_wm_get_hw_state(dev);
|
||||
else if (HAS_PCH_SPLIT(dev))
|
||||
ilk_wm_get_hw_state(dev);
|
||||
|
||||
if (force_restore) {
|
||||
|
|
|
@ -1164,6 +1164,7 @@ void gen6_update_ring_freq(struct drm_device *dev);
|
|||
void gen6_rps_idle(struct drm_i915_private *dev_priv);
|
||||
void gen6_rps_boost(struct drm_i915_private *dev_priv);
|
||||
void ilk_wm_get_hw_state(struct drm_device *dev);
|
||||
void skl_wm_get_hw_state(struct drm_device *dev);
|
||||
|
||||
|
||||
/* intel_sdvo.c */
|
||||
|
|
|
@ -3624,6 +3624,110 @@ ilk_update_sprite_wm(struct drm_plane *plane,
|
|||
ilk_update_wm(crtc);
|
||||
}
|
||||
|
||||
static void skl_pipe_wm_active_state(uint32_t val,
|
||||
struct skl_pipe_wm *active,
|
||||
bool is_transwm,
|
||||
bool is_cursor,
|
||||
int i,
|
||||
int level)
|
||||
{
|
||||
bool is_enabled = (val & PLANE_WM_EN) != 0;
|
||||
|
||||
if (!is_transwm) {
|
||||
if (!is_cursor) {
|
||||
active->wm[level].plane_en[i] = is_enabled;
|
||||
active->wm[level].plane_res_b[i] =
|
||||
val & PLANE_WM_BLOCKS_MASK;
|
||||
active->wm[level].plane_res_l[i] =
|
||||
(val >> PLANE_WM_LINES_SHIFT) &
|
||||
PLANE_WM_LINES_MASK;
|
||||
} else {
|
||||
active->wm[level].cursor_en = is_enabled;
|
||||
active->wm[level].cursor_res_b =
|
||||
val & PLANE_WM_BLOCKS_MASK;
|
||||
active->wm[level].cursor_res_l =
|
||||
(val >> PLANE_WM_LINES_SHIFT) &
|
||||
PLANE_WM_LINES_MASK;
|
||||
}
|
||||
} else {
|
||||
if (!is_cursor) {
|
||||
active->trans_wm.plane_en[i] = is_enabled;
|
||||
active->trans_wm.plane_res_b[i] =
|
||||
val & PLANE_WM_BLOCKS_MASK;
|
||||
active->trans_wm.plane_res_l[i] =
|
||||
(val >> PLANE_WM_LINES_SHIFT) &
|
||||
PLANE_WM_LINES_MASK;
|
||||
} else {
|
||||
active->trans_wm.cursor_en = is_enabled;
|
||||
active->trans_wm.cursor_res_b =
|
||||
val & PLANE_WM_BLOCKS_MASK;
|
||||
active->trans_wm.cursor_res_l =
|
||||
(val >> PLANE_WM_LINES_SHIFT) &
|
||||
PLANE_WM_LINES_MASK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct skl_wm_values *hw = &dev_priv->wm.skl_hw;
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||
struct skl_pipe_wm *active = &intel_crtc->wm.skl_active;
|
||||
enum pipe pipe = intel_crtc->pipe;
|
||||
int level, i, max_level;
|
||||
uint32_t temp;
|
||||
|
||||
max_level = ilk_wm_max_level(dev);
|
||||
|
||||
hw->wm_linetime[pipe] = I915_READ(PIPE_WM_LINETIME(pipe));
|
||||
|
||||
for (level = 0; level <= max_level; level++) {
|
||||
for (i = 0; i < intel_num_planes(intel_crtc); i++)
|
||||
hw->plane[pipe][i][level] =
|
||||
I915_READ(PLANE_WM(pipe, i, level));
|
||||
hw->cursor[pipe][level] = I915_READ(CUR_WM(pipe, level));
|
||||
}
|
||||
|
||||
for (i = 0; i < intel_num_planes(intel_crtc); i++)
|
||||
hw->plane_trans[pipe][i] = I915_READ(PLANE_WM_TRANS(pipe, i));
|
||||
hw->cursor_trans[pipe] = I915_READ(CUR_WM_TRANS(pipe));
|
||||
|
||||
if (!intel_crtc_active(crtc))
|
||||
return;
|
||||
|
||||
hw->dirty[pipe] = true;
|
||||
|
||||
active->linetime = hw->wm_linetime[pipe];
|
||||
|
||||
for (level = 0; level <= max_level; level++) {
|
||||
for (i = 0; i < intel_num_planes(intel_crtc); i++) {
|
||||
temp = hw->plane[pipe][i][level];
|
||||
skl_pipe_wm_active_state(temp, active, false,
|
||||
false, i, level);
|
||||
}
|
||||
temp = hw->cursor[pipe][level];
|
||||
skl_pipe_wm_active_state(temp, active, false, true, i, level);
|
||||
}
|
||||
|
||||
for (i = 0; i < intel_num_planes(intel_crtc); i++) {
|
||||
temp = hw->plane_trans[pipe][i];
|
||||
skl_pipe_wm_active_state(temp, active, true, false, i, 0);
|
||||
}
|
||||
|
||||
temp = hw->cursor_trans[pipe];
|
||||
skl_pipe_wm_active_state(temp, active, true, true, i, 0);
|
||||
}
|
||||
|
||||
void skl_wm_get_hw_state(struct drm_device *dev)
|
||||
{
|
||||
struct drm_crtc *crtc;
|
||||
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
|
||||
skl_pipe_wm_get_hw_state(crtc);
|
||||
}
|
||||
|
||||
static void ilk_pipe_wm_get_hw_state(struct drm_crtc *crtc)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
|
|
Загрузка…
Ссылка в новой задаче