1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291
|
// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
/* Copyright 2017-2019 IBM Corp. */
#include <chip.h>
/* OCC Functions */
extern void occ_pstates_init(void);
extern void occ_fsp_init(void);
int find_master_and_slave_occ(uint64_t **master, uint64_t **slave,
int *nr_masters, int *nr_slaves);
/* OCC interrupt for P8 */
extern void occ_p8_interrupt(uint32_t chip_id);
extern void occ_send_dummy_interrupt(void);
/* OCC interrupt for P9 */
extern void occ_p9_interrupt(uint32_t chip_id);
/* OCC load support */
extern void occ_poke_load_queue(void);
/* OCC/Host PNOR ownership */
enum pnor_owner {
PNOR_OWNER_HOST,
PNOR_OWNER_EXTERNAL,
};
extern void occ_pnor_set_owner(enum pnor_owner owner);
/* GPU presence detection */
bool occ_get_gpu_presence(struct proc_chip *chip, int gpu_num);
/* OCC Inband Sensors */
extern bool occ_sensors_init(void);
extern int occ_sensor_read(u32 handle, __be64 *data);
extern int occ_sensor_group_clear(u32 group_hndl, int token);
extern void occ_add_sensor_groups(struct dt_node *sg, __be32 *phandles,
u32 *ptype, int nr_phandles, int chipid);
extern int occ_sensor_group_enable(u32 group_hndl, int token, bool enable);
extern bool is_occ_reset(void);
/*
* OCC Sensor Data
*
* OCC sensor data will use BAR2 (OCC Common is per physical drawer).
* Starting address is at offset 0x00580000 from BAR2 base address.
* Maximum size is 1.5MB.
*
* -------------------------------------------------------------------------
* | Start (Offset from | End | Size |Description |
* | BAR2 base address) | | | |
* -------------------------------------------------------------------------
* | 0x00580000 | 0x005A57FF |150kB |OCC 0 Sensor Data Block|
* | 0x005A5800 | 0x005CAFFF |150kB |OCC 1 Sensor Data Block|
* | : | : | : | : |
* | 0x00686800 | 0x006ABFFF |150kB |OCC 7 Sensor Data Block|
* | 0x006AC000 | 0x006FFFFF |336kB |Reserved |
* -------------------------------------------------------------------------
*
*
* OCC N Sensor Data Block Layout (150kB)
*
* The sensor data block layout is the same for each OCC N. It contains
* sensor-header-block, sensor-names buffer, sensor-readings-ping buffer and
* sensor-readings-pong buffer.
*
* ----------------------------------------------------------------------------
* | Start (Offset from OCC | End | Size |Description |
* | N Sensor Data Block) | | | |
* ----------------------------------------------------------------------------
* | 0x00000000 | 0x000003FF |1kB |Sensor Data Header Block |
* | 0x00000400 | 0x0000CBFF |50kB |Sensor Names |
* | 0x0000CC00 | 0x0000DBFF |4kB |Reserved |
* | 0x0000DC00 | 0x00017BFF |40kB |Sensor Readings ping buffer|
* | 0x00017C00 | 0x00018BFF |4kB |Reserved |
* | 0x00018C00 | 0x00022BFF |40kB |Sensor Readings pong buffer|
* | 0x00022C00 | 0x000257FF |11kB |Reserved |
* ----------------------------------------------------------------------------
*
* Sensor Data Header Block : This is written once by the OCC during
* initialization after a load or reset. Layout is defined in 'struct
* occ_sensor_data_header'
*
* Sensor Names : This is written once by the OCC during initialization after a
* load or reset. It contains static information for each sensor. The number of
* sensors, format version and length of each sensor is defined in
* 'Sensor Data Header Block'. Format of each sensor name is defined in
* 'struct occ_sensor_name'. The first sensor starts at offset 0 followed
* immediately by the next sensor.
*
* Sensor Readings Ping/Pong Buffer:
* There are two 40kB buffers to store the sensor readings. One buffer that
* is currently being updated by the OCC and one that is available to be read.
* Each of these buffers will be of the same format. The number of sensors and
* the format version of the ping and pong buffers is defined in the
* 'Sensor Data Header Block'.
*
* Each sensor within the ping and pong buffers may be of a different format
* and length. For each sensor the length and format is determined by its
* 'struct occ_sensor_name.structure_type' in the Sensor Names buffer.
*
* --------------------------------------------------------------------------
* | Offset | Byte0 | Byte1 | Byte2 | Byte3 | Byte4 | Byte5 | Byte6 | Byte7 |
* --------------------------------------------------------------------------
* | 0x0000 |Valid | Reserved |
* | |(0x01) | |
* --------------------------------------------------------------------------
* | 0x0008 | Sensor Readings |
* --------------------------------------------------------------------------
* | : | : |
* --------------------------------------------------------------------------
* | 0xA000 | End of Data |
* --------------------------------------------------------------------------
*
*/
#define MAX_OCCS 8
#define MAX_CHARS_SENSOR_NAME 16
#define MAX_CHARS_SENSOR_UNIT 4
#define OCC_SENSOR_DATA_BLOCK_OFFSET 0x00580000
#define OCC_SENSOR_DATA_BLOCK_SIZE 0x00025800
/*
* These should match the definitions inside the OCC source:
* occ/src/occ_405/sensor/sensor_info.c
*/
enum occ_sensor_type {
OCC_SENSOR_TYPE_GENERIC = 0x0001,
OCC_SENSOR_TYPE_CURRENT = 0x0002,
OCC_SENSOR_TYPE_VOLTAGE = 0x0004,
OCC_SENSOR_TYPE_TEMPERATURE = 0x0008,
OCC_SENSOR_TYPE_UTILIZATION = 0x0010,
OCC_SENSOR_TYPE_TIME = 0x0020,
OCC_SENSOR_TYPE_FREQUENCY = 0x0040,
OCC_SENSOR_TYPE_POWER = 0x0080,
OCC_SENSOR_TYPE_PERFORMANCE = 0x0200,
};
#define OCC_ENABLED_SENSOR_MASK (OCC_SENSOR_TYPE_GENERIC | \
OCC_SENSOR_TYPE_CURRENT | \
OCC_SENSOR_TYPE_VOLTAGE | \
OCC_SENSOR_TYPE_TIME | \
OCC_SENSOR_TYPE_TEMPERATURE | \
OCC_SENSOR_TYPE_POWER | \
OCC_SENSOR_TYPE_UTILIZATION | \
OCC_SENSOR_TYPE_FREQUENCY | \
OCC_SENSOR_TYPE_PERFORMANCE);
enum occ_sensor_location {
OCC_SENSOR_LOC_SYSTEM = 0x0001,
OCC_SENSOR_LOC_PROCESSOR = 0x0002,
OCC_SENSOR_LOC_PARTITION = 0x0004,
OCC_SENSOR_LOC_MEMORY = 0x0008,
OCC_SENSOR_LOC_VRM = 0x0010,
OCC_SENSOR_LOC_OCC = 0x0020,
OCC_SENSOR_LOC_CORE = 0x0040,
OCC_SENSOR_LOC_GPU = 0x0080,
OCC_SENSOR_LOC_QUAD = 0x0100,
};
enum sensor_struct_type {
OCC_SENSOR_READING_FULL = 0x01,
OCC_SENSOR_READING_COUNTER = 0x02,
};
/**
* struct occ_sensor_data_header - Sensor Data Header Block
* @valid: When the value is 0x01 it indicates
* that this header block and the sensor
* names buffer are ready
* @version: Format version of this block
* @nr_sensors: Number of sensors in names, ping and
* pong buffer
* @reading_version: Format version of the Ping/Pong buffer
* @names_offset: Offset to the location of names buffer
* @names_version: Format version of names buffer
* @names_length: Length of each sensor in names buffer
* @reading_ping_offset: Offset to the location of Ping buffer
* @reading_pong_offset: Offset to the location of Pong buffer
* @pad/reserved: Unused data
*/
struct occ_sensor_data_header {
u8 valid;
u8 version;
__be16 nr_sensors;
u8 reading_version;
u8 pad[3];
__be32 names_offset;
u8 names_version;
u8 name_length;
u16 reserved;
__be32 reading_ping_offset;
__be32 reading_pong_offset;
} __attribute__((__packed__));
/**
* struct occ_sensor_name - Format of Sensor Name
* @name: Sensor name
* @units: Sensor units of measurement
* @gsid: Global sensor id (OCC)
* @freq: Update frequency
* @scale_factor: Scaling factor
* @type: Sensor type as defined in
* 'enum occ_sensor_type'
* @location: Sensor location as defined in
* 'enum occ_sensor_location'
* @structure_type: Indicates type of data structure used
* for the sensor readings in the ping and
* pong buffers for this sensor as defined
* in 'enum sensor_struct_type'
* @reading_offset: Offset from the start of the ping/pong
* reading buffers for this sensor
* @sensor_data: Sensor specific info
* @pad: Padding to fit the size of 48 bytes.
*/
struct occ_sensor_name {
char name[MAX_CHARS_SENSOR_NAME];
char units[MAX_CHARS_SENSOR_UNIT];
__be16 gsid;
__be32 freq;
__be32 scale_factor;
__be16 type;
__be16 location;
u8 structure_type;
__be32 reading_offset;
u8 sensor_data;
u8 pad[8];
} __attribute__((__packed__));
/**
* struct occ_sensor_record - Sensor Reading Full
* @gsid: Global sensor id (OCC)
* @timestamp: Time base counter value while updating
* the sensor
* @sample: Latest sample of this sensor
* @sample_min: Minimum value since last OCC reset
* @sample_max: Maximum value since last OCC reset
* @csm_min: Minimum value since last reset request
* by CSM (CORAL)
* @csm_max: Maximum value since last reset request
* by CSM (CORAL)
* @profiler_min: Minimum value since last reset request
* by profiler (CORAL)
* @profiler_max: Maximum value since last reset request
* by profiler (CORAL)
* @job_scheduler_min: Minimum value since last reset request
* by job scheduler(CORAL)
* @job_scheduler_max: Maximum value since last reset request
* by job scheduler (CORAL)
* @accumulator: Accumulator for this sensor
* @update_tag: Count of the number of ticks that have
* passed between updates
* @pad: Padding to fit the size of 48 bytes
*/
struct occ_sensor_record {
u16 gsid;
__be64 timestamp;
__be16 sample;
__be16 sample_min;
__be16 sample_max;
__be16 csm_min;
__be16 csm_max;
__be16 profiler_min;
__be16 profiler_max;
__be16 job_scheduler_min;
__be16 job_scheduler_max;
__be64 accumulator;
__be32 update_tag;
u8 pad[8];
} __attribute__((__packed__));
/**
* struct occ_sensor_counter - Sensor Reading Counter
* @gsid: Global sensor id (OCC)
* @timestamp: Time base counter value while updating
* the sensor
* @accumulator: Accumulator/Counter
* @sample: Latest sample of this sensor (0/1)
* @pad: Padding to fit the size of 24 bytes
*/
struct occ_sensor_counter {
u16 gsid;
__be64 timestamp;
__be64 accumulator;
u8 sample;
u8 pad[5];
} __attribute__((__packed__));
|