aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.19.8/0232-drm-amd-display-support-48-MHZ-refclk-off.patch
blob: e3ecc7c1a701e0442934b3c5601a5891d10c355c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
From be3a38e1d3bd0fcccc3e8e38ea401f02002850b1 Mon Sep 17 00:00:00 2001
From: Eric Yang <Eric.Yang2@amd.com>
Date: Wed, 15 Aug 2018 17:35:50 -0400
Subject: [PATCH 0232/2940] drm/amd/display: support 48 MHZ refclk off

[Why]
On PCO and up, whenever SMU receive message to indicate active
display count = 0. SMU will turn off 48MHZ TMDP reference clock
by writing to 1 TMDP_48M_Refclk_Driver_PWDN. Once this clock is
off, no PHY register will respond to register access. This means
our current sequence of notifying display count along with requesting
clock will cause driver to hang when accessing PHY registers after
displays count goes to 0.

[How]
Separate the PPSMC_MSG_SetDisplayCount message from the SMU messages
that request clocks, have display own sequencing of this message so
that we can send it at the appropriate time.
Do not redundantly power off HW when entering S3, S4, since display
should already be called to disable all streams. And ASIC soon be
powered down.

Signed-off-by: Eric Yang <Eric.Yang2@amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c | 36 ++++++++++++++++++++++--
 1 file changed, 33 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 803b7e815959..8ac1350610a7 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -1376,6 +1376,34 @@ static struct dc_stream_status *stream_get_status(
 
 static const enum surface_update_type update_surface_trace_level = UPDATE_TYPE_FULL;
 
+static void notify_display_count_to_smu(
+		struct dc *dc,
+		struct dc_state *context)
+{
+	int i, display_count;
+	struct pp_smu_funcs_rv *pp_smu = dc->res_pool->pp_smu;
+
+	/*
+	 * if function pointer not set up, this message is
+	 * sent as part of pplib_apply_display_requirements.
+	 * So just return.
+	 */
+	if (!pp_smu->set_display_count)
+		return;
+
+	display_count = 0;
+	for (i = 0; i < context->stream_count; i++) {
+		const struct dc_stream_state *stream = context->streams[i];
+
+		/* only notify active stream */
+		if (stream->dpms_off)
+			continue;
+
+		display_count++;
+	}
+
+	pp_smu->set_display_count(&pp_smu->pp_smu, display_count);
+}
 
 static void commit_planes_do_stream_update(struct dc *dc,
 		struct dc_stream_state *stream,
@@ -1429,13 +1457,17 @@ static void commit_planes_do_stream_update(struct dc *dc,
 					core_link_disable_stream(pipe_ctx, KEEP_ACQUIRED_RESOURCE);
 					dc->hwss.pplib_apply_display_requirements(
 						dc, dc->current_state);
+					notify_display_count_to_smu(dc, dc->current_state);
 				} else {
 					dc->hwss.pplib_apply_display_requirements(
 						dc, dc->current_state);
+					notify_display_count_to_smu(dc, dc->current_state);
 					core_link_enable_stream(dc->current_state, pipe_ctx);
 				}
 			}
 
+
+
 			if (stream_update->abm_level && pipe_ctx->stream_res.abm) {
 				if (pipe_ctx->stream_res.tg->funcs->is_blanked) {
 					// if otg funcs defined check if blanked before programming
@@ -1671,9 +1703,7 @@ void dc_set_power_state(
 		dc->hwss.init_hw(dc);
 		break;
 	default:
-
-		dc->hwss.power_down(dc);
-
+		ASSERT(dc->current_state->stream_count == 0);
 		/* Zero out the current context so that on resume we start with
 		 * clean state, and dc hw programming optimizations will not
 		 * cause any trouble.
-- 
2.17.1