From patchwork Tue Sep 19 21:56:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lyude Paul X-Patchwork-Id: 142232 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:172:b0:3f2:4152:657d with SMTP id h50csp3893370vqi; Tue, 19 Sep 2023 22:33:58 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHnaMCOx+za591SNaXzFo/SvLJzVqGJWCX1L476ERW4brgugNuuQvf+eGVdHp35vZqFUIGQ X-Received: by 2002:a17:906:11a:b0:9ae:4b25:d89f with SMTP id 26-20020a170906011a00b009ae4b25d89fmr477640eje.6.1695188038235; Tue, 19 Sep 2023 22:33:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1695188038; cv=none; d=google.com; s=arc-20160816; b=QVw/7lfrSnWmLA6PPSadCJaHvIg7a1rbNxBLTQz/jp4sWZ06KU4ytBtvDue4Bgrto1 N9Q8u+dUM2/fzS9DGqAvTNLoD2Ypsdul9sH9jqTLrSs3HZHwrJjAx2vVUjnh0vYQcrBy Uw0tSewJ0hFcxpiEWUJCR0xHbTVXFGVWYq+6G+HalJlKEraRDFO3E53UhT6p1kjpR+Gz woOXf1IMIXiObPwTMBy416QZ4RVnO08HVJiJ+qNcSCy0hgUQmnWGRdGvmfynn2QxuTLm 7eTX2rx72VLwRGx81MonJs+HI6aZYEqzT8c5CrTtFdG8mVZAcSfrryF6PyBj5w2cqx8C ilvw== 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=b0bdqNW1AoK4+3IwmD+pp0C78rCHOQoOkyPe8GiClM8=; fh=2SXWb2ts99eE+OYESnujeGpShOsteg1KtZEhV4aGij8=; b=kcRGPL1eJB8XI5BmXXPDf3vfGwihjHSeHUPuO3Tm3PeBOUqdjjPnRCtW98U+t/tfua 5SkGW6itZP+a5KjJQRPfXLFfluunl+LSBsfdChfdxGFa6g2NnmtuIPm4UHzdEcaydh8j mwR8kWL15RtuZ7rYa4/u041cIzEz3gCdISgf0mk06cfzgEd8mBAUPOeKNhXisjkWUmxk KgO3DJCG9NJTrAmTbl7NRr0Uur6/6nkcN45EgWGnx1iS8KoSUiwv2x42KREb1/iSzbrZ WaST9QDmsZqse+XDhpE84x7dyH1gCrnWgRYQUBpSf4tUnuecJHeDI01Dlg1wWGrYvrvN /I3g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b="V6t6nR/A"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:4 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from howler.vger.email (howler.vger.email. [2620:137:e000::3:4]) by mx.google.com with ESMTPS id z21-20020a170906241500b009a1b857e3b5si10560451eja.170.2023.09.19.22.33.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 19 Sep 2023 22:33:58 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:4 as permitted sender) client-ip=2620:137:e000::3:4; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b="V6t6nR/A"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:4 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by howler.vger.email (Postfix) with ESMTP id 6FE2A8227797; Tue, 19 Sep 2023 15:07:06 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at howler.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233422AbjISWGZ (ORCPT + 26 others); Tue, 19 Sep 2023 18:06:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43934 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233453AbjISWGT (ORCPT ); Tue, 19 Sep 2023 18:06:19 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 75EB4BE for ; Tue, 19 Sep 2023 15:05:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1695161125; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=b0bdqNW1AoK4+3IwmD+pp0C78rCHOQoOkyPe8GiClM8=; b=V6t6nR/AnAPR+sN8XsP5Ufg3OJOXN1Q6Mg6YcjIKr0qt2lUN7bRvZYsLZoma1fEx+83Qmh Mma+5eO63NSd5rhIq6K7LuX4GUJdL76lo++k+ql3eCgzXPNopIvnQdATbPcVpioITBHJIc 4SwLRmzjfwafCWPu4Cdkoo9aMVqITm4= Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-417-qHdtqAbfNluKkqcFP7EolA-1; Tue, 19 Sep 2023 18:05:22 -0400 X-MC-Unique: qHdtqAbfNluKkqcFP7EolA-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id F2B491E441DA; Tue, 19 Sep 2023 22:05:21 +0000 (UTC) Received: from emerald.lyude.net (unknown [10.22.18.67]) by smtp.corp.redhat.com (Postfix) with ESMTP id 91EB540C2070; Tue, 19 Sep 2023 22:05:21 +0000 (UTC) From: Lyude Paul To: dri-devel@lists.freedesktop.org, nouveau@lists.freedesktop.org Cc: Ben Skeggs , Danilo Krummrich , Karol Herbst , David Airlie , Daniel Vetter , Kees Cook , linux-kernel@vger.kernel.org (open list) Subject: [PATCH v3 07/44] drm/nouveau/disp: add output detect method Date: Tue, 19 Sep 2023 17:56:02 -0400 Message-ID: <20230919220442.202488-8-lyude@redhat.com> In-Reply-To: <20230919220442.202488-1-lyude@redhat.com> References: <20230919220442.202488-1-lyude@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.1 X-Spam-Status: No, score=1.2 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, RCVD_IN_DNSWL_BLOCKED,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL, RCVD_IN_SBL_CSS,SPF_HELO_NONE,SPF_NONE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Level: * X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (howler.vger.email [0.0.0.0]); Tue, 19 Sep 2023 15:07:06 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1777533492476037957 X-GMAIL-MSGID: 1777533492476037957 From: Ben Skeggs This will check the relevant hotplug pin and skip the DDC probe we currently do if a display is present. - preparation for GSP-RM. Signed-off-by: Ben Skeggs Reviewed-by: Lyude Paul Acked-by: Danilo Krummrich Signed-off-by: Lyude Paul --- drivers/gpu/drm/nouveau/include/nvif/conn.h | 5 -- drivers/gpu/drm/nouveau/include/nvif/if0011.h | 11 ---- drivers/gpu/drm/nouveau/include/nvif/if0012.h | 12 ++++ drivers/gpu/drm/nouveau/include/nvif/outp.h | 9 +++ drivers/gpu/drm/nouveau/nouveau_connector.c | 60 ++++++++++++------- drivers/gpu/drm/nouveau/nouveau_dp.c | 10 +--- drivers/gpu/drm/nouveau/nvif/conn.c | 14 ----- drivers/gpu/drm/nouveau/nvif/outp.c | 25 ++++++++ drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c | 1 + .../gpu/drm/nouveau/nvkm/engine/disp/outp.c | 28 +++++++++ .../gpu/drm/nouveau/nvkm/engine/disp/outp.h | 6 ++ .../gpu/drm/nouveau/nvkm/engine/disp/uconn.c | 41 ------------- .../gpu/drm/nouveau/nvkm/engine/disp/uoutp.c | 24 ++++++++ 13 files changed, 145 insertions(+), 101 deletions(-) diff --git a/drivers/gpu/drm/nouveau/include/nvif/conn.h b/drivers/gpu/drm/nouveau/include/nvif/conn.h index dc355e1dfafa0..8a6017a358976 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/conn.h +++ b/drivers/gpu/drm/nouveau/include/nvif/conn.h @@ -18,11 +18,6 @@ nvif_conn_id(struct nvif_conn *conn) return conn->object.handle; } -#define NVIF_CONN_HPD_STATUS_UNSUPPORTED 0 /* negative if query fails */ -#define NVIF_CONN_HPD_STATUS_NOT_PRESENT 1 -#define NVIF_CONN_HPD_STATUS_PRESENT 2 -int nvif_conn_hpd_status(struct nvif_conn *); - int nvif_conn_event_ctor(struct nvif_conn *, const char *name, nvif_event_func, u8 types, struct nvif_event *); #endif diff --git a/drivers/gpu/drm/nouveau/include/nvif/if0011.h b/drivers/gpu/drm/nouveau/include/nvif/if0011.h index 69b0b779f9424..0c25288a5a789 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/if0011.h +++ b/drivers/gpu/drm/nouveau/include/nvif/if0011.h @@ -20,15 +20,4 @@ union nvif_conn_event_args { __u8 pad02[6]; } v0; }; - -#define NVIF_CONN_V0_HPD_STATUS 0x00000000 - -union nvif_conn_hpd_status_args { - struct nvif_conn_hpd_status_v0 { - __u8 version; - __u8 support; - __u8 present; - __u8 pad03[5]; - } v0; -}; #endif diff --git a/drivers/gpu/drm/nouveau/include/nvif/if0012.h b/drivers/gpu/drm/nouveau/include/nvif/if0012.h index 7c56f653070c9..923bc30af2a92 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/if0012.h +++ b/drivers/gpu/drm/nouveau/include/nvif/if0012.h @@ -12,6 +12,8 @@ union nvif_outp_args { } v0; }; +#define NVIF_OUTP_V0_DETECT 0x00 + #define NVIF_OUTP_V0_ACQUIRE 0x11 #define NVIF_OUTP_V0_RELEASE 0x12 @@ -24,6 +26,16 @@ union nvif_outp_args { #define NVIF_OUTP_V0_DP_RETRAIN 0x73 #define NVIF_OUTP_V0_DP_MST_VCPI 0x78 +union nvif_outp_detect_args { + struct nvif_outp_detect_v0 { + __u8 version; +#define NVIF_OUTP_DETECT_V0_NOT_PRESENT 0x00 +#define NVIF_OUTP_DETECT_V0_PRESENT 0x01 +#define NVIF_OUTP_DETECT_V0_UNKNOWN 0x02 + __u8 status; + } v0; +}; + union nvif_outp_load_detect_args { struct nvif_outp_load_detect_v0 { __u8 version; diff --git a/drivers/gpu/drm/nouveau/include/nvif/outp.h b/drivers/gpu/drm/nouveau/include/nvif/outp.h index fa76a7b5e4b37..c3e1e4d2f1a11 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/outp.h +++ b/drivers/gpu/drm/nouveau/include/nvif/outp.h @@ -17,6 +17,15 @@ struct nvif_outp { int nvif_outp_ctor(struct nvif_disp *, const char *name, int id, struct nvif_outp *); void nvif_outp_dtor(struct nvif_outp *); + +enum nvif_outp_detect_status { + NOT_PRESENT, + PRESENT, + UNKNOWN, +}; + +enum nvif_outp_detect_status nvif_outp_detect(struct nvif_outp *); + int nvif_outp_load_detect(struct nvif_outp *, u32 loadval); int nvif_outp_acquire_rgb_crt(struct nvif_outp *); int nvif_outp_acquire_tmds(struct nvif_outp *, int head, diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 68b4fb4bec63f..a290a2844547c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -413,6 +413,7 @@ nouveau_connector_ddc_detect(struct drm_connector *connector) { struct drm_device *dev = connector->dev; struct pci_dev *pdev = to_pci_dev(dev->dev); + struct nouveau_connector *conn = nouveau_connector(connector); struct nouveau_encoder *nv_encoder = NULL, *found = NULL; struct drm_encoder *encoder; int ret; @@ -421,33 +422,48 @@ nouveau_connector_ddc_detect(struct drm_connector *connector) drm_connector_for_each_possible_encoder(connector, encoder) { nv_encoder = nouveau_encoder(encoder); - switch (nv_encoder->dcb->type) { - case DCB_OUTPUT_DP: - ret = nouveau_dp_detect(nouveau_connector(connector), - nv_encoder); - if (ret == NOUVEAU_DP_MST) - return NULL; - else if (ret == NOUVEAU_DP_SST) - found = nv_encoder; + if (nvif_object_constructed(&nv_encoder->outp.object)) { + enum nvif_outp_detect_status status; + + if (nv_encoder->dcb->type == DCB_OUTPUT_DP) { + ret = nouveau_dp_detect(conn, nv_encoder); + if (ret == NOUVEAU_DP_MST) + return NULL; + if (ret != NOUVEAU_DP_SST) + continue; + + return nv_encoder; + } else { + status = nvif_outp_detect(&nv_encoder->outp); + switch (status) { + case PRESENT: + return nv_encoder; + case NOT_PRESENT: + continue; + case UNKNOWN: + break; + default: + WARN_ON(1); + break; + } + } + } - break; - case DCB_OUTPUT_LVDS: + if (!nv_encoder->i2c) + continue; + + if (nv_encoder->dcb->type == DCB_OUTPUT_LVDS) { switcheroo_ddc = !!(vga_switcheroo_handler_flags() & VGA_SWITCHEROO_CAN_SWITCH_DDC); - fallthrough; - default: - if (!nv_encoder->i2c) - break; + } - if (switcheroo_ddc) - vga_switcheroo_lock_ddc(pdev); - if (nvkm_probe_i2c(nv_encoder->i2c, 0x50)) - found = nv_encoder; - if (switcheroo_ddc) - vga_switcheroo_unlock_ddc(pdev); + if (switcheroo_ddc) + vga_switcheroo_lock_ddc(pdev); + if (nvkm_probe_i2c(nv_encoder->i2c, 0x50)) + found = nv_encoder; + if (switcheroo_ddc) + vga_switcheroo_unlock_ddc(pdev); - break; - } if (found) break; } diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c index 6a4980b2d4d4e..01aa9b9c74a2a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dp.c +++ b/drivers/gpu/drm/nouveau/nouveau_dp.c @@ -132,14 +132,8 @@ nouveau_dp_detect(struct nouveau_connector *nv_connector, } } - /* Check status of HPD pin before attempting an AUX transaction that - * would result in a number of (futile) retries on a connector which - * has no display plugged. - * - * TODO: look into checking this before probing I2C to detect DVI/HDMI - */ - hpd = nvif_conn_hpd_status(&nv_connector->conn); - if (hpd == NVIF_CONN_HPD_STATUS_NOT_PRESENT) { + hpd = nvif_outp_detect(&nv_encoder->outp); + if (hpd == NOT_PRESENT) { nvif_outp_dp_aux_pwr(&nv_encoder->outp, false); goto out; } diff --git a/drivers/gpu/drm/nouveau/nvif/conn.c b/drivers/gpu/drm/nouveau/nvif/conn.c index a3cf91aeae2de..879569d4ba4cc 100644 --- a/drivers/gpu/drm/nouveau/nvif/conn.c +++ b/drivers/gpu/drm/nouveau/nvif/conn.c @@ -45,20 +45,6 @@ nvif_conn_event_ctor(struct nvif_conn *conn, const char *name, nvif_event_func f return ret; } -int -nvif_conn_hpd_status(struct nvif_conn *conn) -{ - struct nvif_conn_hpd_status_v0 args; - int ret; - - args.version = 0; - - ret = nvif_mthd(&conn->object, NVIF_CONN_V0_HPD_STATUS, &args, sizeof(args)); - NVIF_ERRON(ret, &conn->object, "[HPD_STATUS] support:%d present:%d", - args.support, args.present); - return ret ? ret : !!args.support + !!args.present; -} - void nvif_conn_dtor(struct nvif_conn *conn) { diff --git a/drivers/gpu/drm/nouveau/nvif/outp.c b/drivers/gpu/drm/nouveau/nvif/outp.c index c24bc5eae3ecf..7f1daab35a0d2 100644 --- a/drivers/gpu/drm/nouveau/nvif/outp.c +++ b/drivers/gpu/drm/nouveau/nvif/outp.c @@ -210,6 +210,31 @@ nvif_outp_load_detect(struct nvif_outp *outp, u32 loadval) return ret < 0 ? ret : args.load; } +enum nvif_outp_detect_status +nvif_outp_detect(struct nvif_outp *outp) +{ + struct nvif_outp_detect_v0 args; + int ret; + + args.version = 0; + + ret = nvif_mthd(&outp->object, NVIF_OUTP_V0_DETECT, &args, sizeof(args)); + NVIF_ERRON(ret, &outp->object, "[DETECT] status:%02x", args.status); + if (ret) + return UNKNOWN; + + switch (args.status) { + case NVIF_OUTP_DETECT_V0_NOT_PRESENT: return NOT_PRESENT; + case NVIF_OUTP_DETECT_V0_PRESENT: return PRESENT; + case NVIF_OUTP_DETECT_V0_UNKNOWN: return UNKNOWN; + default: + WARN_ON(1); + break; + } + + return UNKNOWN; +} + void nvif_outp_dtor(struct nvif_outp *outp) { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c index b8ac66b4a2c4b..0d2de4769b94f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c @@ -807,6 +807,7 @@ nvkm_dp_func = { .dtor = nvkm_dp_dtor, .init = nvkm_dp_init, .fini = nvkm_dp_fini, + .detect = nvkm_outp_detect, .acquire = nvkm_dp_acquire, .release = nvkm_dp_release, .disable = nvkm_dp_disable, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c index 6094805fbd63b..fb061144438dc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c @@ -22,11 +22,13 @@ * Authors: Ben Skeggs */ #include "outp.h" +#include "conn.h" #include "dp.h" #include "ior.h" #include #include +#include #include void @@ -207,6 +209,31 @@ nvkm_outp_acquire(struct nvkm_outp *outp, u8 user, bool hda) return nvkm_outp_acquire_hda(outp, type, user, false); } +int +nvkm_outp_detect(struct nvkm_outp *outp) +{ + struct nvkm_gpio *gpio = outp->disp->engine.subdev.device->gpio; + int ret = -EINVAL; + + if (outp->conn->info.hpd != DCB_GPIO_UNUSED) { + ret = nvkm_gpio_get(gpio, 0, DCB_GPIO_UNUSED, outp->conn->info.hpd); + if (ret < 0) + return ret; + if (ret) + return 1; + + /*TODO: Look into returning NOT_PRESENT if !HPD on DVI/HDMI. + * + * It's uncertain whether this is accurate for all older chipsets, + * so we're returning UNKNOWN, and the DRM will probe DDC instead. + */ + if (outp->info.type == DCB_OUTPUT_DP) + return 0; + } + + return ret; +} + void nvkm_outp_fini(struct nvkm_outp *outp) { @@ -328,6 +355,7 @@ nvkm_outp_new_(const struct nvkm_outp_func *func, struct nvkm_disp *disp, static const struct nvkm_outp_func nvkm_outp = { + .detect = nvkm_outp_detect, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h index 4e7f873f66e27..8c9fe878f3209 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h @@ -74,6 +74,9 @@ int nvkm_outp_new(struct nvkm_disp *, int index, struct dcb_output *, struct nvk void nvkm_outp_del(struct nvkm_outp **); void nvkm_outp_init(struct nvkm_outp *); void nvkm_outp_fini(struct nvkm_outp *); + +int nvkm_outp_detect(struct nvkm_outp *); + int nvkm_outp_acquire(struct nvkm_outp *, u8 user, bool hda); void nvkm_outp_release(struct nvkm_outp *, u8 user); void nvkm_outp_route(struct nvkm_disp *); @@ -82,6 +85,9 @@ struct nvkm_outp_func { void *(*dtor)(struct nvkm_outp *); void (*init)(struct nvkm_outp *); void (*fini)(struct nvkm_outp *); + + int (*detect)(struct nvkm_outp *); + int (*acquire)(struct nvkm_outp *); void (*release)(struct nvkm_outp *); void (*disable)(struct nvkm_outp *, struct nvkm_ior *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c index dad942be6679c..971cccc0892cc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c @@ -100,46 +100,6 @@ nvkm_uconn_uevent(struct nvkm_object *object, void *argv, u32 argc, struct nvkm_ nvkm_uconn_uevent_gpio); } -static int -nvkm_uconn_mthd_hpd_status(struct nvkm_conn *conn, void *argv, u32 argc) -{ - struct nvkm_gpio *gpio = conn->disp->engine.subdev.device->gpio; - union nvif_conn_hpd_status_args *args = argv; - - if (argc != sizeof(args->v0) || args->v0.version != 0) - return -ENOSYS; - - args->v0.support = gpio && conn->info.hpd != DCB_GPIO_UNUSED; - args->v0.present = 0; - - if (args->v0.support) { - int ret = nvkm_gpio_get(gpio, 0, DCB_GPIO_UNUSED, conn->info.hpd); - - if (WARN_ON(ret < 0)) { - args->v0.support = false; - return 0; - } - - args->v0.present = ret; - } - - return 0; -} - -static int -nvkm_uconn_mthd(struct nvkm_object *object, u32 mthd, void *argv, u32 argc) -{ - struct nvkm_conn *conn = nvkm_uconn(object); - - switch (mthd) { - case NVIF_CONN_V0_HPD_STATUS: return nvkm_uconn_mthd_hpd_status(conn, argv, argc); - default: - break; - } - - return -EINVAL; -} - static void * nvkm_uconn_dtor(struct nvkm_object *object) { @@ -155,7 +115,6 @@ nvkm_uconn_dtor(struct nvkm_object *object) static const struct nvkm_object_func nvkm_uconn = { .dtor = nvkm_uconn_dtor, - .mthd = nvkm_uconn_mthd, .uevent = nvkm_uconn_uevent, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c index 440ea52cc7d2b..43752e216ce88 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c @@ -275,6 +275,29 @@ nvkm_uoutp_mthd_load_detect(struct nvkm_outp *outp, void *argv, u32 argc) return ret; } +static int +nvkm_uoutp_mthd_detect(struct nvkm_outp *outp, void *argv, u32 argc) +{ + union nvif_outp_detect_args *args = argv; + int ret; + + if (argc != sizeof(args->v0) || args->v0.version != 0) + return -ENOSYS; + if (!outp->func->detect) + return -EINVAL; + + ret = outp->func->detect(outp); + switch (ret) { + case 0: args->v0.status = NVIF_OUTP_DETECT_V0_NOT_PRESENT; break; + case 1: args->v0.status = NVIF_OUTP_DETECT_V0_PRESENT; break; + default: + args->v0.status = NVIF_OUTP_DETECT_V0_UNKNOWN; + break; + } + + return 0; +} + static int nvkm_uoutp_mthd_acquired(struct nvkm_outp *outp, u32 mthd, void *argv, u32 argc) { @@ -295,6 +318,7 @@ static int nvkm_uoutp_mthd_noacquire(struct nvkm_outp *outp, u32 mthd, void *argv, u32 argc) { switch (mthd) { + case NVIF_OUTP_V0_DETECT : return nvkm_uoutp_mthd_detect (outp, argv, argc); case NVIF_OUTP_V0_ACQUIRE : return nvkm_uoutp_mthd_acquire (outp, argv, argc); case NVIF_OUTP_V0_LOAD_DETECT: return nvkm_uoutp_mthd_load_detect(outp, argv, argc); case NVIF_OUTP_V0_DP_AUX_PWR : return nvkm_uoutp_mthd_dp_aux_pwr (outp, argv, argc);