diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/clk/nuvoton.h | 9 | ||||
-rw-r--r-- | include/linux/fsi-occ.h | 36 | ||||
-rw-r--r-- | include/linux/fsi-sbefifo.h | 3 | ||||
-rw-r--r-- | include/linux/mfd/intel-peci-client.h | 110 | ||||
-rw-r--r-- | include/linux/peci.h | 142 | ||||
-rw-r--r-- | include/uapi/linux/ncsi.h | 6 | ||||
-rw-r--r-- | include/uapi/linux/peci-ioctl.h | 403 |
7 files changed, 709 insertions, 0 deletions
diff --git a/include/linux/clk/nuvoton.h b/include/linux/clk/nuvoton.h new file mode 100644 index 000000000000..9a474d691786 --- /dev/null +++ b/include/linux/clk/nuvoton.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2014-2019 Nuvoton Technology corporation. */ + +#ifndef __LINUX_CLK_NUVOTON_H_ +#define __LINUX_CLK_NUVOTON_H_ + +void nuvoton_npcm750_clock_init(void); + +#endif diff --git a/include/linux/fsi-occ.h b/include/linux/fsi-occ.h new file mode 100644 index 000000000000..4810368d4fb2 --- /dev/null +++ b/include/linux/fsi-occ.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) IBM Corporation 2017 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERGCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef LINUX_FSI_OCC_H +#define LINUX_FSI_OCC_H + +struct device; + +#define OCC_RESP_CMD_IN_PRG 0xFF +#define OCC_RESP_SUCCESS 0 +#define OCC_RESP_CMD_INVAL 0x11 +#define OCC_RESP_CMD_LEN_INVAL 0x12 +#define OCC_RESP_DATA_INVAL 0x13 +#define OCC_RESP_CHKSUM_ERR 0x14 +#define OCC_RESP_INT_ERR 0x15 +#define OCC_RESP_BAD_STATE 0x16 +#define OCC_RESP_CRIT_EXCEPT 0xE0 +#define OCC_RESP_CRIT_INIT 0xE1 +#define OCC_RESP_CRIT_WATCHDOG 0xE2 +#define OCC_RESP_CRIT_OCB 0xE3 +#define OCC_RESP_CRIT_HW 0xE4 + +extern int fsi_occ_submit(struct device *dev, const void *request, size_t req_len, + void *response, size_t *resp_len); + +#endif /* LINUX_FSI_OCC_H */ diff --git a/include/linux/fsi-sbefifo.h b/include/linux/fsi-sbefifo.h index 13f9ebeaa25e..9f8dcfd3d664 100644 --- a/include/linux/fsi-sbefifo.h +++ b/include/linux/fsi-sbefifo.h @@ -30,4 +30,7 @@ int sbefifo_submit(struct device *dev, const __be32 *command, size_t cmd_len, int sbefifo_parse_status(struct device *dev, u16 cmd, __be32 *response, size_t resp_len, size_t *data_len); +struct fsi_device; +struct fsi_device *sbefifo_get_fsidev(struct device *dev); + #endif /* LINUX_FSI_SBEFIFO_H */ diff --git a/include/linux/mfd/intel-peci-client.h b/include/linux/mfd/intel-peci-client.h new file mode 100644 index 000000000000..8f6d823a59cd --- /dev/null +++ b/include/linux/mfd/intel-peci-client.h @@ -0,0 +1,110 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2018 Intel Corporation */ + +#ifndef __LINUX_MFD_INTEL_PECI_CLIENT_H +#define __LINUX_MFD_INTEL_PECI_CLIENT_H + +#include <linux/peci.h> + +#if IS_ENABLED(CONFIG_X86) +#include <asm/intel-family.h> +#else +/** + * Architectures other than x86 cannot include the header file so define these + * at here. These are needed for detecting type of client x86 CPUs behind a PECI + * connection. + */ +#define INTEL_FAM6_HASWELL_X 0x3F +#define INTEL_FAM6_BROADWELL_X 0x4F +#define INTEL_FAM6_SKYLAKE_X 0x55 +#endif + +#define CORE_MAX_ON_HSX 18 /* Max number of cores on Haswell */ +#define CHAN_RANK_MAX_ON_HSX 8 /* Max number of channel ranks on Haswell */ +#define DIMM_IDX_MAX_ON_HSX 3 /* Max DIMM index per channel on Haswell */ + +#define CORE_MAX_ON_BDX 24 /* Max number of cores on Broadwell */ +#define CHAN_RANK_MAX_ON_BDX 4 /* Max number of channel ranks on Broadwell */ +#define DIMM_IDX_MAX_ON_BDX 3 /* Max DIMM index per channel on Broadwell */ + +#define CORE_MAX_ON_SKX 28 /* Max number of cores on Skylake */ +#define CHAN_RANK_MAX_ON_SKX 6 /* Max number of channel ranks on Skylake */ +#define DIMM_IDX_MAX_ON_SKX 2 /* Max DIMM index per channel on Skylake */ + +#define CORE_NUMS_MAX CORE_MAX_ON_SKX +#define CHAN_RANK_MAX CHAN_RANK_MAX_ON_HSX +#define DIMM_IDX_MAX DIMM_IDX_MAX_ON_HSX +#define DIMM_NUMS_MAX (CHAN_RANK_MAX * DIMM_IDX_MAX) + +/** + * struct cpu_gen_info - CPU generation specific information + * @family: CPU family ID + * @model: CPU model + * @core_max: max number of cores + * @chan_rank_max: max number of channel ranks + * @dimm_idx_max: max number of DIMM indices + * + * CPU generation specific information to identify maximum number of cores and + * DIMM slots. + */ +struct cpu_gen_info { + u16 family; + u8 model; + uint core_max; + uint chan_rank_max; + uint dimm_idx_max; +}; + +/** + * struct peci_client_manager - PECI client manager information + * @client; pointer to the PECI client + * @dev: pointer to the struct device + * @name: PECI client manager name + * @gen_info: CPU generation info of the detected CPU + * + * PECI client manager information for managing PECI sideband functions on a CPU + * client. + */ +struct peci_client_manager { + struct peci_client *client; + struct device *dev; + char name[PECI_NAME_SIZE]; + const struct cpu_gen_info *gen_info; +}; + +/** + * peci_client_read_package_config - read from the Package Configuration Space + * @priv: driver private data structure + * @index: encoding index for the requested service + * @param: parameter to specify the exact data being requested + * @data: data buffer to store the result + * Context: can sleep + * + * A generic PECI command that provides read access to the + * "Package Configuration Space" that is maintained by the PCU, including + * various power and thermal management functions. Typical PCS read services + * supported by the processor may include access to temperature data, energy + * status, run time information, DIMM temperatures and so on. + * + * Return: zero on success, else a negative error code. + */ +static inline int +peci_client_read_package_config(struct peci_client_manager *priv, + u8 index, u16 param, u8 *data) +{ + struct peci_rd_pkg_cfg_msg msg; + int rc; + + msg.addr = priv->client->addr; + msg.index = index; + msg.param = param; + msg.rx_len = 4; + + rc = peci_command(priv->client->adapter, PECI_CMD_RD_PKG_CFG, &msg); + if (!rc) + memcpy(data, msg.pkg_config, 4); + + return rc; +} + +#endif /* __LINUX_MFD_INTEL_PECI_CLIENT_H */ diff --git a/include/linux/peci.h b/include/linux/peci.h new file mode 100644 index 000000000000..d0e47d45d1d0 --- /dev/null +++ b/include/linux/peci.h @@ -0,0 +1,142 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2018 Intel Corporation */ + +#ifndef __LINUX_PECI_H +#define __LINUX_PECI_H + +#include <linux/cdev.h> +#include <linux/device.h> +#include <linux/peci-ioctl.h> +#include <linux/rtmutex.h> + +#define PECI_NAME_SIZE 32 + +struct peci_board_info { + char type[PECI_NAME_SIZE]; + unsigned short addr; /* CPU client address */ + struct device_node *of_node; +}; + +/** + * struct peci_adapter - represent a PECI adapter + * @owner: owner module of the PECI adpater + * @bus_lock: mutex for exclusion of multiple callers + * @dev: device interface to this driver + * @cdev: character device object to create character device + * @nr: the bus number to map + * @name: name of the adapter + * @userspace_clients_lock: mutex for exclusion of clients handling + * @userspace_clients: list of registered clients + * @xfer: low-level transfer function pointer of the adapter + * @cmd_mask: mask for supportable PECI commands + * + * Each PECI adapter can communicate with one or more PECI client children. + * These make a small bus, sharing a single wired PECI connection. + */ +struct peci_adapter { + struct module *owner; + struct rt_mutex bus_lock; + struct device dev; + struct cdev cdev; + int nr; + char name[PECI_NAME_SIZE]; + struct mutex userspace_clients_lock; /* clients list mutex */ + struct list_head userspace_clients; + int (*xfer)(struct peci_adapter *adapter, + struct peci_xfer_msg *msg); + uint cmd_mask; +}; + +static inline struct peci_adapter *to_peci_adapter(void *d) +{ + return container_of(d, struct peci_adapter, dev); +} + +static inline void *peci_get_adapdata(const struct peci_adapter *adapter) +{ + return dev_get_drvdata(&adapter->dev); +} + +static inline void peci_set_adapdata(struct peci_adapter *adapter, void *data) +{ + dev_set_drvdata(&adapter->dev, data); +} + +/** + * struct peci_client - represent a PECI client device + * @dev: driver model device node for the client + * @adapter: manages the bus segment hosting this PECI device + * @addr: address used on the PECI bus connected to the parent adapter + * @name: indicates the type of the device + * @detected: detected PECI clients list + * + * A peci_client identifies a single device (i.e. CPU) connected to a peci bus. + * The behaviour exposed to Linux is defined by the driver managing the device. + */ +struct peci_client { + struct device dev; + struct peci_adapter *adapter; + u8 addr; + char name[PECI_NAME_SIZE]; + struct list_head detected; +}; + +static inline struct peci_client *to_peci_client(void *d) +{ + return container_of(d, struct peci_client, dev); +} + +struct peci_device_id { + char name[PECI_NAME_SIZE]; + unsigned long driver_data; /* Data private to the driver */ +}; + +/** + * struct peci_driver - represent a PECI device driver + * @probe: callback for device binding + * @remove: callback for device unbinding + * @shutdown: callback for device shutdown + * @driver: device driver model driver + * @id_table: list of PECI devices supported by this driver + * + * The driver.owner field should be set to the module owner of this driver. + * The driver.name field should be set to the name of this driver. + */ +struct peci_driver { + int (*probe)(struct peci_client *client); + int (*remove)(struct peci_client *client); + void (*shutdown)(struct peci_client *client); + struct device_driver driver; + const struct peci_device_id *id_table; +}; + +static inline struct peci_driver *to_peci_driver(void *d) +{ + return container_of(d, struct peci_driver, driver); +} + +/** + * module_peci_driver - Helper macro for registering a modular PECI driver + * @__peci_driver: peci_driver struct + * + * Helper macro for PECI drivers which do not do anything special in module + * init/exit. This eliminates a lot of boilerplate. Each module may only + * use this macro once, and calling it replaces module_init() and module_exit() + */ +#define module_peci_driver(__peci_driver) \ + module_driver(__peci_driver, peci_add_driver, peci_del_driver) + +/* use a define to avoid include chaining to get THIS_MODULE */ +#define peci_add_driver(driver) peci_register_driver(THIS_MODULE, driver) + +int peci_register_driver(struct module *owner, struct peci_driver *drv); +void peci_del_driver(struct peci_driver *driver); +struct peci_client *peci_verify_client(struct device *dev); +struct peci_adapter *peci_alloc_adapter(struct device *dev, unsigned int size); +int peci_add_adapter(struct peci_adapter *adapter); +void peci_del_adapter(struct peci_adapter *adapter); +struct peci_adapter *peci_verify_adapter(struct device *dev); +int peci_command(struct peci_adapter *adpater, enum peci_cmd cmd, void *vmsg); +int peci_get_cpu_id(struct peci_adapter *adapter, u8 addr, u32 *cpu_id); + +#endif /* __LINUX_PECI_H */ diff --git a/include/uapi/linux/ncsi.h b/include/uapi/linux/ncsi.h index 4c292ecbb748..0a26a5576645 100644 --- a/include/uapi/linux/ncsi.h +++ b/include/uapi/linux/ncsi.h @@ -23,6 +23,9 @@ * optionally the preferred NCSI_ATTR_CHANNEL_ID. * @NCSI_CMD_CLEAR_INTERFACE: clear any preferred package/channel combination. * Requires NCSI_ATTR_IFINDEX. + * @NCSI_CMD_SEND_CMD: send NC-SI command to network card. + * Requires NCSI_ATTR_IFINDEX, NCSI_ATTR_PACKAGE_ID + * and NCSI_ATTR_CHANNEL_ID. * @NCSI_CMD_MAX: highest command number */ enum ncsi_nl_commands { @@ -30,6 +33,7 @@ enum ncsi_nl_commands { NCSI_CMD_PKG_INFO, NCSI_CMD_SET_INTERFACE, NCSI_CMD_CLEAR_INTERFACE, + NCSI_CMD_SEND_CMD, __NCSI_CMD_AFTER_LAST, NCSI_CMD_MAX = __NCSI_CMD_AFTER_LAST - 1 @@ -43,6 +47,7 @@ enum ncsi_nl_commands { * @NCSI_ATTR_PACKAGE_LIST: nested array of NCSI_PKG_ATTR attributes * @NCSI_ATTR_PACKAGE_ID: package ID * @NCSI_ATTR_CHANNEL_ID: channel ID + * @NCSI_ATTR_DATA: command payload * @NCSI_ATTR_MAX: highest attribute number */ enum ncsi_nl_attrs { @@ -51,6 +56,7 @@ enum ncsi_nl_attrs { NCSI_ATTR_PACKAGE_LIST, NCSI_ATTR_PACKAGE_ID, NCSI_ATTR_CHANNEL_ID, + NCSI_ATTR_DATA, __NCSI_ATTR_AFTER_LAST, NCSI_ATTR_MAX = __NCSI_ATTR_AFTER_LAST - 1 diff --git a/include/uapi/linux/peci-ioctl.h b/include/uapi/linux/peci-ioctl.h new file mode 100644 index 000000000000..a6dae71cbff5 --- /dev/null +++ b/include/uapi/linux/peci-ioctl.h @@ -0,0 +1,403 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2018 Intel Corporation */ + +#ifndef __PECI_IOCTL_H +#define __PECI_IOCTL_H + +#include <linux/ioctl.h> +#include <linux/types.h> + +/* Base Address of 48d */ +#define PECI_BASE_ADDR 0x30 /* The PECI client's default address of 0x30 */ +#define PECI_OFFSET_MAX 8 /* Max numver of CPU clients */ + +/* PCI Access */ +#define MAX_PCI_READ_LEN 24 /* Number of bytes of the PCI Space read */ + +#define PCI_BUS0_CPU0 0x00 +#define PCI_BUS0_CPU1 0x80 +#define PCI_CPUBUSNO_BUS 0x00 +#define PCI_CPUBUSNO_DEV 0x08 +#define PCI_CPUBUSNO_FUNC 0x02 +#define PCI_CPUBUSNO 0xcc +#define PCI_CPUBUSNO_1 0xd0 +#define PCI_CPUBUSNO_VALID 0xd4 + +/* Package Identifier Read Parameter Value */ +#define PKG_ID_CPU_ID 0x0000 /* CPUID Info */ +#define PKG_ID_PLATFORM_ID 0x0001 /* Platform ID */ +#define PKG_ID_UNCORE_ID 0x0002 /* Uncore Device ID */ +#define PKG_ID_MAX_THREAD_ID 0x0003 /* Max Thread ID */ +#define PKG_ID_MICROCODE_REV 0x0004 /* CPU Microcode Update Revision */ +#define PKG_ID_MACHINE_CHECK_STATUS 0x0005 /* Machine Check Status */ + +/* RdPkgConfig Index */ +#define MBX_INDEX_CPU_ID 0 /* Package Identifier Read */ +#define MBX_INDEX_VR_DEBUG 1 /* VR Debug */ +#define MBX_INDEX_PKG_TEMP_READ 2 /* Package Temperature Read */ +#define MBX_INDEX_ENERGY_COUNTER 3 /* Energy counter */ +#define MBX_INDEX_ENERGY_STATUS 4 /* DDR Energy Status */ +#define MBX_INDEX_WAKE_MODE_BIT 5 /* "Wake on PECI" Mode bit */ +#define MBX_INDEX_EPI 6 /* Efficient Performance Indication */ +#define MBX_INDEX_PKG_RAPL_PERF 8 /* Pkg RAPL Performance Status Read */ +#define MBX_INDEX_PER_CORE_DTS_TEMP 9 /* Per Core DTS Temperature Read */ +#define MBX_INDEX_DTS_MARGIN 10 /* DTS thermal margin */ +#define MBX_INDEX_SKT_PWR_THRTL_DUR 11 /* Socket Power Throttled Duration */ +#define MBX_INDEX_CFG_TDP_CONTROL 12 /* TDP Config Control */ +#define MBX_INDEX_CFG_TDP_LEVELS 13 /* TDP Config Levels */ +#define MBX_INDEX_DDR_DIMM_TEMP 14 /* DDR DIMM Temperature */ +#define MBX_INDEX_CFG_ICCMAX 15 /* Configurable ICCMAX */ +#define MBX_INDEX_TEMP_TARGET 16 /* Temperature Target Read */ +#define MBX_INDEX_CURR_CFG_LIMIT 17 /* Current Config Limit */ +#define MBX_INDEX_DIMM_TEMP_READ 20 /* Package Thermal Status Read */ +#define MBX_INDEX_DRAM_IMC_TMP_READ 22 /* DRAM IMC Temperature Read */ +#define MBX_INDEX_DDR_CH_THERM_STAT 23 /* DDR Channel Thermal Status */ +#define MBX_INDEX_PKG_POWER_LIMIT1 26 /* Package Power Limit1 */ +#define MBX_INDEX_PKG_POWER_LIMIT2 27 /* Package Power Limit2 */ +#define MBX_INDEX_TDP 28 /* Thermal design power minimum */ +#define MBX_INDEX_TDP_HIGH 29 /* Thermal design power maximum */ +#define MBX_INDEX_TDP_UNITS 30 /* Units for power/energy registers */ +#define MBX_INDEX_RUN_TIME 31 /* Accumulated Run Time */ +#define MBX_INDEX_CONSTRAINED_TIME 32 /* Thermally Constrained Time Read */ +#define MBX_INDEX_TURBO_RATIO 33 /* Turbo Activation Ratio */ +#define MBX_INDEX_DDR_RAPL_PL1 34 /* DDR RAPL PL1 */ +#define MBX_INDEX_DDR_PWR_INFO_HIGH 35 /* DRAM Power Info Read (high) */ +#define MBX_INDEX_DDR_PWR_INFO_LOW 36 /* DRAM Power Info Read (low) */ +#define MBX_INDEX_DDR_RAPL_PL2 37 /* DDR RAPL PL2 */ +#define MBX_INDEX_DDR_RAPL_STATUS 38 /* DDR RAPL Performance Status */ +#define MBX_INDEX_DDR_HOT_ABSOLUTE 43 /* DDR Hottest Dimm Absolute Temp */ +#define MBX_INDEX_DDR_HOT_RELATIVE 44 /* DDR Hottest Dimm Relative Temp */ +#define MBX_INDEX_DDR_THROTTLE_TIME 45 /* DDR Throttle Time */ +#define MBX_INDEX_DDR_THERM_STATUS 46 /* DDR Thermal Status */ +#define MBX_INDEX_TIME_AVG_TEMP 47 /* Package time-averaged temperature */ +#define MBX_INDEX_TURBO_RATIO_LIMIT 49 /* Turbo Ratio Limit Read */ +#define MBX_INDEX_HWP_AUTO_OOB 53 /* HWP Autonomous Out-of-band */ +#define MBX_INDEX_DDR_WARM_BUDGET 55 /* DDR Warm Power Budget */ +#define MBX_INDEX_DDR_HOT_BUDGET 56 /* DDR Hot Power Budget */ +#define MBX_INDEX_PKG_PSYS_PWR_LIM3 57 /* Package/Psys Power Limit3 */ +#define MBX_INDEX_PKG_PSYS_PWR_LIM1 58 /* Package/Psys Power Limit1 */ +#define MBX_INDEX_PKG_PSYS_PWR_LIM2 59 /* Package/Psys Power Limit2 */ +#define MBX_INDEX_PKG_PSYS_PWR_LIM4 60 /* Package/Psys Power Limit4 */ +#define MBX_INDEX_PERF_LIMIT_REASON 65 /* Performance Limit Reasons */ + +/* WrPkgConfig Index */ +#define MBX_INDEX_DIMM_AMBIENT 19 +#define MBX_INDEX_DIMM_TEMP 24 + +/* Device Specific Completion Code (CC) Definition */ +#define DEV_PECI_CC_SUCCESS 0x40 +#define DEV_PECI_CC_TIMEOUT 0x80 +#define DEV_PECI_CC_OUT_OF_RESOURCE 0x81 +#define DEV_PECI_CC_UNAVAIL_RESOURCE 0x82 +#define DEV_PECI_CC_INVALID_REQ 0x90 + +/* Completion Code mask to check retry needs */ +#define DEV_PECI_CC_RETRY_CHECK_MASK 0xf0 +#define DEV_PECI_CC_NEED_RETRY 0x80 + +/* Skylake EDS says to retry for 250ms */ +#define DEV_PECI_RETRY_TIME_MS 250 +#define DEV_PECI_RETRY_INTERVAL_USEC 10000 +#define DEV_PECI_RETRY_BIT 0x01 + +#define GET_TEMP_WR_LEN 1 +#define GET_TEMP_RD_LEN 2 +#define GET_TEMP_PECI_CMD 0x01 + +#define GET_DIB_WR_LEN 1 +#define GET_DIB_RD_LEN 8 +#define GET_DIB_PECI_CMD 0xf7 + +#define RDPKGCFG_WRITE_LEN 5 +#define RDPKGCFG_READ_LEN_BASE 1 +#define RDPKGCFG_PECI_CMD 0xa1 + +#define WRPKGCFG_WRITE_LEN_BASE 6 +#define WRPKGCFG_READ_LEN 1 +#define WRPKGCFG_PECI_CMD 0xa5 + +#define RDIAMSR_WRITE_LEN 5 +#define RDIAMSR_READ_LEN 9 +#define RDIAMSR_PECI_CMD 0xb1 + +#define WRIAMSR_PECI_CMD 0xb5 + +#define RDPCICFG_WRITE_LEN 6 +#define RDPCICFG_READ_LEN 5 +#define RDPCICFG_PECI_CMD 0x61 + +#define WRPCICFG_PECI_CMD 0x65 + +#define RDPCICFGLOCAL_WRITE_LEN 5 +#define RDPCICFGLOCAL_READ_LEN_BASE 1 +#define RDPCICFGLOCAL_PECI_CMD 0xe1 + +#define WRPCICFGLOCAL_WRITE_LEN_BASE 6 +#define WRPCICFGLOCAL_READ_LEN 1 +#define WRPCICFGLOCAL_PECI_CMD 0xe5 + +#define PECI_BUFFER_SIZE 32 + +/** + * enum peci_cmd - PECI client commands + * @PECI_CMD_XFER: raw PECI transfer + * @PECI_CMD_PING: ping, a required message for all PECI devices + * @PECI_CMD_GET_DIB: get DIB (Device Info Byte) + * @PECI_CMD_GET_TEMP: get maximum die temperature + * @PECI_CMD_RD_PKG_CFG: read access to the PCS (Package Configuration Space) + * @PECI_CMD_WR_PKG_CFG: write access to the PCS (Package Configuration Space) + * @PECI_CMD_RD_IA_MSR: read access to MSRs (Model Specific Registers) + * @PECI_CMD_WR_IA_MSR: write access to MSRs (Model Specific Registers) + * @PECI_CMD_RD_PCI_CFG: sideband read access to the PCI configuration space + * maintained in downstream devices external to the processor + * @PECI_CMD_WR_PCI_CFG: sideband write access to the PCI configuration space + * maintained in downstream devices external to the processor + * @PECI_CMD_RD_PCI_CFG_LOCAL: sideband read access to the PCI configuration + * space that resides within the processor + * @PECI_CMD_WR_PCI_CFG_LOCAL: sideband write access to the PCI configuration + * space that resides within the processor + * + * Available commands depend on client's PECI revision. + */ +enum peci_cmd { + PECI_CMD_XFER = 0, + PECI_CMD_PING, + PECI_CMD_GET_DIB, + PECI_CMD_GET_TEMP, + PECI_CMD_RD_PKG_CFG, + PECI_CMD_WR_PKG_CFG, + PECI_CMD_RD_IA_MSR, + PECI_CMD_WR_IA_MSR, + PECI_CMD_RD_PCI_CFG, + PECI_CMD_WR_PCI_CFG, + PECI_CMD_RD_PCI_CFG_LOCAL, + PECI_CMD_WR_PCI_CFG_LOCAL, + PECI_CMD_MAX +}; + +/** + * struct peci_xfer_msg - raw PECI transfer command + * @addr; address of the client + * @tx_len: number of data to be written in bytes + * @rx_len: number of data to be read in bytes + * @tx_buf: data to be written, or NULL + * @rx_buf: data to be read, or NULL + * + * raw PECI transfer + */ +struct peci_xfer_msg { + __u8 addr; + __u8 tx_len; + __u8 rx_len; + __u8 tx_buf[PECI_BUFFER_SIZE]; + __u8 rx_buf[PECI_BUFFER_SIZE]; +} __attribute__((__packed__)); + +/** + * struct peci_ping_msg - ping command + * @addr: address of the client + * + * Ping() is a required message for all PECI devices. This message is used to + * enumerate devices or determine if a device has been removed, been + * powered-off, etc. + */ +struct peci_ping_msg { + __u8 addr; +} __attribute__((__packed__)); + +/** + * struct peci_get_dib_msg - GetDIB command + * @addr: address of the client + * @dib: DIB data to be read + * + * The processor PECI client implementation of GetDIB() includes an 8-byte + * response and provides information regarding client revision number and the + * number of supported domains. All processor PECI clients support the GetDIB() + * command. + */ +struct peci_get_dib_msg { + __u8 addr; + __u64 dib; +} __attribute__((__packed__)); + +/** + * struct peci_get_temp_msg - GetTemp command + * @addr: address of the client + * @temp_raw: raw temperature data to be read + * + * The GetTemp() command is used to retrieve the maximum die temperature from a + * target PECI address. The temperature is used by the external thermal + * management system to regulate the temperature on the die. The data is + * returned as a negative value representing the number of degrees centigrade + * below the maximum processor junction temperature. + */ +struct peci_get_temp_msg { + __u8 addr; + __s16 temp_raw; +} __attribute__((__packed__)); + +/** + * struct peci_rd_pkg_cfg_msg - RdPkgConfig command + * @addr: address of the client + * @index: encoding index for the requested service + * @param: specific data being requested + * @rx_len: number of data to be read in bytes + * @pkg_config: package config data to be read + * + * The RdPkgConfig() command provides read access to the Package Configuration + * Space (PCS) within the processor, including various power and thermal + * management functions. Typical PCS read services supported by the processor + * may include access to temperature data, energy status, run time information, + * DIMM temperatures and so on. + */ +struct peci_rd_pkg_cfg_msg { + __u8 addr; + __u8 index; + __u16 param; + __u8 rx_len; + __u8 pkg_config[4]; +} __attribute__((__packed__)); + +/** + * struct peci_wr_pkg_cfg_msg - WrPkgConfig command + * @addr: address of the client + * @index: encoding index for the requested service + * @param: specific data being requested + * @tx_len: number of data to be written in bytes + * @value: package config data to be written + * + * The WrPkgConfig() command provides write access to the Package Configuration + * Space (PCS) within the processor, including various power and thermal + * management functions. Typical PCS write services supported by the processor + * may include power limiting, thermal averaging constant programming and so on. + */ +struct peci_wr_pkg_cfg_msg { + __u8 addr; + __u8 index; + __u16 param; + __u8 tx_len; + __u32 value; +} __attribute__((__packed__)); + +/** + * struct peci_rd_ia_msr_msg - RdIAMSR command + * @addr: address of the client + * @thread_id: ID of the specific logical processor + * @address: address of MSR to read from + * @value: data to be read + * + * The RdIAMSR() PECI command provides read access to Model Specific Registers + * (MSRs) defined in the processor's Intel Architecture (IA). + */ +struct peci_rd_ia_msr_msg { + __u8 addr; + __u8 thread_id; + __u16 address; + __u64 value; +} __attribute__((__packed__)); + +/** + * struct peci_rd_pci_cfg_msg - RdPCIConfig command + * @addr: address of the client + * @bus: PCI bus number + * @device: PCI device number + * @function: specific function to read from + * @reg: specific register to read from + * @pci_config: config data to be read + * + * The RdPCIConfig() command provides sideband read access to the PCI + * configuration space maintained in downstream devices external to the + * processor. + */ +struct peci_rd_pci_cfg_msg { + __u8 addr; + __u8 bus; + __u8 device; + __u8 function; + __u16 reg; + __u8 pci_config[4]; +} __attribute__((__packed__)); + +/** + * struct peci_rd_pci_cfg_local_msg - RdPCIConfigLocal command + * @addr: address of the client + * @bus: PCI bus number + * @device: PCI device number + * @function: specific function to read from + * @reg: specific register to read from + * @rx_len: number of data to be read in bytes + * @pci_config: config data to be read + * + * The RdPCIConfigLocal() command provides sideband read access to the PCI + * configuration space that resides within the processor. This includes all + * processor IIO and uncore registers within the PCI configuration space. + */ +struct peci_rd_pci_cfg_local_msg { + __u8 addr; + __u8 bus; + __u8 device; + __u8 function; + __u16 reg; + __u8 rx_len; + __u8 pci_config[4]; +} __attribute__((__packed__)); + +/** + * struct peci_wr_pci_cfg_local_msg - WrPCIConfigLocal command + * @addr: address of the client + * @bus: PCI bus number + * @device: PCI device number + * @function: specific function to read from + * @reg: specific register to read from + * @tx_len: number of data to be written in bytes + * @value: config data to be written + * + * The WrPCIConfigLocal() command provides sideband write access to the PCI + * configuration space that resides within the processor. PECI originators can + * access this space even before BIOS enumeration of the system buses. + */ +struct peci_wr_pci_cfg_local_msg { + __u8 addr; + __u8 bus; + __u8 device; + __u8 function; + __u16 reg; + __u8 tx_len; + __u32 value; +} __attribute__((__packed__)); + +#define PECI_IOC_BASE 0xb7 + +#define PECI_IOC_XFER \ + _IOWR(PECI_IOC_BASE, PECI_CMD_XFER, struct peci_xfer_msg) + +#define PECI_IOC_PING \ + _IOWR(PECI_IOC_BASE, PECI_CMD_PING, struct peci_ping_msg) + +#define PECI_IOC_GET_DIB \ + _IOWR(PECI_IOC_BASE, PECI_CMD_GET_DIB, struct peci_get_dib_msg) + +#define PECI_IOC_GET_TEMP \ + _IOWR(PECI_IOC_BASE, PECI_CMD_GET_TEMP, struct peci_get_temp_msg) + +#define PECI_IOC_RD_PKG_CFG \ + _IOWR(PECI_IOC_BASE, PECI_CMD_RD_PKG_CFG, struct peci_rd_pkg_cfg_msg) + +#define PECI_IOC_WR_PKG_CFG \ + _IOWR(PECI_IOC_BASE, PECI_CMD_WR_PKG_CFG, struct peci_wr_pkg_cfg_msg) + +#define PECI_IOC_RD_IA_MSR \ + _IOWR(PECI_IOC_BASE, PECI_CMD_RD_IA_MSR, struct peci_rd_ia_msr_msg) + +#define PECI_IOC_RD_PCI_CFG \ + _IOWR(PECI_IOC_BASE, PECI_CMD_RD_PCI_CFG, struct peci_rd_pci_cfg_msg) + +#define PECI_IOC_RD_PCI_CFG_LOCAL \ + _IOWR(PECI_IOC_BASE, PECI_CMD_RD_PCI_CFG_LOCAL, \ + struct peci_rd_pci_cfg_local_msg) + +#define PECI_IOC_WR_PCI_CFG_LOCAL \ + _IOWR(PECI_IOC_BASE, PECI_CMD_WR_PCI_CFG_LOCAL, \ + struct peci_wr_pci_cfg_local_msg) + +#endif /* __PECI_IOCTL_H */ |