Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * SCMI Message Protocol driver header
0004  *
0005  * Copyright (C) 2018-2021 ARM Ltd.
0006  */
0007 
0008 #ifndef _LINUX_SCMI_PROTOCOL_H
0009 #define _LINUX_SCMI_PROTOCOL_H
0010 
0011 #include <linux/bitfield.h>
0012 #include <linux/device.h>
0013 #include <linux/notifier.h>
0014 #include <linux/types.h>
0015 
0016 #define SCMI_MAX_STR_SIZE       64
0017 #define SCMI_SHORT_NAME_MAX_SIZE    16
0018 #define SCMI_MAX_NUM_RATES      16
0019 
0020 /**
0021  * struct scmi_revision_info - version information structure
0022  *
0023  * @major_ver: Major ABI version. Change here implies risk of backward
0024  *  compatibility break.
0025  * @minor_ver: Minor ABI version. Change here implies new feature addition,
0026  *  or compatible change in ABI.
0027  * @num_protocols: Number of protocols that are implemented, excluding the
0028  *  base protocol.
0029  * @num_agents: Number of agents in the system.
0030  * @impl_ver: A vendor-specific implementation version.
0031  * @vendor_id: A vendor identifier(Null terminated ASCII string)
0032  * @sub_vendor_id: A sub-vendor identifier(Null terminated ASCII string)
0033  */
0034 struct scmi_revision_info {
0035     u16 major_ver;
0036     u16 minor_ver;
0037     u8 num_protocols;
0038     u8 num_agents;
0039     u32 impl_ver;
0040     char vendor_id[SCMI_SHORT_NAME_MAX_SIZE];
0041     char sub_vendor_id[SCMI_SHORT_NAME_MAX_SIZE];
0042 };
0043 
0044 struct scmi_clock_info {
0045     char name[SCMI_MAX_STR_SIZE];
0046     unsigned int enable_latency;
0047     bool rate_discrete;
0048     bool rate_changed_notifications;
0049     bool rate_change_requested_notifications;
0050     union {
0051         struct {
0052             int num_rates;
0053             u64 rates[SCMI_MAX_NUM_RATES];
0054         } list;
0055         struct {
0056             u64 min_rate;
0057             u64 max_rate;
0058             u64 step_size;
0059         } range;
0060     };
0061 };
0062 
0063 enum scmi_power_scale {
0064     SCMI_POWER_BOGOWATTS,
0065     SCMI_POWER_MILLIWATTS,
0066     SCMI_POWER_MICROWATTS
0067 };
0068 
0069 struct scmi_handle;
0070 struct scmi_device;
0071 struct scmi_protocol_handle;
0072 
0073 /**
0074  * struct scmi_clk_proto_ops - represents the various operations provided
0075  *  by SCMI Clock Protocol
0076  *
0077  * @count_get: get the count of clocks provided by SCMI
0078  * @info_get: get the information of the specified clock
0079  * @rate_get: request the current clock rate of a clock
0080  * @rate_set: set the clock rate of a clock
0081  * @enable: enables the specified clock
0082  * @disable: disables the specified clock
0083  */
0084 struct scmi_clk_proto_ops {
0085     int (*count_get)(const struct scmi_protocol_handle *ph);
0086 
0087     const struct scmi_clock_info __must_check *(*info_get)
0088         (const struct scmi_protocol_handle *ph, u32 clk_id);
0089     int (*rate_get)(const struct scmi_protocol_handle *ph, u32 clk_id,
0090             u64 *rate);
0091     int (*rate_set)(const struct scmi_protocol_handle *ph, u32 clk_id,
0092             u64 rate);
0093     int (*enable)(const struct scmi_protocol_handle *ph, u32 clk_id);
0094     int (*disable)(const struct scmi_protocol_handle *ph, u32 clk_id);
0095     int (*enable_atomic)(const struct scmi_protocol_handle *ph, u32 clk_id);
0096     int (*disable_atomic)(const struct scmi_protocol_handle *ph,
0097                   u32 clk_id);
0098 };
0099 
0100 /**
0101  * struct scmi_perf_proto_ops - represents the various operations provided
0102  *  by SCMI Performance Protocol
0103  *
0104  * @limits_set: sets limits on the performance level of a domain
0105  * @limits_get: gets limits on the performance level of a domain
0106  * @level_set: sets the performance level of a domain
0107  * @level_get: gets the performance level of a domain
0108  * @device_domain_id: gets the scmi domain id for a given device
0109  * @transition_latency_get: gets the DVFS transition latency for a given device
0110  * @device_opps_add: adds all the OPPs for a given device
0111  * @freq_set: sets the frequency for a given device using sustained frequency
0112  *  to sustained performance level mapping
0113  * @freq_get: gets the frequency for a given device using sustained frequency
0114  *  to sustained performance level mapping
0115  * @est_power_get: gets the estimated power cost for a given performance domain
0116  *  at a given frequency
0117  * @fast_switch_possible: indicates if fast DVFS switching is possible or not
0118  *  for a given device
0119  * @power_scale_mw_get: indicates if the power values provided are in milliWatts
0120  *  or in some other (abstract) scale
0121  */
0122 struct scmi_perf_proto_ops {
0123     int (*limits_set)(const struct scmi_protocol_handle *ph, u32 domain,
0124               u32 max_perf, u32 min_perf);
0125     int (*limits_get)(const struct scmi_protocol_handle *ph, u32 domain,
0126               u32 *max_perf, u32 *min_perf);
0127     int (*level_set)(const struct scmi_protocol_handle *ph, u32 domain,
0128              u32 level, bool poll);
0129     int (*level_get)(const struct scmi_protocol_handle *ph, u32 domain,
0130              u32 *level, bool poll);
0131     int (*device_domain_id)(struct device *dev);
0132     int (*transition_latency_get)(const struct scmi_protocol_handle *ph,
0133                       struct device *dev);
0134     int (*device_opps_add)(const struct scmi_protocol_handle *ph,
0135                    struct device *dev);
0136     int (*freq_set)(const struct scmi_protocol_handle *ph, u32 domain,
0137             unsigned long rate, bool poll);
0138     int (*freq_get)(const struct scmi_protocol_handle *ph, u32 domain,
0139             unsigned long *rate, bool poll);
0140     int (*est_power_get)(const struct scmi_protocol_handle *ph, u32 domain,
0141                  unsigned long *rate, unsigned long *power);
0142     bool (*fast_switch_possible)(const struct scmi_protocol_handle *ph,
0143                      struct device *dev);
0144     enum scmi_power_scale (*power_scale_get)(const struct scmi_protocol_handle *ph);
0145 };
0146 
0147 /**
0148  * struct scmi_power_proto_ops - represents the various operations provided
0149  *  by SCMI Power Protocol
0150  *
0151  * @num_domains_get: get the count of power domains provided by SCMI
0152  * @name_get: gets the name of a power domain
0153  * @state_set: sets the power state of a power domain
0154  * @state_get: gets the power state of a power domain
0155  */
0156 struct scmi_power_proto_ops {
0157     int (*num_domains_get)(const struct scmi_protocol_handle *ph);
0158     const char *(*name_get)(const struct scmi_protocol_handle *ph,
0159                 u32 domain);
0160 #define SCMI_POWER_STATE_TYPE_SHIFT 30
0161 #define SCMI_POWER_STATE_ID_MASK    (BIT(28) - 1)
0162 #define SCMI_POWER_STATE_PARAM(type, id) \
0163     ((((type) & BIT(0)) << SCMI_POWER_STATE_TYPE_SHIFT) | \
0164         ((id) & SCMI_POWER_STATE_ID_MASK))
0165 #define SCMI_POWER_STATE_GENERIC_ON SCMI_POWER_STATE_PARAM(0, 0)
0166 #define SCMI_POWER_STATE_GENERIC_OFF    SCMI_POWER_STATE_PARAM(1, 0)
0167     int (*state_set)(const struct scmi_protocol_handle *ph, u32 domain,
0168              u32 state);
0169     int (*state_get)(const struct scmi_protocol_handle *ph, u32 domain,
0170              u32 *state);
0171 };
0172 
0173 /**
0174  * struct scmi_sensor_reading  - represent a timestamped read
0175  *
0176  * Used by @reading_get_timestamped method.
0177  *
0178  * @value: The signed value sensor read.
0179  * @timestamp: An unsigned timestamp for the sensor read, as provided by
0180  *         SCMI platform. Set to zero when not available.
0181  */
0182 struct scmi_sensor_reading {
0183     long long value;
0184     unsigned long long timestamp;
0185 };
0186 
0187 /**
0188  * struct scmi_range_attrs  - specifies a sensor or axis values' range
0189  * @min_range: The minimum value which can be represented by the sensor/axis.
0190  * @max_range: The maximum value which can be represented by the sensor/axis.
0191  */
0192 struct scmi_range_attrs {
0193     long long min_range;
0194     long long max_range;
0195 };
0196 
0197 /**
0198  * struct scmi_sensor_axis_info  - describes one sensor axes
0199  * @id: The axes ID.
0200  * @type: Axes type. Chosen amongst one of @enum scmi_sensor_class.
0201  * @scale: Power-of-10 multiplier applied to the axis unit.
0202  * @name: NULL-terminated string representing axes name as advertised by
0203  *    SCMI platform.
0204  * @extended_attrs: Flag to indicate the presence of additional extended
0205  *          attributes for this axes.
0206  * @resolution: Extended attribute representing the resolution of the axes.
0207  *      Set to 0 if not reported by this axes.
0208  * @exponent: Extended attribute representing the power-of-10 multiplier that
0209  *        is applied to the resolution field. Set to 0 if not reported by
0210  *        this axes.
0211  * @attrs: Extended attributes representing minimum and maximum values
0212  *     measurable by this axes. Set to 0 if not reported by this sensor.
0213  */
0214 struct scmi_sensor_axis_info {
0215     unsigned int id;
0216     unsigned int type;
0217     int scale;
0218     char name[SCMI_MAX_STR_SIZE];
0219     bool extended_attrs;
0220     unsigned int resolution;
0221     int exponent;
0222     struct scmi_range_attrs attrs;
0223 };
0224 
0225 /**
0226  * struct scmi_sensor_intervals_info  - describes number and type of available
0227  *  update intervals
0228  * @segmented: Flag for segmented intervals' representation. When True there
0229  *         will be exactly 3 intervals in @desc, with each entry
0230  *         representing a member of a segment in this order:
0231  *         {lowest update interval, highest update interval, step size}
0232  * @count: Number of intervals described in @desc.
0233  * @desc: Array of @count interval descriptor bitmask represented as detailed in
0234  *    the SCMI specification: it can be accessed using the accompanying
0235  *    macros.
0236  * @prealloc_pool: A minimal preallocated pool of desc entries used to avoid
0237  *         lesser-than-64-bytes dynamic allocation for small @count
0238  *         values.
0239  */
0240 struct scmi_sensor_intervals_info {
0241     bool segmented;
0242     unsigned int count;
0243 #define SCMI_SENS_INTVL_SEGMENT_LOW 0
0244 #define SCMI_SENS_INTVL_SEGMENT_HIGH    1
0245 #define SCMI_SENS_INTVL_SEGMENT_STEP    2
0246     unsigned int *desc;
0247 #define SCMI_SENS_INTVL_GET_SECS(x)     FIELD_GET(GENMASK(20, 5), (x))
0248 #define SCMI_SENS_INTVL_GET_EXP(x)                  \
0249     ({                              \
0250         int __signed_exp = FIELD_GET(GENMASK(4, 0), (x));   \
0251                                     \
0252         if (__signed_exp & BIT(4))              \
0253             __signed_exp |= GENMASK(31, 5);         \
0254         __signed_exp;                       \
0255     })
0256 #define SCMI_MAX_PREALLOC_POOL          16
0257     unsigned int prealloc_pool[SCMI_MAX_PREALLOC_POOL];
0258 };
0259 
0260 /**
0261  * struct scmi_sensor_info - represents information related to one of the
0262  * available sensors.
0263  * @id: Sensor ID.
0264  * @type: Sensor type. Chosen amongst one of @enum scmi_sensor_class.
0265  * @scale: Power-of-10 multiplier applied to the sensor unit.
0266  * @num_trip_points: Number of maximum configurable trip points.
0267  * @async: Flag for asynchronous read support.
0268  * @update: Flag for continuouos update notification support.
0269  * @timestamped: Flag for timestamped read support.
0270  * @tstamp_scale: Power-of-10 multiplier applied to the sensor timestamps to
0271  *        represent it in seconds.
0272  * @num_axis: Number of supported axis if any. Reported as 0 for scalar sensors.
0273  * @axis: Pointer to an array of @num_axis descriptors.
0274  * @intervals: Descriptor of available update intervals.
0275  * @sensor_config: A bitmask reporting the current sensor configuration as
0276  *         detailed in the SCMI specification: it can accessed and
0277  *         modified through the accompanying macros.
0278  * @name: NULL-terminated string representing sensor name as advertised by
0279  *    SCMI platform.
0280  * @extended_scalar_attrs: Flag to indicate the presence of additional extended
0281  *             attributes for this sensor.
0282  * @sensor_power: Extended attribute representing the average power
0283  *        consumed by the sensor in microwatts (uW) when it is active.
0284  *        Reported here only for scalar sensors.
0285  *        Set to 0 if not reported by this sensor.
0286  * @resolution: Extended attribute representing the resolution of the sensor.
0287  *      Reported here only for scalar sensors.
0288  *      Set to 0 if not reported by this sensor.
0289  * @exponent: Extended attribute representing the power-of-10 multiplier that is
0290  *        applied to the resolution field.
0291  *        Reported here only for scalar sensors.
0292  *        Set to 0 if not reported by this sensor.
0293  * @scalar_attrs: Extended attributes representing minimum and maximum
0294  *        measurable values by this sensor.
0295  *        Reported here only for scalar sensors.
0296  *        Set to 0 if not reported by this sensor.
0297  */
0298 struct scmi_sensor_info {
0299     unsigned int id;
0300     unsigned int type;
0301     int scale;
0302     unsigned int num_trip_points;
0303     bool async;
0304     bool update;
0305     bool timestamped;
0306     int tstamp_scale;
0307     unsigned int num_axis;
0308     struct scmi_sensor_axis_info *axis;
0309     struct scmi_sensor_intervals_info intervals;
0310     unsigned int sensor_config;
0311 #define SCMI_SENS_CFG_UPDATE_SECS_MASK      GENMASK(31, 16)
0312 #define SCMI_SENS_CFG_GET_UPDATE_SECS(x)                \
0313     FIELD_GET(SCMI_SENS_CFG_UPDATE_SECS_MASK, (x))
0314 
0315 #define SCMI_SENS_CFG_UPDATE_EXP_MASK       GENMASK(15, 11)
0316 #define SCMI_SENS_CFG_GET_UPDATE_EXP(x)                 \
0317     ({                              \
0318         int __signed_exp =                  \
0319             FIELD_GET(SCMI_SENS_CFG_UPDATE_EXP_MASK, (x));  \
0320                                     \
0321         if (__signed_exp & BIT(4))              \
0322             __signed_exp |= GENMASK(31, 5);         \
0323         __signed_exp;                       \
0324     })
0325 
0326 #define SCMI_SENS_CFG_ROUND_MASK        GENMASK(10, 9)
0327 #define SCMI_SENS_CFG_ROUND_AUTO        2
0328 #define SCMI_SENS_CFG_ROUND_UP          1
0329 #define SCMI_SENS_CFG_ROUND_DOWN        0
0330 
0331 #define SCMI_SENS_CFG_TSTAMP_ENABLED_MASK   BIT(1)
0332 #define SCMI_SENS_CFG_TSTAMP_ENABLE     1
0333 #define SCMI_SENS_CFG_TSTAMP_DISABLE        0
0334 #define SCMI_SENS_CFG_IS_TSTAMP_ENABLED(x)              \
0335     FIELD_GET(SCMI_SENS_CFG_TSTAMP_ENABLED_MASK, (x))
0336 
0337 #define SCMI_SENS_CFG_SENSOR_ENABLED_MASK   BIT(0)
0338 #define SCMI_SENS_CFG_SENSOR_ENABLE     1
0339 #define SCMI_SENS_CFG_SENSOR_DISABLE        0
0340     char name[SCMI_MAX_STR_SIZE];
0341 #define SCMI_SENS_CFG_IS_ENABLED(x)     FIELD_GET(BIT(0), (x))
0342     bool extended_scalar_attrs;
0343     unsigned int sensor_power;
0344     unsigned int resolution;
0345     int exponent;
0346     struct scmi_range_attrs scalar_attrs;
0347 };
0348 
0349 /*
0350  * Partial list from Distributed Management Task Force (DMTF) specification:
0351  * DSP0249 (Platform Level Data Model specification)
0352  */
0353 enum scmi_sensor_class {
0354     NONE = 0x0,
0355     UNSPEC = 0x1,
0356     TEMPERATURE_C = 0x2,
0357     TEMPERATURE_F = 0x3,
0358     TEMPERATURE_K = 0x4,
0359     VOLTAGE = 0x5,
0360     CURRENT = 0x6,
0361     POWER = 0x7,
0362     ENERGY = 0x8,
0363     CHARGE = 0x9,
0364     VOLTAMPERE = 0xA,
0365     NITS = 0xB,
0366     LUMENS = 0xC,
0367     LUX = 0xD,
0368     CANDELAS = 0xE,
0369     KPA = 0xF,
0370     PSI = 0x10,
0371     NEWTON = 0x11,
0372     CFM = 0x12,
0373     RPM = 0x13,
0374     HERTZ = 0x14,
0375     SECS = 0x15,
0376     MINS = 0x16,
0377     HOURS = 0x17,
0378     DAYS = 0x18,
0379     WEEKS = 0x19,
0380     MILS = 0x1A,
0381     INCHES = 0x1B,
0382     FEET = 0x1C,
0383     CUBIC_INCHES = 0x1D,
0384     CUBIC_FEET = 0x1E,
0385     METERS = 0x1F,
0386     CUBIC_CM = 0x20,
0387     CUBIC_METERS = 0x21,
0388     LITERS = 0x22,
0389     FLUID_OUNCES = 0x23,
0390     RADIANS = 0x24,
0391     STERADIANS = 0x25,
0392     REVOLUTIONS = 0x26,
0393     CYCLES = 0x27,
0394     GRAVITIES = 0x28,
0395     OUNCES = 0x29,
0396     POUNDS = 0x2A,
0397     FOOT_POUNDS = 0x2B,
0398     OUNCE_INCHES = 0x2C,
0399     GAUSS = 0x2D,
0400     GILBERTS = 0x2E,
0401     HENRIES = 0x2F,
0402     FARADS = 0x30,
0403     OHMS = 0x31,
0404     SIEMENS = 0x32,
0405     MOLES = 0x33,
0406     BECQUERELS = 0x34,
0407     PPM = 0x35,
0408     DECIBELS = 0x36,
0409     DBA = 0x37,
0410     DBC = 0x38,
0411     GRAYS = 0x39,
0412     SIEVERTS = 0x3A,
0413     COLOR_TEMP_K = 0x3B,
0414     BITS = 0x3C,
0415     BYTES = 0x3D,
0416     WORDS = 0x3E,
0417     DWORDS = 0x3F,
0418     QWORDS = 0x40,
0419     PERCENTAGE = 0x41,
0420     PASCALS = 0x42,
0421     COUNTS = 0x43,
0422     GRAMS = 0x44,
0423     NEWTON_METERS = 0x45,
0424     HITS = 0x46,
0425     MISSES = 0x47,
0426     RETRIES = 0x48,
0427     OVERRUNS = 0x49,
0428     UNDERRUNS = 0x4A,
0429     COLLISIONS = 0x4B,
0430     PACKETS = 0x4C,
0431     MESSAGES = 0x4D,
0432     CHARS = 0x4E,
0433     ERRORS = 0x4F,
0434     CORRECTED_ERRS = 0x50,
0435     UNCORRECTABLE_ERRS = 0x51,
0436     SQ_MILS = 0x52,
0437     SQ_INCHES = 0x53,
0438     SQ_FEET = 0x54,
0439     SQ_CM = 0x55,
0440     SQ_METERS = 0x56,
0441     RADIANS_SEC = 0x57,
0442     BPM = 0x58,
0443     METERS_SEC_SQUARED = 0x59,
0444     METERS_SEC = 0x5A,
0445     CUBIC_METERS_SEC = 0x5B,
0446     MM_MERCURY = 0x5C,
0447     RADIANS_SEC_SQUARED = 0x5D,
0448     OEM_UNIT = 0xFF
0449 };
0450 
0451 /**
0452  * struct scmi_sensor_proto_ops - represents the various operations provided
0453  *  by SCMI Sensor Protocol
0454  *
0455  * @count_get: get the count of sensors provided by SCMI
0456  * @info_get: get the information of the specified sensor
0457  * @trip_point_config: selects and configures a trip-point of interest
0458  * @reading_get: gets the current value of the sensor
0459  * @reading_get_timestamped: gets the current value and timestamp, when
0460  *               available, of the sensor. (as of v3.0 spec)
0461  *               Supports multi-axis sensors for sensors which
0462  *               supports it and if the @reading array size of
0463  *               @count entry equals the sensor num_axis
0464  * @config_get: Get sensor current configuration
0465  * @config_set: Set sensor current configuration
0466  */
0467 struct scmi_sensor_proto_ops {
0468     int (*count_get)(const struct scmi_protocol_handle *ph);
0469     const struct scmi_sensor_info __must_check *(*info_get)
0470         (const struct scmi_protocol_handle *ph, u32 sensor_id);
0471     int (*trip_point_config)(const struct scmi_protocol_handle *ph,
0472                  u32 sensor_id, u8 trip_id, u64 trip_value);
0473     int (*reading_get)(const struct scmi_protocol_handle *ph, u32 sensor_id,
0474                u64 *value);
0475     int (*reading_get_timestamped)(const struct scmi_protocol_handle *ph,
0476                        u32 sensor_id, u8 count,
0477                        struct scmi_sensor_reading *readings);
0478     int (*config_get)(const struct scmi_protocol_handle *ph,
0479               u32 sensor_id, u32 *sensor_config);
0480     int (*config_set)(const struct scmi_protocol_handle *ph,
0481               u32 sensor_id, u32 sensor_config);
0482 };
0483 
0484 /**
0485  * struct scmi_reset_proto_ops - represents the various operations provided
0486  *  by SCMI Reset Protocol
0487  *
0488  * @num_domains_get: get the count of reset domains provided by SCMI
0489  * @name_get: gets the name of a reset domain
0490  * @latency_get: gets the reset latency for the specified reset domain
0491  * @reset: resets the specified reset domain
0492  * @assert: explicitly assert reset signal of the specified reset domain
0493  * @deassert: explicitly deassert reset signal of the specified reset domain
0494  */
0495 struct scmi_reset_proto_ops {
0496     int (*num_domains_get)(const struct scmi_protocol_handle *ph);
0497     const char *(*name_get)(const struct scmi_protocol_handle *ph,
0498                 u32 domain);
0499     int (*latency_get)(const struct scmi_protocol_handle *ph, u32 domain);
0500     int (*reset)(const struct scmi_protocol_handle *ph, u32 domain);
0501     int (*assert)(const struct scmi_protocol_handle *ph, u32 domain);
0502     int (*deassert)(const struct scmi_protocol_handle *ph, u32 domain);
0503 };
0504 
0505 enum scmi_voltage_level_mode {
0506     SCMI_VOLTAGE_LEVEL_SET_AUTO,
0507     SCMI_VOLTAGE_LEVEL_SET_SYNC,
0508 };
0509 
0510 /**
0511  * struct scmi_voltage_info - describe one available SCMI Voltage Domain
0512  *
0513  * @id: the domain ID as advertised by the platform
0514  * @segmented: defines the layout of the entries of array @levels_uv.
0515  *         - when True the entries are to be interpreted as triplets,
0516  *           each defining a segment representing a range of equally
0517  *           space voltages: <lowest_volts>, <highest_volt>, <step_uV>
0518  *         - when False the entries simply represent a single discrete
0519  *           supported voltage level
0520  * @negative_volts_allowed: True if any of the entries of @levels_uv represent
0521  *              a negative voltage.
0522  * @async_level_set: True when the voltage domain supports asynchronous level
0523  *           set commands.
0524  * @name: name assigned to the Voltage Domain by platform
0525  * @num_levels: number of total entries in @levels_uv.
0526  * @levels_uv: array of entries describing the available voltage levels for
0527  *         this domain.
0528  */
0529 struct scmi_voltage_info {
0530     unsigned int id;
0531     bool segmented;
0532     bool negative_volts_allowed;
0533     bool async_level_set;
0534     char name[SCMI_MAX_STR_SIZE];
0535     unsigned int num_levels;
0536 #define SCMI_VOLTAGE_SEGMENT_LOW    0
0537 #define SCMI_VOLTAGE_SEGMENT_HIGH   1
0538 #define SCMI_VOLTAGE_SEGMENT_STEP   2
0539     int *levels_uv;
0540 };
0541 
0542 /**
0543  * struct scmi_voltage_proto_ops - represents the various operations provided
0544  * by SCMI Voltage Protocol
0545  *
0546  * @num_domains_get: get the count of voltage domains provided by SCMI
0547  * @info_get: get the information of the specified domain
0548  * @config_set: set the config for the specified domain
0549  * @config_get: get the config of the specified domain
0550  * @level_set: set the voltage level for the specified domain
0551  * @level_get: get the voltage level of the specified domain
0552  */
0553 struct scmi_voltage_proto_ops {
0554     int (*num_domains_get)(const struct scmi_protocol_handle *ph);
0555     const struct scmi_voltage_info __must_check *(*info_get)
0556         (const struct scmi_protocol_handle *ph, u32 domain_id);
0557     int (*config_set)(const struct scmi_protocol_handle *ph, u32 domain_id,
0558               u32 config);
0559 #define SCMI_VOLTAGE_ARCH_STATE_OFF     0x0
0560 #define SCMI_VOLTAGE_ARCH_STATE_ON      0x7
0561     int (*config_get)(const struct scmi_protocol_handle *ph, u32 domain_id,
0562               u32 *config);
0563     int (*level_set)(const struct scmi_protocol_handle *ph, u32 domain_id,
0564              enum scmi_voltage_level_mode mode, s32 volt_uV);
0565     int (*level_get)(const struct scmi_protocol_handle *ph, u32 domain_id,
0566              s32 *volt_uV);
0567 };
0568 
0569 /**
0570  * struct scmi_powercap_info  - Describe one available Powercap domain
0571  *
0572  * @id: Domain ID as advertised by the platform.
0573  * @notify_powercap_cap_change: CAP change notification support.
0574  * @notify_powercap_measurement_change: MEASUREMENTS change notifications
0575  *                     support.
0576  * @async_powercap_cap_set: Asynchronous CAP set support.
0577  * @powercap_cap_config: CAP configuration support.
0578  * @powercap_monitoring: Monitoring (measurements) support.
0579  * @powercap_pai_config: PAI configuration support.
0580  * @powercap_scale_mw: Domain reports power data in milliwatt units.
0581  * @powercap_scale_uw: Domain reports power data in microwatt units.
0582  *             Note that, when both @powercap_scale_mw and
0583  *             @powercap_scale_uw are set to false, the domain
0584  *             reports power data on an abstract linear scale.
0585  * @name: name assigned to the Powercap Domain by platform.
0586  * @min_pai: Minimum configurable PAI.
0587  * @max_pai: Maximum configurable PAI.
0588  * @pai_step: Step size between two consecutive PAI values.
0589  * @min_power_cap: Minimum configurable CAP.
0590  * @max_power_cap: Maximum configurable CAP.
0591  * @power_cap_step: Step size between two consecutive CAP values.
0592  * @sustainable_power: Maximum sustainable power consumption for this domain
0593  *             under normal conditions.
0594  * @accuracy: The accuracy with which the power is measured and reported in
0595  *        integral multiples of 0.001 percent.
0596  * @parent_id: Identifier of the containing parent power capping domain, or the
0597  *         value 0xFFFFFFFF if this powercap domain is a root domain not
0598  *         contained in any other domain.
0599  */
0600 struct scmi_powercap_info {
0601     unsigned int id;
0602     bool notify_powercap_cap_change;
0603     bool notify_powercap_measurement_change;
0604     bool async_powercap_cap_set;
0605     bool powercap_cap_config;
0606     bool powercap_monitoring;
0607     bool powercap_pai_config;
0608     bool powercap_scale_mw;
0609     bool powercap_scale_uw;
0610     bool fastchannels;
0611     char name[SCMI_MAX_STR_SIZE];
0612     unsigned int min_pai;
0613     unsigned int max_pai;
0614     unsigned int pai_step;
0615     unsigned int min_power_cap;
0616     unsigned int max_power_cap;
0617     unsigned int power_cap_step;
0618     unsigned int sustainable_power;
0619     unsigned int accuracy;
0620 #define SCMI_POWERCAP_ROOT_ZONE_ID     0xFFFFFFFFUL
0621     unsigned int parent_id;
0622     struct scmi_fc_info *fc_info;
0623 };
0624 
0625 /**
0626  * struct scmi_powercap_proto_ops - represents the various operations provided
0627  * by SCMI Powercap Protocol
0628  *
0629  * @num_domains_get: get the count of powercap domains provided by SCMI.
0630  * @info_get: get the information for the specified domain.
0631  * @cap_get: get the current CAP value for the specified domain.
0632  * @cap_set: set the CAP value for the specified domain to the provided value;
0633  *       if the domain supports setting the CAP with an asynchronous command
0634  *       this request will finally trigger an asynchronous transfer, but, if
0635  *       @ignore_dresp here is set to true, this call will anyway return
0636  *       immediately without waiting for the related delayed response.
0637  * @pai_get: get the current PAI value for the specified domain.
0638  * @pai_set: set the PAI value for the specified domain to the provided value.
0639  * @measurements_get: retrieve the current average power measurements for the
0640  *            specified domain and the related PAI upon which is
0641  *            calculated.
0642  * @measurements_threshold_set: set the desired low and high power thresholds
0643  *              to be used when registering for notification
0644  *              of type POWERCAP_MEASUREMENTS_NOTIFY with this
0645  *              powercap domain.
0646  *              Note that this must be called at least once
0647  *              before registering any callback with the usual
0648  *              @scmi_notify_ops; moreover, in case this method
0649  *              is called with measurement notifications already
0650  *              enabled it will also trigger, transparently, a
0651  *              proper update of the power thresholds configured
0652  *              in the SCMI backend server.
0653  * @measurements_threshold_get: get the currently configured low and high power
0654  *              thresholds used when registering callbacks for
0655  *              notification POWERCAP_MEASUREMENTS_NOTIFY.
0656  */
0657 struct scmi_powercap_proto_ops {
0658     int (*num_domains_get)(const struct scmi_protocol_handle *ph);
0659     const struct scmi_powercap_info __must_check *(*info_get)
0660         (const struct scmi_protocol_handle *ph, u32 domain_id);
0661     int (*cap_get)(const struct scmi_protocol_handle *ph, u32 domain_id,
0662                u32 *power_cap);
0663     int (*cap_set)(const struct scmi_protocol_handle *ph, u32 domain_id,
0664                u32 power_cap, bool ignore_dresp);
0665     int (*pai_get)(const struct scmi_protocol_handle *ph, u32 domain_id,
0666                u32 *pai);
0667     int (*pai_set)(const struct scmi_protocol_handle *ph, u32 domain_id,
0668                u32 pai);
0669     int (*measurements_get)(const struct scmi_protocol_handle *ph,
0670                 u32 domain_id, u32 *average_power, u32 *pai);
0671     int (*measurements_threshold_set)(const struct scmi_protocol_handle *ph,
0672                       u32 domain_id, u32 power_thresh_low,
0673                       u32 power_thresh_high);
0674     int (*measurements_threshold_get)(const struct scmi_protocol_handle *ph,
0675                       u32 domain_id, u32 *power_thresh_low,
0676                       u32 *power_thresh_high);
0677 };
0678 
0679 /**
0680  * struct scmi_notify_ops  - represents notifications' operations provided by
0681  * SCMI core
0682  * @devm_event_notifier_register: Managed registration of a notifier_block for
0683  *                the requested event
0684  * @devm_event_notifier_unregister: Managed unregistration of a notifier_block
0685  *                  for the requested event
0686  * @event_notifier_register: Register a notifier_block for the requested event
0687  * @event_notifier_unregister: Unregister a notifier_block for the requested
0688  *                 event
0689  *
0690  * A user can register/unregister its own notifier_block against the wanted
0691  * platform instance regarding the desired event identified by the
0692  * tuple: (proto_id, evt_id, src_id) using the provided register/unregister
0693  * interface where:
0694  *
0695  * @sdev: The scmi_device to use when calling the devres managed ops devm_
0696  * @handle: The handle identifying the platform instance to use, when not
0697  *      calling the managed ops devm_
0698  * @proto_id: The protocol ID as in SCMI Specification
0699  * @evt_id: The message ID of the desired event as in SCMI Specification
0700  * @src_id: A pointer to the desired source ID if different sources are
0701  *      possible for the protocol (like domain_id, sensor_id...etc)
0702  *
0703  * @src_id can be provided as NULL if it simply does NOT make sense for
0704  * the protocol at hand, OR if the user is explicitly interested in
0705  * receiving notifications from ANY existent source associated to the
0706  * specified proto_id / evt_id.
0707  *
0708  * Received notifications are finally delivered to the registered users,
0709  * invoking the callback provided with the notifier_block *nb as follows:
0710  *
0711  *  int user_cb(nb, evt_id, report)
0712  *
0713  * with:
0714  *
0715  * @nb: The notifier block provided by the user
0716  * @evt_id: The message ID of the delivered event
0717  * @report: A custom struct describing the specific event delivered
0718  */
0719 struct scmi_notify_ops {
0720     int (*devm_event_notifier_register)(struct scmi_device *sdev,
0721                         u8 proto_id, u8 evt_id,
0722                         const u32 *src_id,
0723                         struct notifier_block *nb);
0724     int (*devm_event_notifier_unregister)(struct scmi_device *sdev,
0725                           u8 proto_id, u8 evt_id,
0726                           const u32 *src_id,
0727                           struct notifier_block *nb);
0728     int (*event_notifier_register)(const struct scmi_handle *handle,
0729                        u8 proto_id, u8 evt_id,
0730                        const u32 *src_id,
0731                        struct notifier_block *nb);
0732     int (*event_notifier_unregister)(const struct scmi_handle *handle,
0733                      u8 proto_id, u8 evt_id,
0734                      const u32 *src_id,
0735                      struct notifier_block *nb);
0736 };
0737 
0738 /**
0739  * struct scmi_handle - Handle returned to ARM SCMI clients for usage.
0740  *
0741  * @dev: pointer to the SCMI device
0742  * @version: pointer to the structure containing SCMI version information
0743  * @devm_protocol_acquire: devres managed method to get hold of a protocol,
0744  *             causing its initialization and related resource
0745  *             accounting
0746  * @devm_protocol_get: devres managed method to acquire a protocol and get specific
0747  *             operations and a dedicated protocol handler
0748  * @devm_protocol_put: devres managed method to release a protocol
0749  * @is_transport_atomic: method to check if the underlying transport for this
0750  *           instance handle is configured to support atomic
0751  *           transactions for commands.
0752  *           Some users of the SCMI stack in the upper layers could
0753  *           be interested to know if they can assume SCMI
0754  *           command transactions associated to this handle will
0755  *           never sleep and act accordingly.
0756  *           An optional atomic threshold value could be returned
0757  *           where configured.
0758  * @notify_ops: pointer to set of notifications related operations
0759  */
0760 struct scmi_handle {
0761     struct device *dev;
0762     struct scmi_revision_info *version;
0763 
0764     int __must_check (*devm_protocol_acquire)(struct scmi_device *sdev,
0765                           u8 proto);
0766     const void __must_check *
0767         (*devm_protocol_get)(struct scmi_device *sdev, u8 proto,
0768                      struct scmi_protocol_handle **ph);
0769     void (*devm_protocol_put)(struct scmi_device *sdev, u8 proto);
0770     bool (*is_transport_atomic)(const struct scmi_handle *handle,
0771                     unsigned int *atomic_threshold);
0772 
0773     const struct scmi_notify_ops *notify_ops;
0774 };
0775 
0776 enum scmi_std_protocol {
0777     SCMI_PROTOCOL_BASE = 0x10,
0778     SCMI_PROTOCOL_POWER = 0x11,
0779     SCMI_PROTOCOL_SYSTEM = 0x12,
0780     SCMI_PROTOCOL_PERF = 0x13,
0781     SCMI_PROTOCOL_CLOCK = 0x14,
0782     SCMI_PROTOCOL_SENSOR = 0x15,
0783     SCMI_PROTOCOL_RESET = 0x16,
0784     SCMI_PROTOCOL_VOLTAGE = 0x17,
0785     SCMI_PROTOCOL_POWERCAP = 0x18,
0786 };
0787 
0788 enum scmi_system_events {
0789     SCMI_SYSTEM_SHUTDOWN,
0790     SCMI_SYSTEM_COLDRESET,
0791     SCMI_SYSTEM_WARMRESET,
0792     SCMI_SYSTEM_POWERUP,
0793     SCMI_SYSTEM_SUSPEND,
0794     SCMI_SYSTEM_MAX
0795 };
0796 
0797 struct scmi_device {
0798     u32 id;
0799     u8 protocol_id;
0800     const char *name;
0801     struct device dev;
0802     struct scmi_handle *handle;
0803 };
0804 
0805 #define to_scmi_dev(d) container_of(d, struct scmi_device, dev)
0806 
0807 struct scmi_device *
0808 scmi_device_create(struct device_node *np, struct device *parent, int protocol,
0809            const char *name);
0810 void scmi_device_destroy(struct scmi_device *scmi_dev);
0811 
0812 struct scmi_device_id {
0813     u8 protocol_id;
0814     const char *name;
0815 };
0816 
0817 struct scmi_driver {
0818     const char *name;
0819     int (*probe)(struct scmi_device *sdev);
0820     void (*remove)(struct scmi_device *sdev);
0821     const struct scmi_device_id *id_table;
0822 
0823     struct device_driver driver;
0824 };
0825 
0826 #define to_scmi_driver(d) container_of(d, struct scmi_driver, driver)
0827 
0828 #if IS_REACHABLE(CONFIG_ARM_SCMI_PROTOCOL)
0829 int scmi_driver_register(struct scmi_driver *driver,
0830              struct module *owner, const char *mod_name);
0831 void scmi_driver_unregister(struct scmi_driver *driver);
0832 #else
0833 static inline int
0834 scmi_driver_register(struct scmi_driver *driver, struct module *owner,
0835              const char *mod_name)
0836 {
0837     return -EINVAL;
0838 }
0839 
0840 static inline void scmi_driver_unregister(struct scmi_driver *driver) {}
0841 #endif /* CONFIG_ARM_SCMI_PROTOCOL */
0842 
0843 #define scmi_register(driver) \
0844     scmi_driver_register(driver, THIS_MODULE, KBUILD_MODNAME)
0845 #define scmi_unregister(driver) \
0846     scmi_driver_unregister(driver)
0847 
0848 /**
0849  * module_scmi_driver() - Helper macro for registering a scmi driver
0850  * @__scmi_driver: scmi_driver structure
0851  *
0852  * Helper macro for scmi drivers to set up proper module init / exit
0853  * functions.  Replaces module_init() and module_exit() and keeps people from
0854  * printing pointless things to the kernel log when their driver is loaded.
0855  */
0856 #define module_scmi_driver(__scmi_driver)   \
0857     module_driver(__scmi_driver, scmi_register, scmi_unregister)
0858 
0859 /**
0860  * module_scmi_protocol() - Helper macro for registering a scmi protocol
0861  * @__scmi_protocol: scmi_protocol structure
0862  *
0863  * Helper macro for scmi drivers to set up proper module init / exit
0864  * functions.  Replaces module_init() and module_exit() and keeps people from
0865  * printing pointless things to the kernel log when their driver is loaded.
0866  */
0867 #define module_scmi_protocol(__scmi_protocol)   \
0868     module_driver(__scmi_protocol,      \
0869               scmi_protocol_register, scmi_protocol_unregister)
0870 
0871 struct scmi_protocol;
0872 int scmi_protocol_register(const struct scmi_protocol *proto);
0873 void scmi_protocol_unregister(const struct scmi_protocol *proto);
0874 
0875 /* SCMI Notification API - Custom Event Reports */
0876 enum scmi_notification_events {
0877     SCMI_EVENT_POWER_STATE_CHANGED = 0x0,
0878     SCMI_EVENT_CLOCK_RATE_CHANGED = 0x0,
0879     SCMI_EVENT_CLOCK_RATE_CHANGE_REQUESTED = 0x1,
0880     SCMI_EVENT_PERFORMANCE_LIMITS_CHANGED = 0x0,
0881     SCMI_EVENT_PERFORMANCE_LEVEL_CHANGED = 0x1,
0882     SCMI_EVENT_SENSOR_TRIP_POINT_EVENT = 0x0,
0883     SCMI_EVENT_SENSOR_UPDATE = 0x1,
0884     SCMI_EVENT_RESET_ISSUED = 0x0,
0885     SCMI_EVENT_BASE_ERROR_EVENT = 0x0,
0886     SCMI_EVENT_SYSTEM_POWER_STATE_NOTIFIER = 0x0,
0887     SCMI_EVENT_POWERCAP_CAP_CHANGED = 0x0,
0888     SCMI_EVENT_POWERCAP_MEASUREMENTS_CHANGED = 0x1,
0889 };
0890 
0891 struct scmi_power_state_changed_report {
0892     ktime_t     timestamp;
0893     unsigned int    agent_id;
0894     unsigned int    domain_id;
0895     unsigned int    power_state;
0896 };
0897 
0898 struct scmi_clock_rate_notif_report {
0899     ktime_t         timestamp;
0900     unsigned int        agent_id;
0901     unsigned int        clock_id;
0902     unsigned long long  rate;
0903 };
0904 
0905 struct scmi_system_power_state_notifier_report {
0906     ktime_t     timestamp;
0907     unsigned int    agent_id;
0908 #define SCMI_SYSPOWER_IS_REQUEST_GRACEFUL(flags)    ((flags) & BIT(0))
0909     unsigned int    flags;
0910     unsigned int    system_state;
0911     unsigned int    timeout;
0912 };
0913 
0914 struct scmi_perf_limits_report {
0915     ktime_t     timestamp;
0916     unsigned int    agent_id;
0917     unsigned int    domain_id;
0918     unsigned int    range_max;
0919     unsigned int    range_min;
0920 };
0921 
0922 struct scmi_perf_level_report {
0923     ktime_t     timestamp;
0924     unsigned int    agent_id;
0925     unsigned int    domain_id;
0926     unsigned int    performance_level;
0927 };
0928 
0929 struct scmi_sensor_trip_point_report {
0930     ktime_t     timestamp;
0931     unsigned int    agent_id;
0932     unsigned int    sensor_id;
0933     unsigned int    trip_point_desc;
0934 };
0935 
0936 struct scmi_sensor_update_report {
0937     ktime_t             timestamp;
0938     unsigned int            agent_id;
0939     unsigned int            sensor_id;
0940     unsigned int            readings_count;
0941     struct scmi_sensor_reading  readings[];
0942 };
0943 
0944 struct scmi_reset_issued_report {
0945     ktime_t     timestamp;
0946     unsigned int    agent_id;
0947     unsigned int    domain_id;
0948     unsigned int    reset_state;
0949 };
0950 
0951 struct scmi_base_error_report {
0952     ktime_t         timestamp;
0953     unsigned int        agent_id;
0954     bool            fatal;
0955     unsigned int        cmd_count;
0956     unsigned long long  reports[];
0957 };
0958 
0959 struct scmi_powercap_cap_changed_report {
0960     ktime_t     timestamp;
0961     unsigned int    agent_id;
0962     unsigned int    domain_id;
0963     unsigned int    power_cap;
0964     unsigned int    pai;
0965 };
0966 
0967 struct scmi_powercap_meas_changed_report {
0968     ktime_t     timestamp;
0969     unsigned int    agent_id;
0970     unsigned int    domain_id;
0971     unsigned int    power;
0972 };
0973 #endif /* _LINUX_SCMI_PROTOCOL_H */