浏览代码

disp: msm: rsc: fix RSC handling of state and timing updates

This patch addresses 2 issues with RSC; 1) internal tracking of
certain state updates, and 2) skipping certain timing updates
in CLK state that are required.

1) With primary in video mode, RSC will override the video mode
state in favor of clock mode on RSC rev3+ HW but this override
is applied after updating the client's state and checking if a
state change is required.

If RSC is already in clock state and the client provides a video
mode state update, the state change check will proceed since the
client request doesn't match the current state, but then the
requested state gets overridden so that it does match and another
switch to clock state occurs. Fix this by moving the state update
and state change check after applying the override. Also update
the event log so the state transitions are logged properly to
help identify similar issues in the future.

2) If continuous splash is still active on a secondary display
and primary gets a mode switch, the timing update is skipped
since the RSC client requests for a CLK state update. When
secondary is then used and goes idle, solver mode can get
enabled with the wrong timing.

Primary is the only encoder allowed to provide timing updates
and it votes for CLK state when splash is active on another
display or if QSync is enabled. In both cases timing updates
should be applied in case of later transitions to solver mode.
To address the issue, add a check which ensures timing updates
are applied for these corner cases.

Change-Id: I54ca0898d2f430b7e8c601de7309fc57d717e0bb
Signed-off-by: Steve Cohen <[email protected]>
Steve Cohen 4 年之前
父节点
当前提交
0e0eb8ac11
共有 1 个文件被更改,包括 22 次插入9 次删除
  1. 22 9
      msm/sde_rsc.c

+ 22 - 9
msm/sde_rsc.c

@@ -925,21 +925,34 @@ int sde_rsc_client_state_update(struct sde_rsc_client *caller_client,
 	mutex_lock(&rsc->client_lock);
 	SDE_EVT32_VERBOSE(caller_client->id, caller_client->current_state,
 			state, rsc->current_state, SDE_EVTLOG_FUNC_ENTRY);
-	caller_client->crtc_id = crtc_id;
-	caller_client->current_state = state;
-
-	if ((rsc->current_state == state) && !config) {
-		pr_debug("no state change: %d\n", state);
-		goto end;
-	}
 
 	pr_debug("%pS: rsc state:%d request client:%s state:%d\n",
 		__builtin_return_address(0), rsc->current_state,
 		caller_client->name, state);
 
+	/**
+	 * This can only happen if splash is active or qsync is enabled.
+	 * In both cases timers need to be updated for when a transition to
+	 * solver occurs. Update timers now as config might not be available
+	 * at next switch. Updates for cmd/vid are handled when switching to
+	 * those states.
+	 */
+	if (config && (state == SDE_RSC_CLK_STATE) &&
+			(caller_client == rsc->primary_client))
+		sde_rsc_timer_calculate(rsc, config, state);
+
 	if ((state == SDE_RSC_VID_STATE) && (rsc->version >= SDE_RSC_REV_3))
 		state = SDE_RSC_CLK_STATE;
 
+	caller_client->crtc_id = crtc_id;
+	caller_client->current_state = state;
+
+	if ((rsc->current_state == state) && !config) {
+		SDE_EVT32(caller_client->id, caller_client->current_state,
+			state, rsc->current_state, SDE_EVTLOG_FUNC_CASE3);
+		goto end;
+	}
+
 	if (rsc->current_state == SDE_RSC_IDLE_STATE)
 		sde_rsc_resource_enable(rsc);
 
@@ -993,10 +1006,10 @@ int sde_rsc_client_state_update(struct sde_rsc_client *caller_client,
 
 	pr_debug("state switch successfully complete: %d\n", state);
 	SDE_ATRACE_INT("rsc_state", state);
-	rsc->current_state = state;
-	rsc->update_tcs_content = true;
 	SDE_EVT32(caller_client->id, caller_client->current_state,
 			state, rsc->current_state, SDE_EVTLOG_FUNC_EXIT);
+	rsc->current_state = state;
+	rsc->update_tcs_content = true;
 
 clk_disable:
 	if (rsc->current_state == SDE_RSC_IDLE_STATE)