lkml.org 
[lkml]   [2020]   [Mar]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
Subject[PATCH v8 4/5] drm/i915: Add helper code for ACPI privacy screen
From
Add helper functions that can allow i915 to detect and control
an integrated privacy screen via ACPI methods. These shall be used
in the next patch.

Signed-off-by: Rajat Jain <rajatja@google.com>
---
v8: Initial version. formed by refactoring the previous patch 4.
print the connector name in the debug messages.

drivers/gpu/drm/i915/Makefile | 3 +-
.../drm/i915/display/intel_privacy_screen.c | 184 ++++++++++++++++++
.../drm/i915/display/intel_privacy_screen.h | 27 +++
3 files changed, 213 insertions(+), 1 deletion(-)
create mode 100644 drivers/gpu/drm/i915/display/intel_privacy_screen.c
create mode 100644 drivers/gpu/drm/i915/display/intel_privacy_screen.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 9f887a86e555d..da42389107f9c 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -209,7 +209,8 @@ i915-y += \
display/intel_vga.o
i915-$(CONFIG_ACPI) += \
display/intel_acpi.o \
- display/intel_opregion.o
+ display/intel_opregion.o \
+ display/intel_privacy_screen.o
i915-$(CONFIG_DRM_FBDEV_EMULATION) += \
display/intel_fbdev.o

diff --git a/drivers/gpu/drm/i915/display/intel_privacy_screen.c b/drivers/gpu/drm/i915/display/intel_privacy_screen.c
new file mode 100644
index 0000000000000..66039103c821b
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_privacy_screen.c
@@ -0,0 +1,184 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/*
+ * Intel ACPI privacy screen code
+ *
+ * Copyright © 2020 Google Inc.
+ *
+ * This code can help detect and control an integrated EPS (electronic
+ * privacy screen) via ACPI functions. It expects an ACPI node for the
+ * drm connector device with the following elements:
+ *
+ * UUID should be "c7033113-8720-4ceb-9090-9d52b3e52d73"
+ *
+ * _ADR = ACPI address per Spec (also see intel_acpi_device_id_update())
+ * https://uefi.org/sites/default/files/resources/ACPI_6_3_final_Jan30.pdf
+ * Pages 1119 - 1123.
+ *
+ * _DSM method that will perform the following functions according to
+ * Local1 argument passed to it:
+ * - Local1 = 0 (EPS capabilities): Report EPS presence and capabilities.
+ * - Local1 = 1 (EPS State) : _DSM returns 1 if EPS is enabled, 0 otherwise.
+ * - Local1 = 2 (EPS Enable) : _DSM enables EPS
+ * - Local1 = 3 (EPS Disable): _DSM disables EPS
+ *
+ * Here is a sample ACPI node:
+ *
+ * Scope (\_SB.PCI0.GFX0) // Intel graphics device (PCI device)
+ * {
+ * Method (_DOD, 0, NotSerialized) // _DOD: Display Output Devices
+ * {
+ * Return (Package (0x01)
+ * {
+ * 0x80010400
+ * })
+ * }
+ *
+ * Device (LCD)
+ * {
+ * Name (_ADR, 0x80010400) // _ADR: Address
+ * Name (_STA, 0x0F) // _STA: Status
+ *
+ * Method (EPSP, 0, NotSerialized) // EPS Present
+ * {
+ * Return (0x01)
+ * }
+ *
+ * Method (EPSS, 0, NotSerialized) // EPS State
+ * {
+ * Local0 = \_SB.PCI0.GRXS (0xCD)
+ * Return (Local0)
+ * }
+ *
+ * Method (EPSE, 0, NotSerialized) // EPS Enable
+ * {
+ * \_SB.PCI0.STXS (0xCD)
+ * }
+ *
+ * Method (EPSD, 0, NotSerialized) // EPS Disable
+ * {
+ * \_SB.PCI0.CTXS (0xCD)
+ * }
+ *
+ * Method (_DSM, 4, Serialized) // _DSM: Device-Specific Method
+ * {
+ * ToBuffer (Arg0, Local0)
+ * If ((Local0 == ToUUID ("c7033113-8720-4ceb-9090-9d52b3e52d73")))
+ * {
+ * ToInteger (Arg2, Local1)
+ * If ((Local1 == Zero))
+ * {
+ * Local2 = EPSP ()
+ * If ((Local2 == One))
+ * {
+ * Return (Buffer (One)
+ * {
+ * 0x0F
+ * })
+ * }
+ * }
+ *
+ * If ((Local1 == One))
+ * {
+ * Return (EPSS ())
+ * }
+ *
+ * If ((Local1 == 0x02))
+ * {
+ * EPSE ()
+ * }
+ *
+ * If ((Local1 == 0x03))
+ * {
+ * EPSD ()
+ * }
+ *
+ * Return (Buffer (One)
+ * {
+ * 0x00
+ * })
+ * }
+ *
+ * Return (Buffer (One)
+ * {
+ * 0x00
+ * })
+ * }
+ * }
+ * }
+ */
+
+#include <linux/acpi.h>
+
+#include "intel_privacy_screen.h"
+
+#define CONN_NAME(conn) \
+ (conn->base.kdev ? dev_name(conn->base.kdev) : "NONAME")
+
+#define CONNECTOR_DSM_REVID 1
+
+#define CONNECTOR_DSM_FN_PRIVACY_ENABLE 2
+#define CONNECTOR_DSM_FN_PRIVACY_DISABLE 3
+
+static const guid_t drm_conn_dsm_guid =
+ GUID_INIT(0xC7033113, 0x8720, 0x4CEB,
+ 0x90, 0x90, 0x9D, 0x52, 0xB3, 0xE5, 0x2D, 0x73);
+
+/* Makes _DSM call to set privacy screen status */
+static void acpi_privacy_screen_call_dsm(struct intel_connector *connector,
+ u64 func)
+{
+ union acpi_object *obj;
+ acpi_handle acpi_handle = connector->acpi_handle;
+ struct drm_device *drm = connector->base.dev;
+
+ if (!acpi_handle)
+ return;
+
+ obj = acpi_evaluate_dsm(acpi_handle, &drm_conn_dsm_guid,
+ CONNECTOR_DSM_REVID, func, NULL);
+ if (!obj) {
+ drm_err(drm, "%s: failed to evaluate _DSM for fn %llx\n",
+ CONN_NAME(connector), func);
+ return;
+ }
+
+ ACPI_FREE(obj);
+}
+
+void intel_privacy_screen_set_val(struct intel_connector *connector,
+ enum drm_privacy_screen_status val)
+{
+ struct drm_device *drm = connector->base.dev;
+
+ if (val == PRIVACY_SCREEN_DISABLED) {
+ drm_dbg_kms(drm, "%s: disabling privacy-screen\n",
+ CONN_NAME(connector));
+ acpi_privacy_screen_call_dsm(connector,
+ CONNECTOR_DSM_FN_PRIVACY_DISABLE);
+ } else {
+ drm_dbg_kms(drm, "%s: enabling privacy-screen\n",
+ CONN_NAME(connector));
+ acpi_privacy_screen_call_dsm(connector,
+ CONNECTOR_DSM_FN_PRIVACY_ENABLE);
+ }
+}
+
+bool intel_privacy_screen_present(struct intel_connector *connector)
+{
+ acpi_handle handle = connector->acpi_handle;
+ struct drm_device *drm = connector->base.dev;
+
+ if (handle &&
+ acpi_check_dsm(handle, &drm_conn_dsm_guid,
+ CONNECTOR_DSM_REVID,
+ 1 << CONNECTOR_DSM_FN_PRIVACY_ENABLE |
+ 1 << CONNECTOR_DSM_FN_PRIVACY_DISABLE)) {
+ drm_info(drm, "%s: supports ACPI privacy-screen\n",
+ CONN_NAME(connector));
+ return true;
+ }
+
+ drm_dbg_kms(drm, "%s: doesn't support ACPI privacy-screen\n",
+ CONN_NAME(connector));
+ return false;
+}
diff --git a/drivers/gpu/drm/i915/display/intel_privacy_screen.h b/drivers/gpu/drm/i915/display/intel_privacy_screen.h
new file mode 100644
index 0000000000000..8655745ff9085
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_privacy_screen.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/*
+ * Copyright © 2020 Google Inc.
+ */
+
+#ifndef __DRM_PRIVACY_SCREEN_H__
+#define __DRM_PRIVACY_SCREEN_H__
+
+#include "intel_display_types.h"
+
+#ifdef CONFIG_ACPI
+bool intel_privacy_screen_present(struct intel_connector *connector);
+void intel_privacy_screen_set_val(struct intel_connector *connector,
+ enum drm_privacy_screen_status val);
+#else
+static bool intel_privacy_screen_present(struct intel_connector *connector)
+{
+ return false;
+}
+
+static void
+intel_privacy_screen_set_val(struct intel_connector *connector,
+ enum drm_privacy_screen_status val)
+{ }
+#endif /* CONFIG_ACPI */
+
+#endif /* __DRM_PRIVACY_SCREEN_H__ */
--
2.25.1.481.gfbce0eb801-goog
\
 
 \ /
  Last update: 2020-03-12 01:58    [W:0.042 / U:0.572 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site