linux/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c

// SPDX-License-Identifier: MIT
/*
 * Copyright © 2023 Intel Corporation
 */

#include <linux/component.h>

#include <drm/intel/i915_component.h>
#include <drm/intel/i915_gsc_proxy_mei_interface.h>

#include "gt/intel_gt.h"
#include "gt/intel_gt_print.h"
#include "intel_gsc_proxy.h"
#include "intel_gsc_uc.h"
#include "intel_gsc_uc_heci_cmd_submit.h"
#include "i915_drv.h"
#include "i915_reg.h"

/*
 * GSC proxy:
 * The GSC uC needs to communicate with the CSME to perform certain operations.
 * Since the GSC can't perform this communication directly on platforms where it
 * is integrated in GT, i915 needs to transfer the messages from GSC to CSME
 * and back. i915 must manually start the proxy flow after the GSC is loaded to
 * signal to GSC that we're ready to handle its messages and allow it to query
 * its init data from CSME; GSC will then trigger an HECI2 interrupt if it needs
 * to send messages to CSME again.
 * The proxy flow is as follow:
 * 1 - i915 submits a request to GSC asking for the message to CSME
 * 2 - GSC replies with the proxy header + payload for CSME
 * 3 - i915 sends the reply from GSC as-is to CSME via the mei proxy component
 * 4 - CSME replies with the proxy header + payload for GSC
 * 5 - i915 submits a request to GSC with the reply from CSME
 * 6 - GSC replies either with a new header + payload (same as step 2, so we
 *     restart from there) or with an end message.
 */

/*
 * The component should load quite quickly in most cases, but it could take
 * a bit. Using a very big timeout just to cover the worst case scenario
 */
#define GSC_PROXY_INIT_TIMEOUT_MS

/* the protocol supports up to 32K in each direction */
#define GSC_PROXY_BUFFER_SIZE
#define GSC_PROXY_CHANNEL_SIZE
#define GSC_PROXY_MAX_MSG_SIZE

/* FW-defined proxy header */
struct intel_gsc_proxy_header {} __packed;

/* FW-defined proxy types */
enum intel_gsc_proxy_type {};

struct gsc_proxy_msg {} __packed;

static int proxy_send_to_csme(struct intel_gsc_uc *gsc)
{}

static int proxy_send_to_gsc(struct intel_gsc_uc *gsc)
{}

static int validate_proxy_header(struct intel_gsc_proxy_header *header,
				 u32 source, u32 dest)
{}

static int proxy_query(struct intel_gsc_uc *gsc)
{}

int intel_gsc_proxy_request_handler(struct intel_gsc_uc *gsc)
{}

void intel_gsc_proxy_irq_handler(struct intel_gsc_uc *gsc, u32 iir)
{}

static int i915_gsc_proxy_component_bind(struct device *i915_kdev,
					 struct device *mei_kdev, void *data)
{}

static void i915_gsc_proxy_component_unbind(struct device *i915_kdev,
					    struct device *mei_kdev, void *data)
{}

static const struct component_ops i915_gsc_proxy_component_ops =;

static int proxy_channel_alloc(struct intel_gsc_uc *gsc)
{}

static void proxy_channel_free(struct intel_gsc_uc *gsc)
{}

void intel_gsc_proxy_fini(struct intel_gsc_uc *gsc)
{}

int intel_gsc_proxy_init(struct intel_gsc_uc *gsc)
{}