Message ID | 20230405142440.191939-3-j-choudhary@ti.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp355825vqo; Wed, 5 Apr 2023 07:36:34 -0700 (PDT) X-Google-Smtp-Source: AKy350YNDgqvbeWVSw73lLqnctLaQ3XACEBW9yvHVr+m3aVVAxxlibdMH+7rNjl1AMrHpQC6NcWf X-Received: by 2002:a05:6a20:2a0a:b0:db:6237:e76 with SMTP id e10-20020a056a202a0a00b000db62370e76mr5245042pzh.15.1680705394152; Wed, 05 Apr 2023 07:36:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680705394; cv=none; d=google.com; s=arc-20160816; b=yc5DVu9TirBQOzAAJj+f8bs720JM7IvQbN5HEHtENlnBiJeARcWZgmpSV4o5SE94Ti xhkoLGmEtYYd94qA+F18somD5rh2F6KUUVfz0m4zDdklIMJ4WCE0lVL4zhq0AfyfLGZ4 6iaKyYPyDC/yQcrcJk92//hdl6JntgdBTyvEXOnFt1G+edM5BqeggejuWza3Z7geXEy/ GBBioMub/3T2vTNiu8nVJCg4unSUdE7iwgYWENYQNijiyPeMUwO2EK1PTdUnp2M8KT2y Uyd9FN9b78c9rw1i45PVXswo2Fhk1EYwsVVWckjUNl+IVFd+Fg1uwGxLLecRNZtKHmdI EC8A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=IIg8Hw2d+AztRioYXlvly6uzmoxjKPtZvpXX4icR5Mk=; b=lAF9eYUywuQuCqewhGWmj7tzBppJXAeCfHgexCUDh4FT6tRf8PEr3r6jNOiex1/uup 1Dy622OKH3LEKcR6U36cEJKTxTcsXAveiJDh5NK3bDl/7vrXTT7q7cSp4hliXqpJE+RB GHeUwofA/SkA9YHZKRDcEx3ZufUcBoQvcRsn/GQSovkL/3oD5YhA1yUvMeHXpqPlD+5V FL+kSmTLTVhQhrpYq81NF9LnDpDHobhHAkIbTGPKmenpc0NsV5I6SBX/A0VBlrYzxH6P 15KizF8q0+To6ecmSV86Gunoa9UfoCEt3bZpsUtkgdfn3nS/wV62CQjJ9KHobiySyNBQ CeNQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=QEOidwmJ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id t127-20020a625f85000000b00627e9b0d5d7si12546897pfb.354.2023.04.05.07.36.18; Wed, 05 Apr 2023 07:36:34 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=QEOidwmJ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238393AbjDEOZa (ORCPT <rfc822;lkml4gm@gmail.com> + 99 others); Wed, 5 Apr 2023 10:25:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55052 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238246AbjDEOZY (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Wed, 5 Apr 2023 10:25:24 -0400 Received: from lelv0142.ext.ti.com (lelv0142.ext.ti.com [198.47.23.249]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 467CE49E6; Wed, 5 Apr 2023 07:25:12 -0700 (PDT) Received: from fllv0034.itg.ti.com ([10.64.40.246]) by lelv0142.ext.ti.com (8.15.2/8.15.2) with ESMTP id 335EOjYq018196; Wed, 5 Apr 2023 09:24:45 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1680704685; bh=IIg8Hw2d+AztRioYXlvly6uzmoxjKPtZvpXX4icR5Mk=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=QEOidwmJUfL0gZvptL6rL2APLDQ9IKaE5fjGSlXaS6Gz5wQNNdtnO3M321mayrH9X Wqqhq/8JsmbXuQv0lri4Xoo03+rD6V3TrJuP9yVjQpldAr85l8lH4m5DMQInODAmYU MjrrI3ZodlIyDdWKvWp3Cl+kTLrtI7RW2ktaP1pc= Received: from DFLE114.ent.ti.com (dfle114.ent.ti.com [10.64.6.35]) by fllv0034.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 335EOjUQ064587 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 5 Apr 2023 09:24:45 -0500 Received: from DFLE110.ent.ti.com (10.64.6.31) by DFLE114.ent.ti.com (10.64.6.35) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.16; Wed, 5 Apr 2023 09:24:45 -0500 Received: from fllv0039.itg.ti.com (10.64.41.19) by DFLE110.ent.ti.com (10.64.6.31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.16 via Frontend Transport; Wed, 5 Apr 2023 09:24:45 -0500 Received: from localhost (ileaxei01-snat2.itg.ti.com [10.180.69.6]) by fllv0039.itg.ti.com (8.15.2/8.15.2) with ESMTP id 335EOiA3029128; Wed, 5 Apr 2023 09:24:44 -0500 From: Jayesh Choudhary <j-choudhary@ti.com> To: <dri-devel@lists.freedesktop.org>, <devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>, <krzysztof.kozlowski@linaro.org> CC: <andrzej.hajda@intel.com>, <neil.armstrong@linaro.org>, <rfoss@kernel.org>, <Laurent.pinchart@ideasonboard.com>, <jonas@kwiboo.se>, <jernej.skrabec@gmail.com>, <airlied@gmail.com>, <daniel@ffwll.ch>, <robh+dt@kernel.org>, <krzysztof.kozlowski+dt@linaro.org>, <sam@ravnborg.org>, <jani.nikula@intel.com>, <tzimmermann@suse.de>, <javierm@redhat.com>, <ville.syrjala@linux.intel.com>, <r-ravikumar@ti.com>, <lyude@redhat.com>, <alexander.deucher@amd.com>, <sjakhade@cadence.com>, <yamonkar@cadence.com>, <a-bhatia1@ti.com>, <tomi.valkeinen@ideasonboard.com>, <j-choudhary@ti.com> Subject: [PATCH v2 2/2] drm: bridge: cdns-mhdp8546: Add support for no-hpd Date: Wed, 5 Apr 2023 19:54:40 +0530 Message-ID: <20230405142440.191939-3-j-choudhary@ti.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230405142440.191939-1-j-choudhary@ti.com> References: <20230405142440.191939-1-j-choudhary@ti.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-Spam-Status: No, score=-2.5 required=5.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED,SPF_HELO_PASS, SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1762347339234706602?= X-GMAIL-MSGID: =?utf-8?q?1762347339234706602?= |
Series |
"no-hpd" support in CDNS DP bridge driver
|
|
Commit Message
Jayesh Choudhary
April 5, 2023, 2:24 p.m. UTC
From: Rahul T R <r-ravikumar@ti.com> In J721S2 EVMs DP0 hpd is not connected to correct hpd pin on SOC, to handle such cases, Add support for "no-hpd" property in the device tree node to disable hpd Also change the log level for dpcd read failuers to debug, since framework retries 32 times for each read Signed-off-by: Rahul T R <r-ravikumar@ti.com> Signed-off-by: Jayesh Choudhary <j-choudhary@ti.com> --- .../drm/bridge/cadence/cdns-mhdp8546-core.c | 37 ++++++++++++++++--- .../drm/bridge/cadence/cdns-mhdp8546-core.h | 1 + 2 files changed, 33 insertions(+), 5 deletions(-)
Comments
Hi Jayesh, Thank you for the patch. On Wed, Apr 05, 2023 at 07:54:40PM +0530, Jayesh Choudhary wrote: > From: Rahul T R <r-ravikumar@ti.com> > > In J721S2 EVMs DP0 hpd is not connected to correct > hpd pin on SOC, to handle such cases, Add support for > "no-hpd" property in the device tree node to disable > hpd s/hpd/hpd./ You can also reflow the commit message to 72 columns. > Also change the log level for dpcd read failuers to > debug, since framework retries 32 times for each read s/read/read./ Doesn't this apply to writes as well ? > Signed-off-by: Rahul T R <r-ravikumar@ti.com> > Signed-off-by: Jayesh Choudhary <j-choudhary@ti.com> > --- > .../drm/bridge/cadence/cdns-mhdp8546-core.c | 37 ++++++++++++++++--- > .../drm/bridge/cadence/cdns-mhdp8546-core.h | 1 + > 2 files changed, 33 insertions(+), 5 deletions(-) > > diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c > index f6822dfa3805..e177794b069d 100644 > --- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c > +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c > @@ -54,6 +54,8 @@ > #include "cdns-mhdp8546-hdcp.h" > #include "cdns-mhdp8546-j721e.h" > > +static int cdns_mhdp_update_link_status(struct cdns_mhdp_device *mhdp); > + > static int cdns_mhdp_mailbox_read(struct cdns_mhdp_device *mhdp) > { > int ret, empty; > @@ -749,7 +751,7 @@ static int cdns_mhdp_fw_activate(const struct firmware *fw, > * MHDP_HW_STOPPED happens only due to driver removal when > * bridge should already be detached. > */ > - if (mhdp->bridge_attached) > + if (mhdp->bridge_attached && !mhdp->no_hpd) > writel(~(u32)CDNS_APB_INT_MASK_SW_EVENT_INT, > mhdp->regs + CDNS_APB_INT_MASK); > > @@ -845,7 +847,7 @@ static ssize_t cdns_mhdp_transfer(struct drm_dp_aux *aux, > ret = cdns_mhdp_dpcd_read(mhdp, msg->address, > msg->buffer, msg->size); > if (ret) { > - dev_err(mhdp->dev, > + dev_dbg(mhdp->dev, > "Failed to read DPCD addr %u\n", > msg->address); > > @@ -1738,6 +1740,19 @@ static int cdns_mhdp_attach(struct drm_bridge *bridge, > > spin_unlock(&mhdp->start_lock); > > + if (mhdp->no_hpd) { > + ret = wait_event_timeout(mhdp->fw_load_wq, > + mhdp->hw_state == MHDP_HW_READY, > + msecs_to_jiffies(100)); > + if (ret == 0) { > + dev_err(mhdp->dev, "%s: Timeout waiting for fw loading\n", > + __func__); > + return -ETIMEDOUT; > + } > + > + cdns_mhdp_update_link_status(mhdp); > + return 0; > + } Missing blank line. It's not clear to me while you need to wait for the state to change to MHDP_HW_READY in the no_hpd case. This should be explained in the commit message. > /* Enable SW event interrupts */ > if (hw_ready) > writel(~(u32)CDNS_APB_INT_MASK_SW_EVENT_INT, > @@ -2256,7 +2271,16 @@ static int cdns_mhdp_update_link_status(struct cdns_mhdp_device *mhdp) > > mutex_lock(&mhdp->link_mutex); > > - mhdp->plugged = cdns_mhdp_detect_hpd(mhdp, &hpd_pulse); > + if (mhdp->no_hpd) { > + ret = drm_dp_dpcd_read_link_status(&mhdp->aux, status); > + hpd_pulse = false; > + if (ret < 0) > + mhdp->plugged = false; > + else > + mhdp->plugged = true; I think there's an issue with how the driver uses mhdp->plugged. In the no_hpd case, you try to detect if a display is connected by reading the link status at attach time, and then never update mhdp->plugged. This means that if no display is connected at that point, functions like cdns_mhdp_get_edid() will always fail, even if a display gets plugged later. As the goal of this series is (as far as I understand) support systems where the HPD signal could be connected to a SoC GPIO instead of the bridge, I don't think this is good enough. > + } else { > + mhdp->plugged = cdns_mhdp_detect_hpd(mhdp, &hpd_pulse); > + } > > if (!mhdp->plugged) { > cdns_mhdp_link_down(mhdp); > @@ -2451,6 +2475,8 @@ static int cdns_mhdp_probe(struct platform_device *pdev) > mhdp->aux.dev = dev; > mhdp->aux.transfer = cdns_mhdp_transfer; > > + mhdp->no_hpd = of_property_read_bool(dev->of_node, "cdns,no-hpd"); > + > mhdp->regs = devm_platform_ioremap_resource(pdev, 0); > if (IS_ERR(mhdp->regs)) { > dev_err(dev, "Failed to get memory resource\n"); > @@ -2526,8 +2552,9 @@ static int cdns_mhdp_probe(struct platform_device *pdev) > > mhdp->bridge.of_node = pdev->dev.of_node; > mhdp->bridge.funcs = &cdns_mhdp_bridge_funcs; > - mhdp->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | > - DRM_BRIDGE_OP_HPD; > + mhdp->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID; > + if (!mhdp->no_hpd) > + mhdp->bridge.ops |= DRM_BRIDGE_OP_HPD; > mhdp->bridge.type = DRM_MODE_CONNECTOR_DisplayPort; > if (mhdp->info) > mhdp->bridge.timings = mhdp->info->timings; > diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h > index bedddd510d17..6786ccb51387 100644 > --- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h > +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h > @@ -388,6 +388,7 @@ struct cdns_mhdp_device { > > bool link_up; > bool plugged; > + bool no_hpd; > > /* > * "start_lock" protects the access to bridge_attached and
On 06/04/23 07:22, Laurent Pinchart wrote: > Hi Jayesh, > > Thank you for the patch. > > On Wed, Apr 05, 2023 at 07:54:40PM +0530, Jayesh Choudhary wrote: >> From: Rahul T R <r-ravikumar@ti.com> >> >> In J721S2 EVMs DP0 hpd is not connected to correct >> hpd pin on SOC, to handle such cases, Add support for >> "no-hpd" property in the device tree node to disable >> hpd > > s/hpd/hpd./ > > You can also reflow the commit message to 72 columns. Okay. Thanks for the suggestion. Will do. > >> Also change the log level for dpcd read failuers to >> debug, since framework retries 32 times for each read > > s/read/read./ > > Doesn't this apply to writes as well ? Based on message request, we went into the conditional that uses read. So just changing the log-level for dpcd read was enough to get rid of the debug logs. > >> Signed-off-by: Rahul T R <r-ravikumar@ti.com> >> Signed-off-by: Jayesh Choudhary <j-choudhary@ti.com> >> --- >> .../drm/bridge/cadence/cdns-mhdp8546-core.c | 37 ++++++++++++++++--- >> .../drm/bridge/cadence/cdns-mhdp8546-core.h | 1 + >> 2 files changed, 33 insertions(+), 5 deletions(-) >> >> diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c >> index f6822dfa3805..e177794b069d 100644 >> --- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c >> +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c >> @@ -54,6 +54,8 @@ >> #include "cdns-mhdp8546-hdcp.h" >> #include "cdns-mhdp8546-j721e.h" >> >> +static int cdns_mhdp_update_link_status(struct cdns_mhdp_device *mhdp); >> + >> static int cdns_mhdp_mailbox_read(struct cdns_mhdp_device *mhdp) >> { >> int ret, empty; >> @@ -749,7 +751,7 @@ static int cdns_mhdp_fw_activate(const struct firmware *fw, >> * MHDP_HW_STOPPED happens only due to driver removal when >> * bridge should already be detached. >> */ >> - if (mhdp->bridge_attached) >> + if (mhdp->bridge_attached && !mhdp->no_hpd) >> writel(~(u32)CDNS_APB_INT_MASK_SW_EVENT_INT, >> mhdp->regs + CDNS_APB_INT_MASK); >> >> @@ -845,7 +847,7 @@ static ssize_t cdns_mhdp_transfer(struct drm_dp_aux *aux, >> ret = cdns_mhdp_dpcd_read(mhdp, msg->address, >> msg->buffer, msg->size); >> if (ret) { >> - dev_err(mhdp->dev, >> + dev_dbg(mhdp->dev, >> "Failed to read DPCD addr %u\n", >> msg->address); >> >> @@ -1738,6 +1740,19 @@ static int cdns_mhdp_attach(struct drm_bridge *bridge, >> >> spin_unlock(&mhdp->start_lock); >> >> + if (mhdp->no_hpd) { >> + ret = wait_event_timeout(mhdp->fw_load_wq, >> + mhdp->hw_state == MHDP_HW_READY, >> + msecs_to_jiffies(100)); >> + if (ret == 0) { >> + dev_err(mhdp->dev, "%s: Timeout waiting for fw loading\n", >> + __func__); >> + return -ETIMEDOUT; >> + } >> + >> + cdns_mhdp_update_link_status(mhdp); >> + return 0; >> + } > > Missing blank line. > > It's not clear to me while you need to wait for the state to change to > MHDP_HW_READY in the no_hpd case. This should be explained in the commit > message. > >> /* Enable SW event interrupts */ >> if (hw_ready) >> writel(~(u32)CDNS_APB_INT_MASK_SW_EVENT_INT, >> @@ -2256,7 +2271,16 @@ static int cdns_mhdp_update_link_status(struct cdns_mhdp_device *mhdp) >> >> mutex_lock(&mhdp->link_mutex); >> >> - mhdp->plugged = cdns_mhdp_detect_hpd(mhdp, &hpd_pulse); >> + if (mhdp->no_hpd) { >> + ret = drm_dp_dpcd_read_link_status(&mhdp->aux, status); >> + hpd_pulse = false; >> + if (ret < 0) >> + mhdp->plugged = false; >> + else >> + mhdp->plugged = true; > > I think there's an issue with how the driver uses mhdp->plugged. In the > no_hpd case, you try to detect if a display is connected by reading the > link status at attach time, and then never update mhdp->plugged. This > means that if no display is connected at that point, functions like > cdns_mhdp_get_edid() will always fail, even if a display gets plugged > later. As the goal of this series is (as far as I understand) support > systems where the HPD signal could be connected to a SoC GPIO instead of > the bridge, I don't think this is good enough. In the driver, I see that this is the only call which changes mhdp->plugged. Do you have any suggestions on how to work on this? Polling the value of drm_dp_dpdc_read_link_status does not seem like a clean way. Here by doing this, we are settling for few functionalities of display. Thanks, -Jayesh > >> + } else { >> + mhdp->plugged = cdns_mhdp_detect_hpd(mhdp, &hpd_pulse); >> + } >> >> if (!mhdp->plugged) { >> cdns_mhdp_link_down(mhdp); >> @@ -2451,6 +2475,8 @@ static int cdns_mhdp_probe(struct platform_device *pdev) >> mhdp->aux.dev = dev; >> mhdp->aux.transfer = cdns_mhdp_transfer; >> >> + mhdp->no_hpd = of_property_read_bool(dev->of_node, "cdns,no-hpd"); >> + >> mhdp->regs = devm_platform_ioremap_resource(pdev, 0); >> if (IS_ERR(mhdp->regs)) { >> dev_err(dev, "Failed to get memory resource\n"); >> @@ -2526,8 +2552,9 @@ static int cdns_mhdp_probe(struct platform_device *pdev) >> >> mhdp->bridge.of_node = pdev->dev.of_node; >> mhdp->bridge.funcs = &cdns_mhdp_bridge_funcs; >> - mhdp->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | >> - DRM_BRIDGE_OP_HPD; >> + mhdp->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID; >> + if (!mhdp->no_hpd) >> + mhdp->bridge.ops |= DRM_BRIDGE_OP_HPD; >> mhdp->bridge.type = DRM_MODE_CONNECTOR_DisplayPort; >> if (mhdp->info) >> mhdp->bridge.timings = mhdp->info->timings; >> diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h >> index bedddd510d17..6786ccb51387 100644 >> --- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h >> +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h >> @@ -388,6 +388,7 @@ struct cdns_mhdp_device { >> >> bool link_up; >> bool plugged; >> + bool no_hpd; >> >> /* >> * "start_lock" protects the access to bridge_attached and >
On 14/04/2023 18:10, Jayesh Choudhary wrote: > > > On 06/04/23 07:22, Laurent Pinchart wrote: >> Hi Jayesh, >> >> Thank you for the patch. >> >> On Wed, Apr 05, 2023 at 07:54:40PM +0530, Jayesh Choudhary wrote: >>> From: Rahul T R <r-ravikumar@ti.com> >>> >>> In J721S2 EVMs DP0 hpd is not connected to correct >>> hpd pin on SOC, to handle such cases, Add support for >>> "no-hpd" property in the device tree node to disable >>> hpd >> >> s/hpd/hpd./ >> >> You can also reflow the commit message to 72 columns. > > Okay. Thanks for the suggestion. Will do. > >> >>> Also change the log level for dpcd read failuers to >>> debug, since framework retries 32 times for each read >> >> s/read/read./ >> >> Doesn't this apply to writes as well ? > > Based on message request, we went into the conditional that uses > read. So just changing the log-level for dpcd read was enough to > get rid of the debug logs. > >> >>> Signed-off-by: Rahul T R <r-ravikumar@ti.com> >>> Signed-off-by: Jayesh Choudhary <j-choudhary@ti.com> >>> --- >>> .../drm/bridge/cadence/cdns-mhdp8546-core.c | 37 ++++++++++++++++--- >>> .../drm/bridge/cadence/cdns-mhdp8546-core.h | 1 + >>> 2 files changed, 33 insertions(+), 5 deletions(-) >>> >>> diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c >>> b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c >>> index f6822dfa3805..e177794b069d 100644 >>> --- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c >>> +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c >>> @@ -54,6 +54,8 @@ >>> #include "cdns-mhdp8546-hdcp.h" >>> #include "cdns-mhdp8546-j721e.h" >>> +static int cdns_mhdp_update_link_status(struct cdns_mhdp_device *mhdp); >>> + >>> static int cdns_mhdp_mailbox_read(struct cdns_mhdp_device *mhdp) >>> { >>> int ret, empty; >>> @@ -749,7 +751,7 @@ static int cdns_mhdp_fw_activate(const struct >>> firmware *fw, >>> * MHDP_HW_STOPPED happens only due to driver removal when >>> * bridge should already be detached. >>> */ >>> - if (mhdp->bridge_attached) >>> + if (mhdp->bridge_attached && !mhdp->no_hpd) >>> writel(~(u32)CDNS_APB_INT_MASK_SW_EVENT_INT, >>> mhdp->regs + CDNS_APB_INT_MASK); >>> @@ -845,7 +847,7 @@ static ssize_t cdns_mhdp_transfer(struct >>> drm_dp_aux *aux, >>> ret = cdns_mhdp_dpcd_read(mhdp, msg->address, >>> msg->buffer, msg->size); >>> if (ret) { >>> - dev_err(mhdp->dev, >>> + dev_dbg(mhdp->dev, >>> "Failed to read DPCD addr %u\n", >>> msg->address); I don't much like this change. Now the write and read paths have different log level. This also affects the with-hpd case. And it "hides" error prints for "real" errors. Now, I think it's a valid question whether this function should use dev_dbg rather than dev_err (both write and read cases), as dev_err may be a bit spammy, and this might perhaps be user triggerable. If the DP transfer is used for polling I think there should be specific handling for that case here. Before the driver polls with DP transfer, set a flag, and then in this function skip logging altogether. I don't think you want to spam the debug log with DPCD errors either. >>> @@ -1738,6 +1740,19 @@ static int cdns_mhdp_attach(struct drm_bridge >>> *bridge, >>> spin_unlock(&mhdp->start_lock); >>> + if (mhdp->no_hpd) { >>> + ret = wait_event_timeout(mhdp->fw_load_wq, >>> + mhdp->hw_state == MHDP_HW_READY, >>> + msecs_to_jiffies(100)); >>> + if (ret == 0) { >>> + dev_err(mhdp->dev, "%s: Timeout waiting for fw loading\n", >>> + __func__); >>> + return -ETIMEDOUT; >>> + } >>> + >>> + cdns_mhdp_update_link_status(mhdp); >>> + return 0; >>> + } >> >> Missing blank line. >> >> It's not clear to me while you need to wait for the state to change to >> MHDP_HW_READY in the no_hpd case. This should be explained in the commit >> message. I presume it's because both the firmware loading and bridge attach happens asynchronously. With HPD the driver acts only on the interrupt, which is enabled only after both have happened. Here the driver waits in the attach until everything is ready, and then probes the DP. But it does feel hacky. >>> /* Enable SW event interrupts */ >>> if (hw_ready) >>> writel(~(u32)CDNS_APB_INT_MASK_SW_EVENT_INT, >>> @@ -2256,7 +2271,16 @@ static int cdns_mhdp_update_link_status(struct >>> cdns_mhdp_device *mhdp) >>> mutex_lock(&mhdp->link_mutex); >>> - mhdp->plugged = cdns_mhdp_detect_hpd(mhdp, &hpd_pulse); >>> + if (mhdp->no_hpd) { >>> + ret = drm_dp_dpcd_read_link_status(&mhdp->aux, status); >>> + hpd_pulse = false; >>> + if (ret < 0) >>> + mhdp->plugged = false; >>> + else >>> + mhdp->plugged = true; >> >> I think there's an issue with how the driver uses mhdp->plugged. In the >> no_hpd case, you try to detect if a display is connected by reading the >> link status at attach time, and then never update mhdp->plugged. This >> means that if no display is connected at that point, functions like >> cdns_mhdp_get_edid() will always fail, even if a display gets plugged >> later. As the goal of this series is (as far as I understand) support >> systems where the HPD signal could be connected to a SoC GPIO instead of >> the bridge, I don't think this is good enough. > > In the driver, I see that this is the only call which changes > mhdp->plugged. Do you have any suggestions on how to work on this? > Polling the value of drm_dp_dpdc_read_link_status does not seem like a > clean way. > Here by doing this, we are settling for few functionalities of display. I think it depends a bit on what you want to support. The HW sounds quite broken, as HPD is rather important feature of DP. Did you check the DP spec if it has any guidelines on how to handle no HPD case? You could perhaps say that you only support eDP without HPD on this HW. Then the broken HPD doesn't matter. If you want to support normal DP, I think you have to do some kind of polling to make the DP somewhat usable, or a manual detect in certain strategic places (probe time, get_edid, get_modes, perhaps?). Is there anything in the PHY that could inform that something has been connected? I remember some HDMI PHYs can tell if something is connected to the pins. It's not HPD, but could be used to filter away other, slower, polling. Or maybe the mdhp has something to help here. Also, if you do polling, I don't think you need to go via the drm_dp_dpcd_read_link_status. You could first just use cdns_mhdp_dpcd_read directly, and if that succeeds, then proceed getting more info from the monitor. Tomi
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c index f6822dfa3805..e177794b069d 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c @@ -54,6 +54,8 @@ #include "cdns-mhdp8546-hdcp.h" #include "cdns-mhdp8546-j721e.h" +static int cdns_mhdp_update_link_status(struct cdns_mhdp_device *mhdp); + static int cdns_mhdp_mailbox_read(struct cdns_mhdp_device *mhdp) { int ret, empty; @@ -749,7 +751,7 @@ static int cdns_mhdp_fw_activate(const struct firmware *fw, * MHDP_HW_STOPPED happens only due to driver removal when * bridge should already be detached. */ - if (mhdp->bridge_attached) + if (mhdp->bridge_attached && !mhdp->no_hpd) writel(~(u32)CDNS_APB_INT_MASK_SW_EVENT_INT, mhdp->regs + CDNS_APB_INT_MASK); @@ -845,7 +847,7 @@ static ssize_t cdns_mhdp_transfer(struct drm_dp_aux *aux, ret = cdns_mhdp_dpcd_read(mhdp, msg->address, msg->buffer, msg->size); if (ret) { - dev_err(mhdp->dev, + dev_dbg(mhdp->dev, "Failed to read DPCD addr %u\n", msg->address); @@ -1738,6 +1740,19 @@ static int cdns_mhdp_attach(struct drm_bridge *bridge, spin_unlock(&mhdp->start_lock); + if (mhdp->no_hpd) { + ret = wait_event_timeout(mhdp->fw_load_wq, + mhdp->hw_state == MHDP_HW_READY, + msecs_to_jiffies(100)); + if (ret == 0) { + dev_err(mhdp->dev, "%s: Timeout waiting for fw loading\n", + __func__); + return -ETIMEDOUT; + } + + cdns_mhdp_update_link_status(mhdp); + return 0; + } /* Enable SW event interrupts */ if (hw_ready) writel(~(u32)CDNS_APB_INT_MASK_SW_EVENT_INT, @@ -2256,7 +2271,16 @@ static int cdns_mhdp_update_link_status(struct cdns_mhdp_device *mhdp) mutex_lock(&mhdp->link_mutex); - mhdp->plugged = cdns_mhdp_detect_hpd(mhdp, &hpd_pulse); + if (mhdp->no_hpd) { + ret = drm_dp_dpcd_read_link_status(&mhdp->aux, status); + hpd_pulse = false; + if (ret < 0) + mhdp->plugged = false; + else + mhdp->plugged = true; + } else { + mhdp->plugged = cdns_mhdp_detect_hpd(mhdp, &hpd_pulse); + } if (!mhdp->plugged) { cdns_mhdp_link_down(mhdp); @@ -2451,6 +2475,8 @@ static int cdns_mhdp_probe(struct platform_device *pdev) mhdp->aux.dev = dev; mhdp->aux.transfer = cdns_mhdp_transfer; + mhdp->no_hpd = of_property_read_bool(dev->of_node, "cdns,no-hpd"); + mhdp->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(mhdp->regs)) { dev_err(dev, "Failed to get memory resource\n"); @@ -2526,8 +2552,9 @@ static int cdns_mhdp_probe(struct platform_device *pdev) mhdp->bridge.of_node = pdev->dev.of_node; mhdp->bridge.funcs = &cdns_mhdp_bridge_funcs; - mhdp->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | - DRM_BRIDGE_OP_HPD; + mhdp->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID; + if (!mhdp->no_hpd) + mhdp->bridge.ops |= DRM_BRIDGE_OP_HPD; mhdp->bridge.type = DRM_MODE_CONNECTOR_DisplayPort; if (mhdp->info) mhdp->bridge.timings = mhdp->info->timings; diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h index bedddd510d17..6786ccb51387 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h @@ -388,6 +388,7 @@ struct cdns_mhdp_device { bool link_up; bool plugged; + bool no_hpd; /* * "start_lock" protects the access to bridge_attached and