Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * System Control and Management Interface (SCMI) Message Protocol
0004  * protocols common header file containing some definitions, structures
0005  * and function prototypes used in all the different SCMI protocols.
0006  *
0007  * Copyright (C) 2022 ARM Ltd.
0008  */
0009 #ifndef _SCMI_PROTOCOLS_H
0010 #define _SCMI_PROTOCOLS_H
0011 
0012 #include <linux/bitfield.h>
0013 #include <linux/completion.h>
0014 #include <linux/device.h>
0015 #include <linux/errno.h>
0016 #include <linux/kernel.h>
0017 #include <linux/hashtable.h>
0018 #include <linux/list.h>
0019 #include <linux/module.h>
0020 #include <linux/refcount.h>
0021 #include <linux/scmi_protocol.h>
0022 #include <linux/spinlock.h>
0023 #include <linux/types.h>
0024 
0025 #include <asm/unaligned.h>
0026 
0027 #define PROTOCOL_REV_MINOR_MASK GENMASK(15, 0)
0028 #define PROTOCOL_REV_MAJOR_MASK GENMASK(31, 16)
0029 #define PROTOCOL_REV_MAJOR(x)   ((u16)(FIELD_GET(PROTOCOL_REV_MAJOR_MASK, (x))))
0030 #define PROTOCOL_REV_MINOR(x)   ((u16)(FIELD_GET(PROTOCOL_REV_MINOR_MASK, (x))))
0031 
0032 enum scmi_common_cmd {
0033     PROTOCOL_VERSION = 0x0,
0034     PROTOCOL_ATTRIBUTES = 0x1,
0035     PROTOCOL_MESSAGE_ATTRIBUTES = 0x2,
0036 };
0037 
0038 /**
0039  * struct scmi_msg_resp_prot_version - Response for a message
0040  *
0041  * @minor_version: Minor version of the ABI that firmware supports
0042  * @major_version: Major version of the ABI that firmware supports
0043  *
0044  * In general, ABI version changes follow the rule that minor version increments
0045  * are backward compatible. Major revision changes in ABI may not be
0046  * backward compatible.
0047  *
0048  * Response to a generic message with message type SCMI_MSG_VERSION
0049  */
0050 struct scmi_msg_resp_prot_version {
0051     __le16 minor_version;
0052     __le16 major_version;
0053 };
0054 
0055 /**
0056  * struct scmi_msg - Message(Tx/Rx) structure
0057  *
0058  * @buf: Buffer pointer
0059  * @len: Length of data in the Buffer
0060  */
0061 struct scmi_msg {
0062     void *buf;
0063     size_t len;
0064 };
0065 
0066 /**
0067  * struct scmi_msg_hdr - Message(Tx/Rx) header
0068  *
0069  * @id: The identifier of the message being sent
0070  * @protocol_id: The identifier of the protocol used to send @id message
0071  * @type: The SCMI type for this message
0072  * @seq: The token to identify the message. When a message returns, the
0073  *  platform returns the whole message header unmodified including the
0074  *  token
0075  * @status: Status of the transfer once it's complete
0076  * @poll_completion: Indicate if the transfer needs to be polled for
0077  *  completion or interrupt mode is used
0078  */
0079 struct scmi_msg_hdr {
0080     u8 id;
0081     u8 protocol_id;
0082     u8 type;
0083     u16 seq;
0084     u32 status;
0085     bool poll_completion;
0086 };
0087 
0088 /**
0089  * struct scmi_xfer - Structure representing a message flow
0090  *
0091  * @transfer_id: Unique ID for debug & profiling purpose
0092  * @hdr: Transmit message header
0093  * @tx: Transmit message
0094  * @rx: Receive message, the buffer should be pre-allocated to store
0095  *  message. If request-ACK protocol is used, we can reuse the same
0096  *  buffer for the rx path as we use for the tx path.
0097  * @done: command message transmit completion event
0098  * @async_done: pointer to delayed response message received event completion
0099  * @pending: True for xfers added to @pending_xfers hashtable
0100  * @node: An hlist_node reference used to store this xfer, alternatively, on
0101  *    the free list @free_xfers or in the @pending_xfers hashtable
0102  * @users: A refcount to track the active users for this xfer.
0103  *     This is meant to protect against the possibility that, when a command
0104  *     transaction times out concurrently with the reception of a valid
0105  *     response message, the xfer could be finally put on the TX path, and
0106  *     so vanish, while on the RX path scmi_rx_callback() is still
0107  *     processing it: in such a case this refcounting will ensure that, even
0108  *     though the timed-out transaction will anyway cause the command
0109  *     request to be reported as failed by time-out, the underlying xfer
0110  *     cannot be discarded and possibly reused until the last one user on
0111  *     the RX path has released it.
0112  * @busy: An atomic flag to ensure exclusive write access to this xfer
0113  * @state: The current state of this transfer, with states transitions deemed
0114  *     valid being:
0115  *      - SCMI_XFER_SENT_OK -> SCMI_XFER_RESP_OK [ -> SCMI_XFER_DRESP_OK ]
0116  *      - SCMI_XFER_SENT_OK -> SCMI_XFER_DRESP_OK
0117  *        (Missing synchronous response is assumed OK and ignored)
0118  * @lock: A spinlock to protect state and busy fields.
0119  * @priv: A pointer for transport private usage.
0120  */
0121 struct scmi_xfer {
0122     int transfer_id;
0123     struct scmi_msg_hdr hdr;
0124     struct scmi_msg tx;
0125     struct scmi_msg rx;
0126     struct completion done;
0127     struct completion *async_done;
0128     bool pending;
0129     struct hlist_node node;
0130     refcount_t users;
0131 #define SCMI_XFER_FREE      0
0132 #define SCMI_XFER_BUSY      1
0133     atomic_t busy;
0134 #define SCMI_XFER_SENT_OK   0
0135 #define SCMI_XFER_RESP_OK   1
0136 #define SCMI_XFER_DRESP_OK  2
0137     int state;
0138     /* A lock to protect state and busy fields */
0139     spinlock_t lock;
0140     void *priv;
0141 };
0142 
0143 struct scmi_xfer_ops;
0144 struct scmi_proto_helpers_ops;
0145 
0146 /**
0147  * struct scmi_protocol_handle  - Reference to an initialized protocol instance
0148  *
0149  * @dev: A reference to the associated SCMI instance device (handle->dev).
0150  * @xops: A reference to a struct holding refs to the core xfer operations that
0151  *    can be used by the protocol implementation to generate SCMI messages.
0152  * @set_priv: A method to set protocol private data for this instance.
0153  * @get_priv: A method to get protocol private data previously set.
0154  *
0155  * This structure represents a protocol initialized against specific SCMI
0156  * instance and it will be used as follows:
0157  * - as a parameter fed from the core to the protocol initialization code so
0158  *   that it can access the core xfer operations to build and generate SCMI
0159  *   messages exclusively for the specific underlying protocol instance.
0160  * - as an opaque handle fed by an SCMI driver user when it tries to access
0161  *   this protocol through its own protocol operations.
0162  *   In this case this handle will be returned as an opaque object together
0163  *   with the related protocol operations when the SCMI driver tries to access
0164  *   the protocol.
0165  */
0166 struct scmi_protocol_handle {
0167     struct device *dev;
0168     const struct scmi_xfer_ops *xops;
0169     const struct scmi_proto_helpers_ops *hops;
0170     int (*set_priv)(const struct scmi_protocol_handle *ph, void *priv);
0171     void *(*get_priv)(const struct scmi_protocol_handle *ph);
0172 };
0173 
0174 /**
0175  * struct scmi_iterator_state  - Iterator current state descriptor
0176  * @desc_index: Starting index for the current mulit-part request.
0177  * @num_returned: Number of returned items in the last multi-part reply.
0178  * @num_remaining: Number of remaining items in the multi-part message.
0179  * @max_resources: Maximum acceptable number of items, configured by the caller
0180  *         depending on the underlying resources that it is querying.
0181  * @loop_idx: The iterator loop index in the current multi-part reply.
0182  * @rx_len: Size in bytes of the currenly processed message; it can be used by
0183  *      the user of the iterator to verify a reply size.
0184  * @priv: Optional pointer to some additional state-related private data setup
0185  *    by the caller during the iterations.
0186  */
0187 struct scmi_iterator_state {
0188     unsigned int desc_index;
0189     unsigned int num_returned;
0190     unsigned int num_remaining;
0191     unsigned int max_resources;
0192     unsigned int loop_idx;
0193     size_t rx_len;
0194     void *priv;
0195 };
0196 
0197 /**
0198  * struct scmi_iterator_ops  - Custom iterator operations
0199  * @prepare_message: An operation to provide the custom logic to fill in the
0200  *           SCMI command request pointed by @message. @desc_index is
0201  *           a reference to the next index to use in the multi-part
0202  *           request.
0203  * @update_state: An operation to provide the custom logic to update the
0204  *        iterator state from the actual message response.
0205  * @process_response: An operation to provide the custom logic needed to process
0206  *            each chunk of the multi-part message.
0207  */
0208 struct scmi_iterator_ops {
0209     void (*prepare_message)(void *message, unsigned int desc_index,
0210                 const void *priv);
0211     int (*update_state)(struct scmi_iterator_state *st,
0212                 const void *response, void *priv);
0213     int (*process_response)(const struct scmi_protocol_handle *ph,
0214                 const void *response,
0215                 struct scmi_iterator_state *st, void *priv);
0216 };
0217 
0218 struct scmi_fc_db_info {
0219     int width;
0220     u64 set;
0221     u64 mask;
0222     void __iomem *addr;
0223 };
0224 
0225 struct scmi_fc_info {
0226     void __iomem *set_addr;
0227     void __iomem *get_addr;
0228     struct scmi_fc_db_info *set_db;
0229 };
0230 
0231 /**
0232  * struct scmi_proto_helpers_ops  - References to common protocol helpers
0233  * @extended_name_get: A common helper function to retrieve extended naming
0234  *             for the specified resource using the specified command.
0235  *             Result is returned as a NULL terminated string in the
0236  *             pre-allocated area pointed to by @name with maximum
0237  *             capacity of @len bytes.
0238  * @iter_response_init: A common helper to initialize a generic iterator to
0239  *          parse multi-message responses: when run the iterator
0240  *          will take care to send the initial command request as
0241  *          specified by @msg_id and @tx_size and then to parse the
0242  *          multi-part responses using the custom operations
0243  *          provided in @ops.
0244  * @iter_response_run: A common helper to trigger the run of a previously
0245  *             initialized iterator.
0246  * @fastchannel_init: A common helper used to initialize FC descriptors by
0247  *            gathering FC descriptions from the SCMI platform server.
0248  * @fastchannel_db_ring: A common helper to ring a FC doorbell.
0249  */
0250 struct scmi_proto_helpers_ops {
0251     int (*extended_name_get)(const struct scmi_protocol_handle *ph,
0252                  u8 cmd_id, u32 res_id, char *name, size_t len);
0253     void *(*iter_response_init)(const struct scmi_protocol_handle *ph,
0254                     struct scmi_iterator_ops *ops,
0255                     unsigned int max_resources, u8 msg_id,
0256                     size_t tx_size, void *priv);
0257     int (*iter_response_run)(void *iter);
0258     void (*fastchannel_init)(const struct scmi_protocol_handle *ph,
0259                  u8 describe_id, u32 message_id,
0260                  u32 valid_size, u32 domain,
0261                  void __iomem **p_addr,
0262                  struct scmi_fc_db_info **p_db);
0263     void (*fastchannel_db_ring)(struct scmi_fc_db_info *db);
0264 };
0265 
0266 /**
0267  * struct scmi_xfer_ops  - References to the core SCMI xfer operations.
0268  * @version_get: Get this version protocol.
0269  * @xfer_get_init: Initialize one struct xfer if any xfer slot is free.
0270  * @reset_rx_to_maxsz: Reset rx size to max transport size.
0271  * @do_xfer: Do the SCMI transfer.
0272  * @do_xfer_with_response: Do the SCMI transfer waiting for a response.
0273  * @xfer_put: Free the xfer slot.
0274  *
0275  * Note that all this operations expect a protocol handle as first parameter;
0276  * they then internally use it to infer the underlying protocol number: this
0277  * way is not possible for a protocol implementation to forge messages for
0278  * another protocol.
0279  */
0280 struct scmi_xfer_ops {
0281     int (*version_get)(const struct scmi_protocol_handle *ph, u32 *version);
0282     int (*xfer_get_init)(const struct scmi_protocol_handle *ph, u8 msg_id,
0283                  size_t tx_size, size_t rx_size,
0284                  struct scmi_xfer **p);
0285     void (*reset_rx_to_maxsz)(const struct scmi_protocol_handle *ph,
0286                   struct scmi_xfer *xfer);
0287     int (*do_xfer)(const struct scmi_protocol_handle *ph,
0288                struct scmi_xfer *xfer);
0289     int (*do_xfer_with_response)(const struct scmi_protocol_handle *ph,
0290                      struct scmi_xfer *xfer);
0291     void (*xfer_put)(const struct scmi_protocol_handle *ph,
0292              struct scmi_xfer *xfer);
0293 };
0294 
0295 typedef int (*scmi_prot_init_ph_fn_t)(const struct scmi_protocol_handle *);
0296 
0297 /**
0298  * struct scmi_protocol  - Protocol descriptor
0299  * @id: Protocol ID.
0300  * @owner: Module reference if any.
0301  * @instance_init: Mandatory protocol initialization function.
0302  * @instance_deinit: Optional protocol de-initialization function.
0303  * @ops: Optional reference to the operations provided by the protocol and
0304  *   exposed in scmi_protocol.h.
0305  * @events: An optional reference to the events supported by this protocol.
0306  */
0307 struct scmi_protocol {
0308     const u8                id;
0309     struct module               *owner;
0310     const scmi_prot_init_ph_fn_t        instance_init;
0311     const scmi_prot_init_ph_fn_t        instance_deinit;
0312     const void              *ops;
0313     const struct scmi_protocol_events   *events;
0314 };
0315 
0316 #define DEFINE_SCMI_PROTOCOL_REGISTER_UNREGISTER(name, proto)   \
0317 static const struct scmi_protocol *__this_proto = &(proto); \
0318                                 \
0319 int __init scmi_##name##_register(void)             \
0320 {                               \
0321     return scmi_protocol_register(__this_proto);        \
0322 }                               \
0323                                 \
0324 void __exit scmi_##name##_unregister(void)          \
0325 {                               \
0326     scmi_protocol_unregister(__this_proto);         \
0327 }
0328 
0329 #define DECLARE_SCMI_REGISTER_UNREGISTER(func)      \
0330     int __init scmi_##func##_register(void);    \
0331     void __exit scmi_##func##_unregister(void)
0332 DECLARE_SCMI_REGISTER_UNREGISTER(base);
0333 DECLARE_SCMI_REGISTER_UNREGISTER(clock);
0334 DECLARE_SCMI_REGISTER_UNREGISTER(perf);
0335 DECLARE_SCMI_REGISTER_UNREGISTER(power);
0336 DECLARE_SCMI_REGISTER_UNREGISTER(reset);
0337 DECLARE_SCMI_REGISTER_UNREGISTER(sensors);
0338 DECLARE_SCMI_REGISTER_UNREGISTER(voltage);
0339 DECLARE_SCMI_REGISTER_UNREGISTER(system);
0340 DECLARE_SCMI_REGISTER_UNREGISTER(powercap);
0341 
0342 #endif /* _SCMI_PROTOCOLS_H */