Merge tag 'drm-intel-next-fixes-2022-10-06-1' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
- Round to closest in g4x+ HDMI clock readout (Ville Syrjälä) - Update MOCS table for EHL (Tejas Upadhyay) - Fix PSR_IMR/IIR field handling (Jouni Högander) - Fix watermark calculations for gen12+ RC CCS modifier (Ville Syrjälä) - Fix watermark calculations for gen12+ MC CCS modifier (Ville Syrjälä) - Fix watermark calculations for gen12+ CCS+CC modifier (Ville Syrjälä) - Fix watermark calculations for DG2 CCS modifiers (Ville Syrjälä) - Fix watermark calculations for DG2 CCS+CC modifier (Ville Syrjälä) - Reject excessive dotclocks early (Ville Syrjälä) Signed-off-by: Dave Airlie <airlied@redhat.com> From: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/Yz6rkXI9HKFUvtWK@tursulin-desk
This commit is contained in:
commit
d6fe5887ca
|
@ -120,7 +120,7 @@ static void intel_hdmi_get_config(struct intel_encoder *encoder,
|
||||||
pipe_config->hw.adjusted_mode.flags |= flags;
|
pipe_config->hw.adjusted_mode.flags |= flags;
|
||||||
|
|
||||||
if ((tmp & SDVO_COLOR_FORMAT_MASK) == HDMI_COLOR_FORMAT_12bpc)
|
if ((tmp & SDVO_COLOR_FORMAT_MASK) == HDMI_COLOR_FORMAT_12bpc)
|
||||||
dotclock = pipe_config->port_clock * 2 / 3;
|
dotclock = DIV_ROUND_CLOSEST(pipe_config->port_clock * 2, 3);
|
||||||
else
|
else
|
||||||
dotclock = pipe_config->port_clock;
|
dotclock = pipe_config->port_clock;
|
||||||
|
|
||||||
|
|
|
@ -8130,6 +8130,17 @@ static void intel_setup_outputs(struct drm_i915_private *dev_priv)
|
||||||
drm_helper_move_panel_connectors_to_head(&dev_priv->drm);
|
drm_helper_move_panel_connectors_to_head(&dev_priv->drm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int max_dotclock(struct drm_i915_private *i915)
|
||||||
|
{
|
||||||
|
int max_dotclock = i915->max_dotclk_freq;
|
||||||
|
|
||||||
|
/* icl+ might use bigjoiner */
|
||||||
|
if (DISPLAY_VER(i915) >= 11)
|
||||||
|
max_dotclock *= 2;
|
||||||
|
|
||||||
|
return max_dotclock;
|
||||||
|
}
|
||||||
|
|
||||||
static enum drm_mode_status
|
static enum drm_mode_status
|
||||||
intel_mode_valid(struct drm_device *dev,
|
intel_mode_valid(struct drm_device *dev,
|
||||||
const struct drm_display_mode *mode)
|
const struct drm_display_mode *mode)
|
||||||
|
@ -8167,6 +8178,13 @@ intel_mode_valid(struct drm_device *dev,
|
||||||
DRM_MODE_FLAG_CLKDIV2))
|
DRM_MODE_FLAG_CLKDIV2))
|
||||||
return MODE_BAD;
|
return MODE_BAD;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reject clearly excessive dotclocks early to
|
||||||
|
* avoid having to worry about huge integers later.
|
||||||
|
*/
|
||||||
|
if (mode->clock > max_dotclock(dev_priv))
|
||||||
|
return MODE_CLOCK_HIGH;
|
||||||
|
|
||||||
/* Transcoder timing limits */
|
/* Transcoder timing limits */
|
||||||
if (DISPLAY_VER(dev_priv) >= 11) {
|
if (DISPLAY_VER(dev_priv) >= 11) {
|
||||||
hdisplay_max = 16384;
|
hdisplay_max = 16384;
|
||||||
|
|
|
@ -116,34 +116,56 @@ static bool psr2_global_enabled(struct intel_dp *intel_dp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u32 psr_irq_psr_error_bit_get(struct intel_dp *intel_dp)
|
||||||
|
{
|
||||||
|
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
|
||||||
|
|
||||||
|
return DISPLAY_VER(dev_priv) >= 12 ? TGL_PSR_ERROR :
|
||||||
|
EDP_PSR_ERROR(intel_dp->psr.transcoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 psr_irq_post_exit_bit_get(struct intel_dp *intel_dp)
|
||||||
|
{
|
||||||
|
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
|
||||||
|
|
||||||
|
return DISPLAY_VER(dev_priv) >= 12 ? TGL_PSR_POST_EXIT :
|
||||||
|
EDP_PSR_POST_EXIT(intel_dp->psr.transcoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 psr_irq_pre_entry_bit_get(struct intel_dp *intel_dp)
|
||||||
|
{
|
||||||
|
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
|
||||||
|
|
||||||
|
return DISPLAY_VER(dev_priv) >= 12 ? TGL_PSR_PRE_ENTRY :
|
||||||
|
EDP_PSR_PRE_ENTRY(intel_dp->psr.transcoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 psr_irq_mask_get(struct intel_dp *intel_dp)
|
||||||
|
{
|
||||||
|
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
|
||||||
|
|
||||||
|
return DISPLAY_VER(dev_priv) >= 12 ? TGL_PSR_MASK :
|
||||||
|
EDP_PSR_MASK(intel_dp->psr.transcoder);
|
||||||
|
}
|
||||||
|
|
||||||
static void psr_irq_control(struct intel_dp *intel_dp)
|
static void psr_irq_control(struct intel_dp *intel_dp)
|
||||||
{
|
{
|
||||||
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
|
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
|
||||||
enum transcoder trans_shift;
|
|
||||||
i915_reg_t imr_reg;
|
i915_reg_t imr_reg;
|
||||||
u32 mask, val;
|
u32 mask, val;
|
||||||
|
|
||||||
/*
|
if (DISPLAY_VER(dev_priv) >= 12)
|
||||||
* gen12+ has registers relative to transcoder and one per transcoder
|
|
||||||
* using the same bit definition: handle it as TRANSCODER_EDP to force
|
|
||||||
* 0 shift in bit definition
|
|
||||||
*/
|
|
||||||
if (DISPLAY_VER(dev_priv) >= 12) {
|
|
||||||
trans_shift = 0;
|
|
||||||
imr_reg = TRANS_PSR_IMR(intel_dp->psr.transcoder);
|
imr_reg = TRANS_PSR_IMR(intel_dp->psr.transcoder);
|
||||||
} else {
|
else
|
||||||
trans_shift = intel_dp->psr.transcoder;
|
|
||||||
imr_reg = EDP_PSR_IMR;
|
imr_reg = EDP_PSR_IMR;
|
||||||
}
|
|
||||||
|
|
||||||
mask = EDP_PSR_ERROR(trans_shift);
|
mask = psr_irq_psr_error_bit_get(intel_dp);
|
||||||
if (intel_dp->psr.debug & I915_PSR_DEBUG_IRQ)
|
if (intel_dp->psr.debug & I915_PSR_DEBUG_IRQ)
|
||||||
mask |= EDP_PSR_POST_EXIT(trans_shift) |
|
mask |= psr_irq_post_exit_bit_get(intel_dp) |
|
||||||
EDP_PSR_PRE_ENTRY(trans_shift);
|
psr_irq_pre_entry_bit_get(intel_dp);
|
||||||
|
|
||||||
/* Warning: it is masking/setting reserved bits too */
|
|
||||||
val = intel_de_read(dev_priv, imr_reg);
|
val = intel_de_read(dev_priv, imr_reg);
|
||||||
val &= ~EDP_PSR_TRANS_MASK(trans_shift);
|
val &= ~psr_irq_mask_get(intel_dp);
|
||||||
val |= ~mask;
|
val |= ~mask;
|
||||||
intel_de_write(dev_priv, imr_reg, val);
|
intel_de_write(dev_priv, imr_reg, val);
|
||||||
}
|
}
|
||||||
|
@ -191,25 +213,21 @@ void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir)
|
||||||
enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
|
enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
|
||||||
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
|
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
|
||||||
ktime_t time_ns = ktime_get();
|
ktime_t time_ns = ktime_get();
|
||||||
enum transcoder trans_shift;
|
|
||||||
i915_reg_t imr_reg;
|
i915_reg_t imr_reg;
|
||||||
|
|
||||||
if (DISPLAY_VER(dev_priv) >= 12) {
|
if (DISPLAY_VER(dev_priv) >= 12)
|
||||||
trans_shift = 0;
|
|
||||||
imr_reg = TRANS_PSR_IMR(intel_dp->psr.transcoder);
|
imr_reg = TRANS_PSR_IMR(intel_dp->psr.transcoder);
|
||||||
} else {
|
else
|
||||||
trans_shift = intel_dp->psr.transcoder;
|
|
||||||
imr_reg = EDP_PSR_IMR;
|
imr_reg = EDP_PSR_IMR;
|
||||||
}
|
|
||||||
|
|
||||||
if (psr_iir & EDP_PSR_PRE_ENTRY(trans_shift)) {
|
if (psr_iir & psr_irq_pre_entry_bit_get(intel_dp)) {
|
||||||
intel_dp->psr.last_entry_attempt = time_ns;
|
intel_dp->psr.last_entry_attempt = time_ns;
|
||||||
drm_dbg_kms(&dev_priv->drm,
|
drm_dbg_kms(&dev_priv->drm,
|
||||||
"[transcoder %s] PSR entry attempt in 2 vblanks\n",
|
"[transcoder %s] PSR entry attempt in 2 vblanks\n",
|
||||||
transcoder_name(cpu_transcoder));
|
transcoder_name(cpu_transcoder));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (psr_iir & EDP_PSR_POST_EXIT(trans_shift)) {
|
if (psr_iir & psr_irq_post_exit_bit_get(intel_dp)) {
|
||||||
intel_dp->psr.last_exit = time_ns;
|
intel_dp->psr.last_exit = time_ns;
|
||||||
drm_dbg_kms(&dev_priv->drm,
|
drm_dbg_kms(&dev_priv->drm,
|
||||||
"[transcoder %s] PSR exit completed\n",
|
"[transcoder %s] PSR exit completed\n",
|
||||||
|
@ -226,7 +244,7 @@ void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (psr_iir & EDP_PSR_ERROR(trans_shift)) {
|
if (psr_iir & psr_irq_psr_error_bit_get(intel_dp)) {
|
||||||
u32 val;
|
u32 val;
|
||||||
|
|
||||||
drm_warn(&dev_priv->drm, "[transcoder %s] PSR aux error\n",
|
drm_warn(&dev_priv->drm, "[transcoder %s] PSR aux error\n",
|
||||||
|
@ -243,7 +261,7 @@ void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir)
|
||||||
* or unset irq_aux_error.
|
* or unset irq_aux_error.
|
||||||
*/
|
*/
|
||||||
val = intel_de_read(dev_priv, imr_reg);
|
val = intel_de_read(dev_priv, imr_reg);
|
||||||
val |= EDP_PSR_ERROR(trans_shift);
|
val |= psr_irq_psr_error_bit_get(intel_dp);
|
||||||
intel_de_write(dev_priv, imr_reg, val);
|
intel_de_write(dev_priv, imr_reg, val);
|
||||||
|
|
||||||
schedule_work(&intel_dp->psr.work);
|
schedule_work(&intel_dp->psr.work);
|
||||||
|
@ -1194,14 +1212,12 @@ static bool psr_interrupt_error_check(struct intel_dp *intel_dp)
|
||||||
* first time that PSR HW tries to activate so lets keep PSR disabled
|
* first time that PSR HW tries to activate so lets keep PSR disabled
|
||||||
* to avoid any rendering problems.
|
* to avoid any rendering problems.
|
||||||
*/
|
*/
|
||||||
if (DISPLAY_VER(dev_priv) >= 12) {
|
if (DISPLAY_VER(dev_priv) >= 12)
|
||||||
val = intel_de_read(dev_priv,
|
val = intel_de_read(dev_priv,
|
||||||
TRANS_PSR_IIR(intel_dp->psr.transcoder));
|
TRANS_PSR_IIR(intel_dp->psr.transcoder));
|
||||||
val &= EDP_PSR_ERROR(0);
|
else
|
||||||
} else {
|
|
||||||
val = intel_de_read(dev_priv, EDP_PSR_IIR);
|
val = intel_de_read(dev_priv, EDP_PSR_IIR);
|
||||||
val &= EDP_PSR_ERROR(intel_dp->psr.transcoder);
|
val &= psr_irq_psr_error_bit_get(intel_dp);
|
||||||
}
|
|
||||||
if (val) {
|
if (val) {
|
||||||
intel_dp->psr.sink_not_reliable = true;
|
intel_dp->psr.sink_not_reliable = true;
|
||||||
drm_dbg_kms(&dev_priv->drm,
|
drm_dbg_kms(&dev_priv->drm,
|
||||||
|
|
|
@ -1710,10 +1710,22 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
|
||||||
modifier == I915_FORMAT_MOD_4_TILED ||
|
modifier == I915_FORMAT_MOD_4_TILED ||
|
||||||
modifier == I915_FORMAT_MOD_Yf_TILED ||
|
modifier == I915_FORMAT_MOD_Yf_TILED ||
|
||||||
modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
|
modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
|
||||||
modifier == I915_FORMAT_MOD_Yf_TILED_CCS;
|
modifier == I915_FORMAT_MOD_Yf_TILED_CCS ||
|
||||||
|
modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS ||
|
||||||
|
modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS ||
|
||||||
|
modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC ||
|
||||||
|
modifier == I915_FORMAT_MOD_4_TILED_DG2_RC_CCS ||
|
||||||
|
modifier == I915_FORMAT_MOD_4_TILED_DG2_MC_CCS ||
|
||||||
|
modifier == I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC;
|
||||||
wp->x_tiled = modifier == I915_FORMAT_MOD_X_TILED;
|
wp->x_tiled = modifier == I915_FORMAT_MOD_X_TILED;
|
||||||
wp->rc_surface = modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
|
wp->rc_surface = modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
|
||||||
modifier == I915_FORMAT_MOD_Yf_TILED_CCS;
|
modifier == I915_FORMAT_MOD_Yf_TILED_CCS ||
|
||||||
|
modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS ||
|
||||||
|
modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS ||
|
||||||
|
modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC ||
|
||||||
|
modifier == I915_FORMAT_MOD_4_TILED_DG2_RC_CCS ||
|
||||||
|
modifier == I915_FORMAT_MOD_4_TILED_DG2_MC_CCS ||
|
||||||
|
modifier == I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC;
|
||||||
wp->is_planar = intel_format_info_is_yuv_semiplanar(format, modifier);
|
wp->is_planar = intel_format_info_is_yuv_semiplanar(format, modifier);
|
||||||
|
|
||||||
wp->width = width;
|
wp->width = width;
|
||||||
|
|
|
@ -207,6 +207,14 @@ static const struct drm_i915_mocs_entry broxton_mocs_table[] = {
|
||||||
MOCS_ENTRY(15, \
|
MOCS_ENTRY(15, \
|
||||||
LE_3_WB | LE_TC_1_LLC | LE_LRUM(2) | LE_AOM(1), \
|
LE_3_WB | LE_TC_1_LLC | LE_LRUM(2) | LE_AOM(1), \
|
||||||
L3_3_WB), \
|
L3_3_WB), \
|
||||||
|
/* Bypass LLC - Uncached (EHL+) */ \
|
||||||
|
MOCS_ENTRY(16, \
|
||||||
|
LE_1_UC | LE_TC_1_LLC | LE_SCF(1), \
|
||||||
|
L3_1_UC), \
|
||||||
|
/* Bypass LLC - L3 (Read-Only) (EHL+) */ \
|
||||||
|
MOCS_ENTRY(17, \
|
||||||
|
LE_1_UC | LE_TC_1_LLC | LE_SCF(1), \
|
||||||
|
L3_3_WB), \
|
||||||
/* Self-Snoop - L3 + LLC */ \
|
/* Self-Snoop - L3 + LLC */ \
|
||||||
MOCS_ENTRY(18, \
|
MOCS_ENTRY(18, \
|
||||||
LE_3_WB | LE_TC_1_LLC | LE_LRUM(3) | LE_SSE(3), \
|
LE_3_WB | LE_TC_1_LLC | LE_LRUM(3) | LE_SSE(3), \
|
||||||
|
|
|
@ -2157,10 +2157,18 @@
|
||||||
#define TRANS_PSR_IIR(tran) _MMIO_TRANS2(tran, _PSR_IIR_A)
|
#define TRANS_PSR_IIR(tran) _MMIO_TRANS2(tran, _PSR_IIR_A)
|
||||||
#define _EDP_PSR_TRANS_SHIFT(trans) ((trans) == TRANSCODER_EDP ? \
|
#define _EDP_PSR_TRANS_SHIFT(trans) ((trans) == TRANSCODER_EDP ? \
|
||||||
0 : ((trans) - TRANSCODER_A + 1) * 8)
|
0 : ((trans) - TRANSCODER_A + 1) * 8)
|
||||||
#define EDP_PSR_TRANS_MASK(trans) (0x7 << _EDP_PSR_TRANS_SHIFT(trans))
|
#define TGL_PSR_MASK REG_GENMASK(2, 0)
|
||||||
#define EDP_PSR_ERROR(trans) (0x4 << _EDP_PSR_TRANS_SHIFT(trans))
|
#define TGL_PSR_ERROR REG_BIT(2)
|
||||||
#define EDP_PSR_POST_EXIT(trans) (0x2 << _EDP_PSR_TRANS_SHIFT(trans))
|
#define TGL_PSR_POST_EXIT REG_BIT(1)
|
||||||
#define EDP_PSR_PRE_ENTRY(trans) (0x1 << _EDP_PSR_TRANS_SHIFT(trans))
|
#define TGL_PSR_PRE_ENTRY REG_BIT(0)
|
||||||
|
#define EDP_PSR_MASK(trans) (TGL_PSR_MASK << \
|
||||||
|
_EDP_PSR_TRANS_SHIFT(trans))
|
||||||
|
#define EDP_PSR_ERROR(trans) (TGL_PSR_ERROR << \
|
||||||
|
_EDP_PSR_TRANS_SHIFT(trans))
|
||||||
|
#define EDP_PSR_POST_EXIT(trans) (TGL_PSR_POST_EXIT << \
|
||||||
|
_EDP_PSR_TRANS_SHIFT(trans))
|
||||||
|
#define EDP_PSR_PRE_ENTRY(trans) (TGL_PSR_PRE_ENTRY << \
|
||||||
|
_EDP_PSR_TRANS_SHIFT(trans))
|
||||||
|
|
||||||
#define _SRD_AUX_DATA_A 0x60814
|
#define _SRD_AUX_DATA_A 0x60814
|
||||||
#define _SRD_AUX_DATA_EDP 0x6f814
|
#define _SRD_AUX_DATA_EDP 0x6f814
|
||||||
|
|
Loading…
Reference in New Issue