From: Suraj Kandpal <suraj.kandpal@intel.com>
To: intel-gfx@lists.freedesktop.org
Subject: [Intel-gfx] [PATCH v2 6/7] drm/i915/mtl: Adding function to send command to GSC CS
Date: Tue, 13 Dec 2022 12:31:57 +0530 [thread overview]
Message-ID: <20221213070158.2621403-7-suraj.kandpal@intel.com> (raw)
In-Reply-To: <20221213070158.2621403-1-suraj.kandpal@intel.com>
Adding function that takes care of sending command to gsc cs. We start
of with allocation of memory for our command intel_hdcp_gsc_message that
contains gsc cs memory header as directed in specs followed by the
actual payload hdcp message that we want to send.
Spec states that we need to poll pending bit of response header around
20 times each try being 50ms apart hence adding that to current
gsc_msg_send function
Also we use the same function to take care of both sending and receiving
hence no separate function to get the response.
Cc: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Cc: Anshuman Gupta <anshuman.gupta@intel.com>
Signed-off-by: Suraj Kandpal <suraj.kandpal@intel.com>
---
drivers/gpu/drm/i915/Makefile | 1 +
drivers/gpu/drm/i915/display/intel_hdcp_gsc.c | 207 ++++++++++++++++++
drivers/gpu/drm/i915/display/intel_hdcp_gsc.h | 28 +++
drivers/gpu/drm/i915/gt/uc/intel_gsc_fwif.h | 1 +
4 files changed, 237 insertions(+)
create mode 100644 drivers/gpu/drm/i915/display/intel_hdcp_gsc.c
create mode 100644 drivers/gpu/drm/i915/display/intel_hdcp_gsc.h
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index dfa211451a1d..42b8c3430365 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -250,6 +250,7 @@ i915-y += \
display/intel_frontbuffer.o \
display/intel_global_state.o \
display/intel_hdcp.o \
+ display/intel_hdcp_gsc.o \
display/intel_hotplug.o \
display/intel_hti.o \
display/intel_lpe_audio.o \
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c
new file mode 100644
index 000000000000..aea3a1158c75
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c
@@ -0,0 +1,207 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright 2021, Intel Corporation.
+ */
+
+#include "i915_drv.h"
+#include "gt/uc/intel_gsc_fw.h"
+#include "gt/uc/intel_gsc_fwif.h"
+#include "gem/i915_gem_region.h"
+#include "i915_utils.h"
+#include "display/intel_hdcp_gsc.h"
+
+struct intel_hdcp_gsc_message {
+ struct drm_i915_gem_object *obj;
+ struct i915_vma *vma;
+ void *hdcp_cmd;
+};
+
+/*This function helps allocate memory for the command that we will send to gsc cs */
+static int intel_initialize_hdcp_gsc_message(struct drm_i915_private *i915,
+ struct intel_hdcp_gsc_message *hdcp_message)
+{
+ struct intel_gt *gt = i915->media_gt;
+ struct drm_i915_gem_object *obj = NULL;
+ struct i915_vma *vma = NULL;
+ void *cmd;
+ int err;
+
+ hdcp_message->obj = NULL;
+ hdcp_message->hdcp_cmd = NULL;
+ hdcp_message->vma = NULL;
+
+ /* allocate object of one page for HDCP command memory and store it */
+ obj = i915_gem_object_create_shmem(gt->i915, PAGE_SIZE);
+
+ if (IS_ERR(obj)) {
+ drm_err(>->i915->drm, "Failed to allocate HDCP streaming command!\n");
+ return PTR_ERR(obj);
+ }
+
+ cmd = i915_gem_object_pin_map_unlocked(obj, i915_coherent_map_type(gt->i915, obj, true));
+ if (IS_ERR(cmd)) {
+ drm_err(>->i915->drm, "Failed to map gsc message page!\n");
+ err = PTR_ERR(cmd);
+ goto out_unpin;
+ }
+
+ vma = i915_vma_instance(obj, >->ggtt->vm, NULL);
+ if (IS_ERR(vma)) {
+ err = PTR_ERR(vma);
+ goto out_unmap;
+ }
+
+ err = i915_vma_pin(vma, 0, 0, PIN_GLOBAL);
+ if (err)
+ goto out_unmap;
+
+ memset(cmd, 0, obj->base.size);
+
+ hdcp_message->obj = obj;
+ hdcp_message->hdcp_cmd = cmd;
+ hdcp_message->vma = vma;
+
+ return 0;
+
+out_unmap:
+ i915_gem_object_unpin_map(obj);
+out_unpin:
+ i915_gem_object_put(obj);
+ return err;
+}
+
+static void intel_free_hdcp_gsc_message(struct intel_hdcp_gsc_message *hdcp_message)
+{
+ struct drm_i915_gem_object *obj = fetch_and_zero(&hdcp_message->obj);
+
+ if (!obj)
+ return;
+
+ if (hdcp_message->vma)
+ i915_vma_unpin(fetch_and_zero(&hdcp_message->vma));
+
+ i915_gem_object_unpin_map(obj);
+ i915_gem_object_put(obj);
+ kfree(hdcp_message);
+}
+
+static int intel_gsc_send_sync(struct drm_i915_private *i915,
+ struct intel_gsc_mtl_header *header, u64 addr,
+ size_t msg_out_len)
+{
+ struct intel_gt *gt = i915->media_gt;
+ int ret;
+
+ header->flags = 0;
+ ret = intel_gsc_fw_heci_send(>->uc.gsc, addr, header->message_size,
+ addr, msg_out_len + sizeof(*header));
+ if (ret) {
+ drm_err(&i915->drm, "failed to send gsc HDCP msg (%d)\n", ret);
+ return ret;
+ }
+ /*
+ * Checking validity marker for memory sanity
+ */
+ if (header->validity_marker != GSC_HECI_VALIDITY_MARKER) {
+ drm_err(&i915->drm, "invalid validity marker\n");
+ return -EINVAL;
+ }
+
+ if (header->status != 0) {
+ drm_err(&i915->drm, "header status indicates error %d\n",
+ header->status);
+ return -EINVAL;
+ }
+
+ if (header->flags & INTEL_GSC_MSG_PENDING)
+ return -EAGAIN;
+
+ return 0;
+}
+
+/*
+ * This function can now be used for sending requests and will also handle
+ * receipt of reply messages hence no different function of message retrieval
+ * is required. We will initialize intel_hdcp_gsc_message structure then add
+ * gsc cs memory header as stated in specs after which the normal HDCP payload
+ * will follow
+ */
+ssize_t intel_hdcp_gsc_msg_send(struct drm_i915_private *i915, u8 *msg_in,
+ size_t msg_in_len, u8 *msg_out, size_t msg_out_len)
+{
+ struct intel_gt *gt = i915->media_gt;
+ struct intel_gsc_mtl_header *header;
+ const size_t max_msg_size = PAGE_SIZE - sizeof(*header);
+ struct intel_hdcp_gsc_message *hdcp_message;
+ u64 addr;
+ u32 reply_size;
+ int ret, tries = 0;
+
+ if (!intel_uc_uses_gsc_uc(>->uc))
+ return -ENODEV;
+
+ if (msg_in_len > max_msg_size || msg_out_len > max_msg_size)
+ return -ENOSPC;
+
+ hdcp_message = kzalloc(sizeof(*hdcp_message), GFP_KERNEL);
+
+ if (!hdcp_message)
+ return -ENOMEM;
+
+ ret = intel_initialize_hdcp_gsc_message(i915, hdcp_message);
+
+ if (ret) {
+ drm_err(&i915->drm,
+ "Could not initialize hdcp_message\n");
+ goto err;
+ }
+
+ header = hdcp_message->hdcp_cmd;
+ addr = i915_ggtt_offset(hdcp_message->vma);
+
+ memset(header, 0, sizeof(*header));
+ header->validity_marker = GSC_HECI_VALIDITY_MARKER;
+ header->gsc_address = HECI_MEADDRESS_HDCP;
+ header->host_session_handle = 0;
+ header->header_version = MTL_GSC_HEADER_VERSION;
+ header->message_size = msg_in_len + sizeof(*header);
+
+ memcpy(hdcp_message->hdcp_cmd + sizeof(*header), msg_in, msg_in_len);
+
+ /*
+ * Keep sending request in case the pending bit is set no need to add
+ * message handle as we are using same address hence loc. of header is
+ * same and it will contain the message handle. we will send the message
+ * 20 times each message 50 ms apart
+ */
+ do {
+ ret = intel_gsc_send_sync(i915, header, addr, msg_out_len);
+
+ /* Only try again if gsc says so */
+ if (ret != -EAGAIN)
+ break;
+
+ msleep(50);
+
+ } while (++tries < 20);
+
+ if (ret)
+ goto err;
+
+ /* we use the same mem for the reply, so header is in the same loc */
+ reply_size = header->message_size - sizeof(*header);
+ if (reply_size > msg_out_len) {
+ drm_warn(&i915->drm, "caller with insufficient HDCP reply size %u (%d)\n",
+ reply_size, (u32)msg_out_len);
+ reply_size = msg_out_len;
+ } else if (reply_size != msg_out_len) {
+ drm_dbg_kms(&i915->drm, "caller unexpected HCDP reply size %u (%d)\n",
+ reply_size, (u32)msg_out_len);
+ }
+
+ memcpy(msg_out, hdcp_message->hdcp_cmd + sizeof(*header), msg_out_len);
+
+err:
+ intel_free_hdcp_gsc_message(hdcp_message);
+ return ret;
+}
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp_gsc.h b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.h
new file mode 100644
index 000000000000..9f3e3880fe0a
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2021 Intel Corporation
+ */
+
+#ifndef __INTEL_HDCP_GSC_H__
+#define __INTEL_HDCP_GSC_H__
+
+#include <linux/types.h>
+#include <linux/err.h>
+/*
+ * FIXME: Spec states that we need to create a random
+ * host session everytime we send message for now creating
+ * a static host session to avoid clashes not using this
+ * header as of now as we see an error if we use anything
+ * other than 0 as host session
+ */
+#define GSC_HDCP_HOST_HANDLE 0x12233FFEEDD00000
+
+struct drm_i915_private;
+
+ssize_t intel_hdcp_gsc_msg_send(struct drm_i915_private *i915, u8 *msg_in,
+ size_t msg_in_len, u8 *msg_out,
+ size_t msg_out_len);
+int intel_gsc_hdcp_init(struct drm_i915_private *i915);
+int intel_gsc_hdcp_fini(struct drm_i915_private *i915);
+
+#endif /* __INTEL_HDCP_GCS_H__ */
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fwif.h b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fwif.h
index 1c2a04d092a8..19b98c75367a 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fwif.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fwif.h
@@ -34,6 +34,7 @@ struct intel_gsc_mtl_header {
* Bits 16-31: Extension Size
*/
u32 flags;
+#define INTEL_GSC_MSG_PENDING 1
u32 status;
} __packed;
--
2.25.1
next prev parent reply other threads:[~2022-12-13 7:03 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-12-13 7:01 [Intel-gfx] [PATCH v2 0/7] Enable HDCP2.x via GSC CS Suraj Kandpal
2022-12-13 7:01 ` [Intel-gfx] [PATCH v2 1/7] drm/i915/gsc: Create GSC request submission mechanism Suraj Kandpal
2022-12-13 7:01 ` [Intel-gfx] [PATCH v2 2/7] drm/i915/hdcp: Keep cp fw agonstic naming convention Suraj Kandpal
2022-12-13 10:32 ` Jani Nikula
2022-12-13 10:40 ` Kandpal, Suraj
2022-12-13 7:01 ` [Intel-gfx] [PATCH v2 3/7] drm/i915/hdcp: HDCP2.x Refactoring to agnotic cp f/w Suraj Kandpal
2022-12-13 10:24 ` Jani Nikula
2022-12-13 10:32 ` Kandpal, Suraj
2022-12-13 10:40 ` Jani Nikula
2022-12-13 10:45 ` Kandpal, Suraj
2022-12-13 7:01 ` [Intel-gfx] [PATCH v2 4/7] drm/i915/hdcp: Refactor HDCP API structures Suraj Kandpal
2022-12-13 7:01 ` [Intel-gfx] [PATCH v2 5/7] drm/i915/hdcp: Fill wired_cmd_in structures at a single place Suraj Kandpal
2022-12-13 10:43 ` Jani Nikula
2022-12-13 10:50 ` Kandpal, Suraj
2022-12-13 11:08 ` Jani Nikula
2022-12-13 7:01 ` Suraj Kandpal [this message]
2022-12-13 10:47 ` [Intel-gfx] [PATCH v2 6/7] drm/i915/mtl: Adding function to send command to GSC CS Jani Nikula
2022-12-13 7:01 ` [Intel-gfx] [PATCH v2 7/7] drm/i915/mtl: Add HDCP GSC interface Suraj Kandpal
2022-12-13 10:54 ` Jani Nikula
2022-12-13 7:29 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for Enable HDCP2.x via GSC CS (rev2) Patchwork
2022-12-13 7:29 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2022-12-13 7:40 ` [Intel-gfx] ✗ Fi.CI.BAT: failure " Patchwork
2022-12-13 9:28 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2022-12-14 6:23 ` [Intel-gfx] ✗ Fi.CI.IGT: failure " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20221213070158.2621403-7-suraj.kandpal@intel.com \
--to=suraj.kandpal@intel.com \
--cc=intel-gfx@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox