Received: by 2002:a05:6a10:5bc5:0:0:0:0 with SMTP id os5csp995672pxb; Thu, 21 Oct 2021 13:38:29 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzBDLbZ2+f6434XdKRVxJKLZnb7fKQ/IGBrutfKdphjfo0iWoDJdI5Xsjo/g4bYfSkRntnK X-Received: by 2002:a50:9f66:: with SMTP id b93mr3477644edf.85.1634848709418; Thu, 21 Oct 2021 13:38:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1634848709; cv=none; d=google.com; s=arc-20160816; b=lLa2uA7Gcqhxb7SUsq+VE/UQVcZxhOMjxtfhn9baBB3ohaPhnSgeBsljoRYc0kn4ur JqzgJEpLVRYbKRdgu5+0f0kUjdCWZwKUyZO/6poFosIyJE9JUdR608K87MBRIopx+xEs xU1iLo7q+coJe5WnyWk74BrusLq+mXQWEtUS8UBJTG3JCpcEYRC0h74yAhdiTY7NuidM dChRqxP6zqk4xdkMKJ8+WRVhzKyUj6/GnqbJPa1dAjRrUATqhPMkU8f10pojcy5EHxNJ SPuxPIaH+lEZax49T1tFFiy6gWTHZBzMEt+fPnFqlAVIpzLRw65TBLdpCGWcV0Z0VXfZ +qWw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:dkim-signature; bh=qc5yk2ewhoH94OoX+tRZuXvqhmyfRbN00IiOr1tb4iU=; b=U/4XD5+06TGpC/h+VEOHU808U545sj9G8WnvjiFUV8I/vu+7pW8bL2x7B7s04X3aXT Ps+9FqBA6oj5quggxEv37p6M0+x60Kb6feF3luZUI4sC723x7/mvNm113qZlehcvJEIB 8U95yMjIJgCQLVf6f0xFUfAOLuQhl3Fd/Nt0gaKwDmttmaN4dyog/JEVFAFOI0RfTYgC 2k01QXR2ZN2QdpIoq7YGBfYh+4myWDZSQTZkNBv48dncmAkji6SNDvUN4rd1ymzpwsFR FwPPCFDnXtDgo5xs3vXXPiFNFP7EL5cy8f/S4YKjQ+6HHHD6oUWrbH8dbFwww/nDSozb gs1A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b="OoTa6UG/"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id gn41si12162859ejc.594.2021.10.21.13.38.06; Thu, 21 Oct 2021 13:38:29 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b="OoTa6UG/"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231971AbhJUUgY (ORCPT + 99 others); Thu, 21 Oct 2021 16:36:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39558 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231822AbhJUUgX (ORCPT ); Thu, 21 Oct 2021 16:36:23 -0400 Received: from mail-io1-xd2a.google.com (mail-io1-xd2a.google.com [IPv6:2607:f8b0:4864:20::d2a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B2DD3C061764 for ; Thu, 21 Oct 2021 13:34:07 -0700 (PDT) Received: by mail-io1-xd2a.google.com with SMTP id z69so2590623iof.9 for ; Thu, 21 Oct 2021 13:34:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=qc5yk2ewhoH94OoX+tRZuXvqhmyfRbN00IiOr1tb4iU=; b=OoTa6UG/eMXeKDGTA4sYKl0TkjpkdP9n7fq2xELyADWB9E8Sd4SygwGy4lyHjmsbhB Bd6YZ37c8AOWr9YIV9NxUstNzaNqopKTj/6cOldCh4pvfQR0qR+Hq6dvvWxmCiEnm/mW vOyjzuLvJ8JrH0pMnzo9oA25IQVb/OjHBe9d4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=qc5yk2ewhoH94OoX+tRZuXvqhmyfRbN00IiOr1tb4iU=; b=UgXhT5zOWSmi69woRegdNpCOFhHrILjkxOl/NHKYoLd0KoabNDM3f7tPJHiuMXnwm0 OcfHLkhy/siFyCP1Ky6NJ0ix8JiHLo4v/mvPxtBSZWtTOYo6Kr9dfwIMPI5QgJ9BBBy9 Z46WsitxL3HEfLMJ16HKuUummhuwn1PUDKp/gMVT3HFTGY3eurxsu4JZE138E6S+1Z9s s+O3OIyZRfbmyN4G/yg0IiSCwEhaji20C9AqpE5RoZKl98aERN/upSaK85AuTyxtcPGp qoLJqdp0c63aXyk+ay8cUoeiLDHMgqJ59/iAfr5BWRWOJszm356drnskVLnKlTyJDDHw g5NQ== X-Gm-Message-State: AOAM532KbunRxrM38mmgtHatt2wwtxRyh8Trk6ZaGR0/QfyXqwqN+50p gMmroj4frI8rV+qrySH9N5/WPe/fGHVH7g== X-Received: by 2002:a05:6638:134f:: with SMTP id u15mr5377378jad.145.1634848446764; Thu, 21 Oct 2021 13:34:06 -0700 (PDT) Received: from mail-il1-f174.google.com (mail-il1-f174.google.com. [209.85.166.174]) by smtp.gmail.com with ESMTPSA id k83sm3266527iof.12.2021.10.21.13.34.06 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 21 Oct 2021 13:34:06 -0700 (PDT) Received: by mail-il1-f174.google.com with SMTP id y17so2021455ilb.9 for ; Thu, 21 Oct 2021 13:34:06 -0700 (PDT) X-Received: by 2002:a05:6e02:1b09:: with SMTP id i9mr4972431ilv.142.1634848445568; Thu, 21 Oct 2021 13:34:05 -0700 (PDT) MIME-Version: 1.0 References: <20211021122719.1.I56d382006dea67ed8f30729a751fbc75434315b2@changeid> In-Reply-To: From: Doug Anderson Date: Thu, 21 Oct 2021 13:33:52 -0700 X-Gmail-Original-Message-ID: Message-ID: Subject: Re: [PATCH] drm/bridge: Fix the bridge chain order for pre_enable / post_disable To: Sam Ravnborg Cc: Andrzej Hajda , dri-devel , Philip Chen , Boris Brezillon , Daniel Vetter , David Airlie , Jagan Teki , Laurent Pinchart , Maarten Lankhorst , Maxime Ripard , Neil Armstrong , Robert Foss , Thomas Zimmermann , LKML Content-Type: text/plain; charset="UTF-8" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi, On Thu, Oct 21, 2021 at 1:21 PM Sam Ravnborg wrote: > > Hi Douglas, > > On Thu, Oct 21, 2021 at 12:29:01PM -0700, Douglas Anderson wrote: > > Right now, the chaining order of > > pre_enable/enable/disable/post_disable looks like this: > > > > pre_enable: start from connector and move to encoder > > enable: start from encoder and move to connector > > disable: start from connector and move to encoder > > post_disable: start from encoder and move to connector > > > > In the above, it can be seen that at least pre_enable() and > > post_disable() are opposites of each other and enable() and disable() > > are opposites. However, it seems broken that pre_enable() and enable() > > would not move in the same direction. In other parts of Linux you can > > see that various stages move in the same order. For instance, during > > system suspend the "early" calls run in the same order as the normal > > calls run in the same order as the "late" calls run in the same order > > as the "noirq" calls. > > > > Let fix the above so that it makes more sense. Now we'll have: > > > > pre_enable: start from encoder and move to connector > > enable: start from encoder and move to connector > > disable: start from connector and move to encoder > > post_disable: start from connector and move to encoder > > > > This order is chosen because if there are parent-child relationships > > anywhere I would expect that the encoder would be a parent and the > > connector a child--not the other way around. > > This makes good sense as you describe it. I hope others can add more > useful feedback. > Added Andrzej Hajda to the mail, as he have > expressed concerns with the chain of bridges before. > > > > > This can be important when using the DP AUX bus to instantiate a > > panel. The DP AUX bus is likely part of a bridge driver and is a > > parent of the panel. We'd like the bridge to be pre_enabled before the > > panel and the panel to be post_disabled before the > > bridge. Specifically, this allows pm_runtime_put_sync_suspend() in a > > bridge driver's post_suspend to work properly even a panel is under > > it. > > > > NOTE: it's entirely possible that this change could break someone who > > was relying on the old order. Hopefully this isn't the case, but if > > this does break someone it seems like it's better to do it sonner > > rather than later so we can fix everyone to handle the order that > > makes the most sense. > > > > A FURTHER NOTE: Looking closer at commit 4e5763f03e10 ("drm/bridge: > > ti-sn65dsi86: Wrap panel with panel-bridge") you can see that patch > > inadvertently changed the order of things. The order used to be > > correct (panel prepare was at the tail of the bridge enable) but it > > became backwards. We'll restore the original order with this patch. > > > > Fixes: 4e5763f03e10 ("drm/bridge: ti-sn65dsi86: Wrap panel with panel-bridge") > > Fixes: 05193dc38197 ("drm/bridge: Make the bridge chain a double-linked list") > > Signed-off-by: Douglas Anderson > > To make the patch complete the descriptions in drm_bridge_funcs > need to be updated to reflect the new reality. Ah, oops! Sure, I'll plan on a v2 with this but I'll wait for more feedback. > > drivers/gpu/drm/drm_bridge.c | 28 ++++++++++++++-------------- > > 1 file changed, 14 insertions(+), 14 deletions(-) > > > > diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c > > index c96847fc0ebc..98808af59afd 100644 > > --- a/drivers/gpu/drm/drm_bridge.c > > +++ b/drivers/gpu/drm/drm_bridge.c > > @@ -583,18 +583,14 @@ EXPORT_SYMBOL(drm_bridge_chain_mode_set); > > void drm_bridge_chain_pre_enable(struct drm_bridge *bridge) > > If you, or someone else, could r-b or ack the pending patches to remove > this function, this part of the patch would no longer be needed. OK. I will likely be able to take a look next week. Given that I'm helping Philip bringup a board with ps8640 it looks like your patch series will be quite relevant! I guess it would be good to figure out what would be the best order to land them. In my case we need this fix to be easy to pick back to fix the behavior on the Chrome OS 5.4 tree. My fix is easy to pick back, but perhaps yours is as well. Of course we could also just make a local divergent change in our tree if need be, too. > > { > > struct drm_encoder *encoder; > > - struct drm_bridge *iter; > > > > if (!bridge) > > return; > > > > encoder = bridge->encoder; > > - list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) { > > - if (iter->funcs->pre_enable) > > - iter->funcs->pre_enable(iter); > > - > > - if (iter == bridge) > > - break; > > + list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) { > > + if (bridge->funcs->pre_enable) > > + bridge->funcs->pre_enable(bridge); > > } > > } > > EXPORT_SYMBOL(drm_bridge_chain_pre_enable); > > @@ -684,26 +680,30 @@ void drm_atomic_bridge_chain_post_disable(struct drm_bridge *bridge, > > struct drm_atomic_state *old_state) > > { > > struct drm_encoder *encoder; > > + struct drm_bridge *iter; > s/iter/bridge/ would make the patch simpler > And then the bridge argument could be last_bridge or something. > This would IMO increase readability of the code and make the patch smaller. Yeah, I debated this too. I was trying to match drm_bridge_chain_disable() and in my mind keeping the two functions matching is more important than keeping this patch small. Certainly I could add another patch in the series to rename "bridge" to "last_bridge" and "iter" to "bridge" in that function, but that defeats the goal of reducing churn... ...and clearly whoever wrote drm_bridge_chain_disable() liked "iter" better. :-P In any case, I'll change it as you say if everyone likes it better, but otherwise I'll leave it as I have it. > > if (!bridge) > > return; > > > > encoder = bridge->encoder; > > - list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) { > > - if (bridge->funcs->atomic_post_disable) { > > + list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) { > > + if (iter->funcs->atomic_post_disable) { > > struct drm_bridge_state *old_bridge_state; > > > > old_bridge_state = > > drm_atomic_get_old_bridge_state(old_state, > > - bridge); > > + iter); > > if (WARN_ON(!old_bridge_state)) > > return; > > > > - bridge->funcs->atomic_post_disable(bridge, > > - old_bridge_state); > > - } else if (bridge->funcs->post_disable) { > > - bridge->funcs->post_disable(bridge); > > + iter->funcs->atomic_post_disable(iter, > > + old_bridge_state); > > + } else if (iter->funcs->post_disable) { > > + iter->funcs->post_disable(iter); > > } > > + > > + if (iter == bridge) > > + break; > I cannot see why this is needed, we are at the end of the list here > anyway. It's because you can start at something that's not the first bridge in the chain. See commit bab5cca7e609 ("drm/bridge: Fix the stop condition of drm_bridge_chain_pre_enable()")