/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ /* Copyright (c) 2015-2022 Graphcore Ltd. */ /* * IPU device driver. * * Description: Linux device driver parameters. */ #include #include #include #include #include #include #include #include #include #include #include #include #include "ipu_arch_map.h" #include "ipu_defines.h" #include "ipu_signals.h" #include "ipu_sensors.h" #include "icu.h" #ifndef _IPU_DRIVER_H_ #define _IPU_DRIVER_H_ // To allow string expansion correctly using pre-processor tokens #define STR(s) #s #define STRING(s) STR(s) #define IPU_MODULE_AUTHOR "Graphcore Limited" #define IPU_MODULE_LICENSE "GPL" #define IPU_MODULE_DESCRIPTION "IPU PCI Driver" #define IPU_MODULE_NAME "ipu" #define IPU_MODULE_VERSION "1.4.0" // Used as the precise_ver attribute for the kernel module #define SHA_VERSION "7b7a603b-patch" // Increment when an interface is modified or a new API is introduced #define IPU_MODULE_ABI_REVISION (25) #define ICU_CMD_STORE_IPU_PARITY_ERROR_IPU_SHIFT (16) // The word index of the num_errors value in the response #define ICU_RESP_STORE_IPU_PARITY_ERROR_NUM_ERRORS_INDEX (1) // The word index of the error state value in the response #define ICU_RESP_GET_DRIVER_ERROR_STATE_VALUE_INDEX (1) #define ICU_FW_MAJOR_SHIFT (16) #define ICU_FW_MINOR_SHIFT (8) #define ICU_FW_POINT_SHIFT (0) #define ICU_FW_VERSION_MASK (0xff) // 2.6.1 #define ICU_FIRMWARE_VER_HAS_BOOTLOADER_VER (2006001) // 2.5.0 #define ICU_FIRMWARE_VER_SUPPORTS_PARITY_CHECK (2005000) // 2.4.5 #define ICU_FIRMWARE_VER_SUPPORTS_TELEMETRY (2004005) // 2.2.3 #define ICU_FIRMWARE_VER_USE_V2_PROTOCOL (2002003) // 1.5.0 #define ICU_FIRMWARE_VER_HAS_FIRMWARE_VER (1005000) /* * Defines a 'family' of board types. * This is combined with board_variant_t to specify * an exact board type. */ enum board_type_t { IPU_BOARD_TYPE_UNKNOWN, IPU_BOARD_TYPE_C2, IPU_BOARD_TYPE_S1, IPU_BOARD_TYPE_C200, IPU_BOARD_TYPE_M1, IPU_BOARD_TYPE_M2000, /* includes M2000W, etc */ IPU_BOARD_TYPE_C600 }; /* * Used to differentiate between variants of a board type. * If a board does not have any variants, board_variant will be always be * IPU_BOARD_VARIANT_STANDARD * Currently only the M2000 family has variants defined. */ enum board_variant_t { IPU_BOARD_VARIANT_STANDARD = 0, IPU_BOARD_VARIANT_M2000 = 0, IPU_BOARD_VARIANT_M2000W = 1, IPU_BOARD_VARIANT_M2000WX }; enum chr_dev_t { CHRDEV_CONFIG, CHRDEV_EXCHANGE, CHRDEV_MEMORY, #ifdef CONFIG_PCI_P2PDMA CHRDEV_P2P_EXCHANGE, #endif CHRDEV_NUM_FILES }; static inline bool is_ipum_board(enum board_type_t board_type) { return board_type == IPU_BOARD_TYPE_M1 || board_type == IPU_BOARD_TYPE_M2000; } #define IPU_DRIVER_VERSION_MAJOR (1) #define IPU_DRIVER_VERSION_MINOR (4) #define IPU_DRIVER_VERSION_POINT (0) /* Hard-coded during development. Set to zero to dynamically allocate. */ #define IPU_CHRDEV_MAJOR (0) #define IPU_CHRDEV_MINOR (0) #define IPU_KERN_ALERT_PREFIX KERN_ALERT IPU_MODULE_NAME ": " #define IPU_KERN_WARNING_PREFIX KERN_WARNING IPU_MODULE_NAME ": " #define IPU_KERN_INFO_PREFIX KERN_INFO IPU_MODULE_NAME ": " #define SLOT_STRING_SIZE (50) #define VERSION_STRING_SIZE (128) /* * Byte value used to initialise the remote memory before * it is released to the pool */ #define MEM_INIT_VAL (0xFF) extern int global_log_enable; #define ipu_info(ipu, fmt, ...) do { \ if (global_log_enable) \ dev_info(&ipu->pci_dev->dev, fmt, ##__VA_ARGS__); \ } while (0) #define ipu_err(ipu, fmt, ...) dev_err(&ipu->pci_dev->dev, \ fmt, ##__VA_ARGS__) #define ipu_info_ratelimited(ipu, fmt, ...) do { \ if (global_log_enable) \ dev_info_ratelimited(&ipu->pci_dev->dev, fmt, ##__VA_ARGS__); \ } while (0) #define ipu_info_verbose(ipu, fmt, ...) do { \ if (global_log_enable > 1) \ dev_info(&ipu->pci_dev->dev, fmt, ##__VA_ARGS__); \ } while (0) #define NUM_ALL_SENSORS \ (MAX_DIE_TEMP_SENSORS + MAX_BOARD_TEMP_SENSORS + MAX_POWER_SENSORS + \ MAX_APP_SIZES + MAX_IPU_BUSY_DURATIONS) struct id_alloc; struct attached_buffer { struct rb_node node; unsigned int index; /* The index of first entry in the HEXOPT table. */ unsigned int nb_entries; /* Number of HEXOPT entries for the buffer. */ struct page **buffer_pages; /* Array of pointers to the mem pages. */ struct sg_table sgt_dma; /* Scatter-gather table for DMA mappings */ }; struct ipu_sensor { u32 valid; atomic_t value; }; struct contiguous_mem_list_entry { struct list_head list; u64 phys_addr; u64 virt_addr; u64 size; u64 handle; }; struct ipu_hexopt_constant { u32 HEXOPT_NB_ENTRIES; u32 HEXOPT_PAGE_SIZE; }; struct nlc_info { u32 nlc_base; /* Base address of NLC */ u64 acc_cor_err_cnt; /* Accumulated NLC correctable error count */ /* Hex encoding of NLC, used to lookup base address from sysfs attribute * name. * E.g.: sysfs attribute name nlc_w_0b_errcnt has nlc encoding 0x0b */ char nlc_encoding; }; #ifdef CONFIG_PCI_P2PDMA struct ipu_p2p_vma { struct ipu_device *ipu_dev; dma_addr_t phy_addr; void *va; size_t nr_pages; /* mutex to hold pages */ struct mutex mutex; struct page *used_pages[]; }; #endif struct ipu_device { resource_size_t config_start; /* Base address of the config BAR. */ resource_size_t config_size; /* Size of the config BAR. */ resource_size_t exchange_start; /* Base address of the exchange BAR. */ resource_size_t exchange_size; /* Size of the exchange BAR. */ resource_size_t memory_start; /* Base address of reserved memory */ resource_size_t memory_size; /* Size of the reserved memory. */ void __iomem *config; /* Config BAR memory. */ void __iomem *exchange; /* Exchange BAR memory. */ void __iomem *memory; /* Reserved contiguous memory */ void __iomem *spb_acc; /* Skala Packet Bridge ACC region */ void __iomem *config_sec; /* Secondary config BAR memory. */ void __iomem *exchange_sec; /* Secondary exchange BAR memory. */ struct list_head contiguous_mem_head; atomic_t contiguous_mem_handle; struct msix_entry *interrupts; int num_ints; char slot[SLOT_STRING_SIZE]; u64 serial; u64 fw_ver; u8 icu_supports_telemetry; u8 icu_supports_parity_info; u8 icu_use_v2_protocol; // T39830 - avoid using MCUCMDR u8 icu_has_firmware_ver_str; u8 icu_has_bootloader_ver_str; char firmware_version_str[VERSION_STRING_SIZE]; char bootloader_version_str[VERSION_STRING_SIZE]; /* We share one ICU between two IPUs. These IPUs have a unique index. * Some ICU commands require us to pass this index in. */ u8 icu_index; atomic_t tile_clk_speed; struct task_struct *tile_clk_speed_kthread; u32 tile_clk_speed_poll_speed; /* poll interval in seconds*/ u32 prev_clk_throttle_level; atomic_t clk_throttle_threshold1; atomic_t clk_throttle_threshold2; atomic_t clk_throttle_threshold3; u8 power_save_active; enum { NO_ERROR = 0, UNCORRECTABLE_ERROR = 1, NUM_ERROR_STATE } ipu_error_state; u32 ipu_num_parity_errors; u32 ipu_error_threshold_seconds; u32 ipu_error_threshold_num; u32 ipu_fake_parity_error; u8 check_parity_errors; u8 *parity_error_count; struct device *hwmon_dev; struct ipu_sensor sensor[NUM_ALL_SENSORS]; /* * Keep a timestamp of last time we read the sensors, * so we can avoid reading them too often and * loading the ICU unnecessarily */ u64 die_temp_last_update_ts; u64 board_temp_last_update_ts; u64 power_last_update_ts; u32 parity_init_flag; u64 mcu_datr_copy[3]; struct cdev cdev[CHRDEV_NUM_FILES]; unsigned char *config_buffer; dev_t device_id; struct semaphore config_available; struct semaphore exchange_available; struct semaphore memory_available; struct completion mailbox_rsp_available; struct mutex mailbox_available; /* mailbox mutex */ struct pid *user_pid; unsigned int user_device_id; struct class *cl; int is_initialised; enum board_type_t board_type; const char *board_name; enum board_variant_t board_variant; const char *board_variant_name; struct rb_root buffers_tree; DECLARE_HASHTABLE(coherent_mem_allocs, 8); struct pci_dev *pci_dev; struct idr *idr; unsigned int filename_id; unsigned long ints_mask; int supports_dma; void *default_page_vptr; union { /* If 64-bit DMA addresses are supported, use the * dma_handle_t otherwise use the phys_addr_t */ phys_addr_t default_hexopt_phys; dma_addr_t default_hexopt_dma; }; struct page *hsp_notify[2]; u32 hsp[2]; dma_addr_t hsp_pa[2]; struct mailbox_msg mcu_sync_msg_response; int mcu_ioctl_read_pending; int dnc; struct ipu_arch_map *arch_map; struct ipu_hexopt_constant *hexopt_constants; /* mutex to protect accumulated NLC correctable error count */ struct mutex nlc_mutex; struct nlc_info nlc_data[NUM_NLCS]; u64 nlc_total_errcnt; /* Accumulated correctable error count from all NLCs */ u64 nlc_total_errcnt_session; /* Like above but the value may be cleared */ /* end of the members guarded by nlc_mutex */ /* counters for hexopt and hexoatt used bytes */ atomic64_t hexopt_used_bytes; atomic64_t hexoatt_used_bytes; u32 aer_data; u32 user_data; /* Data used by user processes */ /* mutex to protect accumulated error packet count in SPB */ struct mutex spb_mutex; u64 spb_error_pkt_count; /* Accumulated error packet count in SPB */ u64 spb_error_pkt_count_session; /* Like above but the value may be cleared */ }; static inline bool has_power_save_mode(struct ipu_device *ipu_dev) { return (ipu_dev->board_type == IPU_BOARD_TYPE_M2000 && ipu_dev->board_variant == IPU_BOARD_VARIANT_M2000W) || ipu_dev->board_type == IPU_BOARD_TYPE_C600; } static inline bool is_single_ipu_board(struct ipu_device *ipu_dev) { return (ipu_dev->board_type == IPU_BOARD_TYPE_C600); } static inline void check_and_saturate_u64(u64 *count, u32 new_val) { u64 temp_val = *count + new_val; /* Can happen only due to overflow */ if (temp_val < *count) *count = U64_MAX; else *count = temp_val; } #endif