1aa4f886fSSudeep Holla // SPDX-License-Identifier: GPL-2.0 2aa4f886fSSudeep Holla /* 3aa4f886fSSudeep Holla * SCMI Message Protocol driver header 4aa4f886fSSudeep Holla * 5aa4f886fSSudeep Holla * Copyright (C) 2018 ARM Ltd. 6aa4f886fSSudeep Holla */ 7933c5044SSudeep Holla #include <linux/device.h> 8aa4f886fSSudeep Holla #include <linux/types.h> 9aa4f886fSSudeep Holla 10b6f20ff8SSudeep Holla #define SCMI_MAX_STR_SIZE 16 11b6f20ff8SSudeep Holla 12b6f20ff8SSudeep Holla /** 13b6f20ff8SSudeep Holla * struct scmi_revision_info - version information structure 14b6f20ff8SSudeep Holla * 15b6f20ff8SSudeep Holla * @major_ver: Major ABI version. Change here implies risk of backward 16b6f20ff8SSudeep Holla * compatibility break. 17b6f20ff8SSudeep Holla * @minor_ver: Minor ABI version. Change here implies new feature addition, 18b6f20ff8SSudeep Holla * or compatible change in ABI. 19b6f20ff8SSudeep Holla * @num_protocols: Number of protocols that are implemented, excluding the 20b6f20ff8SSudeep Holla * base protocol. 21b6f20ff8SSudeep Holla * @num_agents: Number of agents in the system. 22b6f20ff8SSudeep Holla * @impl_ver: A vendor-specific implementation version. 23b6f20ff8SSudeep Holla * @vendor_id: A vendor identifier(Null terminated ASCII string) 24b6f20ff8SSudeep Holla * @sub_vendor_id: A sub-vendor identifier(Null terminated ASCII string) 25b6f20ff8SSudeep Holla */ 26b6f20ff8SSudeep Holla struct scmi_revision_info { 27b6f20ff8SSudeep Holla u16 major_ver; 28b6f20ff8SSudeep Holla u16 minor_ver; 29b6f20ff8SSudeep Holla u8 num_protocols; 30b6f20ff8SSudeep Holla u8 num_agents; 31b6f20ff8SSudeep Holla u32 impl_ver; 32b6f20ff8SSudeep Holla char vendor_id[SCMI_MAX_STR_SIZE]; 33b6f20ff8SSudeep Holla char sub_vendor_id[SCMI_MAX_STR_SIZE]; 34b6f20ff8SSudeep Holla }; 35b6f20ff8SSudeep Holla 36*a9e3fbfaSSudeep Holla struct scmi_handle; 37*a9e3fbfaSSudeep Holla 38*a9e3fbfaSSudeep Holla /** 39*a9e3fbfaSSudeep Holla * struct scmi_perf_ops - represents the various operations provided 40*a9e3fbfaSSudeep Holla * by SCMI Performance Protocol 41*a9e3fbfaSSudeep Holla * 42*a9e3fbfaSSudeep Holla * @limits_set: sets limits on the performance level of a domain 43*a9e3fbfaSSudeep Holla * @limits_get: gets limits on the performance level of a domain 44*a9e3fbfaSSudeep Holla * @level_set: sets the performance level of a domain 45*a9e3fbfaSSudeep Holla * @level_get: gets the performance level of a domain 46*a9e3fbfaSSudeep Holla * @device_domain_id: gets the scmi domain id for a given device 47*a9e3fbfaSSudeep Holla * @get_transition_latency: gets the DVFS transition latency for a given device 48*a9e3fbfaSSudeep Holla * @add_opps_to_device: adds all the OPPs for a given device 49*a9e3fbfaSSudeep Holla * @freq_set: sets the frequency for a given device using sustained frequency 50*a9e3fbfaSSudeep Holla * to sustained performance level mapping 51*a9e3fbfaSSudeep Holla * @freq_get: gets the frequency for a given device using sustained frequency 52*a9e3fbfaSSudeep Holla * to sustained performance level mapping 53*a9e3fbfaSSudeep Holla */ 54*a9e3fbfaSSudeep Holla struct scmi_perf_ops { 55*a9e3fbfaSSudeep Holla int (*limits_set)(const struct scmi_handle *handle, u32 domain, 56*a9e3fbfaSSudeep Holla u32 max_perf, u32 min_perf); 57*a9e3fbfaSSudeep Holla int (*limits_get)(const struct scmi_handle *handle, u32 domain, 58*a9e3fbfaSSudeep Holla u32 *max_perf, u32 *min_perf); 59*a9e3fbfaSSudeep Holla int (*level_set)(const struct scmi_handle *handle, u32 domain, 60*a9e3fbfaSSudeep Holla u32 level); 61*a9e3fbfaSSudeep Holla int (*level_get)(const struct scmi_handle *handle, u32 domain, 62*a9e3fbfaSSudeep Holla u32 *level); 63*a9e3fbfaSSudeep Holla int (*device_domain_id)(struct device *dev); 64*a9e3fbfaSSudeep Holla int (*get_transition_latency)(const struct scmi_handle *handle, 65*a9e3fbfaSSudeep Holla struct device *dev); 66*a9e3fbfaSSudeep Holla int (*add_opps_to_device)(const struct scmi_handle *handle, 67*a9e3fbfaSSudeep Holla struct device *dev); 68*a9e3fbfaSSudeep Holla int (*freq_set)(const struct scmi_handle *handle, u32 domain, 69*a9e3fbfaSSudeep Holla unsigned long rate); 70*a9e3fbfaSSudeep Holla int (*freq_get)(const struct scmi_handle *handle, u32 domain, 71*a9e3fbfaSSudeep Holla unsigned long *rate); 72*a9e3fbfaSSudeep Holla }; 73*a9e3fbfaSSudeep Holla 74aa4f886fSSudeep Holla /** 75aa4f886fSSudeep Holla * struct scmi_handle - Handle returned to ARM SCMI clients for usage. 76aa4f886fSSudeep Holla * 77aa4f886fSSudeep Holla * @dev: pointer to the SCMI device 78b6f20ff8SSudeep Holla * @version: pointer to the structure containing SCMI version information 79*a9e3fbfaSSudeep Holla * @perf_ops: pointer to set of performance protocol operations 80aa4f886fSSudeep Holla */ 81aa4f886fSSudeep Holla struct scmi_handle { 82aa4f886fSSudeep Holla struct device *dev; 83b6f20ff8SSudeep Holla struct scmi_revision_info *version; 84*a9e3fbfaSSudeep Holla struct scmi_perf_ops *perf_ops; 85*a9e3fbfaSSudeep Holla /* for protocol internal use */ 86*a9e3fbfaSSudeep Holla void *perf_priv; 87b6f20ff8SSudeep Holla }; 88b6f20ff8SSudeep Holla 89b6f20ff8SSudeep Holla enum scmi_std_protocol { 90b6f20ff8SSudeep Holla SCMI_PROTOCOL_BASE = 0x10, 91b6f20ff8SSudeep Holla SCMI_PROTOCOL_POWER = 0x11, 92b6f20ff8SSudeep Holla SCMI_PROTOCOL_SYSTEM = 0x12, 93b6f20ff8SSudeep Holla SCMI_PROTOCOL_PERF = 0x13, 94b6f20ff8SSudeep Holla SCMI_PROTOCOL_CLOCK = 0x14, 95b6f20ff8SSudeep Holla SCMI_PROTOCOL_SENSOR = 0x15, 96aa4f886fSSudeep Holla }; 97933c5044SSudeep Holla 98933c5044SSudeep Holla struct scmi_device { 99933c5044SSudeep Holla u32 id; 100933c5044SSudeep Holla u8 protocol_id; 101933c5044SSudeep Holla struct device dev; 102933c5044SSudeep Holla struct scmi_handle *handle; 103933c5044SSudeep Holla }; 104933c5044SSudeep Holla 105933c5044SSudeep Holla #define to_scmi_dev(d) container_of(d, struct scmi_device, dev) 106933c5044SSudeep Holla 107933c5044SSudeep Holla struct scmi_device * 108933c5044SSudeep Holla scmi_device_create(struct device_node *np, struct device *parent, int protocol); 109933c5044SSudeep Holla void scmi_device_destroy(struct scmi_device *scmi_dev); 110933c5044SSudeep Holla 111933c5044SSudeep Holla struct scmi_device_id { 112933c5044SSudeep Holla u8 protocol_id; 113933c5044SSudeep Holla }; 114933c5044SSudeep Holla 115933c5044SSudeep Holla struct scmi_driver { 116933c5044SSudeep Holla const char *name; 117933c5044SSudeep Holla int (*probe)(struct scmi_device *sdev); 118933c5044SSudeep Holla void (*remove)(struct scmi_device *sdev); 119933c5044SSudeep Holla const struct scmi_device_id *id_table; 120933c5044SSudeep Holla 121933c5044SSudeep Holla struct device_driver driver; 122933c5044SSudeep Holla }; 123933c5044SSudeep Holla 124933c5044SSudeep Holla #define to_scmi_driver(d) container_of(d, struct scmi_driver, driver) 125933c5044SSudeep Holla 126933c5044SSudeep Holla #ifdef CONFIG_ARM_SCMI_PROTOCOL 127933c5044SSudeep Holla int scmi_driver_register(struct scmi_driver *driver, 128933c5044SSudeep Holla struct module *owner, const char *mod_name); 129933c5044SSudeep Holla void scmi_driver_unregister(struct scmi_driver *driver); 130933c5044SSudeep Holla #else 131933c5044SSudeep Holla static inline int 132933c5044SSudeep Holla scmi_driver_register(struct scmi_driver *driver, struct module *owner, 133933c5044SSudeep Holla const char *mod_name) 134933c5044SSudeep Holla { 135933c5044SSudeep Holla return -EINVAL; 136933c5044SSudeep Holla } 137933c5044SSudeep Holla 138933c5044SSudeep Holla static inline void scmi_driver_unregister(struct scmi_driver *driver) {} 139933c5044SSudeep Holla #endif /* CONFIG_ARM_SCMI_PROTOCOL */ 140933c5044SSudeep Holla 141933c5044SSudeep Holla #define scmi_register(driver) \ 142933c5044SSudeep Holla scmi_driver_register(driver, THIS_MODULE, KBUILD_MODNAME) 143933c5044SSudeep Holla #define scmi_unregister(driver) \ 144933c5044SSudeep Holla scmi_driver_unregister(driver) 145933c5044SSudeep Holla 146933c5044SSudeep Holla /** 147933c5044SSudeep Holla * module_scmi_driver() - Helper macro for registering a scmi driver 148933c5044SSudeep Holla * @__scmi_driver: scmi_driver structure 149933c5044SSudeep Holla * 150933c5044SSudeep Holla * Helper macro for scmi drivers to set up proper module init / exit 151933c5044SSudeep Holla * functions. Replaces module_init() and module_exit() and keeps people from 152933c5044SSudeep Holla * printing pointless things to the kernel log when their driver is loaded. 153933c5044SSudeep Holla */ 154933c5044SSudeep Holla #define module_scmi_driver(__scmi_driver) \ 155933c5044SSudeep Holla module_driver(__scmi_driver, scmi_register, scmi_unregister) 156933c5044SSudeep Holla 157933c5044SSudeep Holla typedef int (*scmi_prot_init_fn_t)(struct scmi_handle *); 158933c5044SSudeep Holla int scmi_protocol_register(int protocol_id, scmi_prot_init_fn_t fn); 159933c5044SSudeep Holla void scmi_protocol_unregister(int protocol_id); 160