1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * SCMI Message Protocol driver header
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2018 ARM Ltd.
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun #ifndef _LINUX_SCMI_PROTOCOL_H
9*4882a593Smuzhiyun #define _LINUX_SCMI_PROTOCOL_H
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun #include <linux/bitfield.h>
12*4882a593Smuzhiyun #include <linux/device.h>
13*4882a593Smuzhiyun #include <linux/notifier.h>
14*4882a593Smuzhiyun #include <linux/types.h>
15*4882a593Smuzhiyun #include <linux/android_kabi.h>
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun #define SCMI_MAX_STR_SIZE 16
18*4882a593Smuzhiyun #define SCMI_MAX_NUM_RATES 16
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun /**
21*4882a593Smuzhiyun * struct scmi_revision_info - version information structure
22*4882a593Smuzhiyun *
23*4882a593Smuzhiyun * @major_ver: Major ABI version. Change here implies risk of backward
24*4882a593Smuzhiyun * compatibility break.
25*4882a593Smuzhiyun * @minor_ver: Minor ABI version. Change here implies new feature addition,
26*4882a593Smuzhiyun * or compatible change in ABI.
27*4882a593Smuzhiyun * @num_protocols: Number of protocols that are implemented, excluding the
28*4882a593Smuzhiyun * base protocol.
29*4882a593Smuzhiyun * @num_agents: Number of agents in the system.
30*4882a593Smuzhiyun * @impl_ver: A vendor-specific implementation version.
31*4882a593Smuzhiyun * @vendor_id: A vendor identifier(Null terminated ASCII string)
32*4882a593Smuzhiyun * @sub_vendor_id: A sub-vendor identifier(Null terminated ASCII string)
33*4882a593Smuzhiyun */
34*4882a593Smuzhiyun struct scmi_revision_info {
35*4882a593Smuzhiyun u16 major_ver;
36*4882a593Smuzhiyun u16 minor_ver;
37*4882a593Smuzhiyun u8 num_protocols;
38*4882a593Smuzhiyun u8 num_agents;
39*4882a593Smuzhiyun u32 impl_ver;
40*4882a593Smuzhiyun char vendor_id[SCMI_MAX_STR_SIZE];
41*4882a593Smuzhiyun char sub_vendor_id[SCMI_MAX_STR_SIZE];
42*4882a593Smuzhiyun };
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun struct scmi_clock_info {
45*4882a593Smuzhiyun char name[SCMI_MAX_STR_SIZE];
46*4882a593Smuzhiyun bool rate_discrete;
47*4882a593Smuzhiyun union {
48*4882a593Smuzhiyun struct {
49*4882a593Smuzhiyun int num_rates;
50*4882a593Smuzhiyun u64 rates[SCMI_MAX_NUM_RATES];
51*4882a593Smuzhiyun } list;
52*4882a593Smuzhiyun struct {
53*4882a593Smuzhiyun u64 min_rate;
54*4882a593Smuzhiyun u64 max_rate;
55*4882a593Smuzhiyun u64 step_size;
56*4882a593Smuzhiyun } range;
57*4882a593Smuzhiyun };
58*4882a593Smuzhiyun };
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun struct scmi_handle;
61*4882a593Smuzhiyun struct scmi_device;
62*4882a593Smuzhiyun struct scmi_protocol_handle;
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun /**
65*4882a593Smuzhiyun * struct scmi_clk_proto_ops - represents the various operations provided
66*4882a593Smuzhiyun * by SCMI Clock Protocol
67*4882a593Smuzhiyun *
68*4882a593Smuzhiyun * @count_get: get the count of clocks provided by SCMI
69*4882a593Smuzhiyun * @info_get: get the information of the specified clock
70*4882a593Smuzhiyun * @rate_get: request the current clock rate of a clock
71*4882a593Smuzhiyun * @rate_set: set the clock rate of a clock
72*4882a593Smuzhiyun * @enable: enables the specified clock
73*4882a593Smuzhiyun * @disable: disables the specified clock
74*4882a593Smuzhiyun */
75*4882a593Smuzhiyun struct scmi_clk_proto_ops {
76*4882a593Smuzhiyun int (*count_get)(const struct scmi_protocol_handle *ph);
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun const struct scmi_clock_info *(*info_get)
79*4882a593Smuzhiyun (const struct scmi_protocol_handle *ph, u32 clk_id);
80*4882a593Smuzhiyun int (*rate_get)(const struct scmi_protocol_handle *ph, u32 clk_id,
81*4882a593Smuzhiyun u64 *rate);
82*4882a593Smuzhiyun int (*rate_set)(const struct scmi_protocol_handle *ph, u32 clk_id,
83*4882a593Smuzhiyun u64 rate);
84*4882a593Smuzhiyun int (*enable)(const struct scmi_protocol_handle *ph, u32 clk_id);
85*4882a593Smuzhiyun int (*disable)(const struct scmi_protocol_handle *ph, u32 clk_id);
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun ANDROID_KABI_RESERVE(1);
88*4882a593Smuzhiyun };
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun /**
91*4882a593Smuzhiyun * struct scmi_perf_proto_ops - represents the various operations provided
92*4882a593Smuzhiyun * by SCMI Performance Protocol
93*4882a593Smuzhiyun *
94*4882a593Smuzhiyun * @limits_set: sets limits on the performance level of a domain
95*4882a593Smuzhiyun * @limits_get: gets limits on the performance level of a domain
96*4882a593Smuzhiyun * @level_set: sets the performance level of a domain
97*4882a593Smuzhiyun * @level_get: gets the performance level of a domain
98*4882a593Smuzhiyun * @device_domain_id: gets the scmi domain id for a given device
99*4882a593Smuzhiyun * @transition_latency_get: gets the DVFS transition latency for a given device
100*4882a593Smuzhiyun * @device_opps_add: adds all the OPPs for a given device
101*4882a593Smuzhiyun * @freq_set: sets the frequency for a given device using sustained frequency
102*4882a593Smuzhiyun * to sustained performance level mapping
103*4882a593Smuzhiyun * @freq_get: gets the frequency for a given device using sustained frequency
104*4882a593Smuzhiyun * to sustained performance level mapping
105*4882a593Smuzhiyun * @est_power_get: gets the estimated power cost for a given performance domain
106*4882a593Smuzhiyun * at a given frequency
107*4882a593Smuzhiyun */
108*4882a593Smuzhiyun struct scmi_perf_proto_ops {
109*4882a593Smuzhiyun int (*limits_set)(const struct scmi_protocol_handle *ph, u32 domain,
110*4882a593Smuzhiyun u32 max_perf, u32 min_perf);
111*4882a593Smuzhiyun int (*limits_get)(const struct scmi_protocol_handle *ph, u32 domain,
112*4882a593Smuzhiyun u32 *max_perf, u32 *min_perf);
113*4882a593Smuzhiyun int (*level_set)(const struct scmi_protocol_handle *ph, u32 domain,
114*4882a593Smuzhiyun u32 level, bool poll);
115*4882a593Smuzhiyun int (*level_get)(const struct scmi_protocol_handle *ph, u32 domain,
116*4882a593Smuzhiyun u32 *level, bool poll);
117*4882a593Smuzhiyun int (*device_domain_id)(struct device *dev);
118*4882a593Smuzhiyun int (*transition_latency_get)(const struct scmi_protocol_handle *ph,
119*4882a593Smuzhiyun struct device *dev);
120*4882a593Smuzhiyun int (*device_opps_add)(const struct scmi_protocol_handle *ph,
121*4882a593Smuzhiyun struct device *dev);
122*4882a593Smuzhiyun int (*freq_set)(const struct scmi_protocol_handle *ph, u32 domain,
123*4882a593Smuzhiyun unsigned long rate, bool poll);
124*4882a593Smuzhiyun int (*freq_get)(const struct scmi_protocol_handle *ph, u32 domain,
125*4882a593Smuzhiyun unsigned long *rate, bool poll);
126*4882a593Smuzhiyun int (*est_power_get)(const struct scmi_protocol_handle *ph, u32 domain,
127*4882a593Smuzhiyun unsigned long *rate, unsigned long *power);
128*4882a593Smuzhiyun bool (*fast_switch_possible)(const struct scmi_protocol_handle *ph,
129*4882a593Smuzhiyun struct device *dev);
130*4882a593Smuzhiyun bool (*power_scale_mw_get)(const struct scmi_protocol_handle *ph);
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun ANDROID_KABI_RESERVE(1);
133*4882a593Smuzhiyun };
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun /**
136*4882a593Smuzhiyun * struct scmi_power_proto_ops - represents the various operations provided
137*4882a593Smuzhiyun * by SCMI Power Protocol
138*4882a593Smuzhiyun *
139*4882a593Smuzhiyun * @num_domains_get: get the count of power domains provided by SCMI
140*4882a593Smuzhiyun * @name_get: gets the name of a power domain
141*4882a593Smuzhiyun * @state_set: sets the power state of a power domain
142*4882a593Smuzhiyun * @state_get: gets the power state of a power domain
143*4882a593Smuzhiyun */
144*4882a593Smuzhiyun struct scmi_power_proto_ops {
145*4882a593Smuzhiyun int (*num_domains_get)(const struct scmi_protocol_handle *ph);
146*4882a593Smuzhiyun char *(*name_get)(const struct scmi_protocol_handle *ph, u32 domain);
147*4882a593Smuzhiyun #define SCMI_POWER_STATE_TYPE_SHIFT 30
148*4882a593Smuzhiyun #define SCMI_POWER_STATE_ID_MASK (BIT(28) - 1)
149*4882a593Smuzhiyun #define SCMI_POWER_STATE_PARAM(type, id) \
150*4882a593Smuzhiyun ((((type) & BIT(0)) << SCMI_POWER_STATE_TYPE_SHIFT) | \
151*4882a593Smuzhiyun ((id) & SCMI_POWER_STATE_ID_MASK))
152*4882a593Smuzhiyun #define SCMI_POWER_STATE_GENERIC_ON SCMI_POWER_STATE_PARAM(0, 0)
153*4882a593Smuzhiyun #define SCMI_POWER_STATE_GENERIC_OFF SCMI_POWER_STATE_PARAM(1, 0)
154*4882a593Smuzhiyun int (*state_set)(const struct scmi_protocol_handle *ph, u32 domain,
155*4882a593Smuzhiyun u32 state);
156*4882a593Smuzhiyun int (*state_get)(const struct scmi_protocol_handle *ph, u32 domain,
157*4882a593Smuzhiyun u32 *state);
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun ANDROID_KABI_RESERVE(1);
160*4882a593Smuzhiyun };
161*4882a593Smuzhiyun
162*4882a593Smuzhiyun /**
163*4882a593Smuzhiyun * scmi_sensor_reading - represent a timestamped read
164*4882a593Smuzhiyun *
165*4882a593Smuzhiyun * Used by @reading_get_timestamped method.
166*4882a593Smuzhiyun *
167*4882a593Smuzhiyun * @value: The signed value sensor read.
168*4882a593Smuzhiyun * @timestamp: An unsigned timestamp for the sensor read, as provided by
169*4882a593Smuzhiyun * SCMI platform. Set to zero when not available.
170*4882a593Smuzhiyun */
171*4882a593Smuzhiyun struct scmi_sensor_reading {
172*4882a593Smuzhiyun long long value;
173*4882a593Smuzhiyun unsigned long long timestamp;
174*4882a593Smuzhiyun };
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun /**
177*4882a593Smuzhiyun * scmi_range_attrs - specifies a sensor or axis values' range
178*4882a593Smuzhiyun * @min_range: The minimum value which can be represented by the sensor/axis.
179*4882a593Smuzhiyun * @max_range: The maximum value which can be represented by the sensor/axis.
180*4882a593Smuzhiyun */
181*4882a593Smuzhiyun struct scmi_range_attrs {
182*4882a593Smuzhiyun long long min_range;
183*4882a593Smuzhiyun long long max_range;
184*4882a593Smuzhiyun };
185*4882a593Smuzhiyun
186*4882a593Smuzhiyun /**
187*4882a593Smuzhiyun * scmi_sensor_axis_info - describes one sensor axes
188*4882a593Smuzhiyun * @id: The axes ID.
189*4882a593Smuzhiyun * @type: Axes type. Chosen amongst one of @enum scmi_sensor_class.
190*4882a593Smuzhiyun * @scale: Power-of-10 multiplier applied to the axis unit.
191*4882a593Smuzhiyun * @name: NULL-terminated string representing axes name as advertised by
192*4882a593Smuzhiyun * SCMI platform.
193*4882a593Smuzhiyun * @extended_attrs: Flag to indicate the presence of additional extended
194*4882a593Smuzhiyun * attributes for this axes.
195*4882a593Smuzhiyun * @resolution: Extended attribute representing the resolution of the axes.
196*4882a593Smuzhiyun * Set to 0 if not reported by this axes.
197*4882a593Smuzhiyun * @exponent: Extended attribute representing the power-of-10 multiplier that
198*4882a593Smuzhiyun * is applied to the resolution field. Set to 0 if not reported by
199*4882a593Smuzhiyun * this axes.
200*4882a593Smuzhiyun * @attrs: Extended attributes representing minimum and maximum values
201*4882a593Smuzhiyun * measurable by this axes. Set to 0 if not reported by this sensor.
202*4882a593Smuzhiyun */
203*4882a593Smuzhiyun struct scmi_sensor_axis_info {
204*4882a593Smuzhiyun unsigned int id;
205*4882a593Smuzhiyun unsigned int type;
206*4882a593Smuzhiyun int scale;
207*4882a593Smuzhiyun char name[SCMI_MAX_STR_SIZE];
208*4882a593Smuzhiyun bool extended_attrs;
209*4882a593Smuzhiyun unsigned int resolution;
210*4882a593Smuzhiyun int exponent;
211*4882a593Smuzhiyun struct scmi_range_attrs attrs;
212*4882a593Smuzhiyun };
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun /**
215*4882a593Smuzhiyun * scmi_sensor_intervals_info - describes number and type of available update
216*4882a593Smuzhiyun * intervals
217*4882a593Smuzhiyun * @segmented: Flag for segmented intervals' representation. When True there
218*4882a593Smuzhiyun * will be exactly 3 intervals in @desc, with each entry
219*4882a593Smuzhiyun * representing a member of a segment in this order:
220*4882a593Smuzhiyun * {lowest update interval, highest update interval, step size}
221*4882a593Smuzhiyun * @count: Number of intervals described in @desc.
222*4882a593Smuzhiyun * @desc: Array of @count interval descriptor bitmask represented as detailed in
223*4882a593Smuzhiyun * the SCMI specification: it can be accessed using the accompanying
224*4882a593Smuzhiyun * macros.
225*4882a593Smuzhiyun * @prealloc_pool: A minimal preallocated pool of desc entries used to avoid
226*4882a593Smuzhiyun * lesser-than-64-bytes dynamic allocation for small @count
227*4882a593Smuzhiyun * values.
228*4882a593Smuzhiyun */
229*4882a593Smuzhiyun struct scmi_sensor_intervals_info {
230*4882a593Smuzhiyun bool segmented;
231*4882a593Smuzhiyun unsigned int count;
232*4882a593Smuzhiyun #define SCMI_SENS_INTVL_SEGMENT_LOW 0
233*4882a593Smuzhiyun #define SCMI_SENS_INTVL_SEGMENT_HIGH 1
234*4882a593Smuzhiyun #define SCMI_SENS_INTVL_SEGMENT_STEP 2
235*4882a593Smuzhiyun unsigned int *desc;
236*4882a593Smuzhiyun #define SCMI_SENS_INTVL_GET_SECS(x) FIELD_GET(GENMASK(20, 5), (x))
237*4882a593Smuzhiyun #define SCMI_SENS_INTVL_GET_EXP(x) \
238*4882a593Smuzhiyun ({ \
239*4882a593Smuzhiyun int __signed_exp = FIELD_GET(GENMASK(4, 0), (x)); \
240*4882a593Smuzhiyun \
241*4882a593Smuzhiyun if (__signed_exp & BIT(4)) \
242*4882a593Smuzhiyun __signed_exp |= GENMASK(31, 5); \
243*4882a593Smuzhiyun __signed_exp; \
244*4882a593Smuzhiyun })
245*4882a593Smuzhiyun #define SCMI_MAX_PREALLOC_POOL 16
246*4882a593Smuzhiyun unsigned int prealloc_pool[SCMI_MAX_PREALLOC_POOL];
247*4882a593Smuzhiyun };
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun /**
250*4882a593Smuzhiyun * struct scmi_sensor_info - represents information related to one of the
251*4882a593Smuzhiyun * available sensors.
252*4882a593Smuzhiyun * @id: Sensor ID.
253*4882a593Smuzhiyun * @type: Sensor type. Chosen amongst one of @enum scmi_sensor_class.
254*4882a593Smuzhiyun * @scale: Power-of-10 multiplier applied to the sensor unit.
255*4882a593Smuzhiyun * @num_trip_points: Number of maximum configurable trip points.
256*4882a593Smuzhiyun * @async: Flag for asynchronous read support.
257*4882a593Smuzhiyun * @update: Flag for continuouos update notification support.
258*4882a593Smuzhiyun * @timestamped: Flag for timestamped read support.
259*4882a593Smuzhiyun * @tstamp_scale: Power-of-10 multiplier applied to the sensor timestamps to
260*4882a593Smuzhiyun * represent it in seconds.
261*4882a593Smuzhiyun * @num_axis: Number of supported axis if any. Reported as 0 for scalar sensors.
262*4882a593Smuzhiyun * @axis: Pointer to an array of @num_axis descriptors.
263*4882a593Smuzhiyun * @intervals: Descriptor of available update intervals.
264*4882a593Smuzhiyun * @sensor_config: A bitmask reporting the current sensor configuration as
265*4882a593Smuzhiyun * detailed in the SCMI specification: it can accessed and
266*4882a593Smuzhiyun * modified through the accompanying macros.
267*4882a593Smuzhiyun * @name: NULL-terminated string representing sensor name as advertised by
268*4882a593Smuzhiyun * SCMI platform.
269*4882a593Smuzhiyun * @extended_scalar_attrs: Flag to indicate the presence of additional extended
270*4882a593Smuzhiyun * attributes for this sensor.
271*4882a593Smuzhiyun * @sensor_power: Extended attribute representing the average power
272*4882a593Smuzhiyun * consumed by the sensor in microwatts (uW) when it is active.
273*4882a593Smuzhiyun * Reported here only for scalar sensors.
274*4882a593Smuzhiyun * Set to 0 if not reported by this sensor.
275*4882a593Smuzhiyun * @resolution: Extended attribute representing the resolution of the sensor.
276*4882a593Smuzhiyun * Reported here only for scalar sensors.
277*4882a593Smuzhiyun * Set to 0 if not reported by this sensor.
278*4882a593Smuzhiyun * @exponent: Extended attribute representing the power-of-10 multiplier that is
279*4882a593Smuzhiyun * applied to the resolution field.
280*4882a593Smuzhiyun * Reported here only for scalar sensors.
281*4882a593Smuzhiyun * Set to 0 if not reported by this sensor.
282*4882a593Smuzhiyun * @scalar_attrs: Extended attributes representing minimum and maximum
283*4882a593Smuzhiyun * measurable values by this sensor.
284*4882a593Smuzhiyun * Reported here only for scalar sensors.
285*4882a593Smuzhiyun * Set to 0 if not reported by this sensor.
286*4882a593Smuzhiyun */
287*4882a593Smuzhiyun struct scmi_sensor_info {
288*4882a593Smuzhiyun unsigned int id;
289*4882a593Smuzhiyun unsigned int type;
290*4882a593Smuzhiyun int scale;
291*4882a593Smuzhiyun unsigned int num_trip_points;
292*4882a593Smuzhiyun bool async;
293*4882a593Smuzhiyun bool update;
294*4882a593Smuzhiyun bool timestamped;
295*4882a593Smuzhiyun int tstamp_scale;
296*4882a593Smuzhiyun unsigned int num_axis;
297*4882a593Smuzhiyun struct scmi_sensor_axis_info *axis;
298*4882a593Smuzhiyun struct scmi_sensor_intervals_info intervals;
299*4882a593Smuzhiyun unsigned int sensor_config;
300*4882a593Smuzhiyun #define SCMI_SENS_CFG_UPDATE_SECS_MASK GENMASK(31, 16)
301*4882a593Smuzhiyun #define SCMI_SENS_CFG_GET_UPDATE_SECS(x) \
302*4882a593Smuzhiyun FIELD_GET(SCMI_SENS_CFG_UPDATE_SECS_MASK, (x))
303*4882a593Smuzhiyun
304*4882a593Smuzhiyun #define SCMI_SENS_CFG_UPDATE_EXP_MASK GENMASK(15, 11)
305*4882a593Smuzhiyun #define SCMI_SENS_CFG_GET_UPDATE_EXP(x) \
306*4882a593Smuzhiyun ({ \
307*4882a593Smuzhiyun int __signed_exp = \
308*4882a593Smuzhiyun FIELD_GET(SCMI_SENS_CFG_UPDATE_EXP_MASK, (x)); \
309*4882a593Smuzhiyun \
310*4882a593Smuzhiyun if (__signed_exp & BIT(4)) \
311*4882a593Smuzhiyun __signed_exp |= GENMASK(31, 5); \
312*4882a593Smuzhiyun __signed_exp; \
313*4882a593Smuzhiyun })
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun #define SCMI_SENS_CFG_ROUND_MASK GENMASK(10, 9)
316*4882a593Smuzhiyun #define SCMI_SENS_CFG_ROUND_AUTO 2
317*4882a593Smuzhiyun #define SCMI_SENS_CFG_ROUND_UP 1
318*4882a593Smuzhiyun #define SCMI_SENS_CFG_ROUND_DOWN 0
319*4882a593Smuzhiyun
320*4882a593Smuzhiyun #define SCMI_SENS_CFG_TSTAMP_ENABLED_MASK BIT(1)
321*4882a593Smuzhiyun #define SCMI_SENS_CFG_TSTAMP_ENABLE 1
322*4882a593Smuzhiyun #define SCMI_SENS_CFG_TSTAMP_DISABLE 0
323*4882a593Smuzhiyun #define SCMI_SENS_CFG_IS_TSTAMP_ENABLED(x) \
324*4882a593Smuzhiyun FIELD_GET(SCMI_SENS_CFG_TSTAMP_ENABLED_MASK, (x))
325*4882a593Smuzhiyun
326*4882a593Smuzhiyun #define SCMI_SENS_CFG_SENSOR_ENABLED_MASK BIT(0)
327*4882a593Smuzhiyun #define SCMI_SENS_CFG_SENSOR_ENABLE 1
328*4882a593Smuzhiyun #define SCMI_SENS_CFG_SENSOR_DISABLE 0
329*4882a593Smuzhiyun char name[SCMI_MAX_STR_SIZE];
330*4882a593Smuzhiyun #define SCMI_SENS_CFG_IS_ENABLED(x) FIELD_GET(BIT(0), (x))
331*4882a593Smuzhiyun bool extended_scalar_attrs;
332*4882a593Smuzhiyun unsigned int sensor_power;
333*4882a593Smuzhiyun unsigned int resolution;
334*4882a593Smuzhiyun int exponent;
335*4882a593Smuzhiyun struct scmi_range_attrs scalar_attrs;
336*4882a593Smuzhiyun
337*4882a593Smuzhiyun ANDROID_KABI_RESERVE(1);
338*4882a593Smuzhiyun };
339*4882a593Smuzhiyun
340*4882a593Smuzhiyun /*
341*4882a593Smuzhiyun * Partial list from Distributed Management Task Force (DMTF) specification:
342*4882a593Smuzhiyun * DSP0249 (Platform Level Data Model specification)
343*4882a593Smuzhiyun */
344*4882a593Smuzhiyun enum scmi_sensor_class {
345*4882a593Smuzhiyun NONE = 0x0,
346*4882a593Smuzhiyun UNSPEC = 0x1,
347*4882a593Smuzhiyun TEMPERATURE_C = 0x2,
348*4882a593Smuzhiyun TEMPERATURE_F = 0x3,
349*4882a593Smuzhiyun TEMPERATURE_K = 0x4,
350*4882a593Smuzhiyun VOLTAGE = 0x5,
351*4882a593Smuzhiyun CURRENT = 0x6,
352*4882a593Smuzhiyun POWER = 0x7,
353*4882a593Smuzhiyun ENERGY = 0x8,
354*4882a593Smuzhiyun CHARGE = 0x9,
355*4882a593Smuzhiyun VOLTAMPERE = 0xA,
356*4882a593Smuzhiyun NITS = 0xB,
357*4882a593Smuzhiyun LUMENS = 0xC,
358*4882a593Smuzhiyun LUX = 0xD,
359*4882a593Smuzhiyun CANDELAS = 0xE,
360*4882a593Smuzhiyun KPA = 0xF,
361*4882a593Smuzhiyun PSI = 0x10,
362*4882a593Smuzhiyun NEWTON = 0x11,
363*4882a593Smuzhiyun CFM = 0x12,
364*4882a593Smuzhiyun RPM = 0x13,
365*4882a593Smuzhiyun HERTZ = 0x14,
366*4882a593Smuzhiyun SECS = 0x15,
367*4882a593Smuzhiyun MINS = 0x16,
368*4882a593Smuzhiyun HOURS = 0x17,
369*4882a593Smuzhiyun DAYS = 0x18,
370*4882a593Smuzhiyun WEEKS = 0x19,
371*4882a593Smuzhiyun MILS = 0x1A,
372*4882a593Smuzhiyun INCHES = 0x1B,
373*4882a593Smuzhiyun FEET = 0x1C,
374*4882a593Smuzhiyun CUBIC_INCHES = 0x1D,
375*4882a593Smuzhiyun CUBIC_FEET = 0x1E,
376*4882a593Smuzhiyun METERS = 0x1F,
377*4882a593Smuzhiyun CUBIC_CM = 0x20,
378*4882a593Smuzhiyun CUBIC_METERS = 0x21,
379*4882a593Smuzhiyun LITERS = 0x22,
380*4882a593Smuzhiyun FLUID_OUNCES = 0x23,
381*4882a593Smuzhiyun RADIANS = 0x24,
382*4882a593Smuzhiyun STERADIANS = 0x25,
383*4882a593Smuzhiyun REVOLUTIONS = 0x26,
384*4882a593Smuzhiyun CYCLES = 0x27,
385*4882a593Smuzhiyun GRAVITIES = 0x28,
386*4882a593Smuzhiyun OUNCES = 0x29,
387*4882a593Smuzhiyun POUNDS = 0x2A,
388*4882a593Smuzhiyun FOOT_POUNDS = 0x2B,
389*4882a593Smuzhiyun OUNCE_INCHES = 0x2C,
390*4882a593Smuzhiyun GAUSS = 0x2D,
391*4882a593Smuzhiyun GILBERTS = 0x2E,
392*4882a593Smuzhiyun HENRIES = 0x2F,
393*4882a593Smuzhiyun FARADS = 0x30,
394*4882a593Smuzhiyun OHMS = 0x31,
395*4882a593Smuzhiyun SIEMENS = 0x32,
396*4882a593Smuzhiyun MOLES = 0x33,
397*4882a593Smuzhiyun BECQUERELS = 0x34,
398*4882a593Smuzhiyun PPM = 0x35,
399*4882a593Smuzhiyun DECIBELS = 0x36,
400*4882a593Smuzhiyun DBA = 0x37,
401*4882a593Smuzhiyun DBC = 0x38,
402*4882a593Smuzhiyun GRAYS = 0x39,
403*4882a593Smuzhiyun SIEVERTS = 0x3A,
404*4882a593Smuzhiyun COLOR_TEMP_K = 0x3B,
405*4882a593Smuzhiyun BITS = 0x3C,
406*4882a593Smuzhiyun BYTES = 0x3D,
407*4882a593Smuzhiyun WORDS = 0x3E,
408*4882a593Smuzhiyun DWORDS = 0x3F,
409*4882a593Smuzhiyun QWORDS = 0x40,
410*4882a593Smuzhiyun PERCENTAGE = 0x41,
411*4882a593Smuzhiyun PASCALS = 0x42,
412*4882a593Smuzhiyun COUNTS = 0x43,
413*4882a593Smuzhiyun GRAMS = 0x44,
414*4882a593Smuzhiyun NEWTON_METERS = 0x45,
415*4882a593Smuzhiyun HITS = 0x46,
416*4882a593Smuzhiyun MISSES = 0x47,
417*4882a593Smuzhiyun RETRIES = 0x48,
418*4882a593Smuzhiyun OVERRUNS = 0x49,
419*4882a593Smuzhiyun UNDERRUNS = 0x4A,
420*4882a593Smuzhiyun COLLISIONS = 0x4B,
421*4882a593Smuzhiyun PACKETS = 0x4C,
422*4882a593Smuzhiyun MESSAGES = 0x4D,
423*4882a593Smuzhiyun CHARS = 0x4E,
424*4882a593Smuzhiyun ERRORS = 0x4F,
425*4882a593Smuzhiyun CORRECTED_ERRS = 0x50,
426*4882a593Smuzhiyun UNCORRECTABLE_ERRS = 0x51,
427*4882a593Smuzhiyun SQ_MILS = 0x52,
428*4882a593Smuzhiyun SQ_INCHES = 0x53,
429*4882a593Smuzhiyun SQ_FEET = 0x54,
430*4882a593Smuzhiyun SQ_CM = 0x55,
431*4882a593Smuzhiyun SQ_METERS = 0x56,
432*4882a593Smuzhiyun RADIANS_SEC = 0x57,
433*4882a593Smuzhiyun BPM = 0x58,
434*4882a593Smuzhiyun METERS_SEC_SQUARED = 0x59,
435*4882a593Smuzhiyun METERS_SEC = 0x5A,
436*4882a593Smuzhiyun CUBIC_METERS_SEC = 0x5B,
437*4882a593Smuzhiyun MM_MERCURY = 0x5C,
438*4882a593Smuzhiyun RADIANS_SEC_SQUARED = 0x5D,
439*4882a593Smuzhiyun OEM_UNIT = 0xFF
440*4882a593Smuzhiyun };
441*4882a593Smuzhiyun
442*4882a593Smuzhiyun /**
443*4882a593Smuzhiyun * struct scmi_sensor_proto_ops - represents the various operations provided
444*4882a593Smuzhiyun * by SCMI Sensor Protocol
445*4882a593Smuzhiyun *
446*4882a593Smuzhiyun * @count_get: get the count of sensors provided by SCMI
447*4882a593Smuzhiyun * @info_get: get the information of the specified sensor
448*4882a593Smuzhiyun * @trip_point_config: selects and configures a trip-point of interest
449*4882a593Smuzhiyun * @reading_get: gets the current value of the sensor
450*4882a593Smuzhiyun * @reading_get_timestamped: gets the current value and timestamp, when
451*4882a593Smuzhiyun * available, of the sensor. (as of v3.0 spec)
452*4882a593Smuzhiyun * Supports multi-axis sensors for sensors which
453*4882a593Smuzhiyun * supports it and if the @reading array size of
454*4882a593Smuzhiyun * @count entry equals the sensor num_axis
455*4882a593Smuzhiyun * @config_get: Get sensor current configuration
456*4882a593Smuzhiyun * @config_set: Set sensor current configuration
457*4882a593Smuzhiyun */
458*4882a593Smuzhiyun struct scmi_sensor_proto_ops {
459*4882a593Smuzhiyun int (*count_get)(const struct scmi_protocol_handle *ph);
460*4882a593Smuzhiyun const struct scmi_sensor_info *(*info_get)
461*4882a593Smuzhiyun (const struct scmi_protocol_handle *ph, u32 sensor_id);
462*4882a593Smuzhiyun int (*trip_point_config)(const struct scmi_protocol_handle *ph,
463*4882a593Smuzhiyun u32 sensor_id, u8 trip_id, u64 trip_value);
464*4882a593Smuzhiyun int (*reading_get)(const struct scmi_protocol_handle *ph, u32 sensor_id,
465*4882a593Smuzhiyun u64 *value);
466*4882a593Smuzhiyun int (*reading_get_timestamped)(const struct scmi_protocol_handle *ph,
467*4882a593Smuzhiyun u32 sensor_id, u8 count,
468*4882a593Smuzhiyun struct scmi_sensor_reading *readings);
469*4882a593Smuzhiyun int (*config_get)(const struct scmi_protocol_handle *ph,
470*4882a593Smuzhiyun u32 sensor_id, u32 *sensor_config);
471*4882a593Smuzhiyun int (*config_set)(const struct scmi_protocol_handle *ph,
472*4882a593Smuzhiyun u32 sensor_id, u32 sensor_config);
473*4882a593Smuzhiyun
474*4882a593Smuzhiyun ANDROID_KABI_RESERVE(1);
475*4882a593Smuzhiyun };
476*4882a593Smuzhiyun
477*4882a593Smuzhiyun /**
478*4882a593Smuzhiyun * struct scmi_reset_proto_ops - represents the various operations provided
479*4882a593Smuzhiyun * by SCMI Reset Protocol
480*4882a593Smuzhiyun *
481*4882a593Smuzhiyun * @num_domains_get: get the count of reset domains provided by SCMI
482*4882a593Smuzhiyun * @name_get: gets the name of a reset domain
483*4882a593Smuzhiyun * @latency_get: gets the reset latency for the specified reset domain
484*4882a593Smuzhiyun * @reset: resets the specified reset domain
485*4882a593Smuzhiyun * @assert: explicitly assert reset signal of the specified reset domain
486*4882a593Smuzhiyun * @deassert: explicitly deassert reset signal of the specified reset domain
487*4882a593Smuzhiyun */
488*4882a593Smuzhiyun struct scmi_reset_proto_ops {
489*4882a593Smuzhiyun int (*num_domains_get)(const struct scmi_protocol_handle *ph);
490*4882a593Smuzhiyun char *(*name_get)(const struct scmi_protocol_handle *ph, u32 domain);
491*4882a593Smuzhiyun int (*latency_get)(const struct scmi_protocol_handle *ph, u32 domain);
492*4882a593Smuzhiyun int (*reset)(const struct scmi_protocol_handle *ph, u32 domain);
493*4882a593Smuzhiyun int (*assert)(const struct scmi_protocol_handle *ph, u32 domain);
494*4882a593Smuzhiyun int (*deassert)(const struct scmi_protocol_handle *ph, u32 domain);
495*4882a593Smuzhiyun
496*4882a593Smuzhiyun ANDROID_KABI_RESERVE(1);
497*4882a593Smuzhiyun };
498*4882a593Smuzhiyun
499*4882a593Smuzhiyun /**
500*4882a593Smuzhiyun * struct scmi_voltage_info - describe one available SCMI Voltage Domain
501*4882a593Smuzhiyun *
502*4882a593Smuzhiyun * @id: the domain ID as advertised by the platform
503*4882a593Smuzhiyun * @segmented: defines the layout of the entries of array @levels_uv.
504*4882a593Smuzhiyun * - when True the entries are to be interpreted as triplets,
505*4882a593Smuzhiyun * each defining a segment representing a range of equally
506*4882a593Smuzhiyun * space voltages: <lowest_volts>, <highest_volt>, <step_uV>
507*4882a593Smuzhiyun * - when False the entries simply represent a single discrete
508*4882a593Smuzhiyun * supported voltage level
509*4882a593Smuzhiyun * @negative_volts_allowed: True if any of the entries of @levels_uv represent
510*4882a593Smuzhiyun * a negative voltage.
511*4882a593Smuzhiyun * @attributes: represents Voltage Domain advertised attributes
512*4882a593Smuzhiyun * @name: name assigned to the Voltage Domain by platform
513*4882a593Smuzhiyun * @num_levels: number of total entries in @levels_uv.
514*4882a593Smuzhiyun * @levels_uv: array of entries describing the available voltage levels for
515*4882a593Smuzhiyun * this domain.
516*4882a593Smuzhiyun */
517*4882a593Smuzhiyun struct scmi_voltage_info {
518*4882a593Smuzhiyun unsigned int id;
519*4882a593Smuzhiyun bool segmented;
520*4882a593Smuzhiyun bool negative_volts_allowed;
521*4882a593Smuzhiyun unsigned int attributes;
522*4882a593Smuzhiyun char name[SCMI_MAX_STR_SIZE];
523*4882a593Smuzhiyun unsigned int num_levels;
524*4882a593Smuzhiyun #define SCMI_VOLTAGE_SEGMENT_LOW 0
525*4882a593Smuzhiyun #define SCMI_VOLTAGE_SEGMENT_HIGH 1
526*4882a593Smuzhiyun #define SCMI_VOLTAGE_SEGMENT_STEP 2
527*4882a593Smuzhiyun int *levels_uv;
528*4882a593Smuzhiyun };
529*4882a593Smuzhiyun
530*4882a593Smuzhiyun /**
531*4882a593Smuzhiyun * struct scmi_voltage_proto_ops - represents the various operations provided
532*4882a593Smuzhiyun * by SCMI Voltage Protocol
533*4882a593Smuzhiyun *
534*4882a593Smuzhiyun * @num_domains_get: get the count of voltage domains provided by SCMI
535*4882a593Smuzhiyun * @info_get: get the information of the specified domain
536*4882a593Smuzhiyun * @config_set: set the config for the specified domain
537*4882a593Smuzhiyun * @config_get: get the config of the specified domain
538*4882a593Smuzhiyun * @level_set: set the voltage level for the specified domain
539*4882a593Smuzhiyun * @level_get: get the voltage level of the specified domain
540*4882a593Smuzhiyun */
541*4882a593Smuzhiyun struct scmi_voltage_proto_ops {
542*4882a593Smuzhiyun int (*num_domains_get)(const struct scmi_protocol_handle *ph);
543*4882a593Smuzhiyun const struct scmi_voltage_info __must_check *(*info_get)
544*4882a593Smuzhiyun (const struct scmi_protocol_handle *ph, u32 domain_id);
545*4882a593Smuzhiyun int (*config_set)(const struct scmi_protocol_handle *ph, u32 domain_id,
546*4882a593Smuzhiyun u32 config);
547*4882a593Smuzhiyun #define SCMI_VOLTAGE_ARCH_STATE_OFF 0x0
548*4882a593Smuzhiyun #define SCMI_VOLTAGE_ARCH_STATE_ON 0x7
549*4882a593Smuzhiyun int (*config_get)(const struct scmi_protocol_handle *ph, u32 domain_id,
550*4882a593Smuzhiyun u32 *config);
551*4882a593Smuzhiyun int (*level_set)(const struct scmi_protocol_handle *ph, u32 domain_id,
552*4882a593Smuzhiyun u32 flags, s32 volt_uV);
553*4882a593Smuzhiyun int (*level_get)(const struct scmi_protocol_handle *ph, u32 domain_id,
554*4882a593Smuzhiyun s32 *volt_uV);
555*4882a593Smuzhiyun };
556*4882a593Smuzhiyun
557*4882a593Smuzhiyun /**
558*4882a593Smuzhiyun * struct scmi_notify_ops - represents notifications' operations provided by
559*4882a593Smuzhiyun * SCMI core
560*4882a593Smuzhiyun * @devm_register_event_notifier: Managed registration of a notifier_block for
561*4882a593Smuzhiyun * the requested event
562*4882a593Smuzhiyun * @devm_unregister_event_notifier: Managed unregistration of a notifier_block
563*4882a593Smuzhiyun * for the requested event
564*4882a593Smuzhiyun * @register_event_notifier: Register a notifier_block for the requested event
565*4882a593Smuzhiyun * @unregister_event_notifier: Unregister a notifier_block for the requested
566*4882a593Smuzhiyun * event
567*4882a593Smuzhiyun *
568*4882a593Smuzhiyun * A user can register/unregister its own notifier_block against the wanted
569*4882a593Smuzhiyun * platform instance regarding the desired event identified by the
570*4882a593Smuzhiyun * tuple: (proto_id, evt_id, src_id) using the provided register/unregister
571*4882a593Smuzhiyun * interface where:
572*4882a593Smuzhiyun *
573*4882a593Smuzhiyun * @sdev: The scmi_device to use when calling the devres managed ops devm_
574*4882a593Smuzhiyun * @handle: The handle identifying the platform instance to use, when not
575*4882a593Smuzhiyun * calling the managed ops devm_
576*4882a593Smuzhiyun * @proto_id: The protocol ID as in SCMI Specification
577*4882a593Smuzhiyun * @evt_id: The message ID of the desired event as in SCMI Specification
578*4882a593Smuzhiyun * @src_id: A pointer to the desired source ID if different sources are
579*4882a593Smuzhiyun * possible for the protocol (like domain_id, sensor_id...etc)
580*4882a593Smuzhiyun *
581*4882a593Smuzhiyun * @src_id can be provided as NULL if it simply does NOT make sense for
582*4882a593Smuzhiyun * the protocol at hand, OR if the user is explicitly interested in
583*4882a593Smuzhiyun * receiving notifications from ANY existent source associated to the
584*4882a593Smuzhiyun * specified proto_id / evt_id.
585*4882a593Smuzhiyun *
586*4882a593Smuzhiyun * Received notifications are finally delivered to the registered users,
587*4882a593Smuzhiyun * invoking the callback provided with the notifier_block *nb as follows:
588*4882a593Smuzhiyun *
589*4882a593Smuzhiyun * int user_cb(nb, evt_id, report)
590*4882a593Smuzhiyun *
591*4882a593Smuzhiyun * with:
592*4882a593Smuzhiyun *
593*4882a593Smuzhiyun * @nb: The notifier block provided by the user
594*4882a593Smuzhiyun * @evt_id: The message ID of the delivered event
595*4882a593Smuzhiyun * @report: A custom struct describing the specific event delivered
596*4882a593Smuzhiyun */
597*4882a593Smuzhiyun struct scmi_notify_ops {
598*4882a593Smuzhiyun int (*devm_register_event_notifier)(struct scmi_device *sdev,
599*4882a593Smuzhiyun u8 proto_id, u8 evt_id, u32 *src_id,
600*4882a593Smuzhiyun struct notifier_block *nb);
601*4882a593Smuzhiyun int (*devm_unregister_event_notifier)(struct scmi_device *sdev,
602*4882a593Smuzhiyun u8 proto_id, u8 evt_id,
603*4882a593Smuzhiyun u32 *src_id,
604*4882a593Smuzhiyun struct notifier_block *nb);
605*4882a593Smuzhiyun int (*register_event_notifier)(const struct scmi_handle *handle,
606*4882a593Smuzhiyun u8 proto_id, u8 evt_id, u32 *src_id,
607*4882a593Smuzhiyun struct notifier_block *nb);
608*4882a593Smuzhiyun int (*unregister_event_notifier)(const struct scmi_handle *handle,
609*4882a593Smuzhiyun u8 proto_id, u8 evt_id, u32 *src_id,
610*4882a593Smuzhiyun struct notifier_block *nb);
611*4882a593Smuzhiyun };
612*4882a593Smuzhiyun
613*4882a593Smuzhiyun /**
614*4882a593Smuzhiyun * struct scmi_handle - Handle returned to ARM SCMI clients for usage.
615*4882a593Smuzhiyun *
616*4882a593Smuzhiyun * @dev: pointer to the SCMI device
617*4882a593Smuzhiyun * @version: pointer to the structure containing SCMI version information
618*4882a593Smuzhiyun * @devm_acquire_protocol: devres managed method to get hold of a protocol,
619*4882a593Smuzhiyun * causing its initialization and related resource
620*4882a593Smuzhiyun * accounting
621*4882a593Smuzhiyun * @devm_get_protocol: devres managed method to acquire a protocol, causing
622*4882a593Smuzhiyun * its initialization and resource accounting, while getting
623*4882a593Smuzhiyun * protocol specific operations and a dedicated protocol
624*4882a593Smuzhiyun * handler
625*4882a593Smuzhiyun * @devm_put_protocol: devres managed method to release a protocol acquired
626*4882a593Smuzhiyun * with devm_acquire/get_protocol
627*4882a593Smuzhiyun * @notify_ops: pointer to set of notifications related operations
628*4882a593Smuzhiyun */
629*4882a593Smuzhiyun struct scmi_handle {
630*4882a593Smuzhiyun struct device *dev;
631*4882a593Smuzhiyun struct scmi_revision_info *version;
632*4882a593Smuzhiyun
633*4882a593Smuzhiyun int __must_check (*devm_acquire_protocol)(struct scmi_device *sdev,
634*4882a593Smuzhiyun u8 proto);
635*4882a593Smuzhiyun const void __must_check *
636*4882a593Smuzhiyun (*devm_get_protocol)(struct scmi_device *sdev, u8 proto,
637*4882a593Smuzhiyun struct scmi_protocol_handle **ph);
638*4882a593Smuzhiyun void (*devm_put_protocol)(struct scmi_device *sdev, u8 proto);
639*4882a593Smuzhiyun
640*4882a593Smuzhiyun const struct scmi_notify_ops *notify_ops;
641*4882a593Smuzhiyun
642*4882a593Smuzhiyun ANDROID_KABI_RESERVE(1);
643*4882a593Smuzhiyun };
644*4882a593Smuzhiyun
645*4882a593Smuzhiyun enum scmi_std_protocol {
646*4882a593Smuzhiyun SCMI_PROTOCOL_BASE = 0x10,
647*4882a593Smuzhiyun SCMI_PROTOCOL_POWER = 0x11,
648*4882a593Smuzhiyun SCMI_PROTOCOL_SYSTEM = 0x12,
649*4882a593Smuzhiyun SCMI_PROTOCOL_PERF = 0x13,
650*4882a593Smuzhiyun SCMI_PROTOCOL_CLOCK = 0x14,
651*4882a593Smuzhiyun SCMI_PROTOCOL_SENSOR = 0x15,
652*4882a593Smuzhiyun SCMI_PROTOCOL_RESET = 0x16,
653*4882a593Smuzhiyun SCMI_PROTOCOL_VOLTAGE = 0x17,
654*4882a593Smuzhiyun };
655*4882a593Smuzhiyun
656*4882a593Smuzhiyun enum scmi_system_events {
657*4882a593Smuzhiyun SCMI_SYSTEM_SHUTDOWN,
658*4882a593Smuzhiyun SCMI_SYSTEM_COLDRESET,
659*4882a593Smuzhiyun SCMI_SYSTEM_WARMRESET,
660*4882a593Smuzhiyun SCMI_SYSTEM_POWERUP,
661*4882a593Smuzhiyun SCMI_SYSTEM_SUSPEND,
662*4882a593Smuzhiyun SCMI_SYSTEM_MAX
663*4882a593Smuzhiyun };
664*4882a593Smuzhiyun
665*4882a593Smuzhiyun struct scmi_device {
666*4882a593Smuzhiyun u32 id;
667*4882a593Smuzhiyun u8 protocol_id;
668*4882a593Smuzhiyun const char *name;
669*4882a593Smuzhiyun struct device dev;
670*4882a593Smuzhiyun struct scmi_handle *handle;
671*4882a593Smuzhiyun
672*4882a593Smuzhiyun ANDROID_KABI_RESERVE(1);
673*4882a593Smuzhiyun };
674*4882a593Smuzhiyun
675*4882a593Smuzhiyun #define to_scmi_dev(d) container_of(d, struct scmi_device, dev)
676*4882a593Smuzhiyun
677*4882a593Smuzhiyun struct scmi_device *
678*4882a593Smuzhiyun scmi_device_create(struct device_node *np, struct device *parent, int protocol,
679*4882a593Smuzhiyun const char *name);
680*4882a593Smuzhiyun void scmi_device_destroy(struct scmi_device *scmi_dev);
681*4882a593Smuzhiyun
682*4882a593Smuzhiyun struct scmi_device_id {
683*4882a593Smuzhiyun u8 protocol_id;
684*4882a593Smuzhiyun const char *name;
685*4882a593Smuzhiyun };
686*4882a593Smuzhiyun
687*4882a593Smuzhiyun struct scmi_driver {
688*4882a593Smuzhiyun const char *name;
689*4882a593Smuzhiyun int (*probe)(struct scmi_device *sdev);
690*4882a593Smuzhiyun void (*remove)(struct scmi_device *sdev);
691*4882a593Smuzhiyun const struct scmi_device_id *id_table;
692*4882a593Smuzhiyun
693*4882a593Smuzhiyun struct device_driver driver;
694*4882a593Smuzhiyun };
695*4882a593Smuzhiyun
696*4882a593Smuzhiyun #define to_scmi_driver(d) container_of(d, struct scmi_driver, driver)
697*4882a593Smuzhiyun
698*4882a593Smuzhiyun #if IS_REACHABLE(CONFIG_ARM_SCMI_PROTOCOL)
699*4882a593Smuzhiyun int scmi_driver_register(struct scmi_driver *driver,
700*4882a593Smuzhiyun struct module *owner, const char *mod_name);
701*4882a593Smuzhiyun void scmi_driver_unregister(struct scmi_driver *driver);
702*4882a593Smuzhiyun #else
703*4882a593Smuzhiyun static inline int
scmi_driver_register(struct scmi_driver * driver,struct module * owner,const char * mod_name)704*4882a593Smuzhiyun scmi_driver_register(struct scmi_driver *driver, struct module *owner,
705*4882a593Smuzhiyun const char *mod_name)
706*4882a593Smuzhiyun {
707*4882a593Smuzhiyun return -EINVAL;
708*4882a593Smuzhiyun }
709*4882a593Smuzhiyun
scmi_driver_unregister(struct scmi_driver * driver)710*4882a593Smuzhiyun static inline void scmi_driver_unregister(struct scmi_driver *driver) {}
711*4882a593Smuzhiyun #endif /* CONFIG_ARM_SCMI_PROTOCOL */
712*4882a593Smuzhiyun
713*4882a593Smuzhiyun #define scmi_register(driver) \
714*4882a593Smuzhiyun scmi_driver_register(driver, THIS_MODULE, KBUILD_MODNAME)
715*4882a593Smuzhiyun #define scmi_unregister(driver) \
716*4882a593Smuzhiyun scmi_driver_unregister(driver)
717*4882a593Smuzhiyun
718*4882a593Smuzhiyun /**
719*4882a593Smuzhiyun * module_scmi_driver() - Helper macro for registering a scmi driver
720*4882a593Smuzhiyun * @__scmi_driver: scmi_driver structure
721*4882a593Smuzhiyun *
722*4882a593Smuzhiyun * Helper macro for scmi drivers to set up proper module init / exit
723*4882a593Smuzhiyun * functions. Replaces module_init() and module_exit() and keeps people from
724*4882a593Smuzhiyun * printing pointless things to the kernel log when their driver is loaded.
725*4882a593Smuzhiyun */
726*4882a593Smuzhiyun #define module_scmi_driver(__scmi_driver) \
727*4882a593Smuzhiyun module_driver(__scmi_driver, scmi_register, scmi_unregister)
728*4882a593Smuzhiyun
729*4882a593Smuzhiyun /**
730*4882a593Smuzhiyun * module_scmi_protocol() - Helper macro for registering a scmi protocol
731*4882a593Smuzhiyun * @__scmi_protocol: scmi_protocol structure
732*4882a593Smuzhiyun *
733*4882a593Smuzhiyun * Helper macro for scmi drivers to set up proper module init / exit
734*4882a593Smuzhiyun * functions. Replaces module_init() and module_exit() and keeps people from
735*4882a593Smuzhiyun * printing pointless things to the kernel log when their driver is loaded.
736*4882a593Smuzhiyun */
737*4882a593Smuzhiyun #define module_scmi_protocol(__scmi_protocol) \
738*4882a593Smuzhiyun module_driver(__scmi_protocol, \
739*4882a593Smuzhiyun scmi_protocol_register, scmi_protocol_unregister)
740*4882a593Smuzhiyun
741*4882a593Smuzhiyun struct scmi_protocol;
742*4882a593Smuzhiyun int scmi_protocol_register(const struct scmi_protocol *proto);
743*4882a593Smuzhiyun void scmi_protocol_unregister(const struct scmi_protocol *proto);
744*4882a593Smuzhiyun
745*4882a593Smuzhiyun /* SCMI Notification API - Custom Event Reports */
746*4882a593Smuzhiyun enum scmi_notification_events {
747*4882a593Smuzhiyun SCMI_EVENT_POWER_STATE_CHANGED = 0x0,
748*4882a593Smuzhiyun SCMI_EVENT_PERFORMANCE_LIMITS_CHANGED = 0x0,
749*4882a593Smuzhiyun SCMI_EVENT_PERFORMANCE_LEVEL_CHANGED = 0x1,
750*4882a593Smuzhiyun SCMI_EVENT_SENSOR_TRIP_POINT_EVENT = 0x0,
751*4882a593Smuzhiyun SCMI_EVENT_SENSOR_UPDATE = 0x1,
752*4882a593Smuzhiyun SCMI_EVENT_RESET_ISSUED = 0x0,
753*4882a593Smuzhiyun SCMI_EVENT_BASE_ERROR_EVENT = 0x0,
754*4882a593Smuzhiyun SCMI_EVENT_SYSTEM_POWER_STATE_NOTIFIER = 0x0,
755*4882a593Smuzhiyun };
756*4882a593Smuzhiyun
757*4882a593Smuzhiyun struct scmi_power_state_changed_report {
758*4882a593Smuzhiyun ktime_t timestamp;
759*4882a593Smuzhiyun unsigned int agent_id;
760*4882a593Smuzhiyun unsigned int domain_id;
761*4882a593Smuzhiyun unsigned int power_state;
762*4882a593Smuzhiyun };
763*4882a593Smuzhiyun
764*4882a593Smuzhiyun struct scmi_system_power_state_notifier_report {
765*4882a593Smuzhiyun ktime_t timestamp;
766*4882a593Smuzhiyun unsigned int agent_id;
767*4882a593Smuzhiyun unsigned int flags;
768*4882a593Smuzhiyun unsigned int system_state;
769*4882a593Smuzhiyun };
770*4882a593Smuzhiyun
771*4882a593Smuzhiyun struct scmi_perf_limits_report {
772*4882a593Smuzhiyun ktime_t timestamp;
773*4882a593Smuzhiyun unsigned int agent_id;
774*4882a593Smuzhiyun unsigned int domain_id;
775*4882a593Smuzhiyun unsigned int range_max;
776*4882a593Smuzhiyun unsigned int range_min;
777*4882a593Smuzhiyun };
778*4882a593Smuzhiyun
779*4882a593Smuzhiyun struct scmi_perf_level_report {
780*4882a593Smuzhiyun ktime_t timestamp;
781*4882a593Smuzhiyun unsigned int agent_id;
782*4882a593Smuzhiyun unsigned int domain_id;
783*4882a593Smuzhiyun unsigned int performance_level;
784*4882a593Smuzhiyun };
785*4882a593Smuzhiyun
786*4882a593Smuzhiyun struct scmi_sensor_trip_point_report {
787*4882a593Smuzhiyun ktime_t timestamp;
788*4882a593Smuzhiyun unsigned int agent_id;
789*4882a593Smuzhiyun unsigned int sensor_id;
790*4882a593Smuzhiyun unsigned int trip_point_desc;
791*4882a593Smuzhiyun };
792*4882a593Smuzhiyun
793*4882a593Smuzhiyun struct scmi_sensor_update_report {
794*4882a593Smuzhiyun ktime_t timestamp;
795*4882a593Smuzhiyun unsigned int agent_id;
796*4882a593Smuzhiyun unsigned int sensor_id;
797*4882a593Smuzhiyun unsigned int readings_count;
798*4882a593Smuzhiyun struct scmi_sensor_reading readings[];
799*4882a593Smuzhiyun };
800*4882a593Smuzhiyun
801*4882a593Smuzhiyun struct scmi_reset_issued_report {
802*4882a593Smuzhiyun ktime_t timestamp;
803*4882a593Smuzhiyun unsigned int agent_id;
804*4882a593Smuzhiyun unsigned int domain_id;
805*4882a593Smuzhiyun unsigned int reset_state;
806*4882a593Smuzhiyun };
807*4882a593Smuzhiyun
808*4882a593Smuzhiyun struct scmi_base_error_report {
809*4882a593Smuzhiyun ktime_t timestamp;
810*4882a593Smuzhiyun unsigned int agent_id;
811*4882a593Smuzhiyun bool fatal;
812*4882a593Smuzhiyun unsigned int cmd_count;
813*4882a593Smuzhiyun unsigned long long reports[];
814*4882a593Smuzhiyun };
815*4882a593Smuzhiyun
816*4882a593Smuzhiyun #endif /* _LINUX_SCMI_PROTOCOL_H */
817