root/drivers/misc/habanalabs/include/armcp_if.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


   1 /* SPDX-License-Identifier: GPL-2.0
   2  *
   3  * Copyright 2016-2019 HabanaLabs, Ltd.
   4  * All Rights Reserved.
   5  *
   6  */
   7 
   8 #ifndef ARMCP_IF_H
   9 #define ARMCP_IF_H
  10 
  11 #include <linux/types.h>
  12 
  13 /*
  14  * EVENT QUEUE
  15  */
  16 
  17 struct hl_eq_header {
  18         __le32 reserved;
  19         __le32 ctl;
  20 };
  21 
  22 struct hl_eq_entry {
  23         struct hl_eq_header hdr;
  24         __le64 data[7];
  25 };
  26 
  27 #define HL_EQ_ENTRY_SIZE                sizeof(struct hl_eq_entry)
  28 
  29 #define EQ_CTL_READY_SHIFT              31
  30 #define EQ_CTL_READY_MASK               0x80000000
  31 
  32 #define EQ_CTL_EVENT_TYPE_SHIFT         16
  33 #define EQ_CTL_EVENT_TYPE_MASK          0x03FF0000
  34 
  35 enum pq_init_status {
  36         PQ_INIT_STATUS_NA = 0,
  37         PQ_INIT_STATUS_READY_FOR_CP,
  38         PQ_INIT_STATUS_READY_FOR_HOST
  39 };
  40 
  41 /*
  42  * ArmCP Primary Queue Packets
  43  *
  44  * During normal operation, the host's kernel driver needs to send various
  45  * messages to ArmCP, usually either to SET some value into a H/W periphery or
  46  * to GET the current value of some H/W periphery. For example, SET the
  47  * frequency of MME/TPC and GET the value of the thermal sensor.
  48  *
  49  * These messages can be initiated either by the User application or by the
  50  * host's driver itself, e.g. power management code. In either case, the
  51  * communication from the host's driver to ArmCP will *always* be in
  52  * synchronous mode, meaning that the host will send a single message and poll
  53  * until the message was acknowledged and the results are ready (if results are
  54  * needed).
  55  *
  56  * This means that only a single message can be sent at a time and the host's
  57  * driver must wait for its result before sending the next message. Having said
  58  * that, because these are control messages which are sent in a relatively low
  59  * frequency, this limitation seems acceptable. It's important to note that
  60  * in case of multiple devices, messages to different devices *can* be sent
  61  * at the same time.
  62  *
  63  * The message, inputs/outputs (if relevant) and fence object will be located
  64  * on the device DDR at an address that will be determined by the host's driver.
  65  * During device initialization phase, the host will pass to ArmCP that address.
  66  * Most of the message types will contain inputs/outputs inside the message
  67  * itself. The common part of each message will contain the opcode of the
  68  * message (its type) and a field representing a fence object.
  69  *
  70  * When the host's driver wishes to send a message to ArmCP, it will write the
  71  * message contents to the device DDR, clear the fence object and then write the
  72  * value 484 to the mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR register to issue
  73  * the 484 interrupt-id to the ARM core.
  74  *
  75  * Upon receiving the 484 interrupt-id, ArmCP will read the message from the
  76  * DDR. In case the message is a SET operation, ArmCP will first perform the
  77  * operation and then write to the fence object on the device DDR. In case the
  78  * message is a GET operation, ArmCP will first fill the results section on the
  79  * device DDR and then write to the fence object. If an error occurred, ArmCP
  80  * will fill the rc field with the right error code.
  81  *
  82  * In the meantime, the host's driver will poll on the fence object. Once the
  83  * host sees that the fence object is signaled, it will read the results from
  84  * the device DDR (if relevant) and resume the code execution in the host's
  85  * driver.
  86  *
  87  * To use QMAN packets, the opcode must be the QMAN opcode, shifted by 8
  88  * so the value being put by the host's driver matches the value read by ArmCP
  89  *
  90  * Non-QMAN packets should be limited to values 1 through (2^8 - 1)
  91  *
  92  * Detailed description:
  93  *
  94  * ARMCP_PACKET_DISABLE_PCI_ACCESS -
  95  *       After receiving this packet the embedded CPU must NOT issue PCI
  96  *       transactions (read/write) towards the Host CPU. This also include
  97  *       sending MSI-X interrupts.
  98  *       This packet is usually sent before the device is moved to D3Hot state.
  99  *
 100  * ARMCP_PACKET_ENABLE_PCI_ACCESS -
 101  *       After receiving this packet the embedded CPU is allowed to issue PCI
 102  *       transactions towards the Host CPU, including sending MSI-X interrupts.
 103  *       This packet is usually send after the device is moved to D0 state.
 104  *
 105  * ARMCP_PACKET_TEMPERATURE_GET -
 106  *       Fetch the current temperature / Max / Max Hyst / Critical /
 107  *       Critical Hyst of a specified thermal sensor. The packet's
 108  *       arguments specify the desired sensor and the field to get.
 109  *
 110  * ARMCP_PACKET_VOLTAGE_GET -
 111  *       Fetch the voltage / Max / Min of a specified sensor. The packet's
 112  *       arguments specify the sensor and type.
 113  *
 114  * ARMCP_PACKET_CURRENT_GET -
 115  *       Fetch the current / Max / Min of a specified sensor. The packet's
 116  *       arguments specify the sensor and type.
 117  *
 118  * ARMCP_PACKET_FAN_SPEED_GET -
 119  *       Fetch the speed / Max / Min of a specified fan. The packet's
 120  *       arguments specify the sensor and type.
 121  *
 122  * ARMCP_PACKET_PWM_GET -
 123  *       Fetch the pwm value / mode of a specified pwm. The packet's
 124  *       arguments specify the sensor and type.
 125  *
 126  * ARMCP_PACKET_PWM_SET -
 127  *       Set the pwm value / mode of a specified pwm. The packet's
 128  *       arguments specify the sensor, type and value.
 129  *
 130  * ARMCP_PACKET_FREQUENCY_SET -
 131  *       Set the frequency of a specified PLL. The packet's arguments specify
 132  *       the PLL and the desired frequency. The actual frequency in the device
 133  *       might differ from the requested frequency.
 134  *
 135  * ARMCP_PACKET_FREQUENCY_GET -
 136  *       Fetch the frequency of a specified PLL. The packet's arguments specify
 137  *       the PLL.
 138  *
 139  * ARMCP_PACKET_LED_SET -
 140  *       Set the state of a specified led. The packet's arguments
 141  *       specify the led and the desired state.
 142  *
 143  * ARMCP_PACKET_I2C_WR -
 144  *       Write 32-bit value to I2C device. The packet's arguments specify the
 145  *       I2C bus, address and value.
 146  *
 147  * ARMCP_PACKET_I2C_RD -
 148  *       Read 32-bit value from I2C device. The packet's arguments specify the
 149  *       I2C bus and address.
 150  *
 151  * ARMCP_PACKET_INFO_GET -
 152  *       Fetch information from the device as specified in the packet's
 153  *       structure. The host's driver passes the max size it allows the ArmCP to
 154  *       write to the structure, to prevent data corruption in case of
 155  *       mismatched driver/FW versions.
 156  *
 157  * ARMCP_PACKET_FLASH_PROGRAM_REMOVED - this packet was removed
 158  *
 159  * ARMCP_PACKET_UNMASK_RAZWI_IRQ -
 160  *       Unmask the given IRQ. The IRQ number is specified in the value field.
 161  *       The packet is sent after receiving an interrupt and printing its
 162  *       relevant information.
 163  *
 164  * ARMCP_PACKET_UNMASK_RAZWI_IRQ_ARRAY -
 165  *       Unmask the given IRQs. The IRQs numbers are specified in an array right
 166  *       after the armcp_packet structure, where its first element is the array
 167  *       length. The packet is sent after a soft reset was done in order to
 168  *       handle any interrupts that were sent during the reset process.
 169  *
 170  * ARMCP_PACKET_TEST -
 171  *       Test packet for ArmCP connectivity. The CPU will put the fence value
 172  *       in the result field.
 173  *
 174  * ARMCP_PACKET_FREQUENCY_CURR_GET -
 175  *       Fetch the current frequency of a specified PLL. The packet's arguments
 176  *       specify the PLL.
 177  *
 178  * ARMCP_PACKET_MAX_POWER_GET -
 179  *       Fetch the maximal power of the device.
 180  *
 181  * ARMCP_PACKET_MAX_POWER_SET -
 182  *       Set the maximal power of the device. The packet's arguments specify
 183  *       the power.
 184  *
 185  * ARMCP_PACKET_EEPROM_DATA_GET -
 186  *       Get EEPROM data from the ArmCP kernel. The buffer is specified in the
 187  *       addr field. The CPU will put the returned data size in the result
 188  *       field. In addition, the host's driver passes the max size it allows the
 189  *       ArmCP to write to the structure, to prevent data corruption in case of
 190  *       mismatched driver/FW versions.
 191  *
 192  */
 193 
 194 enum armcp_packet_id {
 195         ARMCP_PACKET_DISABLE_PCI_ACCESS = 1,    /* internal */
 196         ARMCP_PACKET_ENABLE_PCI_ACCESS,         /* internal */
 197         ARMCP_PACKET_TEMPERATURE_GET,           /* sysfs */
 198         ARMCP_PACKET_VOLTAGE_GET,               /* sysfs */
 199         ARMCP_PACKET_CURRENT_GET,               /* sysfs */
 200         ARMCP_PACKET_FAN_SPEED_GET,             /* sysfs */
 201         ARMCP_PACKET_PWM_GET,                   /* sysfs */
 202         ARMCP_PACKET_PWM_SET,                   /* sysfs */
 203         ARMCP_PACKET_FREQUENCY_SET,             /* sysfs */
 204         ARMCP_PACKET_FREQUENCY_GET,             /* sysfs */
 205         ARMCP_PACKET_LED_SET,                   /* debugfs */
 206         ARMCP_PACKET_I2C_WR,                    /* debugfs */
 207         ARMCP_PACKET_I2C_RD,                    /* debugfs */
 208         ARMCP_PACKET_INFO_GET,                  /* IOCTL */
 209         ARMCP_PACKET_FLASH_PROGRAM_REMOVED,
 210         ARMCP_PACKET_UNMASK_RAZWI_IRQ,          /* internal */
 211         ARMCP_PACKET_UNMASK_RAZWI_IRQ_ARRAY,    /* internal */
 212         ARMCP_PACKET_TEST,                      /* internal */
 213         ARMCP_PACKET_FREQUENCY_CURR_GET,        /* sysfs */
 214         ARMCP_PACKET_MAX_POWER_GET,             /* sysfs */
 215         ARMCP_PACKET_MAX_POWER_SET,             /* sysfs */
 216         ARMCP_PACKET_EEPROM_DATA_GET,           /* sysfs */
 217 };
 218 
 219 #define ARMCP_PACKET_FENCE_VAL  0xFE8CE7A5
 220 
 221 #define ARMCP_PKT_CTL_RC_SHIFT          12
 222 #define ARMCP_PKT_CTL_RC_MASK           0x0000F000
 223 
 224 #define ARMCP_PKT_CTL_OPCODE_SHIFT      16
 225 #define ARMCP_PKT_CTL_OPCODE_MASK       0x1FFF0000
 226 
 227 struct armcp_packet {
 228         union {
 229                 __le64 value;   /* For SET packets */
 230                 __le64 result;  /* For GET packets */
 231                 __le64 addr;    /* For PQ */
 232         };
 233 
 234         __le32 ctl;
 235 
 236         __le32 fence;           /* Signal to host that message is completed */
 237 
 238         union {
 239                 struct {/* For temperature/current/voltage/fan/pwm get/set */
 240                         __le16 sensor_index;
 241                         __le16 type;
 242                 };
 243 
 244                 struct {        /* For I2C read/write */
 245                         __u8 i2c_bus;
 246                         __u8 i2c_addr;
 247                         __u8 i2c_reg;
 248                         __u8 pad; /* unused */
 249                 };
 250 
 251                 /* For frequency get/set */
 252                 __le32 pll_index;
 253 
 254                 /* For led set */
 255                 __le32 led_index;
 256 
 257                 /* For get Armcp info/EEPROM data */
 258                 __le32 data_max_size;
 259         };
 260 };
 261 
 262 struct armcp_unmask_irq_arr_packet {
 263         struct armcp_packet armcp_pkt;
 264         __le32 length;
 265         __le32 irqs[0];
 266 };
 267 
 268 enum armcp_packet_rc {
 269         armcp_packet_success,
 270         armcp_packet_invalid,
 271         armcp_packet_fault
 272 };
 273 
 274 enum armcp_temp_type {
 275         armcp_temp_input,
 276         armcp_temp_max = 6,
 277         armcp_temp_max_hyst,
 278         armcp_temp_crit,
 279         armcp_temp_crit_hyst
 280 };
 281 
 282 enum armcp_in_attributes {
 283         armcp_in_input,
 284         armcp_in_min,
 285         armcp_in_max
 286 };
 287 
 288 enum armcp_curr_attributes {
 289         armcp_curr_input,
 290         armcp_curr_min,
 291         armcp_curr_max
 292 };
 293 
 294 enum armcp_fan_attributes {
 295         armcp_fan_input,
 296         armcp_fan_min = 2,
 297         armcp_fan_max
 298 };
 299 
 300 enum armcp_pwm_attributes {
 301         armcp_pwm_input,
 302         armcp_pwm_enable
 303 };
 304 
 305 /* Event Queue Packets */
 306 
 307 struct eq_generic_event {
 308         __le64 data[7];
 309 };
 310 
 311 /*
 312  * ArmCP info
 313  */
 314 
 315 #define CARD_NAME_MAX_LEN               16
 316 #define VERSION_MAX_LEN                 128
 317 #define ARMCP_MAX_SENSORS               128
 318 
 319 struct armcp_sensor {
 320         __le32 type;
 321         __le32 flags;
 322 };
 323 
 324 /**
 325  * struct armcp_info - Info from ArmCP that is necessary to the host's driver
 326  * @sensors: available sensors description.
 327  * @kernel_version: ArmCP linux kernel version.
 328  * @reserved: reserved field.
 329  * @cpld_version: CPLD programmed F/W version.
 330  * @infineon_version: Infineon main DC-DC version.
 331  * @fuse_version: silicon production FUSE information.
 332  * @thermal_version: thermald S/W version.
 333  * @armcp_version: ArmCP S/W version.
 334  * @dram_size: available DRAM size.
 335  * @card_name: card name that will be displayed in HWMON subsystem on the host
 336  */
 337 struct armcp_info {
 338         struct armcp_sensor sensors[ARMCP_MAX_SENSORS];
 339         __u8 kernel_version[VERSION_MAX_LEN];
 340         __le32 reserved[3];
 341         __le32 cpld_version;
 342         __le32 infineon_version;
 343         __u8 fuse_version[VERSION_MAX_LEN];
 344         __u8 thermal_version[VERSION_MAX_LEN];
 345         __u8 armcp_version[VERSION_MAX_LEN];
 346         __le64 dram_size;
 347         char card_name[CARD_NAME_MAX_LEN];
 348 };
 349 
 350 #endif /* ARMCP_IF_H */

/* [<][>][^][v][top][bottom][index][help] */