// SPDX-License-Identifier: GPL-2.0 /* * Copyright © 2020 - 2021 Intel Corporation */ /** * DOC: MEI_PXP Client Driver * * The mei_pxp driver acts as a translation layer between PXP * protocol implementer (I915) and ME FW by translating PXP * negotiation messages to ME FW command payloads and vice versa. */ #include <linux/delay.h> #include <linux/module.h> #include <linux/pci.h> #include <linux/slab.h> #include <linux/mei.h> #include <linux/mei_cl_bus.h> #include <linux/component.h> #include <drm/drm_connector.h> #include <drm/intel/i915_component.h> #include <drm/intel/i915_pxp_tee_interface.h> #include "mei_pxp.h" static inline int mei_pxp_reenable(const struct device *dev, struct mei_cl_device *cldev) { … } /** * mei_pxp_send_message() - Sends a PXP message to ME FW. * @dev: device corresponding to the mei_cl_device * @message: a message buffer to send * @size: size of the message * @timeout_ms: timeout in milliseconds, zero means wait indefinitely. * * Returns: 0 on Success, <0 on Failure with the following defined failures. * -ENODEV: Client was not connected. * Caller may attempt to try again immediately. * -ENOMEM: Internal memory allocation failure experienced. * Caller may sleep to allow kernel reclaim before retrying. * -EINTR : Calling thread received a signal. Caller may choose * to abandon with the same thread id. * -ETIME : Request is timed out. * Caller may attempt to try again immediately. */ static int mei_pxp_send_message(struct device *dev, const void *message, size_t size, unsigned long timeout_ms) { … } /** * mei_pxp_receive_message() - Receives a PXP message from ME FW. * @dev: device corresponding to the mei_cl_device * @buffer: a message buffer to contain the received message * @size: size of the buffer * @timeout_ms: timeout in milliseconds, zero means wait indefinitely. * * Returns: number of bytes send on Success, <0 on Failure with the following defined failures. * -ENODEV: Client was not connected. * Caller may attempt to try again from send immediately. * -ENOMEM: Internal memory allocation failure experienced. * Caller may sleep to allow kernel reclaim before retrying. * -EINTR : Calling thread received a signal. Caller will need to repeat calling * (with a different owning thread) to retrieve existing unclaimed response * (and may discard it). * -ETIME : Request is timed out. * Caller may attempt to try again from send immediately. */ static int mei_pxp_receive_message(struct device *dev, void *buffer, size_t size, unsigned long timeout_ms) { … } /** * mei_pxp_gsc_command() - sends a gsc command, by sending * a sgl mei message to gsc and receiving reply from gsc * * @dev: device corresponding to the mei_cl_device * @client_id: client id to send the command to * @fence_id: fence id to send the command to * @sg_in: scatter gather list containing addresses for rx message buffer * @total_in_len: total length of data in 'in' sg, can be less than the sum of buffers sizes * @sg_out: scatter gather list containing addresses for tx message buffer * * Return: bytes sent on Success, <0 on Failure */ static ssize_t mei_pxp_gsc_command(struct device *dev, u8 client_id, u32 fence_id, struct scatterlist *sg_in, size_t total_in_len, struct scatterlist *sg_out) { … } static const struct i915_pxp_component_ops mei_pxp_ops = …; static int mei_component_master_bind(struct device *dev) { … } static void mei_component_master_unbind(struct device *dev) { … } static const struct component_master_ops mei_component_master_ops = …; /** * mei_pxp_component_match - compare function for matching mei pxp. * * The function checks if the driver is i915, the subcomponent is PXP * and the grand parent of pxp and the parent of i915 are the same * PCH device. * * @dev: master device * @subcomponent: subcomponent to match (I915_COMPONENT_PXP) * @data: compare data (mei pxp device) * * Return: * * 1 - if components match * * 0 - otherwise */ static int mei_pxp_component_match(struct device *dev, int subcomponent, void *data) { … } static int mei_pxp_probe(struct mei_cl_device *cldev, const struct mei_cl_device_id *id) { … } static void mei_pxp_remove(struct mei_cl_device *cldev) { … } /* fbf6fcf1-96cf-4e2e-a6a6-1bab8cbe36b1 : PAVP GUID*/ #define MEI_GUID_PXP … static struct mei_cl_device_id mei_pxp_tbl[] = …; MODULE_DEVICE_TABLE(mei, mei_pxp_tbl); static struct mei_cl_driver mei_pxp_driver = …; module_mei_cl_driver(…) …; MODULE_AUTHOR(…) …; MODULE_LICENSE(…) …; MODULE_DESCRIPTION(…) …;