From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2B6DECCA47B for ; Mon, 13 Jun 2022 13:21:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1376393AbiFMNVk (ORCPT ); Mon, 13 Jun 2022 09:21:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60520 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1377232AbiFMNUJ (ORCPT ); Mon, 13 Jun 2022 09:20:09 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BD7596A039; Mon, 13 Jun 2022 04:23:19 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id E1FDB61121; Mon, 13 Jun 2022 11:22:43 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id EFED2C341C5; Mon, 13 Jun 2022 11:22:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1655119363; bh=XR4pBaO0NMis/STcgabovWoFuXApSW2ZcL7eX6Yn8E4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DVZ78e4oL1/5SNLi4xc4HjCyTKp4W14FtzDQrL+pEsLOvbSHHMr/JmL6TSLFuQWc4 VlrWxhkR0O7smgBLBAQPZjiZDxbHpsh+CtOmeNwdnnsulqgNtVTLXThkwT72vVxGdi aRjiUM2LAGx684F/lEsmARRoQATMHqwYIer2N+PQ= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Liu Ying , Brian Norris , Sean Paul , Douglas Anderson Subject: [PATCH 5.15 236/247] drm/atomic: Force bridge self-refresh-exit on CRTC switch Date: Mon, 13 Jun 2022 12:12:18 +0200 Message-Id: <20220613094930.102199941@linuxfoundation.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220613094922.843438024@linuxfoundation.org> References: <20220613094922.843438024@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Brian Norris commit e54a4424925a27ed94dff046db3ce5caf4b1e748 upstream. It's possible to change which CRTC is in use for a given connector/encoder/bridge while we're in self-refresh without fully disabling the connector/encoder/bridge along the way. This can confuse the bridge encoder/bridge, because (a) it needs to track the SR state (trying to perform "active" operations while the panel is still in SR can be Bad(TM)); and (b) it tracks the SR state via the CRTC state (and after the switch, the previous SR state is lost). Thus, we need to either somehow carry the self-refresh state over to the new CRTC, or else force an encoder/bridge self-refresh transition during such a switch. I choose the latter, so we disable the encoder (and exit PSR) before attaching it to the new CRTC (where we can continue to assume a clean (non-self-refresh) state). This fixes PSR issues seen on Rockchip RK3399 systems with drivers/gpu/drm/bridge/analogix/analogix_dp_core.c. Change in v2: - Drop "->enable" condition; this could possibly be "->active" to reflect the intended hardware state, but it also is a little over-specific. We want to make a transition through "disabled" any time we're exiting PSR at the same time as a CRTC switch. (Thanks Liu Ying) Cc: Liu Ying Cc: Fixes: 1452c25b0e60 ("drm: Add helpers to kick off self refresh mode in drivers") Signed-off-by: Brian Norris Reviewed-by: Sean Paul Signed-off-by: Douglas Anderson Link: https://patchwork.freedesktop.org/patch/msgid/20220228122522.v2.2.Ic15a2ef69c540aee8732703103e2cff51fb9c399@changeid Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/drm_atomic_helper.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -996,9 +996,19 @@ crtc_needs_disable(struct drm_crtc_state return drm_atomic_crtc_effectively_active(old_state); /* - * We need to run through the crtc_funcs->disable() function if the CRTC - * is currently on, if it's transitioning to self refresh mode, or if - * it's in self refresh mode and needs to be fully disabled. + * We need to disable bridge(s) and CRTC if we're transitioning out of + * self-refresh and changing CRTCs at the same time, because the + * bridge tracks self-refresh status via CRTC state. + */ + if (old_state->self_refresh_active && + old_state->crtc != new_state->crtc) + return true; + + /* + * We also need to run through the crtc_funcs->disable() function if + * the CRTC is currently on, if it's transitioning to self refresh + * mode, or if it's in self refresh mode and needs to be fully + * disabled. */ return old_state->active || (old_state->self_refresh_active && !new_state->active) ||