Merge tag 'drm-intel-next-queued-2020-11-27' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
drm/i915 features for v5.11: Highlights: - Enable big joiner to join two pipes to one port to overcome pipe restrictions (Manasi, Ville, Maarten) Display: - More DG1 enabling (Lucas, Aditya) - Fixes to cases without display (Lucas, José, Jani) - Initial PSR state improvements (José) - JSL eDP vswing updates (Tejas) - Handle EDID declared max 16 bpc (Ville) - Display refactoring (Ville) Other: - GVT features - Backmerge Signed-off-by: Dave Airlie <airlied@redhat.com> From: Jani Nikula <jani.nikula@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/87czzzkk1s.fsf@intel.com
This commit is contained in:
Коммит
46fe37b98e
|
@ -1492,11 +1492,10 @@ static void gen11_dsi_get_config(struct intel_encoder *encoder,
|
|||
struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
|
||||
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
|
||||
|
||||
intel_dsc_get_config(encoder, pipe_config);
|
||||
|
||||
/* FIXME: adapt icl_ddi_clock_get() for DSI and use that? */
|
||||
pipe_config->port_clock = intel_dpll_get_freq(i915,
|
||||
pipe_config->shared_dpll);
|
||||
pipe_config->shared_dpll,
|
||||
&pipe_config->dpll_hw_state);
|
||||
|
||||
pipe_config->hw.adjusted_mode.crtc_clock = intel_dsi->pclk;
|
||||
if (intel_dsi->dual_link)
|
||||
|
|
|
@ -133,7 +133,6 @@ int intel_digital_connector_atomic_check(struct drm_connector *conn,
|
|||
struct drm_crtc_state *crtc_state;
|
||||
|
||||
intel_hdcp_atomic_check(conn, old_state, new_state);
|
||||
intel_psr_atomic_check(conn, old_state, new_state);
|
||||
|
||||
if (!new_state->crtc)
|
||||
return 0;
|
||||
|
@ -270,14 +269,15 @@ void intel_crtc_free_hw_state(struct intel_crtc_state *crtc_state)
|
|||
intel_crtc_put_color_blobs(crtc_state);
|
||||
}
|
||||
|
||||
void intel_crtc_copy_color_blobs(struct intel_crtc_state *crtc_state)
|
||||
void intel_crtc_copy_color_blobs(struct intel_crtc_state *crtc_state,
|
||||
const struct intel_crtc_state *from_crtc_state)
|
||||
{
|
||||
drm_property_replace_blob(&crtc_state->hw.degamma_lut,
|
||||
crtc_state->uapi.degamma_lut);
|
||||
from_crtc_state->uapi.degamma_lut);
|
||||
drm_property_replace_blob(&crtc_state->hw.gamma_lut,
|
||||
crtc_state->uapi.gamma_lut);
|
||||
from_crtc_state->uapi.gamma_lut);
|
||||
drm_property_replace_blob(&crtc_state->hw.ctm,
|
||||
crtc_state->uapi.ctm);
|
||||
from_crtc_state->uapi.ctm);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -43,7 +43,8 @@ struct drm_crtc_state *intel_crtc_duplicate_state(struct drm_crtc *crtc);
|
|||
void intel_crtc_destroy_state(struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *state);
|
||||
void intel_crtc_free_hw_state(struct intel_crtc_state *crtc_state);
|
||||
void intel_crtc_copy_color_blobs(struct intel_crtc_state *crtc_state);
|
||||
void intel_crtc_copy_color_blobs(struct intel_crtc_state *crtc_state,
|
||||
const struct intel_crtc_state *from_crtc_state);
|
||||
struct drm_atomic_state *intel_atomic_state_alloc(struct drm_device *dev);
|
||||
void intel_atomic_state_free(struct drm_atomic_state *state);
|
||||
void intel_atomic_state_clear(struct drm_atomic_state *state);
|
||||
|
|
|
@ -247,11 +247,19 @@ static void intel_plane_clear_hw_state(struct intel_plane_state *plane_state)
|
|||
}
|
||||
|
||||
void intel_plane_copy_uapi_to_hw_state(struct intel_plane_state *plane_state,
|
||||
const struct intel_plane_state *from_plane_state)
|
||||
const struct intel_plane_state *from_plane_state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
intel_plane_clear_hw_state(plane_state);
|
||||
|
||||
plane_state->hw.crtc = from_plane_state->uapi.crtc;
|
||||
/*
|
||||
* For the bigjoiner slave uapi.crtc will point at
|
||||
* the master crtc. So we explicitly assign the right
|
||||
* slave crtc to hw.crtc. uapi.crtc!=NULL simply indicates
|
||||
* the plane is logically enabled on the uapi level.
|
||||
*/
|
||||
plane_state->hw.crtc = from_plane_state->uapi.crtc ? &crtc->base : NULL;
|
||||
|
||||
plane_state->hw.fb = from_plane_state->uapi.fb;
|
||||
if (plane_state->hw.fb)
|
||||
drm_framebuffer_get(plane_state->hw.fb);
|
||||
|
@ -263,6 +271,21 @@ void intel_plane_copy_uapi_to_hw_state(struct intel_plane_state *plane_state,
|
|||
plane_state->hw.color_encoding = from_plane_state->uapi.color_encoding;
|
||||
plane_state->hw.color_range = from_plane_state->uapi.color_range;
|
||||
plane_state->hw.scaling_filter = from_plane_state->uapi.scaling_filter;
|
||||
|
||||
plane_state->uapi.src = drm_plane_state_src(&from_plane_state->uapi);
|
||||
plane_state->uapi.dst = drm_plane_state_dest(&from_plane_state->uapi);
|
||||
}
|
||||
|
||||
void intel_plane_copy_hw_state(struct intel_plane_state *plane_state,
|
||||
const struct intel_plane_state *from_plane_state)
|
||||
{
|
||||
intel_plane_clear_hw_state(plane_state);
|
||||
|
||||
memcpy(&plane_state->hw, &from_plane_state->hw,
|
||||
sizeof(plane_state->hw));
|
||||
|
||||
if (plane_state->hw.fb)
|
||||
drm_framebuffer_get(plane_state->hw.fb);
|
||||
}
|
||||
|
||||
void intel_plane_set_invisible(struct intel_crtc_state *crtc_state,
|
||||
|
@ -319,15 +342,16 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
|
|||
old_plane_state, new_plane_state);
|
||||
}
|
||||
|
||||
static struct intel_crtc *
|
||||
get_crtc_from_states(const struct intel_plane_state *old_plane_state,
|
||||
const struct intel_plane_state *new_plane_state)
|
||||
static struct intel_plane *
|
||||
intel_crtc_get_plane(struct intel_crtc *crtc, enum plane_id plane_id)
|
||||
{
|
||||
if (new_plane_state->uapi.crtc)
|
||||
return to_intel_crtc(new_plane_state->uapi.crtc);
|
||||
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
|
||||
struct intel_plane *plane;
|
||||
|
||||
if (old_plane_state->uapi.crtc)
|
||||
return to_intel_crtc(old_plane_state->uapi.crtc);
|
||||
for_each_intel_plane_on_crtc(&i915->drm, crtc, plane) {
|
||||
if (plane->id == plane_id)
|
||||
return plane;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -335,23 +359,37 @@ get_crtc_from_states(const struct intel_plane_state *old_plane_state,
|
|||
int intel_plane_atomic_check(struct intel_atomic_state *state,
|
||||
struct intel_plane *plane)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(state->base.dev);
|
||||
struct intel_plane_state *new_plane_state =
|
||||
intel_atomic_get_new_plane_state(state, plane);
|
||||
const struct intel_plane_state *old_plane_state =
|
||||
intel_atomic_get_old_plane_state(state, plane);
|
||||
struct intel_crtc *crtc =
|
||||
get_crtc_from_states(old_plane_state, new_plane_state);
|
||||
const struct intel_crtc_state *old_crtc_state;
|
||||
struct intel_crtc_state *new_crtc_state;
|
||||
const struct intel_plane_state *new_master_plane_state;
|
||||
struct intel_crtc *crtc = intel_get_crtc_for_pipe(i915, plane->pipe);
|
||||
const struct intel_crtc_state *old_crtc_state =
|
||||
intel_atomic_get_old_crtc_state(state, crtc);
|
||||
struct intel_crtc_state *new_crtc_state =
|
||||
intel_atomic_get_new_crtc_state(state, crtc);
|
||||
|
||||
if (new_crtc_state && new_crtc_state->bigjoiner_slave) {
|
||||
struct intel_plane *master_plane =
|
||||
intel_crtc_get_plane(new_crtc_state->bigjoiner_linked_crtc,
|
||||
plane->id);
|
||||
|
||||
new_master_plane_state =
|
||||
intel_atomic_get_new_plane_state(state, master_plane);
|
||||
} else {
|
||||
new_master_plane_state = new_plane_state;
|
||||
}
|
||||
|
||||
intel_plane_copy_uapi_to_hw_state(new_plane_state,
|
||||
new_master_plane_state,
|
||||
crtc);
|
||||
|
||||
intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state);
|
||||
new_plane_state->uapi.visible = false;
|
||||
if (!crtc)
|
||||
if (!new_crtc_state)
|
||||
return 0;
|
||||
|
||||
old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc);
|
||||
new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
|
||||
|
||||
return intel_plane_atomic_check_with_state(old_crtc_state,
|
||||
new_crtc_state,
|
||||
old_plane_state,
|
||||
|
@ -479,6 +517,63 @@ void i9xx_update_planes_on_crtc(struct intel_atomic_state *state,
|
|||
}
|
||||
}
|
||||
|
||||
int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state,
|
||||
struct intel_crtc_state *crtc_state,
|
||||
int min_scale, int max_scale,
|
||||
bool can_position)
|
||||
{
|
||||
struct drm_framebuffer *fb = plane_state->hw.fb;
|
||||
struct drm_rect *src = &plane_state->uapi.src;
|
||||
struct drm_rect *dst = &plane_state->uapi.dst;
|
||||
unsigned int rotation = plane_state->hw.rotation;
|
||||
struct drm_rect clip = {};
|
||||
int hscale, vscale;
|
||||
|
||||
if (!fb) {
|
||||
plane_state->uapi.visible = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
drm_rect_rotate(src, fb->width << 16, fb->height << 16, rotation);
|
||||
|
||||
/* Check scaling */
|
||||
hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
|
||||
vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
|
||||
if (hscale < 0 || vscale < 0) {
|
||||
DRM_DEBUG_KMS("Invalid scaling of plane\n");
|
||||
drm_rect_debug_print("src: ", src, true);
|
||||
drm_rect_debug_print("dst: ", dst, false);
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
if (crtc_state->hw.enable) {
|
||||
clip.x2 = crtc_state->pipe_src_w;
|
||||
clip.y2 = crtc_state->pipe_src_h;
|
||||
}
|
||||
|
||||
/* right side of the image is on the slave crtc, adjust dst to match */
|
||||
if (crtc_state->bigjoiner_slave)
|
||||
drm_rect_translate(dst, -crtc_state->pipe_src_w, 0);
|
||||
|
||||
/*
|
||||
* FIXME: This might need further adjustment for seamless scaling
|
||||
* with phase information, for the 2p2 and 2p1 scenarios.
|
||||
*/
|
||||
plane_state->uapi.visible = drm_rect_clip_scaled(src, dst, &clip);
|
||||
|
||||
drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, rotation);
|
||||
|
||||
if (!can_position && plane_state->uapi.visible &&
|
||||
!drm_rect_equals(dst, &clip)) {
|
||||
DRM_DEBUG_KMS("Plane must cover entire CRTC\n");
|
||||
drm_rect_debug_print("dst: ", dst, false);
|
||||
drm_rect_debug_print("clip: ", &clip, false);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct drm_plane_helper_funcs intel_plane_helper_funcs = {
|
||||
.prepare_fb = intel_prepare_plane_fb,
|
||||
.cleanup_fb = intel_cleanup_plane_fb,
|
||||
|
|
|
@ -24,7 +24,10 @@ unsigned int intel_plane_pixel_rate(const struct intel_crtc_state *crtc_state,
|
|||
unsigned int intel_plane_data_rate(const struct intel_crtc_state *crtc_state,
|
||||
const struct intel_plane_state *plane_state);
|
||||
void intel_plane_copy_uapi_to_hw_state(struct intel_plane_state *plane_state,
|
||||
const struct intel_plane_state *from_plane_state);
|
||||
const struct intel_plane_state *from_plane_state,
|
||||
struct intel_crtc *crtc);
|
||||
void intel_plane_copy_hw_state(struct intel_plane_state *plane_state,
|
||||
const struct intel_plane_state *from_plane_state);
|
||||
void intel_update_plane(struct intel_plane *plane,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
const struct intel_plane_state *plane_state);
|
||||
|
@ -52,6 +55,10 @@ int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_stat
|
|||
int intel_plane_calc_min_cdclk(struct intel_atomic_state *state,
|
||||
struct intel_plane *plane,
|
||||
bool *need_cdclk_calc);
|
||||
int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state,
|
||||
struct intel_crtc_state *crtc_state,
|
||||
int min_scale, int max_scale,
|
||||
bool can_position);
|
||||
void intel_plane_set_invisible(struct intel_crtc_state *crtc_state,
|
||||
struct intel_plane_state *plane_state);
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <drm/drm_scdc_helper.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_trace.h"
|
||||
#include "intel_audio.h"
|
||||
#include "intel_combo_phy.h"
|
||||
#include "intel_connector.h"
|
||||
|
@ -582,6 +583,34 @@ static const struct cnl_ddi_buf_trans ehl_combo_phy_ddi_translations_dp[] = {
|
|||
{ 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 900 900 0.0 */
|
||||
};
|
||||
|
||||
static const struct cnl_ddi_buf_trans jsl_combo_phy_ddi_translations_edp_hbr[] = {
|
||||
/* NT mV Trans mV db */
|
||||
{ 0x8, 0x7F, 0x3F, 0x00, 0x00 }, /* 200 200 0.0 */
|
||||
{ 0x8, 0x7F, 0x38, 0x00, 0x07 }, /* 200 250 1.9 */
|
||||
{ 0x1, 0x7F, 0x33, 0x00, 0x0C }, /* 200 300 3.5 */
|
||||
{ 0xA, 0x35, 0x36, 0x00, 0x09 }, /* 200 350 4.9 */
|
||||
{ 0x8, 0x7F, 0x3F, 0x00, 0x00 }, /* 250 250 0.0 */
|
||||
{ 0x1, 0x7F, 0x38, 0x00, 0x07 }, /* 250 300 1.6 */
|
||||
{ 0xA, 0x35, 0x35, 0x00, 0x0A }, /* 250 350 2.9 */
|
||||
{ 0x1, 0x7F, 0x3F, 0x00, 0x00 }, /* 300 300 0.0 */
|
||||
{ 0xA, 0x35, 0x38, 0x00, 0x07 }, /* 300 350 1.3 */
|
||||
{ 0xA, 0x35, 0x3F, 0x00, 0x00 }, /* 350 350 0.0 */
|
||||
};
|
||||
|
||||
static const struct cnl_ddi_buf_trans jsl_combo_phy_ddi_translations_edp_hbr2[] = {
|
||||
/* NT mV Trans mV db */
|
||||
{ 0x8, 0x7F, 0x3F, 0x00, 0x00 }, /* 200 200 0.0 */
|
||||
{ 0x8, 0x7F, 0x3F, 0x00, 0x00 }, /* 200 250 1.9 */
|
||||
{ 0x1, 0x7F, 0x3D, 0x00, 0x02 }, /* 200 300 3.5 */
|
||||
{ 0xA, 0x35, 0x38, 0x00, 0x07 }, /* 200 350 4.9 */
|
||||
{ 0x8, 0x7F, 0x3F, 0x00, 0x00 }, /* 250 250 0.0 */
|
||||
{ 0x1, 0x7F, 0x3F, 0x00, 0x00 }, /* 250 300 1.6 */
|
||||
{ 0xA, 0x35, 0x3A, 0x00, 0x05 }, /* 250 350 2.9 */
|
||||
{ 0x1, 0x7F, 0x3F, 0x00, 0x00 }, /* 300 300 0.0 */
|
||||
{ 0xA, 0x35, 0x38, 0x00, 0x07 }, /* 300 350 1.3 */
|
||||
{ 0xA, 0x35, 0x3F, 0x00, 0x00 }, /* 350 350 0.0 */
|
||||
};
|
||||
|
||||
struct icl_mg_phy_ddi_buf_trans {
|
||||
u32 cri_txdeemph_override_11_6;
|
||||
u32 cri_txdeemph_override_5_0;
|
||||
|
@ -1162,6 +1191,57 @@ ehl_get_combo_buf_trans(struct intel_encoder *encoder,
|
|||
return ehl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
|
||||
}
|
||||
|
||||
static const struct cnl_ddi_buf_trans *
|
||||
jsl_get_combo_buf_trans_hdmi(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
int *n_entries)
|
||||
{
|
||||
*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_hdmi);
|
||||
return icl_combo_phy_ddi_translations_hdmi;
|
||||
}
|
||||
|
||||
static const struct cnl_ddi_buf_trans *
|
||||
jsl_get_combo_buf_trans_dp(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
int *n_entries)
|
||||
{
|
||||
*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hbr2);
|
||||
return icl_combo_phy_ddi_translations_dp_hbr2;
|
||||
}
|
||||
|
||||
static const struct cnl_ddi_buf_trans *
|
||||
jsl_get_combo_buf_trans_edp(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
int *n_entries)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
|
||||
if (dev_priv->vbt.edp.low_vswing) {
|
||||
if (crtc_state->port_clock > 270000) {
|
||||
*n_entries = ARRAY_SIZE(jsl_combo_phy_ddi_translations_edp_hbr2);
|
||||
return jsl_combo_phy_ddi_translations_edp_hbr2;
|
||||
} else {
|
||||
*n_entries = ARRAY_SIZE(jsl_combo_phy_ddi_translations_edp_hbr);
|
||||
return jsl_combo_phy_ddi_translations_edp_hbr;
|
||||
}
|
||||
}
|
||||
|
||||
return jsl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
|
||||
}
|
||||
|
||||
static const struct cnl_ddi_buf_trans *
|
||||
jsl_get_combo_buf_trans(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
int *n_entries)
|
||||
{
|
||||
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
|
||||
return jsl_get_combo_buf_trans_hdmi(encoder, crtc_state, n_entries);
|
||||
else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
|
||||
return jsl_get_combo_buf_trans_edp(encoder, crtc_state, n_entries);
|
||||
else
|
||||
return jsl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
|
||||
}
|
||||
|
||||
static const struct cnl_ddi_buf_trans *
|
||||
tgl_get_combo_buf_trans_hdmi(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
|
@ -1676,7 +1756,8 @@ static void intel_ddi_clock_get(struct intel_encoder *encoder,
|
|||
encoder->port);
|
||||
else
|
||||
pipe_config->port_clock =
|
||||
intel_dpll_get_freq(dev_priv, pipe_config->shared_dpll);
|
||||
intel_dpll_get_freq(dev_priv, pipe_config->shared_dpll,
|
||||
&pipe_config->dpll_hw_state);
|
||||
|
||||
ddi_dotclock_get(pipe_config);
|
||||
}
|
||||
|
@ -2216,13 +2297,6 @@ static void intel_ddi_get_power_domains(struct intel_encoder *encoder,
|
|||
intel_phy_is_tc(dev_priv, phy))
|
||||
intel_display_power_get(dev_priv,
|
||||
intel_ddi_main_link_aux_domain(dig_port));
|
||||
|
||||
/*
|
||||
* VDSC power is needed when DSC is enabled
|
||||
*/
|
||||
if (crtc_state->dsc.compression_enable)
|
||||
intel_display_power_get(dev_priv,
|
||||
intel_dsc_power_domain(crtc_state));
|
||||
}
|
||||
|
||||
void intel_ddi_enable_pipe_clock(struct intel_encoder *encoder,
|
||||
|
@ -2363,7 +2437,9 @@ static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp,
|
|||
else
|
||||
tgl_get_dkl_buf_trans(encoder, crtc_state, &n_entries);
|
||||
} else if (INTEL_GEN(dev_priv) == 11) {
|
||||
if (IS_JSL_EHL(dev_priv))
|
||||
if (IS_PLATFORM(dev_priv, INTEL_JASPERLAKE))
|
||||
jsl_get_combo_buf_trans(encoder, crtc_state, &n_entries);
|
||||
else if (IS_PLATFORM(dev_priv, INTEL_ELKHARTLAKE))
|
||||
ehl_get_combo_buf_trans(encoder, crtc_state, &n_entries);
|
||||
else if (intel_phy_is_combo(dev_priv, phy))
|
||||
icl_get_combo_buf_trans(encoder, crtc_state, &n_entries);
|
||||
|
@ -2544,7 +2620,9 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder,
|
|||
|
||||
if (INTEL_GEN(dev_priv) >= 12)
|
||||
ddi_translations = tgl_get_combo_buf_trans(encoder, crtc_state, &n_entries);
|
||||
else if (IS_JSL_EHL(dev_priv))
|
||||
else if (IS_PLATFORM(dev_priv, INTEL_JASPERLAKE))
|
||||
ddi_translations = jsl_get_combo_buf_trans(encoder, crtc_state, &n_entries);
|
||||
else if (IS_PLATFORM(dev_priv, INTEL_ELKHARTLAKE))
|
||||
ddi_translations = ehl_get_combo_buf_trans(encoder, crtc_state, &n_entries);
|
||||
else
|
||||
ddi_translations = icl_get_combo_buf_trans(encoder, crtc_state, &n_entries);
|
||||
|
@ -2970,6 +3048,40 @@ static u32 icl_dpclka_cfgcr0_clk_off(struct drm_i915_private *dev_priv,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void dg1_map_plls_to_ports(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_shared_dpll *pll = crtc_state->shared_dpll;
|
||||
enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
|
||||
u32 val;
|
||||
|
||||
/*
|
||||
* If we fail this, something went very wrong: first 2 PLLs should be
|
||||
* used by first 2 phys and last 2 PLLs by last phys
|
||||
*/
|
||||
if (drm_WARN_ON(&dev_priv->drm,
|
||||
(pll->info->id < DPLL_ID_DG1_DPLL2 && phy >= PHY_C) ||
|
||||
(pll->info->id >= DPLL_ID_DG1_DPLL2 && phy < PHY_C)))
|
||||
return;
|
||||
|
||||
mutex_lock(&dev_priv->dpll.lock);
|
||||
|
||||
val = intel_de_read(dev_priv, DG1_DPCLKA_CFGCR0(phy));
|
||||
drm_WARN_ON(&dev_priv->drm,
|
||||
(val & DG1_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)) == 0);
|
||||
|
||||
val &= ~DG1_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy);
|
||||
val |= DG1_DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, phy);
|
||||
intel_de_write(dev_priv, DG1_DPCLKA_CFGCR0(phy), val);
|
||||
intel_de_posting_read(dev_priv, DG1_DPCLKA_CFGCR0(phy));
|
||||
|
||||
val &= ~DG1_DPCLKA_CFGCR0_DDI_CLK_OFF(phy);
|
||||
intel_de_write(dev_priv, DG1_DPCLKA_CFGCR0(phy), val);
|
||||
|
||||
mutex_unlock(&dev_priv->dpll.lock);
|
||||
}
|
||||
|
||||
static void icl_map_plls_to_ports(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
|
@ -3017,6 +3129,19 @@ static void icl_map_plls_to_ports(struct intel_encoder *encoder,
|
|||
mutex_unlock(&dev_priv->dpll.lock);
|
||||
}
|
||||
|
||||
static void dg1_unmap_plls_to_ports(struct intel_encoder *encoder)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
|
||||
|
||||
mutex_lock(&dev_priv->dpll.lock);
|
||||
|
||||
intel_de_rmw(dev_priv, DG1_DPCLKA_CFGCR0(phy), 0,
|
||||
DG1_DPCLKA_CFGCR0_DDI_CLK_OFF(phy));
|
||||
|
||||
mutex_unlock(&dev_priv->dpll.lock);
|
||||
}
|
||||
|
||||
static void icl_unmap_plls_to_ports(struct intel_encoder *encoder)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
|
@ -3032,6 +3157,37 @@ static void icl_unmap_plls_to_ports(struct intel_encoder *encoder)
|
|||
mutex_unlock(&dev_priv->dpll.lock);
|
||||
}
|
||||
|
||||
static void dg1_sanitize_port_clk_off(struct drm_i915_private *dev_priv,
|
||||
u32 port_mask, bool ddi_clk_needed)
|
||||
{
|
||||
enum port port;
|
||||
u32 val;
|
||||
|
||||
for_each_port_masked(port, port_mask) {
|
||||
enum phy phy = intel_port_to_phy(dev_priv, port);
|
||||
bool ddi_clk_off;
|
||||
|
||||
val = intel_de_read(dev_priv, DG1_DPCLKA_CFGCR0(phy));
|
||||
ddi_clk_off = val & DG1_DPCLKA_CFGCR0_DDI_CLK_OFF(phy);
|
||||
|
||||
if (ddi_clk_needed == !ddi_clk_off)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Punt on the case now where clock is gated, but it would
|
||||
* be needed by the port. Something else is really broken then.
|
||||
*/
|
||||
if (drm_WARN_ON(&dev_priv->drm, ddi_clk_needed))
|
||||
continue;
|
||||
|
||||
drm_notice(&dev_priv->drm,
|
||||
"PHY %c is disabled with an ungated DDI clock, gate it\n",
|
||||
phy_name(phy));
|
||||
val |= DG1_DPCLKA_CFGCR0_DDI_CLK_OFF(phy);
|
||||
intel_de_write(dev_priv, DG1_DPCLKA_CFGCR0(phy), val);
|
||||
}
|
||||
}
|
||||
|
||||
static void icl_sanitize_port_clk_off(struct drm_i915_private *dev_priv,
|
||||
u32 port_mask, bool ddi_clk_needed)
|
||||
{
|
||||
|
@ -3114,7 +3270,10 @@ void icl_sanitize_encoder_pll_mapping(struct intel_encoder *encoder)
|
|||
ddi_clk_needed = false;
|
||||
}
|
||||
|
||||
icl_sanitize_port_clk_off(dev_priv, port_mask, ddi_clk_needed);
|
||||
if (IS_DG1(dev_priv))
|
||||
dg1_sanitize_port_clk_off(dev_priv, port_mask, ddi_clk_needed);
|
||||
else
|
||||
icl_sanitize_port_clk_off(dev_priv, port_mask, ddi_clk_needed);
|
||||
}
|
||||
|
||||
static void intel_ddi_clk_select(struct intel_encoder *encoder,
|
||||
|
@ -3507,7 +3666,8 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
|
|||
|
||||
/* 7.l Configure and enable FEC if needed */
|
||||
intel_ddi_enable_fec(encoder, crtc_state);
|
||||
intel_dsc_enable(encoder, crtc_state);
|
||||
if (!crtc_state->bigjoiner)
|
||||
intel_dsc_enable(encoder, crtc_state);
|
||||
}
|
||||
|
||||
static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
|
||||
|
@ -3579,7 +3739,8 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
|
|||
if (!is_mst)
|
||||
intel_ddi_enable_pipe_clock(encoder, crtc_state);
|
||||
|
||||
intel_dsc_enable(encoder, crtc_state);
|
||||
if (!crtc_state->bigjoiner)
|
||||
intel_dsc_enable(encoder, crtc_state);
|
||||
}
|
||||
|
||||
static void intel_ddi_pre_enable_dp(struct intel_atomic_state *state,
|
||||
|
@ -3666,7 +3827,9 @@ static void intel_ddi_pre_enable(struct intel_atomic_state *state,
|
|||
|
||||
drm_WARN_ON(&dev_priv->drm, crtc_state->has_pch_encoder);
|
||||
|
||||
if (INTEL_GEN(dev_priv) >= 11)
|
||||
if (IS_DG1(dev_priv))
|
||||
dg1_map_plls_to_ports(encoder, crtc_state);
|
||||
else if (INTEL_GEN(dev_priv) >= 11)
|
||||
icl_map_plls_to_ports(encoder, crtc_state);
|
||||
|
||||
intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
|
||||
|
@ -3828,6 +3991,21 @@ static void intel_ddi_post_disable(struct intel_atomic_state *state,
|
|||
ilk_pfit_disable(old_crtc_state);
|
||||
}
|
||||
|
||||
if (old_crtc_state->bigjoiner_linked_crtc) {
|
||||
struct intel_atomic_state *state =
|
||||
to_intel_atomic_state(old_crtc_state->uapi.state);
|
||||
struct intel_crtc *slave =
|
||||
old_crtc_state->bigjoiner_linked_crtc;
|
||||
const struct intel_crtc_state *old_slave_crtc_state =
|
||||
intel_atomic_get_old_crtc_state(state, slave);
|
||||
|
||||
intel_crtc_vblank_off(old_slave_crtc_state);
|
||||
trace_intel_pipe_disable(slave);
|
||||
|
||||
intel_dsc_disable(old_slave_crtc_state);
|
||||
skl_scaler_disable(old_slave_crtc_state);
|
||||
}
|
||||
|
||||
/*
|
||||
* When called from DP MST code:
|
||||
* - old_conn_state will be NULL
|
||||
|
@ -3848,7 +4026,9 @@ static void intel_ddi_post_disable(struct intel_atomic_state *state,
|
|||
intel_ddi_post_disable_dp(state, encoder, old_crtc_state,
|
||||
old_conn_state);
|
||||
|
||||
if (INTEL_GEN(dev_priv) >= 11)
|
||||
if (IS_DG1(dev_priv))
|
||||
dg1_unmap_plls_to_ports(encoder);
|
||||
else if (INTEL_GEN(dev_priv) >= 11)
|
||||
icl_unmap_plls_to_ports(encoder);
|
||||
|
||||
if (intel_crtc_has_dp_encoder(old_crtc_state) || is_tc_port)
|
||||
|
@ -4044,7 +4224,8 @@ static void intel_enable_ddi(struct intel_atomic_state *state,
|
|||
{
|
||||
drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder);
|
||||
|
||||
intel_ddi_enable_transcoder_func(encoder, crtc_state);
|
||||
if (!crtc_state->bigjoiner_slave)
|
||||
intel_ddi_enable_transcoder_func(encoder, crtc_state);
|
||||
|
||||
intel_enable_pipe(crtc_state);
|
||||
|
||||
|
@ -4396,20 +4577,14 @@ static void bdw_get_trans_port_sync_config(struct intel_crtc_state *crtc_state)
|
|||
crtc_state->sync_mode_slaves_mask);
|
||||
}
|
||||
|
||||
void intel_ddi_get_config(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *pipe_config)
|
||||
static void intel_ddi_read_func_ctl(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *pipe_config)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
|
||||
enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
|
||||
u32 temp, flags = 0;
|
||||
|
||||
/* XXX: DSI transcoder paranoia */
|
||||
if (drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder)))
|
||||
return;
|
||||
|
||||
intel_dsc_get_config(encoder, pipe_config);
|
||||
|
||||
temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
|
||||
if (temp & TRANS_DDI_PHSYNC)
|
||||
flags |= DRM_MODE_FLAG_PHSYNC;
|
||||
|
@ -4503,6 +4678,30 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
|
|||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void intel_ddi_get_config(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *pipe_config)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
|
||||
|
||||
/* XXX: DSI transcoder paranoia */
|
||||
if (drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder)))
|
||||
return;
|
||||
|
||||
if (pipe_config->bigjoiner_slave) {
|
||||
/* read out pipe settings from master */
|
||||
enum transcoder save = pipe_config->cpu_transcoder;
|
||||
|
||||
/* Our own transcoder needs to be disabled when reading it in intel_ddi_read_func_ctl() */
|
||||
WARN_ON(pipe_config->output_types);
|
||||
pipe_config->cpu_transcoder = (enum transcoder)pipe_config->bigjoiner_linked_crtc->pipe;
|
||||
intel_ddi_read_func_ctl(encoder, pipe_config);
|
||||
pipe_config->cpu_transcoder = save;
|
||||
} else {
|
||||
intel_ddi_read_func_ctl(encoder, pipe_config);
|
||||
}
|
||||
|
||||
pipe_config->has_audio =
|
||||
intel_ddi_is_audio_enabled(dev_priv, cpu_transcoder);
|
||||
|
@ -4528,7 +4727,8 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
|
|||
dev_priv->vbt.edp.bpp = pipe_config->pipe_bpp;
|
||||
}
|
||||
|
||||
intel_ddi_clock_get(encoder, pipe_config);
|
||||
if (!pipe_config->bigjoiner_slave)
|
||||
intel_ddi_clock_get(encoder, pipe_config);
|
||||
|
||||
if (IS_GEN9_LP(dev_priv))
|
||||
pipe_config->lane_lat_optim_mask =
|
||||
|
@ -5126,6 +5326,9 @@ static enum hpd_pin cnl_hpd_pin(struct drm_i915_private *dev_priv,
|
|||
return HPD_PORT_A + port - PORT_A;
|
||||
}
|
||||
|
||||
#define port_tc_name(port) ((port) - PORT_TC1 + '1')
|
||||
#define tc_port_name(tc_port) ((tc_port) - TC_PORT_1 + '1')
|
||||
|
||||
void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
|
||||
{
|
||||
struct intel_digital_port *dig_port;
|
||||
|
@ -5181,9 +5384,9 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
|
|||
DRM_MODE_ENCODER_TMDS,
|
||||
"DDI %s%c/PHY %s%c",
|
||||
port >= PORT_TC1 ? "TC" : "",
|
||||
port >= PORT_TC1 ? port_name(port) : port - PORT_TC1 + '1',
|
||||
port >= PORT_TC1 ? port_tc_name(port) : port_name(port),
|
||||
tc_port != TC_PORT_NONE ? "TC" : "",
|
||||
tc_port != TC_PORT_NONE ? phy_name(phy) : tc_port - TC_PORT_1 + '1');
|
||||
tc_port != TC_PORT_NONE ? tc_port_name(tc_port) : phy_name(phy));
|
||||
} else if (INTEL_GEN(dev_priv) >= 11) {
|
||||
enum tc_port tc_port = intel_port_to_tc(dev_priv, port);
|
||||
|
||||
|
@ -5193,7 +5396,7 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
|
|||
port_name(port),
|
||||
port >= PORT_C ? " (TC)" : "",
|
||||
tc_port != TC_PORT_NONE ? "TC" : "",
|
||||
tc_port != TC_PORT_NONE ? phy_name(phy) : tc_port - TC_PORT_1 + '1');
|
||||
tc_port != TC_PORT_NONE ? tc_port_name(tc_port) : phy_name(phy));
|
||||
} else {
|
||||
drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs,
|
||||
DRM_MODE_ENCODER_TMDS,
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -513,7 +513,8 @@ u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv,
|
|||
bool intel_plane_can_remap(const struct intel_plane_state *plane_state);
|
||||
enum drm_mode_status
|
||||
intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
|
||||
const struct drm_display_mode *mode);
|
||||
const struct drm_display_mode *mode,
|
||||
bool bigjoiner);
|
||||
enum phy intel_port_to_phy(struct drm_i915_private *i915, enum port port);
|
||||
bool is_trans_port_sync_mode(const struct intel_crtc_state *state);
|
||||
|
||||
|
@ -590,8 +591,8 @@ void vlv_force_pll_off(struct drm_i915_private *dev_priv, enum pipe pipe);
|
|||
int lpt_get_iclkip(struct drm_i915_private *dev_priv);
|
||||
bool intel_fuzzy_clock_check(int clock1, int clock2);
|
||||
|
||||
void intel_prepare_reset(struct drm_i915_private *dev_priv);
|
||||
void intel_finish_reset(struct drm_i915_private *dev_priv);
|
||||
void intel_display_prepare_reset(struct drm_i915_private *dev_priv);
|
||||
void intel_display_finish_reset(struct drm_i915_private *dev_priv);
|
||||
void intel_dp_get_m_n(struct intel_crtc *crtc,
|
||||
struct intel_crtc_state *pipe_config);
|
||||
void intel_dp_set_m_n(const struct intel_crtc_state *crtc_state,
|
||||
|
@ -609,8 +610,6 @@ enum intel_display_power_domain
|
|||
intel_aux_power_domain(struct intel_digital_port *dig_port);
|
||||
enum intel_display_power_domain
|
||||
intel_legacy_aux_to_power_domain(enum aux_ch aux_ch);
|
||||
void intel_mode_from_pipe_config(struct drm_display_mode *mode,
|
||||
struct intel_crtc_state *pipe_config);
|
||||
void intel_crtc_arm_fifo_underrun(struct intel_crtc *crtc,
|
||||
struct intel_crtc_state *crtc_state);
|
||||
|
||||
|
|
|
@ -755,6 +755,17 @@ static void plane_rotation(char *buf, size_t bufsize, unsigned int rotation)
|
|||
rotation);
|
||||
}
|
||||
|
||||
static const char *plane_visibility(const struct intel_plane_state *plane_state)
|
||||
{
|
||||
if (plane_state->uapi.visible)
|
||||
return "visible";
|
||||
|
||||
if (plane_state->planar_slave)
|
||||
return "planar-slave";
|
||||
|
||||
return "hidden";
|
||||
}
|
||||
|
||||
static void intel_plane_uapi_info(struct seq_file *m, struct intel_plane *plane)
|
||||
{
|
||||
const struct intel_plane_state *plane_state =
|
||||
|
@ -773,12 +784,19 @@ static void intel_plane_uapi_info(struct seq_file *m, struct intel_plane *plane)
|
|||
plane_rotation(rot_str, sizeof(rot_str),
|
||||
plane_state->uapi.rotation);
|
||||
|
||||
seq_printf(m, "\t\tuapi: fb=%d,%s,%dx%d, src=" DRM_RECT_FP_FMT ", dst=" DRM_RECT_FMT ", rotation=%s\n",
|
||||
seq_printf(m, "\t\tuapi: [FB:%d] %s,0x%llx,%dx%d, visible=%s, src=" DRM_RECT_FP_FMT ", dst=" DRM_RECT_FMT ", rotation=%s\n",
|
||||
fb ? fb->base.id : 0, fb ? format_name.str : "n/a",
|
||||
fb ? fb->modifier : 0,
|
||||
fb ? fb->width : 0, fb ? fb->height : 0,
|
||||
plane_visibility(plane_state),
|
||||
DRM_RECT_FP_ARG(&src),
|
||||
DRM_RECT_ARG(&dst),
|
||||
rot_str);
|
||||
|
||||
if (plane_state->planar_linked_plane)
|
||||
seq_printf(m, "\t\tplanar: Linked to [PLANE:%d:%s] as a %s\n",
|
||||
plane_state->planar_linked_plane->base.base.id, plane_state->planar_linked_plane->base.name,
|
||||
plane_state->planar_slave ? "slave" : "master");
|
||||
}
|
||||
|
||||
static void intel_plane_hw_info(struct seq_file *m, struct intel_plane *plane)
|
||||
|
@ -797,9 +815,9 @@ static void intel_plane_hw_info(struct seq_file *m, struct intel_plane *plane)
|
|||
plane_rotation(rot_str, sizeof(rot_str),
|
||||
plane_state->hw.rotation);
|
||||
|
||||
seq_printf(m, "\t\thw: fb=%d,%s,%dx%d, visible=%s, src=" DRM_RECT_FP_FMT ", dst=" DRM_RECT_FMT ", rotation=%s\n",
|
||||
seq_printf(m, "\t\thw: [FB:%d] %s,0x%llx,%dx%d, visible=%s, src=" DRM_RECT_FP_FMT ", dst=" DRM_RECT_FMT ", rotation=%s\n",
|
||||
fb->base.id, format_name.str,
|
||||
fb->width, fb->height,
|
||||
fb->modifier, fb->width, fb->height,
|
||||
yesno(plane_state->uapi.visible),
|
||||
DRM_RECT_FP_ARG(&plane_state->uapi.src),
|
||||
DRM_RECT_ARG(&plane_state->uapi.dst),
|
||||
|
@ -874,6 +892,12 @@ static void intel_crtc_info(struct seq_file *m, struct intel_crtc *crtc)
|
|||
intel_scaler_info(m, crtc);
|
||||
}
|
||||
|
||||
if (crtc_state->bigjoiner)
|
||||
seq_printf(m, "\tLinked to [CRTC:%d:%s] as a %s\n",
|
||||
crtc_state->bigjoiner_linked_crtc->base.base.id,
|
||||
crtc_state->bigjoiner_linked_crtc->base.name,
|
||||
crtc_state->bigjoiner_slave ? "slave" : "master");
|
||||
|
||||
for_each_intel_encoder_mask(&dev_priv->drm, encoder,
|
||||
crtc_state->uapi.encoder_mask)
|
||||
intel_encoder_info(m, crtc, encoder);
|
||||
|
|
|
@ -4492,30 +4492,24 @@ static u32 get_allowed_dc_mask(const struct drm_i915_private *dev_priv,
|
|||
int requested_dc;
|
||||
int max_dc;
|
||||
|
||||
if (INTEL_GEN(dev_priv) >= 12) {
|
||||
if (IS_DG1(dev_priv))
|
||||
max_dc = 3;
|
||||
else
|
||||
max_dc = 4;
|
||||
/*
|
||||
* DC9 has a separate HW flow from the rest of the DC states,
|
||||
* not depending on the DMC firmware. It's needed by system
|
||||
* suspend/resume, so allow it unconditionally.
|
||||
*/
|
||||
mask = DC_STATE_EN_DC9;
|
||||
} else if (IS_GEN(dev_priv, 11)) {
|
||||
if (IS_DG1(dev_priv))
|
||||
max_dc = 3;
|
||||
else if (INTEL_GEN(dev_priv) >= 12)
|
||||
max_dc = 4;
|
||||
else if (INTEL_GEN(dev_priv) >= 10 || IS_GEN9_BC(dev_priv))
|
||||
max_dc = 2;
|
||||
mask = DC_STATE_EN_DC9;
|
||||
} else if (IS_GEN(dev_priv, 10) || IS_GEN9_BC(dev_priv)) {
|
||||
max_dc = 2;
|
||||
mask = 0;
|
||||
} else if (IS_GEN9_LP(dev_priv)) {
|
||||
else if (IS_GEN9_LP(dev_priv))
|
||||
max_dc = 1;
|
||||
mask = DC_STATE_EN_DC9;
|
||||
} else {
|
||||
else
|
||||
max_dc = 0;
|
||||
mask = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* DC9 has a separate HW flow from the rest of the DC states,
|
||||
* not depending on the DMC firmware. It's needed by system
|
||||
* suspend/resume, so allow it unconditionally.
|
||||
*/
|
||||
mask = IS_GEN9_LP(dev_priv) || INTEL_GEN(dev_priv) >= 11 ?
|
||||
DC_STATE_EN_DC9 : 0;
|
||||
|
||||
if (!dev_priv->params.disable_power_well)
|
||||
max_dc = 0;
|
||||
|
@ -5858,10 +5852,15 @@ static void intel_power_domains_verify_state(struct drm_i915_private *i915)
|
|||
|
||||
void intel_display_power_suspend_late(struct drm_i915_private *i915)
|
||||
{
|
||||
if (INTEL_GEN(i915) >= 11 || IS_GEN9_LP(i915))
|
||||
if (INTEL_GEN(i915) >= 11 || IS_GEN9_LP(i915)) {
|
||||
bxt_enable_dc9(i915);
|
||||
else if (IS_HASWELL(i915) || IS_BROADWELL(i915))
|
||||
/* Tweaked Wa_14010685332:icp,jsp,mcc */
|
||||
if (INTEL_PCH_TYPE(i915) >= PCH_ICP && INTEL_PCH_TYPE(i915) <= PCH_MCC)
|
||||
intel_de_rmw(i915, SOUTH_CHICKEN1,
|
||||
SBCLK_RUN_REFCLK_DIS, SBCLK_RUN_REFCLK_DIS);
|
||||
} else if (IS_HASWELL(i915) || IS_BROADWELL(i915)) {
|
||||
hsw_enable_pc8(i915);
|
||||
}
|
||||
}
|
||||
|
||||
void intel_display_power_resume_early(struct drm_i915_private *i915)
|
||||
|
@ -5869,6 +5868,10 @@ void intel_display_power_resume_early(struct drm_i915_private *i915)
|
|||
if (INTEL_GEN(i915) >= 11 || IS_GEN9_LP(i915)) {
|
||||
gen9_sanitize_dc_state(i915);
|
||||
bxt_disable_dc9(i915);
|
||||
/* Tweaked Wa_14010685332:icp,jsp,mcc */
|
||||
if (INTEL_PCH_TYPE(i915) >= PCH_ICP && INTEL_PCH_TYPE(i915) <= PCH_MCC)
|
||||
intel_de_rmw(i915, SOUTH_CHICKEN1, SBCLK_RUN_REFCLK_DIS, 0);
|
||||
|
||||
} else if (IS_HASWELL(i915) || IS_BROADWELL(i915)) {
|
||||
hsw_disable_pc8(i915);
|
||||
}
|
||||
|
|
|
@ -686,6 +686,7 @@ struct skl_wm_level {
|
|||
u8 plane_res_l;
|
||||
bool plane_en;
|
||||
bool ignore_lines;
|
||||
bool can_sagv;
|
||||
};
|
||||
|
||||
struct skl_plane_wm {
|
||||
|
@ -737,24 +738,35 @@ struct g4x_wm_state {
|
|||
|
||||
struct intel_crtc_wm_state {
|
||||
union {
|
||||
/*
|
||||
* raw:
|
||||
* The "raw" watermark values produced by the formula
|
||||
* given the plane's current state. They do not consider
|
||||
* how much FIFO is actually allocated for each plane.
|
||||
*
|
||||
* optimal:
|
||||
* The "optimal" watermark values given the current
|
||||
* state of the planes and the amount of FIFO
|
||||
* allocated to each, ignoring any previous state
|
||||
* of the planes.
|
||||
*
|
||||
* intermediate:
|
||||
* The "intermediate" watermark values when transitioning
|
||||
* between the old and new "optimal" values. Used when
|
||||
* the watermark registers are single buffered and hence
|
||||
* their state changes asynchronously with regards to the
|
||||
* actual plane registers. These are essentially the
|
||||
* worst case combination of the old and new "optimal"
|
||||
* watermarks, which are therefore safe to use when the
|
||||
* plane is in either its old or new state.
|
||||
*/
|
||||
struct {
|
||||
/*
|
||||
* Intermediate watermarks; these can be
|
||||
* programmed immediately since they satisfy
|
||||
* both the current configuration we're
|
||||
* switching away from and the new
|
||||
* configuration we're switching to.
|
||||
*/
|
||||
struct intel_pipe_wm intermediate;
|
||||
|
||||
/*
|
||||
* Optimal watermarks, programmed post-vblank
|
||||
* when this state is committed.
|
||||
*/
|
||||
struct intel_pipe_wm optimal;
|
||||
} ilk;
|
||||
|
||||
struct {
|
||||
struct skl_pipe_wm raw;
|
||||
/* gen9+ only needs 1-step wm programming */
|
||||
struct skl_pipe_wm optimal;
|
||||
struct skl_ddb_entry ddb;
|
||||
|
@ -763,22 +775,15 @@ struct intel_crtc_wm_state {
|
|||
} skl;
|
||||
|
||||
struct {
|
||||
/* "raw" watermarks (not inverted) */
|
||||
struct g4x_pipe_wm raw[NUM_VLV_WM_LEVELS];
|
||||
/* intermediate watermarks (inverted) */
|
||||
struct vlv_wm_state intermediate;
|
||||
/* optimal watermarks (inverted) */
|
||||
struct vlv_wm_state optimal;
|
||||
/* display FIFO split */
|
||||
struct g4x_pipe_wm raw[NUM_VLV_WM_LEVELS]; /* not inverted */
|
||||
struct vlv_wm_state intermediate; /* inverted */
|
||||
struct vlv_wm_state optimal; /* inverted */
|
||||
struct vlv_fifo_state fifo_state;
|
||||
} vlv;
|
||||
|
||||
struct {
|
||||
/* "raw" watermarks */
|
||||
struct g4x_pipe_wm raw[NUM_G4X_WM_LEVELS];
|
||||
/* intermediate watermarks */
|
||||
struct g4x_wm_state intermediate;
|
||||
/* optimal watermarks */
|
||||
struct g4x_wm_state optimal;
|
||||
} g4x;
|
||||
};
|
||||
|
@ -817,15 +822,22 @@ struct intel_crtc_state {
|
|||
* The following members are used to verify the hardware state:
|
||||
* - enable
|
||||
* - active
|
||||
* - mode / adjusted_mode
|
||||
* - mode / pipe_mode / adjusted_mode
|
||||
* - color property blobs.
|
||||
*
|
||||
* During initial hw readout, they need to be copied to uapi.
|
||||
*
|
||||
* Bigjoiner will allow a transcoder mode that spans 2 pipes;
|
||||
* Use the pipe_mode for calculations like watermarks, pipe
|
||||
* scaler, and bandwidth.
|
||||
*
|
||||
* Use adjusted_mode for things that need to know the full
|
||||
* mode on the transcoder, which spans all pipes.
|
||||
*/
|
||||
struct {
|
||||
bool active, enable;
|
||||
struct drm_property_blob *degamma_lut, *gamma_lut, *ctm;
|
||||
struct drm_display_mode mode, adjusted_mode;
|
||||
struct drm_display_mode mode, pipe_mode, adjusted_mode;
|
||||
enum drm_scaling_filter scaling_filter;
|
||||
} hw;
|
||||
|
||||
|
@ -838,6 +850,7 @@ struct intel_crtc_state {
|
|||
* accordingly.
|
||||
*/
|
||||
#define PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS (1<<0) /* unreliable sync mode.flags */
|
||||
#define PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE (1<<1) /* bigjoiner slave, partial readout */
|
||||
unsigned long quirks;
|
||||
|
||||
unsigned fb_bits; /* framebuffers to flip */
|
||||
|
@ -1019,6 +1032,10 @@ struct intel_crtc_state {
|
|||
|
||||
u32 data_rate[I915_MAX_PLANES];
|
||||
|
||||
/* FIXME unify with data_rate[] */
|
||||
u64 plane_data_rate[I915_MAX_PLANES];
|
||||
u64 uv_plane_data_rate[I915_MAX_PLANES];
|
||||
|
||||
/* Gamma mode programmed on the pipe */
|
||||
u32 gamma_mode;
|
||||
|
||||
|
@ -1063,6 +1080,15 @@ struct intel_crtc_state {
|
|||
/* enable pipe csc? */
|
||||
bool csc_enable;
|
||||
|
||||
/* enable pipe big joiner? */
|
||||
bool bigjoiner;
|
||||
|
||||
/* big joiner slave crtc? */
|
||||
bool bigjoiner_slave;
|
||||
|
||||
/* linked crtc for bigjoiner, either slave or master */
|
||||
struct intel_crtc *bigjoiner_linked_crtc;
|
||||
|
||||
/* Display Stream compression state */
|
||||
struct {
|
||||
bool compression_enable;
|
||||
|
@ -1189,6 +1215,15 @@ struct intel_plane {
|
|||
* the intel_plane_state structure and accessed via plane_state.
|
||||
*/
|
||||
|
||||
int (*min_width)(const struct drm_framebuffer *fb,
|
||||
int color_plane,
|
||||
unsigned int rotation);
|
||||
int (*max_width)(const struct drm_framebuffer *fb,
|
||||
int color_plane,
|
||||
unsigned int rotation);
|
||||
int (*max_height)(const struct drm_framebuffer *fb,
|
||||
int color_plane,
|
||||
unsigned int rotation);
|
||||
unsigned int (*max_stride)(struct intel_plane *plane,
|
||||
u32 pixel_format, u64 modifier,
|
||||
unsigned int rotation);
|
||||
|
|
|
@ -254,6 +254,17 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes)
|
|||
return max_link_clock * max_lanes;
|
||||
}
|
||||
|
||||
bool intel_dp_can_bigjoiner(struct intel_dp *intel_dp)
|
||||
{
|
||||
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
|
||||
struct intel_encoder *encoder = &intel_dig_port->base;
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
|
||||
return INTEL_GEN(dev_priv) >= 12 ||
|
||||
(INTEL_GEN(dev_priv) == 11 &&
|
||||
encoder->port != PORT_A);
|
||||
}
|
||||
|
||||
static int cnl_max_source_rate(struct intel_dp *intel_dp)
|
||||
{
|
||||
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
|
||||
|
@ -519,7 +530,8 @@ small_joiner_ram_size_bits(struct drm_i915_private *i915)
|
|||
|
||||
static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
|
||||
u32 link_clock, u32 lane_count,
|
||||
u32 mode_clock, u32 mode_hdisplay)
|
||||
u32 mode_clock, u32 mode_hdisplay,
|
||||
bool bigjoiner)
|
||||
{
|
||||
u32 bits_per_pixel, max_bpp_small_joiner_ram;
|
||||
int i;
|
||||
|
@ -537,6 +549,10 @@ static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
|
|||
/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
|
||||
max_bpp_small_joiner_ram = small_joiner_ram_size_bits(i915) /
|
||||
mode_hdisplay;
|
||||
|
||||
if (bigjoiner)
|
||||
max_bpp_small_joiner_ram *= 2;
|
||||
|
||||
drm_dbg_kms(&i915->drm, "Max small joiner bpp: %u\n",
|
||||
max_bpp_small_joiner_ram);
|
||||
|
||||
|
@ -546,6 +562,15 @@ static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
|
|||
*/
|
||||
bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
|
||||
|
||||
if (bigjoiner) {
|
||||
u32 max_bpp_bigjoiner =
|
||||
i915->max_cdclk_freq * 48 /
|
||||
intel_dp_mode_to_fec_clock(mode_clock);
|
||||
|
||||
DRM_DEBUG_KMS("Max big joiner bpp: %u\n", max_bpp_bigjoiner);
|
||||
bits_per_pixel = min(bits_per_pixel, max_bpp_bigjoiner);
|
||||
}
|
||||
|
||||
/* Error out if the max bpp is less than smallest allowed valid bpp */
|
||||
if (bits_per_pixel < valid_dsc_bpp[0]) {
|
||||
drm_dbg_kms(&i915->drm, "Unsupported BPP %u, min %u\n",
|
||||
|
@ -568,7 +593,8 @@ static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
|
|||
}
|
||||
|
||||
static u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
|
||||
int mode_clock, int mode_hdisplay)
|
||||
int mode_clock, int mode_hdisplay,
|
||||
bool bigjoiner)
|
||||
{
|
||||
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
|
||||
u8 min_slice_count, i;
|
||||
|
@ -595,12 +621,18 @@ static u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
|
|||
|
||||
/* Find the closest match to the valid slice count values */
|
||||
for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
|
||||
if (valid_dsc_slicecount[i] >
|
||||
drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
|
||||
false))
|
||||
u8 test_slice_count = valid_dsc_slicecount[i] << bigjoiner;
|
||||
|
||||
if (test_slice_count >
|
||||
drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd, false))
|
||||
break;
|
||||
if (min_slice_count <= valid_dsc_slicecount[i])
|
||||
return valid_dsc_slicecount[i];
|
||||
|
||||
/* big joiner needs small joiner to be enabled */
|
||||
if (bigjoiner && test_slice_count < 4)
|
||||
continue;
|
||||
|
||||
if (min_slice_count <= test_slice_count)
|
||||
return test_slice_count;
|
||||
}
|
||||
|
||||
drm_dbg_kms(&i915->drm, "Unsupported Slice Count %d\n",
|
||||
|
@ -717,10 +749,14 @@ intel_dp_mode_valid(struct drm_connector *connector,
|
|||
u16 dsc_max_output_bpp = 0;
|
||||
u8 dsc_slice_count = 0;
|
||||
enum drm_mode_status status;
|
||||
bool dsc = false, bigjoiner = false;
|
||||
|
||||
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
|
||||
return MODE_NO_DBLESCAN;
|
||||
|
||||
if (mode->flags & DRM_MODE_FLAG_DBLCLK)
|
||||
return MODE_H_ILLEGAL;
|
||||
|
||||
if (intel_dp_is_edp(intel_dp) && fixed_mode) {
|
||||
if (mode->hdisplay > fixed_mode->hdisplay)
|
||||
return MODE_PANEL;
|
||||
|
@ -731,6 +767,17 @@ intel_dp_mode_valid(struct drm_connector *connector,
|
|||
target_clock = fixed_mode->clock;
|
||||
}
|
||||
|
||||
if (mode->clock < 10000)
|
||||
return MODE_CLOCK_LOW;
|
||||
|
||||
if ((target_clock > max_dotclk || mode->hdisplay > 5120) &&
|
||||
intel_dp_can_bigjoiner(intel_dp)) {
|
||||
bigjoiner = true;
|
||||
max_dotclk *= 2;
|
||||
}
|
||||
if (target_clock > max_dotclk)
|
||||
return MODE_CLOCK_HIGH;
|
||||
|
||||
max_link_clock = intel_dp_max_link_rate(intel_dp);
|
||||
max_lanes = intel_dp_max_lane_count(intel_dp);
|
||||
|
||||
|
@ -759,30 +806,31 @@ intel_dp_mode_valid(struct drm_connector *connector,
|
|||
max_link_clock,
|
||||
max_lanes,
|
||||
target_clock,
|
||||
mode->hdisplay) >> 4;
|
||||
mode->hdisplay,
|
||||
bigjoiner) >> 4;
|
||||
dsc_slice_count =
|
||||
intel_dp_dsc_get_slice_count(intel_dp,
|
||||
target_clock,
|
||||
mode->hdisplay);
|
||||
mode->hdisplay,
|
||||
bigjoiner);
|
||||
}
|
||||
|
||||
dsc = dsc_max_output_bpp && dsc_slice_count;
|
||||
}
|
||||
|
||||
if ((mode_rate > max_rate && !(dsc_max_output_bpp && dsc_slice_count)) ||
|
||||
target_clock > max_dotclk)
|
||||
/* big joiner configuration needs DSC */
|
||||
if (bigjoiner && !dsc)
|
||||
return MODE_CLOCK_HIGH;
|
||||
|
||||
if (mode->clock < 10000)
|
||||
return MODE_CLOCK_LOW;
|
||||
|
||||
if (mode->flags & DRM_MODE_FLAG_DBLCLK)
|
||||
return MODE_H_ILLEGAL;
|
||||
if (mode_rate > max_rate && !dsc)
|
||||
return MODE_CLOCK_HIGH;
|
||||
|
||||
status = intel_dp_mode_valid_downstream(intel_connector,
|
||||
mode, target_clock);
|
||||
if (status != MODE_OK)
|
||||
return status;
|
||||
|
||||
return intel_mode_valid_max_plane_size(dev_priv, mode);
|
||||
return intel_mode_valid_max_plane_size(dev_priv, mode, bigjoiner);
|
||||
}
|
||||
|
||||
u32 intel_dp_pack_aux(const u8 *src, int src_bytes)
|
||||
|
@ -2052,12 +2100,10 @@ static bool intel_dp_supports_fec(struct intel_dp *intel_dp,
|
|||
static bool intel_dp_supports_dsc(struct intel_dp *intel_dp,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
|
||||
|
||||
if (!intel_dp_is_edp(intel_dp) && !crtc_state->fec_enable)
|
||||
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP) && !crtc_state->fec_enable)
|
||||
return false;
|
||||
|
||||
return intel_dsc_source_support(encoder, crtc_state) &&
|
||||
return intel_dsc_source_support(crtc_state) &&
|
||||
drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd);
|
||||
}
|
||||
|
||||
|
@ -2351,11 +2397,13 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
|
|||
pipe_config->port_clock,
|
||||
pipe_config->lane_count,
|
||||
adjusted_mode->crtc_clock,
|
||||
adjusted_mode->crtc_hdisplay);
|
||||
adjusted_mode->crtc_hdisplay,
|
||||
pipe_config->bigjoiner);
|
||||
dsc_dp_slice_count =
|
||||
intel_dp_dsc_get_slice_count(intel_dp,
|
||||
adjusted_mode->crtc_clock,
|
||||
adjusted_mode->crtc_hdisplay);
|
||||
adjusted_mode->crtc_hdisplay,
|
||||
pipe_config->bigjoiner);
|
||||
if (!dsc_max_output_bpp || !dsc_dp_slice_count) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"Compressed BPP/Slice Count not supported\n");
|
||||
|
@ -2371,14 +2419,15 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
|
|||
* is greater than the maximum Cdclock and if slice count is even
|
||||
* then we need to use 2 VDSC instances.
|
||||
*/
|
||||
if (adjusted_mode->crtc_clock > dev_priv->max_cdclk_freq) {
|
||||
if (pipe_config->dsc.slice_count > 1) {
|
||||
pipe_config->dsc.dsc_split = true;
|
||||
} else {
|
||||
if (adjusted_mode->crtc_clock > dev_priv->max_cdclk_freq ||
|
||||
pipe_config->bigjoiner) {
|
||||
if (pipe_config->dsc.slice_count < 2) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"Cannot split stream to use 2 VDSC instances\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pipe_config->dsc.dsc_split = true;
|
||||
}
|
||||
|
||||
ret = intel_dp_dsc_compute_params(&dig_port->base, pipe_config);
|
||||
|
@ -2449,6 +2498,11 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
|
|||
intel_dp->common_rates[limits.max_clock],
|
||||
limits.max_bpp, adjusted_mode->crtc_clock);
|
||||
|
||||
if ((adjusted_mode->crtc_clock > i915->max_dotclk_freq ||
|
||||
adjusted_mode->crtc_hdisplay > 5120) &&
|
||||
intel_dp_can_bigjoiner(intel_dp))
|
||||
pipe_config->bigjoiner = true;
|
||||
|
||||
/*
|
||||
* Optimize for slow and wide. This is the place to add alternative
|
||||
* optimization policy.
|
||||
|
@ -2457,7 +2511,7 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
|
|||
|
||||
/* enable compression if the mode doesn't fit available BW */
|
||||
drm_dbg_kms(&i915->drm, "Force DSC en = %d\n", intel_dp->force_dsc_en);
|
||||
if (ret || intel_dp->force_dsc_en) {
|
||||
if (ret || intel_dp->force_dsc_en || pipe_config->bigjoiner) {
|
||||
ret = intel_dp_dsc_compute_config(intel_dp, pipe_config,
|
||||
conn_state, &limits);
|
||||
if (ret < 0)
|
||||
|
@ -3778,6 +3832,12 @@ bool intel_dp_initial_fastset_check(struct intel_encoder *encoder,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (CAN_PSR(i915) && intel_dp_is_edp(intel_dp)) {
|
||||
drm_dbg_kms(&i915->drm, "Forcing full modeset to compute PSR state\n");
|
||||
crtc_state->uapi.mode_changed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -106,6 +106,7 @@ bool intel_dp_source_supports_hbr3(struct intel_dp *intel_dp);
|
|||
bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp);
|
||||
int intel_dp_link_required(int pixel_clock, int bpp);
|
||||
int intel_dp_max_data_rate(int max_link_clock, int max_lanes);
|
||||
bool intel_dp_can_bigjoiner(struct intel_dp *intel_dp);
|
||||
bool intel_dp_needs_vsc_sdp(const struct intel_crtc_state *crtc_state,
|
||||
const struct drm_connector_state *conn_state);
|
||||
void intel_dp_compute_psr_vsc_sdp(struct intel_dp *intel_dp,
|
||||
|
|
|
@ -714,7 +714,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,
|
|||
return 0;
|
||||
}
|
||||
|
||||
*status = intel_mode_valid_max_plane_size(dev_priv, mode);
|
||||
*status = intel_mode_valid_max_plane_size(dev_priv, mode, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -141,7 +141,7 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv,
|
|||
"asserting DPLL %s with no DPLL\n", onoff(state)))
|
||||
return;
|
||||
|
||||
cur_state = pll->info->funcs->get_hw_state(dev_priv, pll, &hw_state);
|
||||
cur_state = intel_dpll_get_hw_state(dev_priv, pll, &hw_state);
|
||||
I915_STATE_WARN(cur_state != state,
|
||||
"%s assertion failure (expected %s, current %s)\n",
|
||||
pll->info->name, onoff(state), onoff(cur_state));
|
||||
|
@ -891,11 +891,12 @@ hsw_ddi_wrpll_get_dpll(struct intel_atomic_state *state,
|
|||
}
|
||||
|
||||
static int hsw_ddi_wrpll_get_freq(struct drm_i915_private *dev_priv,
|
||||
const struct intel_shared_dpll *pll)
|
||||
const struct intel_shared_dpll *pll,
|
||||
const struct intel_dpll_hw_state *pll_state)
|
||||
{
|
||||
int refclk;
|
||||
int n, p, r;
|
||||
u32 wrpll = pll->state.hw_state.wrpll;
|
||||
u32 wrpll = pll_state->wrpll;
|
||||
|
||||
switch (wrpll & WRPLL_REF_MASK) {
|
||||
case WRPLL_REF_SPECIAL_HSW:
|
||||
|
@ -962,7 +963,8 @@ hsw_ddi_lcpll_get_dpll(struct intel_crtc_state *crtc_state)
|
|||
}
|
||||
|
||||
static int hsw_ddi_lcpll_get_freq(struct drm_i915_private *i915,
|
||||
const struct intel_shared_dpll *pll)
|
||||
const struct intel_shared_dpll *pll,
|
||||
const struct intel_dpll_hw_state *pll_state)
|
||||
{
|
||||
int link_clock = 0;
|
||||
|
||||
|
@ -1002,11 +1004,12 @@ hsw_ddi_spll_get_dpll(struct intel_atomic_state *state,
|
|||
}
|
||||
|
||||
static int hsw_ddi_spll_get_freq(struct drm_i915_private *i915,
|
||||
const struct intel_shared_dpll *pll)
|
||||
const struct intel_shared_dpll *pll,
|
||||
const struct intel_dpll_hw_state *pll_state)
|
||||
{
|
||||
int link_clock = 0;
|
||||
|
||||
switch (pll->state.hw_state.spll & SPLL_FREQ_MASK) {
|
||||
switch (pll_state->spll & SPLL_FREQ_MASK) {
|
||||
case SPLL_FREQ_810MHz:
|
||||
link_clock = 81000;
|
||||
break;
|
||||
|
@ -1577,9 +1580,9 @@ static bool skl_ddi_hdmi_pll_dividers(struct intel_crtc_state *crtc_state)
|
|||
}
|
||||
|
||||
static int skl_ddi_wrpll_get_freq(struct drm_i915_private *i915,
|
||||
const struct intel_shared_dpll *pll)
|
||||
const struct intel_shared_dpll *pll,
|
||||
const struct intel_dpll_hw_state *pll_state)
|
||||
{
|
||||
const struct intel_dpll_hw_state *pll_state = &pll->state.hw_state;
|
||||
int ref_clock = i915->dpll.ref_clks.nssc;
|
||||
u32 p0, p1, p2, dco_freq;
|
||||
|
||||
|
@ -1688,12 +1691,12 @@ skl_ddi_dp_set_dpll_hw_state(struct intel_crtc_state *crtc_state)
|
|||
}
|
||||
|
||||
static int skl_ddi_lcpll_get_freq(struct drm_i915_private *i915,
|
||||
const struct intel_shared_dpll *pll)
|
||||
const struct intel_shared_dpll *pll,
|
||||
const struct intel_dpll_hw_state *pll_state)
|
||||
{
|
||||
int link_clock = 0;
|
||||
|
||||
switch ((pll->state.hw_state.ctrl1 &
|
||||
DPLL_CTRL1_LINK_RATE_MASK(0)) >>
|
||||
switch ((pll_state->ctrl1 & DPLL_CTRL1_LINK_RATE_MASK(0)) >>
|
||||
DPLL_CTRL1_LINK_RATE_SHIFT(0)) {
|
||||
case DPLL_CTRL1_LINK_RATE_810:
|
||||
link_clock = 81000;
|
||||
|
@ -1771,16 +1774,17 @@ static bool skl_get_dpll(struct intel_atomic_state *state,
|
|||
}
|
||||
|
||||
static int skl_ddi_pll_get_freq(struct drm_i915_private *i915,
|
||||
const struct intel_shared_dpll *pll)
|
||||
const struct intel_shared_dpll *pll,
|
||||
const struct intel_dpll_hw_state *pll_state)
|
||||
{
|
||||
/*
|
||||
* ctrl1 register is already shifted for each pll, just use 0 to get
|
||||
* the internal shift for each field
|
||||
*/
|
||||
if (pll->state.hw_state.ctrl1 & DPLL_CTRL1_HDMI_MODE(0))
|
||||
return skl_ddi_wrpll_get_freq(i915, pll);
|
||||
if (pll_state->ctrl1 & DPLL_CTRL1_HDMI_MODE(0))
|
||||
return skl_ddi_wrpll_get_freq(i915, pll, pll_state);
|
||||
else
|
||||
return skl_ddi_lcpll_get_freq(i915, pll);
|
||||
return skl_ddi_lcpll_get_freq(i915, pll, pll_state);
|
||||
}
|
||||
|
||||
static void skl_update_dpll_ref_clks(struct drm_i915_private *i915)
|
||||
|
@ -2218,9 +2222,9 @@ bxt_ddi_hdmi_set_dpll_hw_state(struct intel_crtc_state *crtc_state)
|
|||
}
|
||||
|
||||
static int bxt_ddi_pll_get_freq(struct drm_i915_private *i915,
|
||||
const struct intel_shared_dpll *pll)
|
||||
const struct intel_shared_dpll *pll,
|
||||
const struct intel_dpll_hw_state *pll_state)
|
||||
{
|
||||
const struct intel_dpll_hw_state *pll_state = &pll->state.hw_state;
|
||||
struct dpll clock;
|
||||
|
||||
clock.m1 = 2;
|
||||
|
@ -2636,20 +2640,23 @@ static bool cnl_ddi_hdmi_pll_dividers(struct intel_crtc_state *crtc_state)
|
|||
}
|
||||
|
||||
/*
|
||||
* Display WA #22010492432: tgl
|
||||
* Display WA #22010492432: ehl, tgl
|
||||
* Program half of the nominal DCO divider fraction value.
|
||||
*/
|
||||
static bool
|
||||
tgl_combo_pll_div_frac_wa_needed(struct drm_i915_private *i915)
|
||||
ehl_combo_pll_div_frac_wa_needed(struct drm_i915_private *i915)
|
||||
{
|
||||
return IS_TIGERLAKE(i915) && i915->dpll.ref_clks.nssc == 38400;
|
||||
return ((IS_PLATFORM(i915, INTEL_ELKHARTLAKE) &&
|
||||
IS_JSL_EHL_REVID(i915, EHL_REVID_B0, REVID_FOREVER)) ||
|
||||
IS_TIGERLAKE(i915)) &&
|
||||
i915->dpll.ref_clks.nssc == 38400;
|
||||
}
|
||||
|
||||
static int __cnl_ddi_wrpll_get_freq(struct drm_i915_private *dev_priv,
|
||||
const struct intel_shared_dpll *pll,
|
||||
const struct intel_dpll_hw_state *pll_state,
|
||||
int ref_clock)
|
||||
{
|
||||
const struct intel_dpll_hw_state *pll_state = &pll->state.hw_state;
|
||||
u32 dco_fraction;
|
||||
u32 p0, p1, p2, dco_freq;
|
||||
|
||||
|
@ -2696,7 +2703,7 @@ static int __cnl_ddi_wrpll_get_freq(struct drm_i915_private *dev_priv,
|
|||
dco_fraction = (pll_state->cfgcr0 & DPLL_CFGCR0_DCO_FRACTION_MASK) >>
|
||||
DPLL_CFGCR0_DCO_FRACTION_SHIFT;
|
||||
|
||||
if (tgl_combo_pll_div_frac_wa_needed(dev_priv))
|
||||
if (ehl_combo_pll_div_frac_wa_needed(dev_priv))
|
||||
dco_fraction *= 2;
|
||||
|
||||
dco_freq += (dco_fraction * ref_clock) / 0x8000;
|
||||
|
@ -2708,9 +2715,11 @@ static int __cnl_ddi_wrpll_get_freq(struct drm_i915_private *dev_priv,
|
|||
}
|
||||
|
||||
static int cnl_ddi_wrpll_get_freq(struct drm_i915_private *i915,
|
||||
const struct intel_shared_dpll *pll)
|
||||
const struct intel_shared_dpll *pll,
|
||||
const struct intel_dpll_hw_state *pll_state)
|
||||
{
|
||||
return __cnl_ddi_wrpll_get_freq(i915, pll, i915->dpll.ref_clks.nssc);
|
||||
return __cnl_ddi_wrpll_get_freq(i915, pll, pll_state,
|
||||
i915->dpll.ref_clks.nssc);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -2759,11 +2768,12 @@ cnl_ddi_dp_set_dpll_hw_state(struct intel_crtc_state *crtc_state)
|
|||
}
|
||||
|
||||
static int cnl_ddi_lcpll_get_freq(struct drm_i915_private *i915,
|
||||
const struct intel_shared_dpll *pll)
|
||||
const struct intel_shared_dpll *pll,
|
||||
const struct intel_dpll_hw_state *pll_state)
|
||||
{
|
||||
int link_clock = 0;
|
||||
|
||||
switch (pll->state.hw_state.cfgcr0 & DPLL_CFGCR0_LINK_RATE_MASK) {
|
||||
switch (pll_state->cfgcr0 & DPLL_CFGCR0_LINK_RATE_MASK) {
|
||||
case DPLL_CFGCR0_LINK_RATE_810:
|
||||
link_clock = 81000;
|
||||
break;
|
||||
|
@ -2846,12 +2856,13 @@ static bool cnl_get_dpll(struct intel_atomic_state *state,
|
|||
}
|
||||
|
||||
static int cnl_ddi_pll_get_freq(struct drm_i915_private *i915,
|
||||
const struct intel_shared_dpll *pll)
|
||||
const struct intel_shared_dpll *pll,
|
||||
const struct intel_dpll_hw_state *pll_state)
|
||||
{
|
||||
if (pll->state.hw_state.cfgcr0 & DPLL_CFGCR0_HDMI_MODE)
|
||||
return cnl_ddi_wrpll_get_freq(i915, pll);
|
||||
if (pll_state->cfgcr0 & DPLL_CFGCR0_HDMI_MODE)
|
||||
return cnl_ddi_wrpll_get_freq(i915, pll, pll_state);
|
||||
else
|
||||
return cnl_ddi_lcpll_get_freq(i915, pll);
|
||||
return cnl_ddi_lcpll_get_freq(i915, pll, pll_state);
|
||||
}
|
||||
|
||||
static void cnl_update_dpll_ref_clks(struct drm_i915_private *i915)
|
||||
|
@ -3036,7 +3047,8 @@ static bool icl_calc_tbt_pll(struct intel_crtc_state *crtc_state,
|
|||
}
|
||||
|
||||
static int icl_ddi_tbt_pll_get_freq(struct drm_i915_private *i915,
|
||||
const struct intel_shared_dpll *pll)
|
||||
const struct intel_shared_dpll *pll,
|
||||
const struct intel_dpll_hw_state *pll_state)
|
||||
{
|
||||
/*
|
||||
* The PLL outputs multiple frequencies at the same time, selection is
|
||||
|
@ -3072,9 +3084,10 @@ icl_calc_wrpll(struct intel_crtc_state *crtc_state,
|
|||
}
|
||||
|
||||
static int icl_ddi_combo_pll_get_freq(struct drm_i915_private *i915,
|
||||
const struct intel_shared_dpll *pll)
|
||||
const struct intel_shared_dpll *pll,
|
||||
const struct intel_dpll_hw_state *pll_state)
|
||||
{
|
||||
return __cnl_ddi_wrpll_get_freq(i915, pll,
|
||||
return __cnl_ddi_wrpll_get_freq(i915, pll, pll_state,
|
||||
icl_wrpll_ref_clock(i915));
|
||||
}
|
||||
|
||||
|
@ -3086,7 +3099,7 @@ static void icl_calc_dpll_state(struct drm_i915_private *i915,
|
|||
|
||||
memset(pll_state, 0, sizeof(*pll_state));
|
||||
|
||||
if (tgl_combo_pll_div_frac_wa_needed(i915))
|
||||
if (ehl_combo_pll_div_frac_wa_needed(i915))
|
||||
dco_fraction = DIV_ROUND_CLOSEST(dco_fraction, 2);
|
||||
|
||||
pll_state->cfgcr0 = DPLL_CFGCR0_DCO_FRACTION(dco_fraction) |
|
||||
|
@ -3399,9 +3412,9 @@ static bool icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state,
|
|||
}
|
||||
|
||||
static int icl_ddi_mg_pll_get_freq(struct drm_i915_private *dev_priv,
|
||||
const struct intel_shared_dpll *pll)
|
||||
const struct intel_shared_dpll *pll,
|
||||
const struct intel_dpll_hw_state *pll_state)
|
||||
{
|
||||
const struct intel_dpll_hw_state *pll_state = &pll->state.hw_state;
|
||||
u32 m1, m2_int, m2_frac, div1, div2, ref_clock;
|
||||
u64 tmp;
|
||||
|
||||
|
@ -4512,16 +4525,33 @@ void intel_update_active_dpll(struct intel_atomic_state *state,
|
|||
* intel_dpll_get_freq - calculate the DPLL's output frequency
|
||||
* @i915: i915 device
|
||||
* @pll: DPLL for which to calculate the output frequency
|
||||
* @pll_state: DPLL state from which to calculate the output frequency
|
||||
*
|
||||
* Return the output frequency corresponding to @pll's current state.
|
||||
* Return the output frequency corresponding to @pll's passed in @pll_state.
|
||||
*/
|
||||
int intel_dpll_get_freq(struct drm_i915_private *i915,
|
||||
const struct intel_shared_dpll *pll)
|
||||
const struct intel_shared_dpll *pll,
|
||||
const struct intel_dpll_hw_state *pll_state)
|
||||
{
|
||||
if (drm_WARN_ON(&i915->drm, !pll->info->funcs->get_freq))
|
||||
return 0;
|
||||
|
||||
return pll->info->funcs->get_freq(i915, pll);
|
||||
return pll->info->funcs->get_freq(i915, pll, pll_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_dpll_get_hw_state - readout the DPLL's hardware state
|
||||
* @i915: i915 device
|
||||
* @pll: DPLL for which to calculate the output frequency
|
||||
* @hw_state: DPLL's hardware state
|
||||
*
|
||||
* Read out @pll's hardware state into @hw_state.
|
||||
*/
|
||||
bool intel_dpll_get_hw_state(struct drm_i915_private *i915,
|
||||
struct intel_shared_dpll *pll,
|
||||
struct intel_dpll_hw_state *hw_state)
|
||||
{
|
||||
return pll->info->funcs->get_hw_state(i915, pll, hw_state);
|
||||
}
|
||||
|
||||
static void readout_dpll_hw_state(struct drm_i915_private *i915,
|
||||
|
@ -4529,8 +4559,7 @@ static void readout_dpll_hw_state(struct drm_i915_private *i915,
|
|||
{
|
||||
struct intel_crtc *crtc;
|
||||
|
||||
pll->on = pll->info->funcs->get_hw_state(i915, pll,
|
||||
&pll->state.hw_state);
|
||||
pll->on = intel_dpll_get_hw_state(i915, pll, &pll->state.hw_state);
|
||||
|
||||
if (IS_JSL_EHL(i915) && pll->on &&
|
||||
pll->info->id == DPLL_ID_EHL_DPLL4) {
|
||||
|
|
|
@ -300,10 +300,11 @@ struct intel_shared_dpll_funcs {
|
|||
* @get_freq:
|
||||
*
|
||||
* Hook for calculating the pll's output frequency based on its
|
||||
* current state.
|
||||
* passed in state.
|
||||
*/
|
||||
int (*get_freq)(struct drm_i915_private *i915,
|
||||
const struct intel_shared_dpll *pll);
|
||||
const struct intel_shared_dpll *pll,
|
||||
const struct intel_dpll_hw_state *pll_state);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -399,7 +400,11 @@ void intel_update_active_dpll(struct intel_atomic_state *state,
|
|||
struct intel_crtc *crtc,
|
||||
struct intel_encoder *encoder);
|
||||
int intel_dpll_get_freq(struct drm_i915_private *i915,
|
||||
const struct intel_shared_dpll *pll);
|
||||
const struct intel_shared_dpll *pll,
|
||||
const struct intel_dpll_hw_state *pll_state);
|
||||
bool intel_dpll_get_hw_state(struct drm_i915_private *i915,
|
||||
struct intel_shared_dpll *pll,
|
||||
struct intel_dpll_hw_state *hw_state);
|
||||
void intel_prepare_shared_dpll(const struct intel_crtc_state *crtc_state);
|
||||
void intel_enable_shared_dpll(const struct intel_crtc_state *crtc_state);
|
||||
void intel_disable_shared_dpll(const struct intel_crtc_state *crtc_state);
|
||||
|
|
|
@ -75,7 +75,7 @@ enum drm_mode_status intel_dsi_mode_valid(struct drm_connector *connector,
|
|||
return MODE_CLOCK_HIGH;
|
||||
}
|
||||
|
||||
return intel_mode_valid_max_plane_size(dev_priv, mode);
|
||||
return intel_mode_valid_max_plane_size(dev_priv, mode, false);
|
||||
}
|
||||
|
||||
struct intel_dsi_host *intel_dsi_host_init(struct intel_dsi *intel_dsi,
|
||||
|
|
|
@ -2274,7 +2274,7 @@ intel_hdmi_mode_valid(struct drm_connector *connector,
|
|||
if (status != MODE_OK)
|
||||
return status;
|
||||
|
||||
return intel_mode_valid_max_plane_size(dev_priv, mode);
|
||||
return intel_mode_valid_max_plane_size(dev_priv, mode, false);
|
||||
}
|
||||
|
||||
bool intel_hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
|
||||
|
|
|
@ -1024,8 +1024,6 @@ void intel_psr_enable(struct intel_dp *intel_dp,
|
|||
if (!CAN_PSR(dev_priv) || dev_priv->psr.dp != intel_dp)
|
||||
return;
|
||||
|
||||
dev_priv->psr.force_mode_changed = false;
|
||||
|
||||
if (!crtc_state->has_psr)
|
||||
return;
|
||||
|
||||
|
@ -1334,8 +1332,6 @@ void intel_psr_update(struct intel_dp *intel_dp,
|
|||
if (!CAN_PSR(dev_priv) || READ_ONCE(psr->dp) != intel_dp)
|
||||
return;
|
||||
|
||||
dev_priv->psr.force_mode_changed = false;
|
||||
|
||||
mutex_lock(&dev_priv->psr.lock);
|
||||
|
||||
enable = crtc_state->has_psr;
|
||||
|
@ -1869,40 +1865,3 @@ bool intel_psr_enabled(struct intel_dp *intel_dp)
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void intel_psr_atomic_check(struct drm_connector *connector,
|
||||
struct drm_connector_state *old_state,
|
||||
struct drm_connector_state *new_state)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(connector->dev);
|
||||
struct intel_connector *intel_connector;
|
||||
struct intel_digital_port *dig_port;
|
||||
struct drm_crtc_state *crtc_state;
|
||||
|
||||
if (!CAN_PSR(dev_priv) || !new_state->crtc ||
|
||||
!dev_priv->psr.force_mode_changed)
|
||||
return;
|
||||
|
||||
intel_connector = to_intel_connector(connector);
|
||||
dig_port = enc_to_dig_port(to_intel_encoder(new_state->best_encoder));
|
||||
if (dev_priv->psr.dp != &dig_port->dp)
|
||||
return;
|
||||
|
||||
crtc_state = drm_atomic_get_new_crtc_state(new_state->state,
|
||||
new_state->crtc);
|
||||
crtc_state->mode_changed = true;
|
||||
}
|
||||
|
||||
void intel_psr_set_force_mode_changed(struct intel_dp *intel_dp)
|
||||
{
|
||||
struct drm_i915_private *dev_priv;
|
||||
|
||||
if (!intel_dp)
|
||||
return;
|
||||
|
||||
dev_priv = dp_to_i915(intel_dp);
|
||||
if (!CAN_PSR(dev_priv) || intel_dp != dev_priv->psr.dp)
|
||||
return;
|
||||
|
||||
dev_priv->psr.force_mode_changed = true;
|
||||
}
|
||||
|
|
|
@ -43,10 +43,6 @@ void intel_psr_short_pulse(struct intel_dp *intel_dp);
|
|||
int intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state,
|
||||
u32 *out_value);
|
||||
bool intel_psr_enabled(struct intel_dp *intel_dp);
|
||||
void intel_psr_atomic_check(struct drm_connector *connector,
|
||||
struct drm_connector_state *old_state,
|
||||
struct drm_connector_state *new_state);
|
||||
void intel_psr_set_force_mode_changed(struct intel_dp *intel_dp);
|
||||
int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc);
|
||||
void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_state);
|
||||
|
|
|
@ -408,6 +408,134 @@ static int skl_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
|
|||
return DIV_ROUND_UP(pixel_rate * num, den);
|
||||
}
|
||||
|
||||
static int skl_plane_max_width(const struct drm_framebuffer *fb,
|
||||
int color_plane,
|
||||
unsigned int rotation)
|
||||
{
|
||||
int cpp = fb->format->cpp[color_plane];
|
||||
|
||||
switch (fb->modifier) {
|
||||
case DRM_FORMAT_MOD_LINEAR:
|
||||
case I915_FORMAT_MOD_X_TILED:
|
||||
/*
|
||||
* Validated limit is 4k, but has 5k should
|
||||
* work apart from the following features:
|
||||
* - Ytile (already limited to 4k)
|
||||
* - FP16 (already limited to 4k)
|
||||
* - render compression (already limited to 4k)
|
||||
* - KVMR sprite and cursor (don't care)
|
||||
* - horizontal panning (TODO verify this)
|
||||
* - pipe and plane scaling (TODO verify this)
|
||||
*/
|
||||
if (cpp == 8)
|
||||
return 4096;
|
||||
else
|
||||
return 5120;
|
||||
case I915_FORMAT_MOD_Y_TILED_CCS:
|
||||
case I915_FORMAT_MOD_Yf_TILED_CCS:
|
||||
case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
|
||||
/* FIXME AUX plane? */
|
||||
case I915_FORMAT_MOD_Y_TILED:
|
||||
case I915_FORMAT_MOD_Yf_TILED:
|
||||
if (cpp == 8)
|
||||
return 2048;
|
||||
else
|
||||
return 4096;
|
||||
default:
|
||||
MISSING_CASE(fb->modifier);
|
||||
return 2048;
|
||||
}
|
||||
}
|
||||
|
||||
static int glk_plane_max_width(const struct drm_framebuffer *fb,
|
||||
int color_plane,
|
||||
unsigned int rotation)
|
||||
{
|
||||
int cpp = fb->format->cpp[color_plane];
|
||||
|
||||
switch (fb->modifier) {
|
||||
case DRM_FORMAT_MOD_LINEAR:
|
||||
case I915_FORMAT_MOD_X_TILED:
|
||||
if (cpp == 8)
|
||||
return 4096;
|
||||
else
|
||||
return 5120;
|
||||
case I915_FORMAT_MOD_Y_TILED_CCS:
|
||||
case I915_FORMAT_MOD_Yf_TILED_CCS:
|
||||
/* FIXME AUX plane? */
|
||||
case I915_FORMAT_MOD_Y_TILED:
|
||||
case I915_FORMAT_MOD_Yf_TILED:
|
||||
if (cpp == 8)
|
||||
return 2048;
|
||||
else
|
||||
return 5120;
|
||||
default:
|
||||
MISSING_CASE(fb->modifier);
|
||||
return 2048;
|
||||
}
|
||||
}
|
||||
|
||||
static int icl_plane_min_width(const struct drm_framebuffer *fb,
|
||||
int color_plane,
|
||||
unsigned int rotation)
|
||||
{
|
||||
/* Wa_14011264657, Wa_14011050563: gen11+ */
|
||||
switch (fb->format->format) {
|
||||
case DRM_FORMAT_C8:
|
||||
return 18;
|
||||
case DRM_FORMAT_RGB565:
|
||||
return 10;
|
||||
case DRM_FORMAT_XRGB8888:
|
||||
case DRM_FORMAT_XBGR8888:
|
||||
case DRM_FORMAT_ARGB8888:
|
||||
case DRM_FORMAT_ABGR8888:
|
||||
case DRM_FORMAT_XRGB2101010:
|
||||
case DRM_FORMAT_XBGR2101010:
|
||||
case DRM_FORMAT_ARGB2101010:
|
||||
case DRM_FORMAT_ABGR2101010:
|
||||
case DRM_FORMAT_XVYU2101010:
|
||||
case DRM_FORMAT_Y212:
|
||||
case DRM_FORMAT_Y216:
|
||||
return 6;
|
||||
case DRM_FORMAT_NV12:
|
||||
return 20;
|
||||
case DRM_FORMAT_P010:
|
||||
case DRM_FORMAT_P012:
|
||||
case DRM_FORMAT_P016:
|
||||
return 12;
|
||||
case DRM_FORMAT_XRGB16161616F:
|
||||
case DRM_FORMAT_XBGR16161616F:
|
||||
case DRM_FORMAT_ARGB16161616F:
|
||||
case DRM_FORMAT_ABGR16161616F:
|
||||
case DRM_FORMAT_XVYU12_16161616:
|
||||
case DRM_FORMAT_XVYU16161616:
|
||||
return 4;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int icl_plane_max_width(const struct drm_framebuffer *fb,
|
||||
int color_plane,
|
||||
unsigned int rotation)
|
||||
{
|
||||
return 5120;
|
||||
}
|
||||
|
||||
static int skl_plane_max_height(const struct drm_framebuffer *fb,
|
||||
int color_plane,
|
||||
unsigned int rotation)
|
||||
{
|
||||
return 4096;
|
||||
}
|
||||
|
||||
static int icl_plane_max_height(const struct drm_framebuffer *fb,
|
||||
int color_plane,
|
||||
unsigned int rotation)
|
||||
{
|
||||
return 4320;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
skl_plane_max_stride(struct intel_plane *plane,
|
||||
u32 pixel_format, u64 modifier,
|
||||
|
@ -2059,10 +2187,8 @@ g4x_sprite_check(struct intel_crtc_state *crtc_state,
|
|||
}
|
||||
}
|
||||
|
||||
ret = drm_atomic_helper_check_plane_state(&plane_state->uapi,
|
||||
&crtc_state->uapi,
|
||||
min_scale, max_scale,
|
||||
true, true);
|
||||
ret = intel_atomic_plane_check_clipping(plane_state, crtc_state,
|
||||
min_scale, max_scale, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -2117,11 +2243,10 @@ vlv_sprite_check(struct intel_crtc_state *crtc_state,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = drm_atomic_helper_check_plane_state(&plane_state->uapi,
|
||||
&crtc_state->uapi,
|
||||
DRM_PLANE_HELPER_NO_SCALING,
|
||||
DRM_PLANE_HELPER_NO_SCALING,
|
||||
true, true);
|
||||
ret = intel_atomic_plane_check_clipping(plane_state, crtc_state,
|
||||
DRM_PLANE_HELPER_NO_SCALING,
|
||||
DRM_PLANE_HELPER_NO_SCALING,
|
||||
true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -2328,10 +2453,8 @@ static int skl_plane_check(struct intel_crtc_state *crtc_state,
|
|||
max_scale = skl_plane_max_scale(dev_priv, fb);
|
||||
}
|
||||
|
||||
ret = drm_atomic_helper_check_plane_state(&plane_state->uapi,
|
||||
&crtc_state->uapi,
|
||||
min_scale, max_scale,
|
||||
true, true);
|
||||
ret = intel_atomic_plane_check_clipping(plane_state, crtc_state,
|
||||
min_scale, max_scale, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -3133,6 +3256,18 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv,
|
|||
fbc->possible_framebuffer_bits |= plane->frontbuffer_bit;
|
||||
}
|
||||
|
||||
if (INTEL_GEN(dev_priv) >= 11) {
|
||||
plane->min_width = icl_plane_min_width;
|
||||
plane->max_width = icl_plane_max_width;
|
||||
plane->max_height = icl_plane_max_height;
|
||||
} else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) {
|
||||
plane->max_width = glk_plane_max_width;
|
||||
plane->max_height = skl_plane_max_height;
|
||||
} else {
|
||||
plane->max_width = skl_plane_max_width;
|
||||
plane->max_height = skl_plane_max_height;
|
||||
}
|
||||
|
||||
plane->max_stride = skl_plane_max_stride;
|
||||
plane->update_plane = skl_update_plane;
|
||||
plane->disable_plane = skl_disable_plane;
|
||||
|
|
|
@ -332,11 +332,10 @@ static const struct rc_parameters *get_rc_params(u16 compressed_bpp,
|
|||
return &rc_parameters[row_index][column_index];
|
||||
}
|
||||
|
||||
bool intel_dsc_source_support(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
bool intel_dsc_source_support(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
const struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
|
||||
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
|
||||
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
|
||||
enum pipe pipe = crtc->pipe;
|
||||
|
||||
|
@ -490,11 +489,10 @@ intel_dsc_power_domain(const struct intel_crtc_state *crtc_state)
|
|||
return POWER_DOMAIN_TRANSCODER_VDSC_PW2;
|
||||
}
|
||||
|
||||
static void intel_dsc_pps_configure(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
const struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
|
||||
enum pipe pipe = crtc->pipe;
|
||||
u32 pps_val = 0;
|
||||
|
@ -503,6 +501,9 @@ static void intel_dsc_pps_configure(struct intel_encoder *encoder,
|
|||
u8 num_vdsc_instances = (crtc_state->dsc.dsc_split) ? 2 : 1;
|
||||
int i = 0;
|
||||
|
||||
if (crtc_state->bigjoiner)
|
||||
num_vdsc_instances *= 2;
|
||||
|
||||
/* Populate PICTURE_PARAMETER_SET_0 registers */
|
||||
pps_val = DSC_VER_MAJ | vdsc_cfg->dsc_version_minor <<
|
||||
DSC_VER_MIN_SHIFT |
|
||||
|
@ -973,55 +974,6 @@ static void intel_dsc_pps_configure(struct intel_encoder *encoder,
|
|||
}
|
||||
}
|
||||
|
||||
void intel_dsc_get_config(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
enum pipe pipe = crtc->pipe;
|
||||
enum intel_display_power_domain power_domain;
|
||||
intel_wakeref_t wakeref;
|
||||
u32 dss_ctl1, dss_ctl2, val;
|
||||
|
||||
if (!intel_dsc_source_support(encoder, crtc_state))
|
||||
return;
|
||||
|
||||
power_domain = intel_dsc_power_domain(crtc_state);
|
||||
|
||||
wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
|
||||
if (!wakeref)
|
||||
return;
|
||||
|
||||
if (!is_pipe_dsc(crtc_state)) {
|
||||
dss_ctl1 = intel_de_read(dev_priv, DSS_CTL1);
|
||||
dss_ctl2 = intel_de_read(dev_priv, DSS_CTL2);
|
||||
} else {
|
||||
dss_ctl1 = intel_de_read(dev_priv, ICL_PIPE_DSS_CTL1(pipe));
|
||||
dss_ctl2 = intel_de_read(dev_priv, ICL_PIPE_DSS_CTL2(pipe));
|
||||
}
|
||||
|
||||
crtc_state->dsc.compression_enable = dss_ctl2 & LEFT_BRANCH_VDSC_ENABLE;
|
||||
if (!crtc_state->dsc.compression_enable)
|
||||
goto out;
|
||||
|
||||
crtc_state->dsc.dsc_split = (dss_ctl2 & RIGHT_BRANCH_VDSC_ENABLE) &&
|
||||
(dss_ctl1 & JOINER_ENABLE);
|
||||
|
||||
/* FIXME: add more state readout as needed */
|
||||
|
||||
/* PPS1 */
|
||||
if (!is_pipe_dsc(crtc_state))
|
||||
val = intel_de_read(dev_priv, DSCA_PICTURE_PARAMETER_SET_1);
|
||||
else
|
||||
val = intel_de_read(dev_priv,
|
||||
ICL_DSC0_PICTURE_PARAMETER_SET_1(pipe));
|
||||
vdsc_cfg->bits_per_pixel = val;
|
||||
crtc_state->dsc.compressed_bpp = vdsc_cfg->bits_per_pixel >> 4;
|
||||
out:
|
||||
intel_display_power_put(dev_priv, power_domain, wakeref);
|
||||
}
|
||||
|
||||
static void intel_dsc_dsi_pps_write(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
|
@ -1060,77 +1012,126 @@ static void intel_dsc_dp_pps_write(struct intel_encoder *encoder,
|
|||
sizeof(dp_dsc_pps_sdp));
|
||||
}
|
||||
|
||||
static i915_reg_t dss_ctl1_reg(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
|
||||
|
||||
if (crtc_state->cpu_transcoder == TRANSCODER_EDP)
|
||||
return DSS_CTL1;
|
||||
|
||||
return ICL_PIPE_DSS_CTL1(pipe);
|
||||
}
|
||||
|
||||
static i915_reg_t dss_ctl2_reg(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
|
||||
|
||||
if (crtc_state->cpu_transcoder == TRANSCODER_EDP)
|
||||
return DSS_CTL2;
|
||||
|
||||
return ICL_PIPE_DSS_CTL2(pipe);
|
||||
}
|
||||
|
||||
void intel_dsc_enable(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
enum pipe pipe = crtc->pipe;
|
||||
i915_reg_t dss_ctl1_reg, dss_ctl2_reg;
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
u32 dss_ctl1_val = 0;
|
||||
u32 dss_ctl2_val = 0;
|
||||
|
||||
if (!crtc_state->dsc.compression_enable)
|
||||
return;
|
||||
|
||||
/* Enable Power wells for VDSC/joining */
|
||||
intel_display_power_get(dev_priv,
|
||||
intel_dsc_power_domain(crtc_state));
|
||||
intel_dsc_pps_configure(crtc_state);
|
||||
|
||||
intel_dsc_pps_configure(encoder, crtc_state);
|
||||
|
||||
if (encoder->type == INTEL_OUTPUT_DSI)
|
||||
intel_dsc_dsi_pps_write(encoder, crtc_state);
|
||||
else
|
||||
intel_dsc_dp_pps_write(encoder, crtc_state);
|
||||
|
||||
if (!is_pipe_dsc(crtc_state)) {
|
||||
dss_ctl1_reg = DSS_CTL1;
|
||||
dss_ctl2_reg = DSS_CTL2;
|
||||
} else {
|
||||
dss_ctl1_reg = ICL_PIPE_DSS_CTL1(pipe);
|
||||
dss_ctl2_reg = ICL_PIPE_DSS_CTL2(pipe);
|
||||
if (!crtc_state->bigjoiner_slave) {
|
||||
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI))
|
||||
intel_dsc_dsi_pps_write(encoder, crtc_state);
|
||||
else
|
||||
intel_dsc_dp_pps_write(encoder, crtc_state);
|
||||
}
|
||||
|
||||
dss_ctl2_val |= LEFT_BRANCH_VDSC_ENABLE;
|
||||
if (crtc_state->dsc.dsc_split) {
|
||||
dss_ctl2_val |= RIGHT_BRANCH_VDSC_ENABLE;
|
||||
dss_ctl1_val |= JOINER_ENABLE;
|
||||
}
|
||||
intel_de_write(dev_priv, dss_ctl1_reg, dss_ctl1_val);
|
||||
intel_de_write(dev_priv, dss_ctl2_reg, dss_ctl2_val);
|
||||
if (crtc_state->bigjoiner) {
|
||||
dss_ctl1_val |= BIG_JOINER_ENABLE;
|
||||
if (!crtc_state->bigjoiner_slave)
|
||||
dss_ctl1_val |= MASTER_BIG_JOINER_ENABLE;
|
||||
}
|
||||
intel_de_write(dev_priv, dss_ctl1_reg(crtc_state), dss_ctl1_val);
|
||||
intel_de_write(dev_priv, dss_ctl2_reg(crtc_state), dss_ctl2_val);
|
||||
}
|
||||
|
||||
void intel_dsc_disable(const struct intel_crtc_state *old_crtc_state)
|
||||
{
|
||||
struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
enum pipe pipe = crtc->pipe;
|
||||
i915_reg_t dss_ctl1_reg, dss_ctl2_reg;
|
||||
u32 dss_ctl1_val = 0, dss_ctl2_val = 0;
|
||||
|
||||
if (!old_crtc_state->dsc.compression_enable)
|
||||
return;
|
||||
|
||||
if (!is_pipe_dsc(old_crtc_state)) {
|
||||
dss_ctl1_reg = DSS_CTL1;
|
||||
dss_ctl2_reg = DSS_CTL2;
|
||||
} else {
|
||||
dss_ctl1_reg = ICL_PIPE_DSS_CTL1(pipe);
|
||||
dss_ctl2_reg = ICL_PIPE_DSS_CTL2(pipe);
|
||||
}
|
||||
dss_ctl1_val = intel_de_read(dev_priv, dss_ctl1_reg);
|
||||
if (dss_ctl1_val & JOINER_ENABLE)
|
||||
dss_ctl1_val &= ~JOINER_ENABLE;
|
||||
intel_de_write(dev_priv, dss_ctl1_reg, dss_ctl1_val);
|
||||
|
||||
dss_ctl2_val = intel_de_read(dev_priv, dss_ctl2_reg);
|
||||
if (dss_ctl2_val & LEFT_BRANCH_VDSC_ENABLE ||
|
||||
dss_ctl2_val & RIGHT_BRANCH_VDSC_ENABLE)
|
||||
dss_ctl2_val &= ~(LEFT_BRANCH_VDSC_ENABLE |
|
||||
RIGHT_BRANCH_VDSC_ENABLE);
|
||||
intel_de_write(dev_priv, dss_ctl2_reg, dss_ctl2_val);
|
||||
|
||||
/* Disable Power wells for VDSC/joining */
|
||||
intel_display_power_put_unchecked(dev_priv,
|
||||
intel_dsc_power_domain(old_crtc_state));
|
||||
intel_de_write(dev_priv, dss_ctl1_reg(old_crtc_state), 0);
|
||||
intel_de_write(dev_priv, dss_ctl2_reg(old_crtc_state), 0);
|
||||
}
|
||||
|
||||
void intel_dsc_get_config(struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
enum pipe pipe = crtc->pipe;
|
||||
enum intel_display_power_domain power_domain;
|
||||
intel_wakeref_t wakeref;
|
||||
u32 dss_ctl1, dss_ctl2, val;
|
||||
|
||||
if (!intel_dsc_source_support(crtc_state))
|
||||
return;
|
||||
|
||||
power_domain = intel_dsc_power_domain(crtc_state);
|
||||
|
||||
wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
|
||||
if (!wakeref)
|
||||
return;
|
||||
|
||||
dss_ctl1 = intel_de_read(dev_priv, dss_ctl1_reg(crtc_state));
|
||||
dss_ctl2 = intel_de_read(dev_priv, dss_ctl2_reg(crtc_state));
|
||||
|
||||
crtc_state->dsc.compression_enable = dss_ctl2 & LEFT_BRANCH_VDSC_ENABLE;
|
||||
if (!crtc_state->dsc.compression_enable)
|
||||
goto out;
|
||||
|
||||
crtc_state->dsc.dsc_split = (dss_ctl2 & RIGHT_BRANCH_VDSC_ENABLE) &&
|
||||
(dss_ctl1 & JOINER_ENABLE);
|
||||
|
||||
if (dss_ctl1 & BIG_JOINER_ENABLE) {
|
||||
crtc_state->bigjoiner = true;
|
||||
|
||||
if (!(dss_ctl1 & MASTER_BIG_JOINER_ENABLE)) {
|
||||
crtc_state->bigjoiner_slave = true;
|
||||
if (!WARN_ON(crtc->pipe == PIPE_A))
|
||||
crtc_state->bigjoiner_linked_crtc =
|
||||
intel_get_crtc_for_pipe(dev_priv, crtc->pipe - 1);
|
||||
} else {
|
||||
if (!WARN_ON(INTEL_NUM_PIPES(dev_priv) == crtc->pipe + 1))
|
||||
crtc_state->bigjoiner_linked_crtc =
|
||||
intel_get_crtc_for_pipe(dev_priv, crtc->pipe + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: add more state readout as needed */
|
||||
|
||||
/* PPS1 */
|
||||
if (!is_pipe_dsc(crtc_state))
|
||||
val = intel_de_read(dev_priv, DSCA_PICTURE_PARAMETER_SET_1);
|
||||
else
|
||||
val = intel_de_read(dev_priv,
|
||||
ICL_DSC0_PICTURE_PARAMETER_SET_1(pipe));
|
||||
vdsc_cfg->bits_per_pixel = val;
|
||||
crtc_state->dsc.compressed_bpp = vdsc_cfg->bits_per_pixel >> 4;
|
||||
out:
|
||||
intel_display_power_put(dev_priv, power_domain, wakeref);
|
||||
}
|
||||
|
|
|
@ -11,15 +11,13 @@
|
|||
struct intel_encoder;
|
||||
struct intel_crtc_state;
|
||||
|
||||
bool intel_dsc_source_support(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
bool intel_dsc_source_support(const struct intel_crtc_state *crtc_state);
|
||||
void intel_dsc_enable(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
void intel_dsc_disable(const struct intel_crtc_state *crtc_state);
|
||||
int intel_dsc_compute_params(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *pipe_config);
|
||||
void intel_dsc_get_config(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *crtc_state);
|
||||
void intel_dsc_get_config(struct intel_crtc_state *crtc_state);
|
||||
enum intel_display_power_domain
|
||||
intel_dsc_power_domain(const struct intel_crtc_state *crtc_state);
|
||||
|
||||
|
|
|
@ -1191,14 +1191,14 @@ static void intel_gt_reset_global(struct intel_gt *gt,
|
|||
|
||||
/* Use a watchdog to ensure that our reset completes */
|
||||
intel_wedge_on_timeout(&w, gt, 5 * HZ) {
|
||||
intel_prepare_reset(gt->i915);
|
||||
intel_display_prepare_reset(gt->i915);
|
||||
|
||||
/* Flush everyone using a resource about to be clobbered */
|
||||
synchronize_srcu_expedited(>->reset.backoff_srcu);
|
||||
|
||||
intel_gt_reset(gt, engine_mask, reason);
|
||||
|
||||
intel_finish_reset(gt->i915);
|
||||
intel_display_finish_reset(gt->i915);
|
||||
}
|
||||
|
||||
if (!test_bit(I915_WEDGED, >->reset.flags))
|
||||
|
|
|
@ -173,22 +173,162 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
|
|||
int pipe;
|
||||
|
||||
if (IS_BROXTON(dev_priv)) {
|
||||
enum transcoder trans;
|
||||
enum port port;
|
||||
|
||||
/* Clear PIPE, DDI, PHY, HPD before setting new */
|
||||
vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &=
|
||||
~(GEN8_DE_PORT_HOTPLUG(HPD_PORT_A) |
|
||||
GEN8_DE_PORT_HOTPLUG(HPD_PORT_B) |
|
||||
GEN8_DE_PORT_HOTPLUG(HPD_PORT_C));
|
||||
|
||||
for_each_pipe(dev_priv, pipe) {
|
||||
vgpu_vreg_t(vgpu, PIPECONF(pipe)) &=
|
||||
~(PIPECONF_ENABLE | I965_PIPECONF_ACTIVE);
|
||||
vgpu_vreg_t(vgpu, DSPCNTR(pipe)) &= ~DISPLAY_PLANE_ENABLE;
|
||||
vgpu_vreg_t(vgpu, SPRCTL(pipe)) &= ~SPRITE_ENABLE;
|
||||
vgpu_vreg_t(vgpu, CURCNTR(pipe)) &= ~MCURSOR_MODE;
|
||||
vgpu_vreg_t(vgpu, CURCNTR(pipe)) |= MCURSOR_MODE_DISABLE;
|
||||
}
|
||||
|
||||
for (trans = TRANSCODER_A; trans <= TRANSCODER_EDP; trans++) {
|
||||
vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(trans)) &=
|
||||
~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK |
|
||||
TRANS_DDI_PORT_MASK | TRANS_DDI_FUNC_ENABLE);
|
||||
}
|
||||
vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) &=
|
||||
~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK |
|
||||
TRANS_DDI_PORT_MASK);
|
||||
|
||||
for (port = PORT_A; port <= PORT_C; port++) {
|
||||
vgpu_vreg_t(vgpu, BXT_PHY_CTL(port)) &=
|
||||
~BXT_PHY_LANE_ENABLED;
|
||||
vgpu_vreg_t(vgpu, BXT_PHY_CTL(port)) |=
|
||||
(BXT_PHY_CMNLANE_POWERDOWN_ACK |
|
||||
BXT_PHY_LANE_POWERDOWN_ACK);
|
||||
|
||||
vgpu_vreg_t(vgpu, BXT_PORT_PLL_ENABLE(port)) &=
|
||||
~(PORT_PLL_POWER_STATE | PORT_PLL_POWER_ENABLE |
|
||||
PORT_PLL_REF_SEL | PORT_PLL_LOCK |
|
||||
PORT_PLL_ENABLE);
|
||||
|
||||
vgpu_vreg_t(vgpu, DDI_BUF_CTL(port)) &=
|
||||
~(DDI_INIT_DISPLAY_DETECTED |
|
||||
DDI_BUF_CTL_ENABLE);
|
||||
vgpu_vreg_t(vgpu, DDI_BUF_CTL(port)) |= DDI_BUF_IS_IDLE;
|
||||
}
|
||||
|
||||
vgpu_vreg_t(vgpu, BXT_P_CR_GT_DISP_PWRON) &= ~(BIT(0) | BIT(1));
|
||||
vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY0)) &=
|
||||
~PHY_POWER_GOOD;
|
||||
vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY1)) &=
|
||||
~PHY_POWER_GOOD;
|
||||
vgpu_vreg_t(vgpu, BXT_PHY_CTL_FAMILY(DPIO_PHY0)) &= ~BIT(30);
|
||||
vgpu_vreg_t(vgpu, BXT_PHY_CTL_FAMILY(DPIO_PHY1)) &= ~BIT(30);
|
||||
|
||||
vgpu_vreg_t(vgpu, SFUSE_STRAP) &= ~SFUSE_STRAP_DDIB_DETECTED;
|
||||
vgpu_vreg_t(vgpu, SFUSE_STRAP) &= ~SFUSE_STRAP_DDIC_DETECTED;
|
||||
|
||||
/*
|
||||
* Only 1 PIPE enabled in current vGPU display and PIPE_A is
|
||||
* tied to TRANSCODER_A in HW, so it's safe to assume PIPE_A,
|
||||
* TRANSCODER_A can be enabled. PORT_x depends on the input of
|
||||
* setup_virtual_dp_monitor.
|
||||
*/
|
||||
vgpu_vreg_t(vgpu, PIPECONF(PIPE_A)) |= PIPECONF_ENABLE;
|
||||
vgpu_vreg_t(vgpu, PIPECONF(PIPE_A)) |= I965_PIPECONF_ACTIVE;
|
||||
|
||||
/*
|
||||
* Golden M/N are calculated based on:
|
||||
* 24 bpp, 4 lanes, 154000 pixel clk (from virtual EDID),
|
||||
* DP link clk 1620 MHz and non-constant_n.
|
||||
* TODO: calculate DP link symbol clk and stream clk m/n.
|
||||
*/
|
||||
vgpu_vreg_t(vgpu, PIPE_DATA_M1(TRANSCODER_A)) = 63 << TU_SIZE_SHIFT;
|
||||
vgpu_vreg_t(vgpu, PIPE_DATA_M1(TRANSCODER_A)) |= 0x5b425e;
|
||||
vgpu_vreg_t(vgpu, PIPE_DATA_N1(TRANSCODER_A)) = 0x800000;
|
||||
vgpu_vreg_t(vgpu, PIPE_LINK_M1(TRANSCODER_A)) = 0x3cd6e;
|
||||
vgpu_vreg_t(vgpu, PIPE_LINK_N1(TRANSCODER_A)) = 0x80000;
|
||||
|
||||
/* Enable per-DDI/PORT vreg */
|
||||
if (intel_vgpu_has_monitor_on_port(vgpu, PORT_A)) {
|
||||
vgpu_vreg_t(vgpu, BXT_P_CR_GT_DISP_PWRON) |= BIT(1);
|
||||
vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY1)) |=
|
||||
PHY_POWER_GOOD;
|
||||
vgpu_vreg_t(vgpu, BXT_PHY_CTL_FAMILY(DPIO_PHY1)) |=
|
||||
BIT(30);
|
||||
vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_A)) |=
|
||||
BXT_PHY_LANE_ENABLED;
|
||||
vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_A)) &=
|
||||
~(BXT_PHY_CMNLANE_POWERDOWN_ACK |
|
||||
BXT_PHY_LANE_POWERDOWN_ACK);
|
||||
vgpu_vreg_t(vgpu, BXT_PORT_PLL_ENABLE(PORT_A)) |=
|
||||
(PORT_PLL_POWER_STATE | PORT_PLL_POWER_ENABLE |
|
||||
PORT_PLL_REF_SEL | PORT_PLL_LOCK |
|
||||
PORT_PLL_ENABLE);
|
||||
vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_A)) |=
|
||||
(DDI_BUF_CTL_ENABLE | DDI_INIT_DISPLAY_DETECTED);
|
||||
vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_A)) &=
|
||||
~DDI_BUF_IS_IDLE;
|
||||
vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)) |=
|
||||
(TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
|
||||
TRANS_DDI_FUNC_ENABLE);
|
||||
vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
|
||||
GEN8_DE_PORT_HOTPLUG(HPD_PORT_A);
|
||||
}
|
||||
|
||||
if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) {
|
||||
vgpu_vreg_t(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDIB_DETECTED;
|
||||
vgpu_vreg_t(vgpu, BXT_P_CR_GT_DISP_PWRON) |= BIT(0);
|
||||
vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY0)) |=
|
||||
PHY_POWER_GOOD;
|
||||
vgpu_vreg_t(vgpu, BXT_PHY_CTL_FAMILY(DPIO_PHY0)) |=
|
||||
BIT(30);
|
||||
vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_B)) |=
|
||||
BXT_PHY_LANE_ENABLED;
|
||||
vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_B)) &=
|
||||
~(BXT_PHY_CMNLANE_POWERDOWN_ACK |
|
||||
BXT_PHY_LANE_POWERDOWN_ACK);
|
||||
vgpu_vreg_t(vgpu, BXT_PORT_PLL_ENABLE(PORT_B)) |=
|
||||
(PORT_PLL_POWER_STATE | PORT_PLL_POWER_ENABLE |
|
||||
PORT_PLL_REF_SEL | PORT_PLL_LOCK |
|
||||
PORT_PLL_ENABLE);
|
||||
vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_B)) |=
|
||||
DDI_BUF_CTL_ENABLE;
|
||||
vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_B)) &=
|
||||
~DDI_BUF_IS_IDLE;
|
||||
vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) |=
|
||||
(TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
|
||||
(PORT_B << TRANS_DDI_PORT_SHIFT) |
|
||||
TRANS_DDI_FUNC_ENABLE);
|
||||
vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
|
||||
GEN8_DE_PORT_HOTPLUG(HPD_PORT_B);
|
||||
}
|
||||
|
||||
if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) {
|
||||
vgpu_vreg_t(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDIC_DETECTED;
|
||||
vgpu_vreg_t(vgpu, BXT_P_CR_GT_DISP_PWRON) |= BIT(0);
|
||||
vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY0)) |=
|
||||
PHY_POWER_GOOD;
|
||||
vgpu_vreg_t(vgpu, BXT_PHY_CTL_FAMILY(DPIO_PHY0)) |=
|
||||
BIT(30);
|
||||
vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_C)) |=
|
||||
BXT_PHY_LANE_ENABLED;
|
||||
vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_C)) &=
|
||||
~(BXT_PHY_CMNLANE_POWERDOWN_ACK |
|
||||
BXT_PHY_LANE_POWERDOWN_ACK);
|
||||
vgpu_vreg_t(vgpu, BXT_PORT_PLL_ENABLE(PORT_C)) |=
|
||||
(PORT_PLL_POWER_STATE | PORT_PLL_POWER_ENABLE |
|
||||
PORT_PLL_REF_SEL | PORT_PLL_LOCK |
|
||||
PORT_PLL_ENABLE);
|
||||
vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_C)) |=
|
||||
DDI_BUF_CTL_ENABLE;
|
||||
vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_C)) &=
|
||||
~DDI_BUF_IS_IDLE;
|
||||
vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) |=
|
||||
(TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
|
||||
(PORT_B << TRANS_DDI_PORT_SHIFT) |
|
||||
TRANS_DDI_FUNC_ENABLE);
|
||||
vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
|
||||
GEN8_DE_PORT_HOTPLUG(HPD_PORT_C);
|
||||
}
|
||||
|
@ -520,6 +660,45 @@ void intel_vgpu_emulate_hotplug(struct intel_vgpu *vgpu, bool connected)
|
|||
vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
|
||||
PORTD_HOTPLUG_STATUS_MASK;
|
||||
intel_vgpu_trigger_virtual_event(vgpu, DP_D_HOTPLUG);
|
||||
} else if (IS_BROXTON(i915)) {
|
||||
if (connected) {
|
||||
if (intel_vgpu_has_monitor_on_port(vgpu, PORT_A)) {
|
||||
vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
|
||||
GEN8_DE_PORT_HOTPLUG(HPD_PORT_A);
|
||||
}
|
||||
if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) {
|
||||
vgpu_vreg_t(vgpu, SFUSE_STRAP) |=
|
||||
SFUSE_STRAP_DDIB_DETECTED;
|
||||
vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
|
||||
GEN8_DE_PORT_HOTPLUG(HPD_PORT_B);
|
||||
}
|
||||
if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) {
|
||||
vgpu_vreg_t(vgpu, SFUSE_STRAP) |=
|
||||
SFUSE_STRAP_DDIC_DETECTED;
|
||||
vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
|
||||
GEN8_DE_PORT_HOTPLUG(HPD_PORT_C);
|
||||
}
|
||||
} else {
|
||||
if (intel_vgpu_has_monitor_on_port(vgpu, PORT_A)) {
|
||||
vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &=
|
||||
~GEN8_DE_PORT_HOTPLUG(HPD_PORT_A);
|
||||
}
|
||||
if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) {
|
||||
vgpu_vreg_t(vgpu, SFUSE_STRAP) &=
|
||||
~SFUSE_STRAP_DDIB_DETECTED;
|
||||
vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &=
|
||||
~GEN8_DE_PORT_HOTPLUG(HPD_PORT_B);
|
||||
}
|
||||
if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) {
|
||||
vgpu_vreg_t(vgpu, SFUSE_STRAP) &=
|
||||
~SFUSE_STRAP_DDIC_DETECTED;
|
||||
vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &=
|
||||
~GEN8_DE_PORT_HOTPLUG(HPD_PORT_C);
|
||||
}
|
||||
}
|
||||
vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
|
||||
PORTB_HOTPLUG_STATUS_MASK;
|
||||
intel_vgpu_trigger_virtual_event(vgpu, DP_B_HOTPLUG);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -636,9 +636,18 @@ static void ggtt_set_host_entry(struct intel_vgpu_mm *mm,
|
|||
struct intel_gvt_gtt_entry *entry, unsigned long index)
|
||||
{
|
||||
struct intel_gvt_gtt_pte_ops *pte_ops = mm->vgpu->gvt->gtt.pte_ops;
|
||||
unsigned long offset = index;
|
||||
|
||||
GEM_BUG_ON(mm->type != INTEL_GVT_MM_GGTT);
|
||||
|
||||
if (vgpu_gmadr_is_aperture(mm->vgpu, index << I915_GTT_PAGE_SHIFT)) {
|
||||
offset -= (vgpu_aperture_gmadr_base(mm->vgpu) >> PAGE_SHIFT);
|
||||
mm->ggtt_mm.host_ggtt_aperture[offset] = entry->val64;
|
||||
} else if (vgpu_gmadr_is_hidden(mm->vgpu, index << I915_GTT_PAGE_SHIFT)) {
|
||||
offset -= (vgpu_hidden_gmadr_base(mm->vgpu) >> PAGE_SHIFT);
|
||||
mm->ggtt_mm.host_ggtt_hidden[offset] = entry->val64;
|
||||
}
|
||||
|
||||
pte_ops->set_entry(NULL, entry, index, false, 0, mm->vgpu);
|
||||
}
|
||||
|
||||
|
@ -1944,6 +1953,21 @@ static struct intel_vgpu_mm *intel_vgpu_create_ggtt_mm(struct intel_vgpu *vgpu)
|
|||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
mm->ggtt_mm.host_ggtt_aperture = vzalloc((vgpu_aperture_sz(vgpu) >> PAGE_SHIFT) * sizeof(u64));
|
||||
if (!mm->ggtt_mm.host_ggtt_aperture) {
|
||||
vfree(mm->ggtt_mm.virtual_ggtt);
|
||||
vgpu_free_mm(mm);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
mm->ggtt_mm.host_ggtt_hidden = vzalloc((vgpu_hidden_sz(vgpu) >> PAGE_SHIFT) * sizeof(u64));
|
||||
if (!mm->ggtt_mm.host_ggtt_hidden) {
|
||||
vfree(mm->ggtt_mm.host_ggtt_aperture);
|
||||
vfree(mm->ggtt_mm.virtual_ggtt);
|
||||
vgpu_free_mm(mm);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
return mm;
|
||||
}
|
||||
|
||||
|
@ -1971,6 +1995,8 @@ void _intel_vgpu_mm_release(struct kref *mm_ref)
|
|||
invalidate_ppgtt_mm(mm);
|
||||
} else {
|
||||
vfree(mm->ggtt_mm.virtual_ggtt);
|
||||
vfree(mm->ggtt_mm.host_ggtt_aperture);
|
||||
vfree(mm->ggtt_mm.host_ggtt_hidden);
|
||||
}
|
||||
|
||||
vgpu_free_mm(mm);
|
||||
|
@ -2852,3 +2878,41 @@ void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu)
|
|||
intel_vgpu_destroy_all_ppgtt_mm(vgpu);
|
||||
intel_vgpu_reset_ggtt(vgpu, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_gvt_restore_ggtt - restore all vGPU's ggtt entries
|
||||
* @gvt: intel gvt device
|
||||
*
|
||||
* This function is called at driver resume stage to restore
|
||||
* GGTT entries of every vGPU.
|
||||
*
|
||||
*/
|
||||
void intel_gvt_restore_ggtt(struct intel_gvt *gvt)
|
||||
{
|
||||
struct intel_vgpu *vgpu;
|
||||
struct intel_vgpu_mm *mm;
|
||||
int id;
|
||||
gen8_pte_t pte;
|
||||
u32 idx, num_low, num_hi, offset;
|
||||
|
||||
/* Restore dirty host ggtt for all vGPUs */
|
||||
idr_for_each_entry(&(gvt)->vgpu_idr, vgpu, id) {
|
||||
mm = vgpu->gtt.ggtt_mm;
|
||||
|
||||
num_low = vgpu_aperture_sz(vgpu) >> PAGE_SHIFT;
|
||||
offset = vgpu_aperture_gmadr_base(vgpu) >> PAGE_SHIFT;
|
||||
for (idx = 0; idx < num_low; idx++) {
|
||||
pte = mm->ggtt_mm.host_ggtt_aperture[idx];
|
||||
if (pte & _PAGE_PRESENT)
|
||||
write_pte64(vgpu->gvt->gt->ggtt, offset + idx, pte);
|
||||
}
|
||||
|
||||
num_hi = vgpu_hidden_sz(vgpu) >> PAGE_SHIFT;
|
||||
offset = vgpu_hidden_gmadr_base(vgpu) >> PAGE_SHIFT;
|
||||
for (idx = 0; idx < num_hi; idx++) {
|
||||
pte = mm->ggtt_mm.host_ggtt_hidden[idx];
|
||||
if (pte & _PAGE_PRESENT)
|
||||
write_pte64(vgpu->gvt->gt->ggtt, offset + idx, pte);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -164,6 +164,9 @@ struct intel_vgpu_mm {
|
|||
} ppgtt_mm;
|
||||
struct {
|
||||
void *virtual_ggtt;
|
||||
/* Save/restore for PM */
|
||||
u64 *host_ggtt_aperture;
|
||||
u64 *host_ggtt_hidden;
|
||||
struct list_head partial_pte_list;
|
||||
} ggtt_mm;
|
||||
};
|
||||
|
@ -280,5 +283,6 @@ int intel_vgpu_emulate_ggtt_mmio_write(struct intel_vgpu *vgpu,
|
|||
unsigned int off, void *p_data, unsigned int bytes);
|
||||
|
||||
void intel_vgpu_destroy_all_ppgtt_mm(struct intel_vgpu *vgpu);
|
||||
void intel_gvt_restore_ggtt(struct intel_gvt *gvt);
|
||||
|
||||
#endif /* _GVT_GTT_H_ */
|
||||
|
|
|
@ -312,7 +312,7 @@ int intel_gvt_init_device(struct drm_i915_private *i915)
|
|||
|
||||
gvt_dbg_core("init gvt device\n");
|
||||
|
||||
idr_init(&gvt->vgpu_idr);
|
||||
idr_init_base(&gvt->vgpu_idr, 1);
|
||||
spin_lock_init(&gvt->scheduler.mmio_context_lock);
|
||||
mutex_init(&gvt->lock);
|
||||
mutex_init(&gvt->sched_lock);
|
||||
|
@ -406,7 +406,16 @@ out_clean_idr:
|
|||
}
|
||||
|
||||
int
|
||||
intel_gvt_register_hypervisor(struct intel_gvt_mpt *m)
|
||||
intel_gvt_pm_resume(struct intel_gvt *gvt)
|
||||
{
|
||||
intel_gvt_restore_fence(gvt);
|
||||
intel_gvt_restore_mmio(gvt);
|
||||
intel_gvt_restore_ggtt(gvt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
intel_gvt_register_hypervisor(const struct intel_gvt_mpt *m)
|
||||
{
|
||||
int ret;
|
||||
void *gvt;
|
||||
|
|
|
@ -56,7 +56,7 @@ struct intel_gvt_host {
|
|||
struct device *dev;
|
||||
bool initialized;
|
||||
int hypervisor_type;
|
||||
struct intel_gvt_mpt *mpt;
|
||||
const struct intel_gvt_mpt *mpt;
|
||||
};
|
||||
|
||||
extern struct intel_gvt_host intel_gvt_host;
|
||||
|
@ -255,7 +255,9 @@ struct intel_gvt_mmio {
|
|||
#define F_CMD_ACCESS (1 << 3)
|
||||
/* This reg has been accessed by a VM */
|
||||
#define F_ACCESSED (1 << 4)
|
||||
/* This reg has been accessed through GPU commands */
|
||||
/* This reg requires save & restore during host PM suspend/resume */
|
||||
#define F_PM_SAVE (1 << 5)
|
||||
/* This reg could be accessed by unaligned address */
|
||||
#define F_UNALIGN (1 << 6)
|
||||
/* This reg is in GVT's mmio save-restor list and in hardware
|
||||
* logical context image
|
||||
|
@ -685,6 +687,7 @@ void intel_gvt_debugfs_remove_vgpu(struct intel_vgpu *vgpu);
|
|||
void intel_gvt_debugfs_init(struct intel_gvt *gvt);
|
||||
void intel_gvt_debugfs_clean(struct intel_gvt *gvt);
|
||||
|
||||
int intel_gvt_pm_resume(struct intel_gvt *gvt);
|
||||
|
||||
#include "trace.h"
|
||||
#include "mpt.h"
|
||||
|
|
|
@ -3120,9 +3120,10 @@ static int init_skl_mmio_info(struct intel_gvt *gvt)
|
|||
MMIO_DFH(TRVATTL3PTRDW(2), D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL);
|
||||
MMIO_DFH(TRVATTL3PTRDW(3), D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL);
|
||||
MMIO_DFH(TRVADR, D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL);
|
||||
MMIO_DFH(TRTTE, D_SKL_PLUS, F_CMD_ACCESS,
|
||||
NULL, gen9_trtte_write);
|
||||
MMIO_DH(_MMIO(0x4dfc), D_SKL_PLUS, NULL, gen9_trtt_chicken_write);
|
||||
MMIO_DFH(TRTTE, D_SKL_PLUS, F_CMD_ACCESS | F_PM_SAVE,
|
||||
NULL, gen9_trtte_write);
|
||||
MMIO_DFH(_MMIO(0x4dfc), D_SKL_PLUS, F_PM_SAVE,
|
||||
NULL, gen9_trtt_chicken_write);
|
||||
|
||||
MMIO_D(_MMIO(0x46430), D_SKL_PLUS);
|
||||
|
||||
|
@ -3671,3 +3672,40 @@ default_rw:
|
|||
intel_vgpu_default_mmio_read(vgpu, offset, pdata, bytes) :
|
||||
intel_vgpu_default_mmio_write(vgpu, offset, pdata, bytes);
|
||||
}
|
||||
|
||||
void intel_gvt_restore_fence(struct intel_gvt *gvt)
|
||||
{
|
||||
struct intel_vgpu *vgpu;
|
||||
int i, id;
|
||||
|
||||
idr_for_each_entry(&(gvt)->vgpu_idr, vgpu, id) {
|
||||
mmio_hw_access_pre(gvt->gt);
|
||||
for (i = 0; i < vgpu_fence_sz(vgpu); i++)
|
||||
intel_vgpu_write_fence(vgpu, i, vgpu_vreg64(vgpu, fence_num_to_offset(i)));
|
||||
mmio_hw_access_post(gvt->gt);
|
||||
}
|
||||
}
|
||||
|
||||
static inline int mmio_pm_restore_handler(struct intel_gvt *gvt,
|
||||
u32 offset, void *data)
|
||||
{
|
||||
struct intel_vgpu *vgpu = data;
|
||||
struct drm_i915_private *dev_priv = gvt->gt->i915;
|
||||
|
||||
if (gvt->mmio.mmio_attribute[offset >> 2] & F_PM_SAVE)
|
||||
I915_WRITE(_MMIO(offset), vgpu_vreg(vgpu, offset));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void intel_gvt_restore_mmio(struct intel_gvt *gvt)
|
||||
{
|
||||
struct intel_vgpu *vgpu;
|
||||
int id;
|
||||
|
||||
idr_for_each_entry(&(gvt)->vgpu_idr, vgpu, id) {
|
||||
mmio_hw_access_pre(gvt->gt);
|
||||
intel_gvt_for_each_tracked_mmio(gvt, mmio_pm_restore_handler, vgpu);
|
||||
mmio_hw_access_post(gvt->gt);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2099,7 +2099,7 @@ static bool kvmgt_is_valid_gfn(unsigned long handle, unsigned long gfn)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static struct intel_gvt_mpt kvmgt_mpt = {
|
||||
static const struct intel_gvt_mpt kvmgt_mpt = {
|
||||
.type = INTEL_GVT_HYPERVISOR_KVM,
|
||||
.host_init = kvmgt_host_init,
|
||||
.host_exit = kvmgt_host_exit,
|
||||
|
|
|
@ -280,6 +280,11 @@ void intel_vgpu_reset_mmio(struct intel_vgpu *vgpu, bool dmlr)
|
|||
vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_C)) |=
|
||||
BXT_PHY_CMNLANE_POWERDOWN_ACK |
|
||||
BXT_PHY_LANE_POWERDOWN_ACK;
|
||||
vgpu_vreg_t(vgpu, SKL_FUSE_STATUS) |=
|
||||
SKL_FUSE_DOWNLOAD_STATUS |
|
||||
SKL_FUSE_PG_DIST_STATUS(SKL_PG0) |
|
||||
SKL_FUSE_PG_DIST_STATUS(SKL_PG1) |
|
||||
SKL_FUSE_PG_DIST_STATUS(SKL_PG2);
|
||||
}
|
||||
} else {
|
||||
#define GVT_GEN8_MMIO_RESET_OFFSET (0x44200)
|
||||
|
|
|
@ -104,4 +104,8 @@ int intel_vgpu_mmio_reg_rw(struct intel_vgpu *vgpu, unsigned int offset,
|
|||
|
||||
int intel_vgpu_mask_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
|
||||
void *p_data, unsigned int bytes);
|
||||
|
||||
void intel_gvt_restore_fence(struct intel_gvt *gvt);
|
||||
void intel_gvt_restore_mmio(struct intel_gvt *gvt);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -392,7 +392,7 @@ static inline bool intel_gvt_hypervisor_is_valid_gfn(
|
|||
return intel_gvt_host.mpt->is_valid_gfn(vgpu->handle, gfn);
|
||||
}
|
||||
|
||||
int intel_gvt_register_hypervisor(struct intel_gvt_mpt *);
|
||||
int intel_gvt_register_hypervisor(const struct intel_gvt_mpt *);
|
||||
void intel_gvt_unregister_hypervisor(void);
|
||||
|
||||
#endif /* _GVT_MPT_H_ */
|
||||
|
|
|
@ -393,7 +393,7 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt,
|
|||
mutex_init(&vgpu->dmabuf_lock);
|
||||
INIT_LIST_HEAD(&vgpu->dmabuf_obj_list_head);
|
||||
INIT_RADIX_TREE(&vgpu->page_track_tree, GFP_KERNEL);
|
||||
idr_init(&vgpu->object_idr);
|
||||
idr_init_base(&vgpu->object_idr, 1);
|
||||
intel_vgpu_init_cfg_space(vgpu, param->primary);
|
||||
vgpu->d3_entered = false;
|
||||
|
||||
|
|
|
@ -1271,6 +1271,8 @@ static int i915_drm_resume(struct drm_device *dev)
|
|||
|
||||
intel_power_domains_enable(dev_priv);
|
||||
|
||||
intel_gvt_resume(dev_priv);
|
||||
|
||||
enable_rpm_wakeref_asserts(&dev_priv->runtime_pm);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -508,7 +508,6 @@ struct i915_psr {
|
|||
bool dc3co_enabled;
|
||||
u32 dc3co_exit_delay;
|
||||
struct delayed_work dc3co_work;
|
||||
bool force_mode_changed;
|
||||
struct drm_dp_vsc_sdp vsc;
|
||||
};
|
||||
|
||||
|
@ -1560,6 +1559,7 @@ extern const struct i915_rev_steppings kbl_revids[];
|
|||
(IS_ICELAKE(p) && IS_REVID(p, since, until))
|
||||
|
||||
#define EHL_REVID_A0 0x0
|
||||
#define EHL_REVID_B0 0x1
|
||||
|
||||
#define IS_JSL_EHL_REVID(p, since, until) \
|
||||
(IS_JSL_EHL(p) && IS_REVID(p, since, until))
|
||||
|
|
|
@ -3058,8 +3058,10 @@ static void gen11_display_irq_reset(struct drm_i915_private *dev_priv)
|
|||
if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP)
|
||||
GEN3_IRQ_RESET(uncore, SDE);
|
||||
|
||||
/* Wa_14010685332:icl,jsl,ehl,tgl,rkl */
|
||||
if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP) {
|
||||
/* Wa_14010685332:cnp/cmp,tgp,adp */
|
||||
if (INTEL_PCH_TYPE(dev_priv) == PCH_CNP ||
|
||||
(INTEL_PCH_TYPE(dev_priv) >= PCH_TGP &&
|
||||
INTEL_PCH_TYPE(dev_priv) < PCH_DG1)) {
|
||||
intel_uncore_rmw(uncore, SOUTH_CHICKEN1,
|
||||
SBCLK_RUN_REFCLK_DIS, SBCLK_RUN_REFCLK_DIS);
|
||||
intel_uncore_rmw(uncore, SOUTH_CHICKEN1,
|
||||
|
@ -4204,10 +4206,6 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
|
|||
struct drm_device *dev = &dev_priv->drm;
|
||||
int i;
|
||||
|
||||
intel_hpd_init_pins(dev_priv);
|
||||
|
||||
intel_hpd_init_work(dev_priv);
|
||||
|
||||
INIT_WORK(&dev_priv->l3_parity.error_work, ivb_parity_work);
|
||||
for (i = 0; i < MAX_L3_SLICES; ++i)
|
||||
dev_priv->l3_parity.remap_info[i] = NULL;
|
||||
|
@ -4216,6 +4214,13 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
|
|||
if (HAS_GT_UC(dev_priv) && INTEL_GEN(dev_priv) < 11)
|
||||
dev_priv->gt.pm_guc_events = GUC_INTR_GUC2HOST << 16;
|
||||
|
||||
if (!HAS_DISPLAY(dev_priv))
|
||||
return;
|
||||
|
||||
intel_hpd_init_pins(dev_priv);
|
||||
|
||||
intel_hpd_init_work(dev_priv);
|
||||
|
||||
dev->vblank_disable_immediate = true;
|
||||
|
||||
/* Most platforms treat the display irq block as an always-on
|
||||
|
@ -4237,21 +4242,18 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
|
|||
*/
|
||||
dev_priv->hotplug.hpd_short_storm_enabled = !HAS_DP_MST(dev_priv);
|
||||
|
||||
if (HAS_GMCH(dev_priv)) {
|
||||
if (I915_HAS_HOTPLUG(dev_priv))
|
||||
dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup;
|
||||
} else {
|
||||
if (HAS_PCH_DG1(dev_priv))
|
||||
dev_priv->display.hpd_irq_setup = dg1_hpd_irq_setup;
|
||||
else if (INTEL_GEN(dev_priv) >= 11)
|
||||
dev_priv->display.hpd_irq_setup = gen11_hpd_irq_setup;
|
||||
else if (IS_GEN9_LP(dev_priv))
|
||||
dev_priv->display.hpd_irq_setup = bxt_hpd_irq_setup;
|
||||
else if (INTEL_PCH_TYPE(dev_priv) >= PCH_SPT)
|
||||
dev_priv->display.hpd_irq_setup = spt_hpd_irq_setup;
|
||||
else
|
||||
dev_priv->display.hpd_irq_setup = ilk_hpd_irq_setup;
|
||||
}
|
||||
if (HAS_PCH_DG1(dev_priv))
|
||||
dev_priv->display.hpd_irq_setup = dg1_hpd_irq_setup;
|
||||
else if (INTEL_GEN(dev_priv) >= 11)
|
||||
dev_priv->display.hpd_irq_setup = gen11_hpd_irq_setup;
|
||||
else if (IS_GEN9_LP(dev_priv))
|
||||
dev_priv->display.hpd_irq_setup = bxt_hpd_irq_setup;
|
||||
else if (INTEL_PCH_TYPE(dev_priv) >= PCH_SPT)
|
||||
dev_priv->display.hpd_irq_setup = spt_hpd_irq_setup;
|
||||
else if (HAS_GMCH(dev_priv) && I915_HAS_HOTPLUG(dev_priv))
|
||||
dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup;
|
||||
else
|
||||
dev_priv->display.hpd_irq_setup = ilk_hpd_irq_setup;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -910,8 +910,13 @@ static int gen8_oa_read(struct i915_perf_stream *stream,
|
|||
DRM_I915_PERF_RECORD_OA_REPORT_LOST);
|
||||
if (ret)
|
||||
return ret;
|
||||
intel_uncore_write(uncore, oastatus_reg,
|
||||
oastatus & ~GEN8_OASTATUS_REPORT_LOST);
|
||||
|
||||
intel_uncore_rmw(uncore, oastatus_reg,
|
||||
GEN8_OASTATUS_COUNTER_OVERFLOW |
|
||||
GEN8_OASTATUS_REPORT_LOST,
|
||||
IS_GEN_RANGE(uncore->i915, 8, 10) ?
|
||||
(GEN8_OASTATUS_HEAD_POINTER_WRAP |
|
||||
GEN8_OASTATUS_TAIL_POINTER_WRAP) : 0);
|
||||
}
|
||||
|
||||
return gen8_append_oa_reports(stream, buf, count, offset);
|
||||
|
|
|
@ -230,12 +230,14 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
|
|||
#define _TRANS(tran, a, b) _PICK_EVEN(tran, a, b)
|
||||
#define _PORT(port, a, b) _PICK_EVEN(port, a, b)
|
||||
#define _PLL(pll, a, b) _PICK_EVEN(pll, a, b)
|
||||
#define _PHY(phy, a, b) _PICK_EVEN(phy, a, b)
|
||||
|
||||
#define _MMIO_PIPE(pipe, a, b) _MMIO(_PIPE(pipe, a, b))
|
||||
#define _MMIO_PLANE(plane, a, b) _MMIO(_PLANE(plane, a, b))
|
||||
#define _MMIO_TRANS(tran, a, b) _MMIO(_TRANS(tran, a, b))
|
||||
#define _MMIO_PORT(port, a, b) _MMIO(_PORT(port, a, b))
|
||||
#define _MMIO_PLL(pll, a, b) _MMIO(_PLL(pll, a, b))
|
||||
#define _MMIO_PHY(phy, a, b) _MMIO(_PHY(phy, a, b))
|
||||
|
||||
#define _PHY3(phy, ...) _PICK(phy, __VA_ARGS__)
|
||||
|
||||
|
@ -677,6 +679,8 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
|
|||
#define GEN7_OASTATUS2_MEM_SELECT_GGTT (1 << 0) /* 0: PPGTT, 1: GGTT */
|
||||
|
||||
#define GEN8_OASTATUS _MMIO(0x2b08)
|
||||
#define GEN8_OASTATUS_TAIL_POINTER_WRAP (1 << 17)
|
||||
#define GEN8_OASTATUS_HEAD_POINTER_WRAP (1 << 16)
|
||||
#define GEN8_OASTATUS_OVERRUN_STATUS (1 << 3)
|
||||
#define GEN8_OASTATUS_COUNTER_OVERFLOW (1 << 2)
|
||||
#define GEN8_OASTATUS_OABUFFER_OVERFLOW (1 << 1)
|
||||
|
@ -10298,6 +10302,7 @@ enum skl_power_gate {
|
|||
#define DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port) (3 << DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(port))
|
||||
#define DPCLKA_CFGCR0_DDI_CLK_SEL(pll, port) ((pll) << DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(port))
|
||||
|
||||
/* ICL Clocks */
|
||||
#define ICL_DPCLKA_CFGCR0 _MMIO(0x164280)
|
||||
#define ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy) (1 << _PICK(phy, 10, 11, 24))
|
||||
#define RKL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy) REG_BIT((phy) + 10)
|
||||
|
@ -10313,6 +10318,27 @@ enum skl_power_gate {
|
|||
#define RKL_DPCLKA_CFGCR0_DDI_CLK_SEL(pll, phy) \
|
||||
((pll) << RKL_DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(phy))
|
||||
|
||||
/*
|
||||
* DG1 Clocks
|
||||
* First registers controls the first A and B, while the second register
|
||||
* controls the phy C and D. The bits on these registers are the
|
||||
* same, but refer to different phys
|
||||
*/
|
||||
#define _DG1_DPCLKA_CFGCR0 0x164280
|
||||
#define _DG1_DPCLKA1_CFGCR0 0x16C280
|
||||
#define _DG1_DPCLKA_PHY_IDX(phy) ((phy) % 2)
|
||||
#define _DG1_DPCLKA_PLL_IDX(pll) ((pll) % 2)
|
||||
#define _DG1_PHY_DPLL_MAP(phy) ((phy) >= PHY_C ? DPLL_ID_DG1_DPLL2 : DPLL_ID_DG1_DPLL0)
|
||||
#define DG1_DPCLKA_CFGCR0(phy) _MMIO_PHY((phy) / 2, \
|
||||
_DG1_DPCLKA_CFGCR0, \
|
||||
_DG1_DPCLKA1_CFGCR0)
|
||||
#define DG1_DPCLKA_CFGCR0_DDI_CLK_OFF(phy) REG_BIT(_DG1_DPCLKA_PHY_IDX(phy) + 10)
|
||||
#define DG1_DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(phy) (_DG1_DPCLKA_PHY_IDX(phy) * 2)
|
||||
#define DG1_DPCLKA_CFGCR0_DDI_CLK_SEL(pll, phy) (_DG1_DPCLKA_PLL_IDX(pll) << DG1_DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(phy))
|
||||
#define DG1_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy) (0x3 << DG1_DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(phy))
|
||||
#define DG1_DPCLKA_CFGCR0_DDI_CLK_SEL_DPLL_MAP(clk_sel, phy) \
|
||||
(((clk_sel) >> DG1_DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(phy)) + _DG1_PHY_DPLL_MAP(phy))
|
||||
|
||||
/* CNL PLL */
|
||||
#define DPLL0_ENABLE 0x46010
|
||||
#define DPLL1_ENABLE 0x46014
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "i915_drv.h"
|
||||
#include "i915_vgpu.h"
|
||||
#include "intel_gvt.h"
|
||||
#include "gvt/gvt.h"
|
||||
|
||||
/**
|
||||
* DOC: Intel GVT-g host support
|
||||
|
@ -147,3 +148,17 @@ void intel_gvt_driver_remove(struct drm_i915_private *dev_priv)
|
|||
|
||||
intel_gvt_clean_device(dev_priv);
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_gvt_resume - GVT resume routine wapper
|
||||
*
|
||||
* @dev_priv: drm i915 private *
|
||||
*
|
||||
* This function is called at the i915 driver resume stage to restore required
|
||||
* HW status for GVT so that vGPU can continue running after resumed.
|
||||
*/
|
||||
void intel_gvt_resume(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
if (intel_gvt_active(dev_priv))
|
||||
intel_gvt_pm_resume(dev_priv->gvt);
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ int intel_gvt_init_device(struct drm_i915_private *dev_priv);
|
|||
void intel_gvt_clean_device(struct drm_i915_private *dev_priv);
|
||||
int intel_gvt_init_host(void);
|
||||
void intel_gvt_sanitize_options(struct drm_i915_private *dev_priv);
|
||||
void intel_gvt_resume(struct drm_i915_private *dev_priv);
|
||||
#else
|
||||
static inline int intel_gvt_init(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
|
@ -46,6 +47,10 @@ static inline void intel_gvt_driver_remove(struct drm_i915_private *dev_priv)
|
|||
static inline void intel_gvt_sanitize_options(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void intel_gvt_resume(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _INTEL_GVT_H_ */
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <drm/drm_plane_helper.h>
|
||||
|
||||
#include "display/intel_atomic.h"
|
||||
#include "display/intel_atomic_plane.h"
|
||||
#include "display/intel_bw.h"
|
||||
#include "display/intel_display_types.h"
|
||||
#include "display/intel_fbc.h"
|
||||
|
@ -899,12 +900,12 @@ static void pnv_update_wm(struct intel_crtc *unused_crtc)
|
|||
|
||||
crtc = single_enabled_crtc(dev_priv);
|
||||
if (crtc) {
|
||||
const struct drm_display_mode *adjusted_mode =
|
||||
&crtc->config->hw.adjusted_mode;
|
||||
const struct drm_display_mode *pipe_mode =
|
||||
&crtc->config->hw.pipe_mode;
|
||||
const struct drm_framebuffer *fb =
|
||||
crtc->base.primary->state->fb;
|
||||
int cpp = fb->format->cpp[0];
|
||||
int clock = adjusted_mode->crtc_clock;
|
||||
int clock = pipe_mode->crtc_clock;
|
||||
|
||||
/* Display SR */
|
||||
wm = intel_calculate_wm(clock, &pnv_display_wm,
|
||||
|
@ -1135,8 +1136,8 @@ static u16 g4x_compute_wm(const struct intel_crtc_state *crtc_state,
|
|||
{
|
||||
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
|
||||
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
|
||||
const struct drm_display_mode *adjusted_mode =
|
||||
&crtc_state->hw.adjusted_mode;
|
||||
const struct drm_display_mode *pipe_mode =
|
||||
&crtc_state->hw.pipe_mode;
|
||||
unsigned int latency = dev_priv->wm.pri_latency[level] * 10;
|
||||
unsigned int clock, htotal, cpp, width, wm;
|
||||
|
||||
|
@ -1163,8 +1164,8 @@ static u16 g4x_compute_wm(const struct intel_crtc_state *crtc_state,
|
|||
level != G4X_WM_LEVEL_NORMAL)
|
||||
cpp = max(cpp, 4u);
|
||||
|
||||
clock = adjusted_mode->crtc_clock;
|
||||
htotal = adjusted_mode->crtc_htotal;
|
||||
clock = pipe_mode->crtc_clock;
|
||||
htotal = pipe_mode->crtc_htotal;
|
||||
|
||||
width = drm_rect_width(&plane_state->uapi.dst);
|
||||
|
||||
|
@ -1660,8 +1661,8 @@ static u16 vlv_compute_wm_level(const struct intel_crtc_state *crtc_state,
|
|||
{
|
||||
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
|
||||
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
|
||||
const struct drm_display_mode *adjusted_mode =
|
||||
&crtc_state->hw.adjusted_mode;
|
||||
const struct drm_display_mode *pipe_mode =
|
||||
&crtc_state->hw.pipe_mode;
|
||||
unsigned int clock, htotal, cpp, width, wm;
|
||||
|
||||
if (dev_priv->wm.pri_latency[level] == 0)
|
||||
|
@ -1671,8 +1672,8 @@ static u16 vlv_compute_wm_level(const struct intel_crtc_state *crtc_state,
|
|||
return 0;
|
||||
|
||||
cpp = plane_state->hw.fb->format->cpp[0];
|
||||
clock = adjusted_mode->crtc_clock;
|
||||
htotal = adjusted_mode->crtc_htotal;
|
||||
clock = pipe_mode->crtc_clock;
|
||||
htotal = pipe_mode->crtc_htotal;
|
||||
width = crtc_state->pipe_src_w;
|
||||
|
||||
if (plane->id == PLANE_CURSOR) {
|
||||
|
@ -2261,12 +2262,12 @@ static void i965_update_wm(struct intel_crtc *unused_crtc)
|
|||
if (crtc) {
|
||||
/* self-refresh has much higher latency */
|
||||
static const int sr_latency_ns = 12000;
|
||||
const struct drm_display_mode *adjusted_mode =
|
||||
&crtc->config->hw.adjusted_mode;
|
||||
const struct drm_display_mode *pipe_mode =
|
||||
&crtc->config->hw.pipe_mode;
|
||||
const struct drm_framebuffer *fb =
|
||||
crtc->base.primary->state->fb;
|
||||
int clock = adjusted_mode->crtc_clock;
|
||||
int htotal = adjusted_mode->crtc_htotal;
|
||||
int clock = pipe_mode->crtc_clock;
|
||||
int htotal = pipe_mode->crtc_htotal;
|
||||
int hdisplay = crtc->config->pipe_src_w;
|
||||
int cpp = fb->format->cpp[0];
|
||||
int entries;
|
||||
|
@ -2345,8 +2346,8 @@ static void i9xx_update_wm(struct intel_crtc *unused_crtc)
|
|||
fifo_size = dev_priv->display.get_fifo_size(dev_priv, PLANE_A);
|
||||
crtc = intel_get_crtc_for_plane(dev_priv, PLANE_A);
|
||||
if (intel_crtc_active(crtc)) {
|
||||
const struct drm_display_mode *adjusted_mode =
|
||||
&crtc->config->hw.adjusted_mode;
|
||||
const struct drm_display_mode *pipe_mode =
|
||||
&crtc->config->hw.pipe_mode;
|
||||
const struct drm_framebuffer *fb =
|
||||
crtc->base.primary->state->fb;
|
||||
int cpp;
|
||||
|
@ -2356,7 +2357,7 @@ static void i9xx_update_wm(struct intel_crtc *unused_crtc)
|
|||
else
|
||||
cpp = fb->format->cpp[0];
|
||||
|
||||
planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock,
|
||||
planea_wm = intel_calculate_wm(pipe_mode->crtc_clock,
|
||||
wm_info, fifo_size, cpp,
|
||||
pessimal_latency_ns);
|
||||
enabled = crtc;
|
||||
|
@ -2372,8 +2373,8 @@ static void i9xx_update_wm(struct intel_crtc *unused_crtc)
|
|||
fifo_size = dev_priv->display.get_fifo_size(dev_priv, PLANE_B);
|
||||
crtc = intel_get_crtc_for_plane(dev_priv, PLANE_B);
|
||||
if (intel_crtc_active(crtc)) {
|
||||
const struct drm_display_mode *adjusted_mode =
|
||||
&crtc->config->hw.adjusted_mode;
|
||||
const struct drm_display_mode *pipe_mode =
|
||||
&crtc->config->hw.pipe_mode;
|
||||
const struct drm_framebuffer *fb =
|
||||
crtc->base.primary->state->fb;
|
||||
int cpp;
|
||||
|
@ -2383,7 +2384,7 @@ static void i9xx_update_wm(struct intel_crtc *unused_crtc)
|
|||
else
|
||||
cpp = fb->format->cpp[0];
|
||||
|
||||
planeb_wm = intel_calculate_wm(adjusted_mode->crtc_clock,
|
||||
planeb_wm = intel_calculate_wm(pipe_mode->crtc_clock,
|
||||
wm_info, fifo_size, cpp,
|
||||
pessimal_latency_ns);
|
||||
if (enabled == NULL)
|
||||
|
@ -2421,12 +2422,12 @@ static void i9xx_update_wm(struct intel_crtc *unused_crtc)
|
|||
if (HAS_FW_BLC(dev_priv) && enabled) {
|
||||
/* self-refresh has much higher latency */
|
||||
static const int sr_latency_ns = 6000;
|
||||
const struct drm_display_mode *adjusted_mode =
|
||||
&enabled->config->hw.adjusted_mode;
|
||||
const struct drm_display_mode *pipe_mode =
|
||||
&enabled->config->hw.pipe_mode;
|
||||
const struct drm_framebuffer *fb =
|
||||
enabled->base.primary->state->fb;
|
||||
int clock = adjusted_mode->crtc_clock;
|
||||
int htotal = adjusted_mode->crtc_htotal;
|
||||
int clock = pipe_mode->crtc_clock;
|
||||
int htotal = pipe_mode->crtc_htotal;
|
||||
int hdisplay = enabled->config->pipe_src_w;
|
||||
int cpp;
|
||||
int entries;
|
||||
|
@ -2474,7 +2475,7 @@ static void i845_update_wm(struct intel_crtc *unused_crtc)
|
|||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(unused_crtc->base.dev);
|
||||
struct intel_crtc *crtc;
|
||||
const struct drm_display_mode *adjusted_mode;
|
||||
const struct drm_display_mode *pipe_mode;
|
||||
u32 fwater_lo;
|
||||
int planea_wm;
|
||||
|
||||
|
@ -2482,8 +2483,8 @@ static void i845_update_wm(struct intel_crtc *unused_crtc)
|
|||
if (crtc == NULL)
|
||||
return;
|
||||
|
||||
adjusted_mode = &crtc->config->hw.adjusted_mode;
|
||||
planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock,
|
||||
pipe_mode = &crtc->config->hw.pipe_mode;
|
||||
planea_wm = intel_calculate_wm(pipe_mode->crtc_clock,
|
||||
&i845_wm_info,
|
||||
dev_priv->display.get_fifo_size(dev_priv, PLANE_A),
|
||||
4, pessimal_latency_ns);
|
||||
|
@ -2573,7 +2574,7 @@ static u32 ilk_compute_pri_wm(const struct intel_crtc_state *crtc_state,
|
|||
return method1;
|
||||
|
||||
method2 = ilk_wm_method2(crtc_state->pixel_rate,
|
||||
crtc_state->hw.adjusted_mode.crtc_htotal,
|
||||
crtc_state->hw.pipe_mode.crtc_htotal,
|
||||
drm_rect_width(&plane_state->uapi.dst),
|
||||
cpp, mem_value);
|
||||
|
||||
|
@ -2601,7 +2602,7 @@ static u32 ilk_compute_spr_wm(const struct intel_crtc_state *crtc_state,
|
|||
|
||||
method1 = ilk_wm_method1(crtc_state->pixel_rate, cpp, mem_value);
|
||||
method2 = ilk_wm_method2(crtc_state->pixel_rate,
|
||||
crtc_state->hw.adjusted_mode.crtc_htotal,
|
||||
crtc_state->hw.pipe_mode.crtc_htotal,
|
||||
drm_rect_width(&plane_state->uapi.dst),
|
||||
cpp, mem_value);
|
||||
return min(method1, method2);
|
||||
|
@ -2626,7 +2627,7 @@ static u32 ilk_compute_cur_wm(const struct intel_crtc_state *crtc_state,
|
|||
cpp = plane_state->hw.fb->format->cpp[0];
|
||||
|
||||
return ilk_wm_method2(crtc_state->pixel_rate,
|
||||
crtc_state->hw.adjusted_mode.crtc_htotal,
|
||||
crtc_state->hw.pipe_mode.crtc_htotal,
|
||||
drm_rect_width(&plane_state->uapi.dst),
|
||||
cpp, mem_value);
|
||||
}
|
||||
|
@ -3873,9 +3874,7 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
|
|||
{
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
struct intel_plane *plane;
|
||||
const struct intel_plane_state *plane_state;
|
||||
int level, latency;
|
||||
enum plane_id plane_id;
|
||||
|
||||
if (!intel_has_sagv(dev_priv))
|
||||
return false;
|
||||
|
@ -3883,12 +3882,13 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
|
|||
if (!crtc_state->hw.active)
|
||||
return true;
|
||||
|
||||
if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
|
||||
if (crtc_state->hw.pipe_mode.flags & DRM_MODE_FLAG_INTERLACE)
|
||||
return false;
|
||||
|
||||
intel_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) {
|
||||
for_each_plane_id_on_crtc(crtc, plane_id) {
|
||||
const struct skl_plane_wm *wm =
|
||||
&crtc_state->wm.skl.optimal.planes[plane->id];
|
||||
&crtc_state->wm.skl.optimal.planes[plane_id];
|
||||
int level;
|
||||
|
||||
/* Skip this plane if it's not enabled */
|
||||
if (!wm->wm[0].plane_en)
|
||||
|
@ -3899,19 +3899,12 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
|
|||
!wm->wm[level].plane_en; --level)
|
||||
{ }
|
||||
|
||||
latency = dev_priv->wm.skl_latency[level];
|
||||
|
||||
if (skl_needs_memory_bw_wa(dev_priv) &&
|
||||
plane_state->uapi.fb->modifier ==
|
||||
I915_FORMAT_MOD_X_TILED)
|
||||
latency += 15;
|
||||
|
||||
/*
|
||||
* If any of the planes on this pipe don't enable wm levels that
|
||||
* incur memory latencies higher than sagv_block_time_us we
|
||||
* can't enable SAGV.
|
||||
*/
|
||||
if (latency < dev_priv->sagv_block_time_us)
|
||||
if (!wm->wm[level].can_sagv)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -4174,8 +4167,8 @@ skl_ddb_get_pipe_allocation_limits(struct drm_i915_private *dev_priv,
|
|||
*/
|
||||
total_slice_mask = dbuf_slice_mask;
|
||||
for_each_new_intel_crtc_in_state(intel_state, crtc, crtc_state, i) {
|
||||
const struct drm_display_mode *adjusted_mode =
|
||||
&crtc_state->hw.adjusted_mode;
|
||||
const struct drm_display_mode *pipe_mode =
|
||||
&crtc_state->hw.pipe_mode;
|
||||
enum pipe pipe = crtc->pipe;
|
||||
int hdisplay, vdisplay;
|
||||
u32 pipe_dbuf_slice_mask;
|
||||
|
@ -4205,7 +4198,7 @@ skl_ddb_get_pipe_allocation_limits(struct drm_i915_private *dev_priv,
|
|||
if (dbuf_slice_mask != pipe_dbuf_slice_mask)
|
||||
continue;
|
||||
|
||||
drm_mode_get_hv_timing(adjusted_mode, &hdisplay, &vdisplay);
|
||||
drm_mode_get_hv_timing(pipe_mode, &hdisplay, &vdisplay);
|
||||
|
||||
total_width_in_range += hdisplay;
|
||||
|
||||
|
@ -4704,50 +4697,63 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *crtc_state,
|
|||
}
|
||||
|
||||
static u64
|
||||
skl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
|
||||
u64 *plane_data_rate,
|
||||
u64 *uv_plane_data_rate)
|
||||
skl_get_total_relative_data_rate(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
struct intel_plane *plane;
|
||||
struct intel_crtc_state *crtc_state =
|
||||
intel_atomic_get_new_crtc_state(state, crtc);
|
||||
const struct intel_plane_state *plane_state;
|
||||
struct intel_plane *plane;
|
||||
u64 total_data_rate = 0;
|
||||
enum plane_id plane_id;
|
||||
int i;
|
||||
|
||||
/* Calculate and cache data rate for each plane */
|
||||
intel_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) {
|
||||
enum plane_id plane_id = plane->id;
|
||||
u64 rate;
|
||||
for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
|
||||
if (plane->pipe != crtc->pipe)
|
||||
continue;
|
||||
|
||||
plane_id = plane->id;
|
||||
|
||||
/* packed/y */
|
||||
rate = skl_plane_relative_data_rate(crtc_state, plane_state, 0);
|
||||
plane_data_rate[plane_id] = rate;
|
||||
total_data_rate += rate;
|
||||
crtc_state->plane_data_rate[plane_id] =
|
||||
skl_plane_relative_data_rate(crtc_state, plane_state, 0);
|
||||
|
||||
/* uv-plane */
|
||||
rate = skl_plane_relative_data_rate(crtc_state, plane_state, 1);
|
||||
uv_plane_data_rate[plane_id] = rate;
|
||||
total_data_rate += rate;
|
||||
crtc_state->uv_plane_data_rate[plane_id] =
|
||||
skl_plane_relative_data_rate(crtc_state, plane_state, 1);
|
||||
}
|
||||
|
||||
for_each_plane_id_on_crtc(crtc, plane_id) {
|
||||
total_data_rate += crtc_state->plane_data_rate[plane_id];
|
||||
total_data_rate += crtc_state->uv_plane_data_rate[plane_id];
|
||||
}
|
||||
|
||||
return total_data_rate;
|
||||
}
|
||||
|
||||
static u64
|
||||
icl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
|
||||
u64 *plane_data_rate)
|
||||
icl_get_total_relative_data_rate(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
struct intel_plane *plane;
|
||||
struct intel_crtc_state *crtc_state =
|
||||
intel_atomic_get_new_crtc_state(state, crtc);
|
||||
const struct intel_plane_state *plane_state;
|
||||
struct intel_plane *plane;
|
||||
u64 total_data_rate = 0;
|
||||
enum plane_id plane_id;
|
||||
int i;
|
||||
|
||||
/* Calculate and cache data rate for each plane */
|
||||
intel_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) {
|
||||
enum plane_id plane_id = plane->id;
|
||||
u64 rate;
|
||||
for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
|
||||
if (plane->pipe != crtc->pipe)
|
||||
continue;
|
||||
|
||||
plane_id = plane->id;
|
||||
|
||||
if (!plane_state->planar_linked_plane) {
|
||||
rate = skl_plane_relative_data_rate(crtc_state, plane_state, 0);
|
||||
plane_data_rate[plane_id] = rate;
|
||||
total_data_rate += rate;
|
||||
crtc_state->plane_data_rate[plane_id] =
|
||||
skl_plane_relative_data_rate(crtc_state, plane_state, 0);
|
||||
} else {
|
||||
enum plane_id y_plane_id;
|
||||
|
||||
|
@ -4762,17 +4768,18 @@ icl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
|
|||
continue;
|
||||
|
||||
/* Y plane rate is calculated on the slave */
|
||||
rate = skl_plane_relative_data_rate(crtc_state, plane_state, 0);
|
||||
y_plane_id = plane_state->planar_linked_plane->id;
|
||||
plane_data_rate[y_plane_id] = rate;
|
||||
total_data_rate += rate;
|
||||
crtc_state->plane_data_rate[y_plane_id] =
|
||||
skl_plane_relative_data_rate(crtc_state, plane_state, 0);
|
||||
|
||||
rate = skl_plane_relative_data_rate(crtc_state, plane_state, 1);
|
||||
plane_data_rate[plane_id] = rate;
|
||||
total_data_rate += rate;
|
||||
crtc_state->plane_data_rate[plane_id] =
|
||||
skl_plane_relative_data_rate(crtc_state, plane_state, 1);
|
||||
}
|
||||
}
|
||||
|
||||
for_each_plane_id_on_crtc(crtc, plane_id)
|
||||
total_data_rate += crtc_state->plane_data_rate[plane_id];
|
||||
|
||||
return total_data_rate;
|
||||
}
|
||||
|
||||
|
@ -4791,9 +4798,11 @@ skl_plane_wm_level(const struct intel_crtc_state *crtc_state,
|
|||
}
|
||||
|
||||
static int
|
||||
skl_allocate_pipe_ddb(struct intel_crtc_state *crtc_state)
|
||||
skl_allocate_pipe_ddb(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
struct intel_crtc_state *crtc_state =
|
||||
intel_atomic_get_new_crtc_state(state, crtc);
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
struct skl_ddb_entry *alloc = &crtc_state->wm.skl.ddb;
|
||||
u16 alloc_size, start = 0;
|
||||
|
@ -4802,8 +4811,6 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *crtc_state)
|
|||
u64 total_data_rate;
|
||||
enum plane_id plane_id;
|
||||
int num_active;
|
||||
u64 plane_data_rate[I915_MAX_PLANES] = {};
|
||||
u64 uv_plane_data_rate[I915_MAX_PLANES] = {};
|
||||
u32 blocks;
|
||||
int level;
|
||||
int ret;
|
||||
|
@ -4843,13 +4850,10 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *crtc_state)
|
|||
|
||||
if (INTEL_GEN(dev_priv) >= 11)
|
||||
total_data_rate =
|
||||
icl_get_total_relative_data_rate(crtc_state,
|
||||
plane_data_rate);
|
||||
icl_get_total_relative_data_rate(state, crtc);
|
||||
else
|
||||
total_data_rate =
|
||||
skl_get_total_relative_data_rate(crtc_state,
|
||||
plane_data_rate,
|
||||
uv_plane_data_rate);
|
||||
skl_get_total_relative_data_rate(state, crtc);
|
||||
|
||||
ret = skl_ddb_get_pipe_allocation_limits(dev_priv, crtc_state,
|
||||
total_data_rate,
|
||||
|
@ -4930,7 +4934,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *crtc_state)
|
|||
if (total_data_rate == 0)
|
||||
break;
|
||||
|
||||
rate = plane_data_rate[plane_id];
|
||||
rate = crtc_state->plane_data_rate[plane_id];
|
||||
extra = min_t(u16, alloc_size,
|
||||
DIV64_U64_ROUND_UP(alloc_size * rate,
|
||||
total_data_rate));
|
||||
|
@ -4941,7 +4945,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *crtc_state)
|
|||
if (total_data_rate == 0)
|
||||
break;
|
||||
|
||||
rate = uv_plane_data_rate[plane_id];
|
||||
rate = crtc_state->uv_plane_data_rate[plane_id];
|
||||
extra = min_t(u16, alloc_size,
|
||||
DIV64_U64_ROUND_UP(alloc_size * rate,
|
||||
total_data_rate));
|
||||
|
@ -5093,36 +5097,12 @@ intel_get_linetime_us(const struct intel_crtc_state *crtc_state)
|
|||
if (drm_WARN_ON(&dev_priv->drm, pixel_rate == 0))
|
||||
return u32_to_fixed16(0);
|
||||
|
||||
crtc_htotal = crtc_state->hw.adjusted_mode.crtc_htotal;
|
||||
crtc_htotal = crtc_state->hw.pipe_mode.crtc_htotal;
|
||||
linetime_us = div_fixed16(crtc_htotal * 1000, pixel_rate);
|
||||
|
||||
return linetime_us;
|
||||
}
|
||||
|
||||
static u32
|
||||
skl_adjusted_plane_pixel_rate(const struct intel_crtc_state *crtc_state,
|
||||
const struct intel_plane_state *plane_state)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
|
||||
u64 adjusted_pixel_rate;
|
||||
uint_fixed_16_16_t downscale_amount;
|
||||
|
||||
/* Shouldn't reach here on disabled planes... */
|
||||
if (drm_WARN_ON(&dev_priv->drm,
|
||||
!intel_wm_plane_visible(crtc_state, plane_state)))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Adjusted plane pixel rate is just the pipe's adjusted pixel rate
|
||||
* with additional adjustments for plane-specific scaling.
|
||||
*/
|
||||
adjusted_pixel_rate = crtc_state->pixel_rate;
|
||||
downscale_amount = skl_plane_downscale_amount(crtc_state, plane_state);
|
||||
|
||||
return mul_round_up_u32_fixed16(adjusted_pixel_rate,
|
||||
downscale_amount);
|
||||
}
|
||||
|
||||
static int
|
||||
skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
|
||||
int width, const struct drm_format_info *format,
|
||||
|
@ -5235,7 +5215,7 @@ skl_compute_plane_wm_params(const struct intel_crtc_state *crtc_state,
|
|||
return skl_compute_wm_params(crtc_state, width,
|
||||
fb->format, fb->modifier,
|
||||
plane_state->hw.rotation,
|
||||
skl_adjusted_plane_pixel_rate(crtc_state, plane_state),
|
||||
intel_plane_pixel_rate(crtc_state, plane_state),
|
||||
wp, color_plane);
|
||||
}
|
||||
|
||||
|
@ -5282,14 +5262,14 @@ static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state,
|
|||
method1 = skl_wm_method1(dev_priv, wp->plane_pixel_rate,
|
||||
wp->cpp, latency, wp->dbuf_block_size);
|
||||
method2 = skl_wm_method2(wp->plane_pixel_rate,
|
||||
crtc_state->hw.adjusted_mode.crtc_htotal,
|
||||
crtc_state->hw.pipe_mode.crtc_htotal,
|
||||
latency,
|
||||
wp->plane_blocks_per_line);
|
||||
|
||||
if (wp->y_tiled) {
|
||||
selected_result = max_fixed16(method2, wp->y_tile_minimum);
|
||||
} else {
|
||||
if ((wp->cpp * crtc_state->hw.adjusted_mode.crtc_htotal /
|
||||
if ((wp->cpp * crtc_state->hw.pipe_mode.crtc_htotal /
|
||||
wp->dbuf_block_size < 1) &&
|
||||
(wp->plane_bytes_per_line / wp->dbuf_block_size < 1)) {
|
||||
selected_result = method2;
|
||||
|
@ -5373,6 +5353,9 @@ static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state,
|
|||
/* Bspec says: value >= plane ddb allocation -> invalid, hence the +1 here */
|
||||
result->min_ddb_alloc = max(min_ddb_alloc, res_blocks) + 1;
|
||||
result->plane_en = true;
|
||||
|
||||
if (INTEL_GEN(dev_priv) < 12)
|
||||
result->can_sagv = latency >= dev_priv->sagv_block_time_us;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -5478,7 +5461,7 @@ static int skl_build_plane_wm_single(struct intel_crtc_state *crtc_state,
|
|||
{
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
struct skl_plane_wm *wm = &crtc_state->wm.skl.optimal.planes[plane_id];
|
||||
struct skl_plane_wm *wm = &crtc_state->wm.skl.raw.planes[plane_id];
|
||||
struct skl_wm_params wm_params;
|
||||
int ret;
|
||||
|
||||
|
@ -5501,7 +5484,7 @@ static int skl_build_plane_wm_uv(struct intel_crtc_state *crtc_state,
|
|||
const struct intel_plane_state *plane_state,
|
||||
enum plane_id plane_id)
|
||||
{
|
||||
struct skl_plane_wm *wm = &crtc_state->wm.skl.optimal.planes[plane_id];
|
||||
struct skl_plane_wm *wm = &crtc_state->wm.skl.raw.planes[plane_id];
|
||||
struct skl_wm_params wm_params;
|
||||
int ret;
|
||||
|
||||
|
@ -5522,10 +5505,13 @@ static int skl_build_plane_wm(struct intel_crtc_state *crtc_state,
|
|||
const struct intel_plane_state *plane_state)
|
||||
{
|
||||
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
|
||||
const struct drm_framebuffer *fb = plane_state->hw.fb;
|
||||
enum plane_id plane_id = plane->id;
|
||||
struct skl_plane_wm *wm = &crtc_state->wm.skl.raw.planes[plane_id];
|
||||
const struct drm_framebuffer *fb = plane_state->hw.fb;
|
||||
int ret;
|
||||
|
||||
memset(wm, 0, sizeof(*wm));
|
||||
|
||||
if (!intel_wm_plane_visible(crtc_state, plane_state))
|
||||
return 0;
|
||||
|
||||
|
@ -5547,10 +5533,14 @@ static int skl_build_plane_wm(struct intel_crtc_state *crtc_state,
|
|||
static int icl_build_plane_wm(struct intel_crtc_state *crtc_state,
|
||||
const struct intel_plane_state *plane_state)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
|
||||
enum plane_id plane_id = to_intel_plane(plane_state->uapi.plane)->id;
|
||||
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
|
||||
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
|
||||
enum plane_id plane_id = plane->id;
|
||||
struct skl_plane_wm *wm = &crtc_state->wm.skl.raw.planes[plane_id];
|
||||
int ret;
|
||||
|
||||
memset(wm, 0, sizeof(*wm));
|
||||
|
||||
/* Watermarks calculated in master */
|
||||
if (plane_state->planar_slave)
|
||||
return 0;
|
||||
|
@ -5583,22 +5573,24 @@ static int icl_build_plane_wm(struct intel_crtc_state *crtc_state,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int skl_build_pipe_wm(struct intel_crtc_state *crtc_state)
|
||||
static int skl_build_pipe_wm(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
|
||||
struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal;
|
||||
struct intel_plane *plane;
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
struct intel_crtc_state *crtc_state =
|
||||
intel_atomic_get_new_crtc_state(state, crtc);
|
||||
const struct intel_plane_state *plane_state;
|
||||
int ret;
|
||||
struct intel_plane *plane;
|
||||
int ret, i;
|
||||
|
||||
/*
|
||||
* We'll only calculate watermarks for planes that are actually
|
||||
* enabled, so make sure all other planes are set as disabled.
|
||||
*/
|
||||
memset(pipe_wm->planes, 0, sizeof(pipe_wm->planes));
|
||||
|
||||
intel_atomic_crtc_state_for_each_plane_state(plane, plane_state,
|
||||
crtc_state) {
|
||||
for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
|
||||
/*
|
||||
* FIXME should perhaps check {old,new}_plane_crtc->hw.crtc
|
||||
* instead but we don't populate that correctly for NV12 Y
|
||||
* planes so for now hack this.
|
||||
*/
|
||||
if (plane->pipe != crtc->pipe)
|
||||
continue;
|
||||
|
||||
if (INTEL_GEN(dev_priv) >= 11)
|
||||
ret = icl_build_plane_wm(crtc_state, plane_state);
|
||||
|
@ -5608,6 +5600,8 @@ static int skl_build_pipe_wm(struct intel_crtc_state *crtc_state)
|
|||
return ret;
|
||||
}
|
||||
|
||||
crtc_state->wm.skl.optimal = crtc_state->wm.skl.raw;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -5794,7 +5788,7 @@ skl_compute_ddb(struct intel_atomic_state *state)
|
|||
|
||||
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
|
||||
new_crtc_state, i) {
|
||||
ret = skl_allocate_pipe_ddb(new_crtc_state);
|
||||
ret = skl_allocate_pipe_ddb(state, crtc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -6092,7 +6086,6 @@ skl_compute_wm(struct intel_atomic_state *state)
|
|||
{
|
||||
struct intel_crtc *crtc;
|
||||
struct intel_crtc_state *new_crtc_state;
|
||||
struct intel_crtc_state *old_crtc_state;
|
||||
int ret, i;
|
||||
|
||||
ret = skl_ddb_add_affected_pipes(state);
|
||||
|
@ -6104,9 +6097,8 @@ skl_compute_wm(struct intel_atomic_state *state)
|
|||
* Note that skl_ddb_add_affected_pipes may have added more CRTC's that
|
||||
* weren't otherwise being modified if pipe allocations had to change.
|
||||
*/
|
||||
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
|
||||
new_crtc_state, i) {
|
||||
ret = skl_build_pipe_wm(new_crtc_state);
|
||||
for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
|
||||
ret = skl_build_pipe_wm(state, crtc);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
@ -6124,8 +6116,7 @@ skl_compute_wm(struct intel_atomic_state *state)
|
|||
* based on how much ddb is available. Now we can actually
|
||||
* check if the final watermarks changed.
|
||||
*/
|
||||
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
|
||||
new_crtc_state, i) {
|
||||
for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
|
||||
ret = skl_wm_add_affected_planes(state, crtc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -6271,6 +6262,7 @@ void skl_wm_get_hw_state(struct drm_i915_private *dev_priv)
|
|||
crtc_state = to_intel_crtc_state(crtc->base.state);
|
||||
|
||||
skl_pipe_wm_get_hw_state(crtc, &crtc_state->wm.skl.optimal);
|
||||
crtc_state->wm.skl.raw = crtc_state->wm.skl.optimal;
|
||||
}
|
||||
|
||||
if (dev_priv->active_pipes) {
|
||||
|
|
|
@ -584,20 +584,19 @@
|
|||
|
||||
/* EHL */
|
||||
#define INTEL_EHL_IDS(info) \
|
||||
INTEL_VGA_DEVICE(0x4500, info), \
|
||||
INTEL_VGA_DEVICE(0x4571, info), \
|
||||
INTEL_VGA_DEVICE(0x4551, info), \
|
||||
INTEL_VGA_DEVICE(0x4541, info), \
|
||||
INTEL_VGA_DEVICE(0x4551, info), \
|
||||
INTEL_VGA_DEVICE(0x4555, info), \
|
||||
INTEL_VGA_DEVICE(0x4557, info), \
|
||||
INTEL_VGA_DEVICE(0x4555, info)
|
||||
INTEL_VGA_DEVICE(0x4571, info)
|
||||
|
||||
/* JSL */
|
||||
#define INTEL_JSL_IDS(info) \
|
||||
INTEL_VGA_DEVICE(0x4E71, info), \
|
||||
INTEL_VGA_DEVICE(0x4E61, info), \
|
||||
INTEL_VGA_DEVICE(0x4E57, info), \
|
||||
INTEL_VGA_DEVICE(0x4E51, info), \
|
||||
INTEL_VGA_DEVICE(0x4E55, info), \
|
||||
INTEL_VGA_DEVICE(0x4E51, info)
|
||||
INTEL_VGA_DEVICE(0x4E57, info), \
|
||||
INTEL_VGA_DEVICE(0x4E61, info), \
|
||||
INTEL_VGA_DEVICE(0x4E71, info)
|
||||
|
||||
/* TGL */
|
||||
#define INTEL_TGL_12_GT1_IDS(info) \
|
||||
|
|
Загрузка…
Ссылка в новой задаче