Skip to content

Commit 54fd314

Browse files
dhnkrnrodrigovivi
authored andcommitted
drm/i915/psr: Control PSR interrupts via debugfs
Interrupts other than the one for AUX errors are required only for debug, so unmask them via debugfs when the user requests debug. User can make such a request with echo 1 > <DEBUG_FS>/dri/0/i915_edp_psr_debug There are no locks to serialize PSR debug enabling from irq_postinstall() and debugfs for simplicity. As irq_postinstall() is called only during module initialization/resume and IGT subtests aren't expected to modify PSR debug at those times, we should be safe. v2: Unroll loops (Ville) Avoid resetting error mask bits. v3: Unmask interrupts in postinstall() if debug was still enabled. Avoid RMW (Ville) v4: Avoid extra IMR write introduced in the previous version.(Jose) Style changes, renames (Jose). Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com> Reviewed-by: Jose Roberto de Souza <jose.souza@intel.com> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20180405013717.24254-1-dhinakaran.pandiyan@intel.com
1 parent e04f7ec commit 54fd314

File tree

5 files changed

+108
-40
lines changed

5 files changed

+108
-40
lines changed

drivers/gpu/drm/i915/i915_debugfs.c

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2690,6 +2690,39 @@ static int i915_edp_psr_status(struct seq_file *m, void *data)
26902690
return 0;
26912691
}
26922692

2693+
static int
2694+
i915_edp_psr_debug_set(void *data, u64 val)
2695+
{
2696+
struct drm_i915_private *dev_priv = data;
2697+
2698+
if (!CAN_PSR(dev_priv))
2699+
return -ENODEV;
2700+
2701+
DRM_DEBUG_KMS("PSR debug %s\n", enableddisabled(val));
2702+
2703+
intel_runtime_pm_get(dev_priv);
2704+
intel_psr_irq_control(dev_priv, !!val);
2705+
intel_runtime_pm_put(dev_priv);
2706+
2707+
return 0;
2708+
}
2709+
2710+
static int
2711+
i915_edp_psr_debug_get(void *data, u64 *val)
2712+
{
2713+
struct drm_i915_private *dev_priv = data;
2714+
2715+
if (!CAN_PSR(dev_priv))
2716+
return -ENODEV;
2717+
2718+
*val = READ_ONCE(dev_priv->psr.debug);
2719+
return 0;
2720+
}
2721+
2722+
DEFINE_SIMPLE_ATTRIBUTE(i915_edp_psr_debug_fops,
2723+
i915_edp_psr_debug_get, i915_edp_psr_debug_set,
2724+
"%llu\n");
2725+
26932726
static int i915_sink_crc(struct seq_file *m, void *data)
26942727
{
26952728
struct drm_i915_private *dev_priv = node_to_i915(m->private);
@@ -4862,7 +4895,8 @@ static const struct i915_debugfs_files {
48624895
{"i915_guc_log_relay", &i915_guc_log_relay_fops},
48634896
{"i915_hpd_storm_ctl", &i915_hpd_storm_ctl_fops},
48644897
{"i915_ipc_status", &i915_ipc_status_fops},
4865-
{"i915_drrs_ctl", &i915_drrs_ctl_fops}
4898+
{"i915_drrs_ctl", &i915_drrs_ctl_fops},
4899+
{"i915_edp_psr_debug", &i915_edp_psr_debug_fops}
48664900
};
48674901

48684902
int i915_debugfs_register(struct drm_i915_private *dev_priv)

drivers/gpu/drm/i915/i915_drv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,7 @@ struct i915_psr {
610610
bool has_hw_tracking;
611611
bool psr2_enabled;
612612
u8 sink_sync_latency;
613+
bool debug;
613614

614615
void (*enable_source)(struct intel_dp *,
615616
const struct intel_crtc_state *);

drivers/gpu/drm/i915/i915_irq.c

Lines changed: 12 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2452,40 +2452,6 @@ static void ilk_display_irq_handler(struct drm_i915_private *dev_priv,
24522452
ironlake_rps_change_irq_handler(dev_priv);
24532453
}
24542454

2455-
static void hsw_edp_psr_irq_handler(struct drm_i915_private *dev_priv)
2456-
{
2457-
u32 edp_psr_iir = I915_READ(EDP_PSR_IIR);
2458-
u32 edp_psr_imr = I915_READ(EDP_PSR_IMR);
2459-
u32 mask = BIT(TRANSCODER_EDP);
2460-
enum transcoder cpu_transcoder;
2461-
2462-
if (INTEL_GEN(dev_priv) >= 8)
2463-
mask |= BIT(TRANSCODER_A) |
2464-
BIT(TRANSCODER_B) |
2465-
BIT(TRANSCODER_C);
2466-
2467-
for_each_cpu_transcoder_masked(dev_priv, cpu_transcoder, mask) {
2468-
if (edp_psr_iir & EDP_PSR_ERROR(cpu_transcoder))
2469-
DRM_DEBUG_KMS("Transcoder %s PSR error\n",
2470-
transcoder_name(cpu_transcoder));
2471-
2472-
if (edp_psr_iir & EDP_PSR_PRE_ENTRY(cpu_transcoder)) {
2473-
DRM_DEBUG_KMS("Transcoder %s PSR prepare entry in 2 vblanks\n",
2474-
transcoder_name(cpu_transcoder));
2475-
edp_psr_imr |= EDP_PSR_PRE_ENTRY(cpu_transcoder);
2476-
}
2477-
2478-
if (edp_psr_iir & EDP_PSR_POST_EXIT(cpu_transcoder)) {
2479-
DRM_DEBUG_KMS("Transcoder %s PSR exit completed\n",
2480-
transcoder_name(cpu_transcoder));
2481-
edp_psr_imr &= ~EDP_PSR_PRE_ENTRY(cpu_transcoder);
2482-
}
2483-
}
2484-
2485-
I915_WRITE(EDP_PSR_IMR, edp_psr_imr);
2486-
I915_WRITE(EDP_PSR_IIR, edp_psr_iir);
2487-
}
2488-
24892455
static void ivb_display_irq_handler(struct drm_i915_private *dev_priv,
24902456
u32 de_iir)
24912457
{
@@ -2498,8 +2464,12 @@ static void ivb_display_irq_handler(struct drm_i915_private *dev_priv,
24982464
if (de_iir & DE_ERR_INT_IVB)
24992465
ivb_err_int_handler(dev_priv);
25002466

2501-
if (de_iir & DE_EDP_PSR_INT_HSW)
2502-
hsw_edp_psr_irq_handler(dev_priv);
2467+
if (de_iir & DE_EDP_PSR_INT_HSW) {
2468+
u32 psr_iir = I915_READ(EDP_PSR_IIR);
2469+
2470+
intel_psr_irq_handler(dev_priv, psr_iir);
2471+
I915_WRITE(EDP_PSR_IIR, psr_iir);
2472+
}
25032473

25042474
if (de_iir & DE_AUX_CHANNEL_A_IVB)
25052475
dp_aux_irq_handler(dev_priv);
@@ -2641,7 +2611,10 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl)
26412611
}
26422612

26432613
if (iir & GEN8_DE_EDP_PSR) {
2644-
hsw_edp_psr_irq_handler(dev_priv);
2614+
u32 psr_iir = I915_READ(EDP_PSR_IIR);
2615+
2616+
intel_psr_irq_handler(dev_priv, psr_iir);
2617+
I915_WRITE(EDP_PSR_IIR, psr_iir);
26452618
found = true;
26462619
}
26472620

@@ -3820,7 +3793,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
38203793

38213794
if (IS_HASWELL(dev_priv)) {
38223795
gen3_assert_iir_is_zero(dev_priv, EDP_PSR_IIR);
3823-
I915_WRITE(EDP_PSR_IMR, 0);
3796+
intel_psr_irq_control(dev_priv, dev_priv->psr.debug);
38243797
display_mask |= DE_EDP_PSR_INT_HSW;
38253798
}
38263799

@@ -3960,7 +3933,7 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
39603933
de_port_enables |= GEN8_PORT_DP_A_HOTPLUG;
39613934

39623935
gen3_assert_iir_is_zero(dev_priv, EDP_PSR_IIR);
3963-
I915_WRITE(EDP_PSR_IMR, 0);
3936+
intel_psr_irq_control(dev_priv, dev_priv->psr.debug);
39643937

39653938
for_each_pipe(dev_priv, pipe) {
39663939
dev_priv->de_irq_mask[pipe] = ~de_pipe_masked;

drivers/gpu/drm/i915/intel_drv.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1899,6 +1899,8 @@ void intel_psr_single_frame_update(struct drm_i915_private *dev_priv,
18991899
unsigned frontbuffer_bits);
19001900
void intel_psr_compute_config(struct intel_dp *intel_dp,
19011901
struct intel_crtc_state *crtc_state);
1902+
void intel_psr_irq_control(struct drm_i915_private *dev_priv, bool debug);
1903+
void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir);
19021904

19031905
/* intel_runtime_pm.c */
19041906
int intel_power_domains_init(struct drm_i915_private *);

drivers/gpu/drm/i915/intel_psr.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,64 @@ static void psr_aux_io_power_put(struct intel_dp *intel_dp)
9393
intel_display_power_put(dev_priv, psr_aux_domain(intel_dp));
9494
}
9595

96+
void intel_psr_irq_control(struct drm_i915_private *dev_priv, bool debug)
97+
{
98+
u32 debug_mask, mask;
99+
100+
/* No PSR interrupts on VLV/CHV */
101+
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
102+
return;
103+
104+
mask = EDP_PSR_ERROR(TRANSCODER_EDP);
105+
debug_mask = EDP_PSR_POST_EXIT(TRANSCODER_EDP) |
106+
EDP_PSR_PRE_ENTRY(TRANSCODER_EDP);
107+
108+
if (INTEL_GEN(dev_priv) >= 8) {
109+
mask |= EDP_PSR_ERROR(TRANSCODER_A) |
110+
EDP_PSR_ERROR(TRANSCODER_B) |
111+
EDP_PSR_ERROR(TRANSCODER_C);
112+
113+
debug_mask |= EDP_PSR_POST_EXIT(TRANSCODER_A) |
114+
EDP_PSR_PRE_ENTRY(TRANSCODER_A) |
115+
EDP_PSR_POST_EXIT(TRANSCODER_B) |
116+
EDP_PSR_PRE_ENTRY(TRANSCODER_B) |
117+
EDP_PSR_POST_EXIT(TRANSCODER_C) |
118+
EDP_PSR_PRE_ENTRY(TRANSCODER_C);
119+
}
120+
121+
if (debug)
122+
mask |= debug_mask;
123+
124+
WRITE_ONCE(dev_priv->psr.debug, debug);
125+
I915_WRITE(EDP_PSR_IMR, ~mask);
126+
}
127+
128+
void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir)
129+
{
130+
u32 transcoders = BIT(TRANSCODER_EDP);
131+
enum transcoder cpu_transcoder;
132+
133+
if (INTEL_GEN(dev_priv) >= 8)
134+
transcoders |= BIT(TRANSCODER_A) |
135+
BIT(TRANSCODER_B) |
136+
BIT(TRANSCODER_C);
137+
138+
for_each_cpu_transcoder_masked(dev_priv, cpu_transcoder, transcoders) {
139+
/* FIXME: Exit PSR and link train manually when this happens. */
140+
if (psr_iir & EDP_PSR_ERROR(cpu_transcoder))
141+
DRM_DEBUG_KMS("[transcoder %s] PSR aux error\n",
142+
transcoder_name(cpu_transcoder));
143+
144+
if (psr_iir & EDP_PSR_PRE_ENTRY(cpu_transcoder))
145+
DRM_DEBUG_KMS("[transcoder %s] PSR entry attempt in 2 vblanks\n",
146+
transcoder_name(cpu_transcoder));
147+
148+
if (psr_iir & EDP_PSR_POST_EXIT(cpu_transcoder))
149+
DRM_DEBUG_KMS("[transcoder %s] PSR exit completed\n",
150+
transcoder_name(cpu_transcoder));
151+
}
152+
}
153+
96154
static bool intel_dp_get_y_coord_required(struct intel_dp *intel_dp)
97155
{
98156
uint8_t psr_caps = 0;

0 commit comments

Comments
 (0)