18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright 2016-17 IBM Corp. 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#ifndef _VAS_H 78c2ecf20Sopenharmony_ci#define _VAS_H 88c2ecf20Sopenharmony_ci#include <linux/atomic.h> 98c2ecf20Sopenharmony_ci#include <linux/idr.h> 108c2ecf20Sopenharmony_ci#include <asm/vas.h> 118c2ecf20Sopenharmony_ci#include <linux/io.h> 128c2ecf20Sopenharmony_ci#include <linux/dcache.h> 138c2ecf20Sopenharmony_ci#include <linux/mutex.h> 148c2ecf20Sopenharmony_ci#include <linux/stringify.h> 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci/* 178c2ecf20Sopenharmony_ci * Overview of Virtual Accelerator Switchboard (VAS). 188c2ecf20Sopenharmony_ci * 198c2ecf20Sopenharmony_ci * VAS is a hardware "switchboard" that allows senders and receivers to 208c2ecf20Sopenharmony_ci * exchange messages with _minimal_ kernel involvment. The receivers are 218c2ecf20Sopenharmony_ci * typically NX coprocessor engines that perform compression or encryption 228c2ecf20Sopenharmony_ci * in hardware, but receivers can also be other software threads. 238c2ecf20Sopenharmony_ci * 248c2ecf20Sopenharmony_ci * Senders are user/kernel threads that submit compression/encryption or 258c2ecf20Sopenharmony_ci * other requests to the receivers. Senders must format their messages as 268c2ecf20Sopenharmony_ci * Coprocessor Request Blocks (CRB)s and submit them using the "copy" and 278c2ecf20Sopenharmony_ci * "paste" instructions which were introduced in Power9. 288c2ecf20Sopenharmony_ci * 298c2ecf20Sopenharmony_ci * A Power node can have (upto?) 8 Power chips. There is one instance of 308c2ecf20Sopenharmony_ci * VAS in each Power9 chip. Each instance of VAS has 64K windows or ports, 318c2ecf20Sopenharmony_ci * Senders and receivers must each connect to a separate window before they 328c2ecf20Sopenharmony_ci * can exchange messages through the switchboard. 338c2ecf20Sopenharmony_ci * 348c2ecf20Sopenharmony_ci * Each window is described by two types of window contexts: 358c2ecf20Sopenharmony_ci * 368c2ecf20Sopenharmony_ci * Hypervisor Window Context (HVWC) of size VAS_HVWC_SIZE bytes 378c2ecf20Sopenharmony_ci * 388c2ecf20Sopenharmony_ci * OS/User Window Context (UWC) of size VAS_UWC_SIZE bytes. 398c2ecf20Sopenharmony_ci * 408c2ecf20Sopenharmony_ci * A window context can be viewed as a set of 64-bit registers. The settings 418c2ecf20Sopenharmony_ci * in these registers configure/control/determine the behavior of the VAS 428c2ecf20Sopenharmony_ci * hardware when messages are sent/received through the window. The registers 438c2ecf20Sopenharmony_ci * in the HVWC are configured by the kernel while the registers in the UWC can 448c2ecf20Sopenharmony_ci * be configured by the kernel or by the user space application that is using 458c2ecf20Sopenharmony_ci * the window. 468c2ecf20Sopenharmony_ci * 478c2ecf20Sopenharmony_ci * The HVWCs for all windows on a specific instance of VAS are in a contiguous 488c2ecf20Sopenharmony_ci * range of hardware addresses or Base address region (BAR) referred to as the 498c2ecf20Sopenharmony_ci * HVWC BAR for the instance. Similarly the UWCs for all windows on an instance 508c2ecf20Sopenharmony_ci * are referred to as the UWC BAR for the instance. 518c2ecf20Sopenharmony_ci * 528c2ecf20Sopenharmony_ci * The two BARs for each instance are defined Power9 MMIO Ranges spreadsheet 538c2ecf20Sopenharmony_ci * and available to the kernel in the VAS node's "reg" property in the device 548c2ecf20Sopenharmony_ci * tree: 558c2ecf20Sopenharmony_ci * 568c2ecf20Sopenharmony_ci * /proc/device-tree/vasm@.../reg 578c2ecf20Sopenharmony_ci * 588c2ecf20Sopenharmony_ci * (see vas_probe() for details on the reg property). 598c2ecf20Sopenharmony_ci * 608c2ecf20Sopenharmony_ci * The kernel maps the HVWC and UWC BAR regions into the kernel address 618c2ecf20Sopenharmony_ci * space (hvwc_map and uwc_map). The kernel can then access the window 628c2ecf20Sopenharmony_ci * contexts of a specific window using: 638c2ecf20Sopenharmony_ci * 648c2ecf20Sopenharmony_ci * hvwc = hvwc_map + winid * VAS_HVWC_SIZE. 658c2ecf20Sopenharmony_ci * uwc = uwc_map + winid * VAS_UWC_SIZE. 668c2ecf20Sopenharmony_ci * 678c2ecf20Sopenharmony_ci * where winid is the window index (0..64K). 688c2ecf20Sopenharmony_ci * 698c2ecf20Sopenharmony_ci * As mentioned, a window context is used to "configure" a window. Besides 708c2ecf20Sopenharmony_ci * this configuration address, each _send_ window also has a unique hardware 718c2ecf20Sopenharmony_ci * "paste" address that is used to submit requests/CRBs (see vas_paste_crb()). 728c2ecf20Sopenharmony_ci * 738c2ecf20Sopenharmony_ci * The hardware paste address for a window is computed using the "paste 748c2ecf20Sopenharmony_ci * base address" and "paste win id shift" reg properties in the VAS device 758c2ecf20Sopenharmony_ci * tree node using: 768c2ecf20Sopenharmony_ci * 778c2ecf20Sopenharmony_ci * paste_addr = paste_base + ((winid << paste_win_id_shift)) 788c2ecf20Sopenharmony_ci * 798c2ecf20Sopenharmony_ci * (again, see vas_probe() for ->paste_base_addr and ->paste_win_id_shift). 808c2ecf20Sopenharmony_ci * 818c2ecf20Sopenharmony_ci * The kernel maps this hardware address into the sender's address space 828c2ecf20Sopenharmony_ci * after which they can use the 'paste' instruction (new in Power9) to 838c2ecf20Sopenharmony_ci * send a message (submit a request aka CRB) to the coprocessor. 848c2ecf20Sopenharmony_ci * 858c2ecf20Sopenharmony_ci * NOTE: In the initial version, senders can only in-kernel drivers/threads. 868c2ecf20Sopenharmony_ci * Support for user space threads will be added in follow-on patches. 878c2ecf20Sopenharmony_ci * 888c2ecf20Sopenharmony_ci * TODO: Do we need to map the UWC into user address space so they can return 898c2ecf20Sopenharmony_ci * credits? Its NA for NX but may be needed for other receive windows. 908c2ecf20Sopenharmony_ci * 918c2ecf20Sopenharmony_ci */ 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci#define VAS_WINDOWS_PER_CHIP (64 << 10) 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci/* 968c2ecf20Sopenharmony_ci * Hypervisor and OS/USer Window Context sizes 978c2ecf20Sopenharmony_ci */ 988c2ecf20Sopenharmony_ci#define VAS_HVWC_SIZE 512 998c2ecf20Sopenharmony_ci#define VAS_UWC_SIZE PAGE_SIZE 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci/* 1028c2ecf20Sopenharmony_ci * Initial per-process credits. 1038c2ecf20Sopenharmony_ci * Max send window credits: 4K-1 (12-bits in VAS_TX_WCRED) 1048c2ecf20Sopenharmony_ci * 1058c2ecf20Sopenharmony_ci * TODO: Needs tuning for per-process credits 1068c2ecf20Sopenharmony_ci */ 1078c2ecf20Sopenharmony_ci#define VAS_TX_WCREDS_MAX ((4 << 10) - 1) 1088c2ecf20Sopenharmony_ci#define VAS_WCREDS_DEFAULT (1 << 10) 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci/* 1118c2ecf20Sopenharmony_ci * VAS Window Context Register Offsets and bitmasks. 1128c2ecf20Sopenharmony_ci * See Section 3.1.4 of VAS Work book 1138c2ecf20Sopenharmony_ci */ 1148c2ecf20Sopenharmony_ci#define VAS_LPID_OFFSET 0x010 1158c2ecf20Sopenharmony_ci#define VAS_LPID PPC_BITMASK(0, 11) 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci#define VAS_PID_OFFSET 0x018 1188c2ecf20Sopenharmony_ci#define VAS_PID_ID PPC_BITMASK(0, 19) 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci#define VAS_XLATE_MSR_OFFSET 0x020 1218c2ecf20Sopenharmony_ci#define VAS_XLATE_MSR_DR PPC_BIT(0) 1228c2ecf20Sopenharmony_ci#define VAS_XLATE_MSR_TA PPC_BIT(1) 1238c2ecf20Sopenharmony_ci#define VAS_XLATE_MSR_PR PPC_BIT(2) 1248c2ecf20Sopenharmony_ci#define VAS_XLATE_MSR_US PPC_BIT(3) 1258c2ecf20Sopenharmony_ci#define VAS_XLATE_MSR_HV PPC_BIT(4) 1268c2ecf20Sopenharmony_ci#define VAS_XLATE_MSR_SF PPC_BIT(5) 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci#define VAS_XLATE_LPCR_OFFSET 0x028 1298c2ecf20Sopenharmony_ci#define VAS_XLATE_LPCR_PAGE_SIZE PPC_BITMASK(0, 2) 1308c2ecf20Sopenharmony_ci#define VAS_XLATE_LPCR_ISL PPC_BIT(3) 1318c2ecf20Sopenharmony_ci#define VAS_XLATE_LPCR_TC PPC_BIT(4) 1328c2ecf20Sopenharmony_ci#define VAS_XLATE_LPCR_SC PPC_BIT(5) 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci#define VAS_XLATE_CTL_OFFSET 0x030 1358c2ecf20Sopenharmony_ci#define VAS_XLATE_MODE PPC_BITMASK(0, 1) 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci#define VAS_AMR_OFFSET 0x040 1388c2ecf20Sopenharmony_ci#define VAS_AMR PPC_BITMASK(0, 63) 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci#define VAS_SEIDR_OFFSET 0x048 1418c2ecf20Sopenharmony_ci#define VAS_SEIDR PPC_BITMASK(0, 63) 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci#define VAS_FAULT_TX_WIN_OFFSET 0x050 1448c2ecf20Sopenharmony_ci#define VAS_FAULT_TX_WIN PPC_BITMASK(48, 63) 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ci#define VAS_OSU_INTR_SRC_RA_OFFSET 0x060 1478c2ecf20Sopenharmony_ci#define VAS_OSU_INTR_SRC_RA PPC_BITMASK(8, 63) 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci#define VAS_HV_INTR_SRC_RA_OFFSET 0x070 1508c2ecf20Sopenharmony_ci#define VAS_HV_INTR_SRC_RA PPC_BITMASK(8, 63) 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci#define VAS_PSWID_OFFSET 0x078 1538c2ecf20Sopenharmony_ci#define VAS_PSWID_EA_HANDLE PPC_BITMASK(0, 31) 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci#define VAS_SPARE1_OFFSET 0x080 1568c2ecf20Sopenharmony_ci#define VAS_SPARE2_OFFSET 0x088 1578c2ecf20Sopenharmony_ci#define VAS_SPARE3_OFFSET 0x090 1588c2ecf20Sopenharmony_ci#define VAS_SPARE4_OFFSET 0x130 1598c2ecf20Sopenharmony_ci#define VAS_SPARE5_OFFSET 0x160 1608c2ecf20Sopenharmony_ci#define VAS_SPARE6_OFFSET 0x188 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci#define VAS_LFIFO_BAR_OFFSET 0x0A0 1638c2ecf20Sopenharmony_ci#define VAS_LFIFO_BAR PPC_BITMASK(8, 53) 1648c2ecf20Sopenharmony_ci#define VAS_PAGE_MIGRATION_SELECT PPC_BITMASK(54, 56) 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci#define VAS_LDATA_STAMP_CTL_OFFSET 0x0A8 1678c2ecf20Sopenharmony_ci#define VAS_LDATA_STAMP PPC_BITMASK(0, 1) 1688c2ecf20Sopenharmony_ci#define VAS_XTRA_WRITE PPC_BIT(2) 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci#define VAS_LDMA_CACHE_CTL_OFFSET 0x0B0 1718c2ecf20Sopenharmony_ci#define VAS_LDMA_TYPE PPC_BITMASK(0, 1) 1728c2ecf20Sopenharmony_ci#define VAS_LDMA_FIFO_DISABLE PPC_BIT(2) 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci#define VAS_LRFIFO_PUSH_OFFSET 0x0B8 1758c2ecf20Sopenharmony_ci#define VAS_LRFIFO_PUSH PPC_BITMASK(0, 15) 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci#define VAS_CURR_MSG_COUNT_OFFSET 0x0C0 1788c2ecf20Sopenharmony_ci#define VAS_CURR_MSG_COUNT PPC_BITMASK(0, 7) 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_ci#define VAS_LNOTIFY_AFTER_COUNT_OFFSET 0x0C8 1818c2ecf20Sopenharmony_ci#define VAS_LNOTIFY_AFTER_COUNT PPC_BITMASK(0, 7) 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci#define VAS_LRX_WCRED_OFFSET 0x0E0 1848c2ecf20Sopenharmony_ci#define VAS_LRX_WCRED PPC_BITMASK(0, 15) 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_ci#define VAS_LRX_WCRED_ADDER_OFFSET 0x190 1878c2ecf20Sopenharmony_ci#define VAS_LRX_WCRED_ADDER PPC_BITMASK(0, 15) 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci#define VAS_TX_WCRED_OFFSET 0x0F0 1908c2ecf20Sopenharmony_ci#define VAS_TX_WCRED PPC_BITMASK(4, 15) 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ci#define VAS_TX_WCRED_ADDER_OFFSET 0x1A0 1938c2ecf20Sopenharmony_ci#define VAS_TX_WCRED_ADDER PPC_BITMASK(4, 15) 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_ci#define VAS_LFIFO_SIZE_OFFSET 0x100 1968c2ecf20Sopenharmony_ci#define VAS_LFIFO_SIZE PPC_BITMASK(0, 3) 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ci#define VAS_WINCTL_OFFSET 0x108 1998c2ecf20Sopenharmony_ci#define VAS_WINCTL_OPEN PPC_BIT(0) 2008c2ecf20Sopenharmony_ci#define VAS_WINCTL_REJ_NO_CREDIT PPC_BIT(1) 2018c2ecf20Sopenharmony_ci#define VAS_WINCTL_PIN PPC_BIT(2) 2028c2ecf20Sopenharmony_ci#define VAS_WINCTL_TX_WCRED_MODE PPC_BIT(3) 2038c2ecf20Sopenharmony_ci#define VAS_WINCTL_RX_WCRED_MODE PPC_BIT(4) 2048c2ecf20Sopenharmony_ci#define VAS_WINCTL_TX_WORD_MODE PPC_BIT(5) 2058c2ecf20Sopenharmony_ci#define VAS_WINCTL_RX_WORD_MODE PPC_BIT(6) 2068c2ecf20Sopenharmony_ci#define VAS_WINCTL_RSVD_TXBUF PPC_BIT(7) 2078c2ecf20Sopenharmony_ci#define VAS_WINCTL_THRESH_CTL PPC_BITMASK(8, 9) 2088c2ecf20Sopenharmony_ci#define VAS_WINCTL_FAULT_WIN PPC_BIT(10) 2098c2ecf20Sopenharmony_ci#define VAS_WINCTL_NX_WIN PPC_BIT(11) 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ci#define VAS_WIN_STATUS_OFFSET 0x110 2128c2ecf20Sopenharmony_ci#define VAS_WIN_BUSY PPC_BIT(1) 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci#define VAS_WIN_CTX_CACHING_CTL_OFFSET 0x118 2158c2ecf20Sopenharmony_ci#define VAS_CASTOUT_REQ PPC_BIT(0) 2168c2ecf20Sopenharmony_ci#define VAS_PUSH_TO_MEM PPC_BIT(1) 2178c2ecf20Sopenharmony_ci#define VAS_WIN_CACHE_STATUS PPC_BIT(4) 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci#define VAS_TX_RSVD_BUF_COUNT_OFFSET 0x120 2208c2ecf20Sopenharmony_ci#define VAS_RXVD_BUF_COUNT PPC_BITMASK(58, 63) 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci#define VAS_LRFIFO_WIN_PTR_OFFSET 0x128 2238c2ecf20Sopenharmony_ci#define VAS_LRX_WIN_ID PPC_BITMASK(0, 15) 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci/* 2268c2ecf20Sopenharmony_ci * Local Notification Control Register controls what happens in _response_ 2278c2ecf20Sopenharmony_ci * to a paste command and hence applies only to receive windows. 2288c2ecf20Sopenharmony_ci */ 2298c2ecf20Sopenharmony_ci#define VAS_LNOTIFY_CTL_OFFSET 0x138 2308c2ecf20Sopenharmony_ci#define VAS_NOTIFY_DISABLE PPC_BIT(0) 2318c2ecf20Sopenharmony_ci#define VAS_INTR_DISABLE PPC_BIT(1) 2328c2ecf20Sopenharmony_ci#define VAS_NOTIFY_EARLY PPC_BIT(2) 2338c2ecf20Sopenharmony_ci#define VAS_NOTIFY_OSU_INTR PPC_BIT(3) 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci#define VAS_LNOTIFY_PID_OFFSET 0x140 2368c2ecf20Sopenharmony_ci#define VAS_LNOTIFY_PID PPC_BITMASK(0, 19) 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_ci#define VAS_LNOTIFY_LPID_OFFSET 0x148 2398c2ecf20Sopenharmony_ci#define VAS_LNOTIFY_LPID PPC_BITMASK(0, 11) 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci#define VAS_LNOTIFY_TID_OFFSET 0x150 2428c2ecf20Sopenharmony_ci#define VAS_LNOTIFY_TID PPC_BITMASK(0, 15) 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_ci#define VAS_LNOTIFY_SCOPE_OFFSET 0x158 2458c2ecf20Sopenharmony_ci#define VAS_LNOTIFY_MIN_SCOPE PPC_BITMASK(0, 1) 2468c2ecf20Sopenharmony_ci#define VAS_LNOTIFY_MAX_SCOPE PPC_BITMASK(2, 3) 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci#define VAS_NX_UTIL_OFFSET 0x1B0 2498c2ecf20Sopenharmony_ci#define VAS_NX_UTIL PPC_BITMASK(0, 63) 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_ci/* SE: Side effects */ 2528c2ecf20Sopenharmony_ci#define VAS_NX_UTIL_SE_OFFSET 0x1B8 2538c2ecf20Sopenharmony_ci#define VAS_NX_UTIL_SE PPC_BITMASK(0, 63) 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_ci#define VAS_NX_UTIL_ADDER_OFFSET 0x180 2568c2ecf20Sopenharmony_ci#define VAS_NX_UTIL_ADDER PPC_BITMASK(32, 63) 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_ci/* 2598c2ecf20Sopenharmony_ci * VREG(x): 2608c2ecf20Sopenharmony_ci * Expand a register's short name (eg: LPID) into two parameters: 2618c2ecf20Sopenharmony_ci * - the register's short name in string form ("LPID"), and 2628c2ecf20Sopenharmony_ci * - the name of the macro (eg: VAS_LPID_OFFSET), defining the 2638c2ecf20Sopenharmony_ci * register's offset in the window context 2648c2ecf20Sopenharmony_ci */ 2658c2ecf20Sopenharmony_ci#define VREG_SFX(n, s) __stringify(n), VAS_##n##s 2668c2ecf20Sopenharmony_ci#define VREG(r) VREG_SFX(r, _OFFSET) 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_ci/* 2698c2ecf20Sopenharmony_ci * Local Notify Scope Control Register. (Receive windows only). 2708c2ecf20Sopenharmony_ci */ 2718c2ecf20Sopenharmony_cienum vas_notify_scope { 2728c2ecf20Sopenharmony_ci VAS_SCOPE_LOCAL, 2738c2ecf20Sopenharmony_ci VAS_SCOPE_GROUP, 2748c2ecf20Sopenharmony_ci VAS_SCOPE_VECTORED_GROUP, 2758c2ecf20Sopenharmony_ci VAS_SCOPE_UNUSED, 2768c2ecf20Sopenharmony_ci}; 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_ci/* 2798c2ecf20Sopenharmony_ci * Local DMA Cache Control Register (Receive windows only). 2808c2ecf20Sopenharmony_ci */ 2818c2ecf20Sopenharmony_cienum vas_dma_type { 2828c2ecf20Sopenharmony_ci VAS_DMA_TYPE_INJECT, 2838c2ecf20Sopenharmony_ci VAS_DMA_TYPE_WRITE, 2848c2ecf20Sopenharmony_ci}; 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_ci/* 2878c2ecf20Sopenharmony_ci * Local Notify Scope Control Register. (Receive windows only). 2888c2ecf20Sopenharmony_ci * Not applicable to NX receive windows. 2898c2ecf20Sopenharmony_ci */ 2908c2ecf20Sopenharmony_cienum vas_notify_after_count { 2918c2ecf20Sopenharmony_ci VAS_NOTIFY_AFTER_256 = 0, 2928c2ecf20Sopenharmony_ci VAS_NOTIFY_NONE, 2938c2ecf20Sopenharmony_ci VAS_NOTIFY_AFTER_2 2948c2ecf20Sopenharmony_ci}; 2958c2ecf20Sopenharmony_ci 2968c2ecf20Sopenharmony_ci/* 2978c2ecf20Sopenharmony_ci * NX can generate an interrupt for multiple faults and expects kernel 2988c2ecf20Sopenharmony_ci * to process all of them. So read all valid CRB entries until find the 2998c2ecf20Sopenharmony_ci * invalid one. So use pswid which is pasted by NX and ccw[0] (reserved 3008c2ecf20Sopenharmony_ci * bit in BE) to check valid CRB. CCW[0] will not be touched by user 3018c2ecf20Sopenharmony_ci * space. Application gets CRB formt error if it updates this bit. 3028c2ecf20Sopenharmony_ci * 3038c2ecf20Sopenharmony_ci * Invalidate FIFO during allocation and process all entries from last 3048c2ecf20Sopenharmony_ci * successful read until finds invalid pswid and ccw[0] values. 3058c2ecf20Sopenharmony_ci * After reading each CRB entry from fault FIFO, the kernel invalidate 3068c2ecf20Sopenharmony_ci * it by updating pswid with FIFO_INVALID_ENTRY and CCW[0] with 3078c2ecf20Sopenharmony_ci * CCW0_INVALID. 3088c2ecf20Sopenharmony_ci */ 3098c2ecf20Sopenharmony_ci#define FIFO_INVALID_ENTRY 0xffffffff 3108c2ecf20Sopenharmony_ci#define CCW0_INVALID 1 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_ci/* 3138c2ecf20Sopenharmony_ci * One per instance of VAS. Each instance will have a separate set of 3148c2ecf20Sopenharmony_ci * receive windows, one per coprocessor type. 3158c2ecf20Sopenharmony_ci * 3168c2ecf20Sopenharmony_ci * See also function header of set_vinst_win() for details on ->windows[] 3178c2ecf20Sopenharmony_ci * and ->rxwin[] tables. 3188c2ecf20Sopenharmony_ci */ 3198c2ecf20Sopenharmony_cistruct vas_instance { 3208c2ecf20Sopenharmony_ci int vas_id; 3218c2ecf20Sopenharmony_ci struct ida ida; 3228c2ecf20Sopenharmony_ci struct list_head node; 3238c2ecf20Sopenharmony_ci struct platform_device *pdev; 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_ci u64 hvwc_bar_start; 3268c2ecf20Sopenharmony_ci u64 uwc_bar_start; 3278c2ecf20Sopenharmony_ci u64 paste_base_addr; 3288c2ecf20Sopenharmony_ci u64 paste_win_id_shift; 3298c2ecf20Sopenharmony_ci 3308c2ecf20Sopenharmony_ci u64 irq_port; 3318c2ecf20Sopenharmony_ci int virq; 3328c2ecf20Sopenharmony_ci int fault_crbs; 3338c2ecf20Sopenharmony_ci int fault_fifo_size; 3348c2ecf20Sopenharmony_ci int fifo_in_progress; /* To wake up thread or return IRQ_HANDLED */ 3358c2ecf20Sopenharmony_ci spinlock_t fault_lock; /* Protects fifo_in_progress update */ 3368c2ecf20Sopenharmony_ci void *fault_fifo; 3378c2ecf20Sopenharmony_ci struct vas_window *fault_win; /* Fault window */ 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ci struct mutex mutex; 3408c2ecf20Sopenharmony_ci struct vas_window *rxwin[VAS_COP_TYPE_MAX]; 3418c2ecf20Sopenharmony_ci struct vas_window *windows[VAS_WINDOWS_PER_CHIP]; 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_ci char *dbgname; 3448c2ecf20Sopenharmony_ci struct dentry *dbgdir; 3458c2ecf20Sopenharmony_ci}; 3468c2ecf20Sopenharmony_ci 3478c2ecf20Sopenharmony_ci/* 3488c2ecf20Sopenharmony_ci * In-kernel state a VAS window. One per window. 3498c2ecf20Sopenharmony_ci */ 3508c2ecf20Sopenharmony_cistruct vas_window { 3518c2ecf20Sopenharmony_ci /* Fields common to send and receive windows */ 3528c2ecf20Sopenharmony_ci struct vas_instance *vinst; 3538c2ecf20Sopenharmony_ci int winid; 3548c2ecf20Sopenharmony_ci bool tx_win; /* True if send window */ 3558c2ecf20Sopenharmony_ci bool nx_win; /* True if NX window */ 3568c2ecf20Sopenharmony_ci bool user_win; /* True if user space window */ 3578c2ecf20Sopenharmony_ci void *hvwc_map; /* HV window context */ 3588c2ecf20Sopenharmony_ci void *uwc_map; /* OS/User window context */ 3598c2ecf20Sopenharmony_ci struct pid *pid; /* Linux process id of owner */ 3608c2ecf20Sopenharmony_ci struct pid *tgid; /* Thread group ID of owner */ 3618c2ecf20Sopenharmony_ci struct mm_struct *mm; /* Linux process mm_struct */ 3628c2ecf20Sopenharmony_ci int wcreds_max; /* Window credits */ 3638c2ecf20Sopenharmony_ci 3648c2ecf20Sopenharmony_ci char *dbgname; 3658c2ecf20Sopenharmony_ci struct dentry *dbgdir; 3668c2ecf20Sopenharmony_ci 3678c2ecf20Sopenharmony_ci /* Fields applicable only to send windows */ 3688c2ecf20Sopenharmony_ci void *paste_kaddr; 3698c2ecf20Sopenharmony_ci char *paste_addr_name; 3708c2ecf20Sopenharmony_ci struct vas_window *rxwin; 3718c2ecf20Sopenharmony_ci 3728c2ecf20Sopenharmony_ci /* Feilds applicable only to receive windows */ 3738c2ecf20Sopenharmony_ci enum vas_cop_type cop; 3748c2ecf20Sopenharmony_ci atomic_t num_txwins; 3758c2ecf20Sopenharmony_ci}; 3768c2ecf20Sopenharmony_ci 3778c2ecf20Sopenharmony_ci/* 3788c2ecf20Sopenharmony_ci * Container for the hardware state of a window. One per-window. 3798c2ecf20Sopenharmony_ci * 3808c2ecf20Sopenharmony_ci * A VAS Window context is a 512-byte area in the hardware that contains 3818c2ecf20Sopenharmony_ci * a set of 64-bit registers. Individual bit-fields in these registers 3828c2ecf20Sopenharmony_ci * determine the configuration/operation of the hardware. struct vas_winctx 3838c2ecf20Sopenharmony_ci * is a container for the register fields in the window context. 3848c2ecf20Sopenharmony_ci */ 3858c2ecf20Sopenharmony_cistruct vas_winctx { 3868c2ecf20Sopenharmony_ci u64 rx_fifo; 3878c2ecf20Sopenharmony_ci int rx_fifo_size; 3888c2ecf20Sopenharmony_ci int wcreds_max; 3898c2ecf20Sopenharmony_ci int rsvd_txbuf_count; 3908c2ecf20Sopenharmony_ci 3918c2ecf20Sopenharmony_ci bool user_win; 3928c2ecf20Sopenharmony_ci bool nx_win; 3938c2ecf20Sopenharmony_ci bool fault_win; 3948c2ecf20Sopenharmony_ci bool rsvd_txbuf_enable; 3958c2ecf20Sopenharmony_ci bool pin_win; 3968c2ecf20Sopenharmony_ci bool rej_no_credit; 3978c2ecf20Sopenharmony_ci bool tx_wcred_mode; 3988c2ecf20Sopenharmony_ci bool rx_wcred_mode; 3998c2ecf20Sopenharmony_ci bool tx_word_mode; 4008c2ecf20Sopenharmony_ci bool rx_word_mode; 4018c2ecf20Sopenharmony_ci bool data_stamp; 4028c2ecf20Sopenharmony_ci bool xtra_write; 4038c2ecf20Sopenharmony_ci bool notify_disable; 4048c2ecf20Sopenharmony_ci bool intr_disable; 4058c2ecf20Sopenharmony_ci bool fifo_disable; 4068c2ecf20Sopenharmony_ci bool notify_early; 4078c2ecf20Sopenharmony_ci bool notify_os_intr_reg; 4088c2ecf20Sopenharmony_ci 4098c2ecf20Sopenharmony_ci int lpid; 4108c2ecf20Sopenharmony_ci int pidr; /* value from SPRN_PID, not linux pid */ 4118c2ecf20Sopenharmony_ci int lnotify_lpid; 4128c2ecf20Sopenharmony_ci int lnotify_pid; 4138c2ecf20Sopenharmony_ci int lnotify_tid; 4148c2ecf20Sopenharmony_ci u32 pswid; 4158c2ecf20Sopenharmony_ci int rx_win_id; 4168c2ecf20Sopenharmony_ci int fault_win_id; 4178c2ecf20Sopenharmony_ci int tc_mode; 4188c2ecf20Sopenharmony_ci 4198c2ecf20Sopenharmony_ci u64 irq_port; 4208c2ecf20Sopenharmony_ci 4218c2ecf20Sopenharmony_ci enum vas_dma_type dma_type; 4228c2ecf20Sopenharmony_ci enum vas_notify_scope min_scope; 4238c2ecf20Sopenharmony_ci enum vas_notify_scope max_scope; 4248c2ecf20Sopenharmony_ci enum vas_notify_after_count notify_after_count; 4258c2ecf20Sopenharmony_ci}; 4268c2ecf20Sopenharmony_ci 4278c2ecf20Sopenharmony_ciextern struct mutex vas_mutex; 4288c2ecf20Sopenharmony_ci 4298c2ecf20Sopenharmony_ciextern struct vas_instance *find_vas_instance(int vasid); 4308c2ecf20Sopenharmony_ciextern void vas_init_dbgdir(void); 4318c2ecf20Sopenharmony_ciextern void vas_instance_init_dbgdir(struct vas_instance *vinst); 4328c2ecf20Sopenharmony_ciextern void vas_window_init_dbgdir(struct vas_window *win); 4338c2ecf20Sopenharmony_ciextern void vas_window_free_dbgdir(struct vas_window *win); 4348c2ecf20Sopenharmony_ciextern int vas_setup_fault_window(struct vas_instance *vinst); 4358c2ecf20Sopenharmony_ciextern irqreturn_t vas_fault_thread_fn(int irq, void *data); 4368c2ecf20Sopenharmony_ciextern irqreturn_t vas_fault_handler(int irq, void *dev_id); 4378c2ecf20Sopenharmony_ciextern void vas_return_credit(struct vas_window *window, bool tx); 4388c2ecf20Sopenharmony_ciextern struct vas_window *vas_pswid_to_window(struct vas_instance *vinst, 4398c2ecf20Sopenharmony_ci uint32_t pswid); 4408c2ecf20Sopenharmony_ciextern void vas_win_paste_addr(struct vas_window *window, u64 *addr, 4418c2ecf20Sopenharmony_ci int *len); 4428c2ecf20Sopenharmony_ci 4438c2ecf20Sopenharmony_cistatic inline int vas_window_pid(struct vas_window *window) 4448c2ecf20Sopenharmony_ci{ 4458c2ecf20Sopenharmony_ci return pid_vnr(window->pid); 4468c2ecf20Sopenharmony_ci} 4478c2ecf20Sopenharmony_ci 4488c2ecf20Sopenharmony_cistatic inline void vas_log_write(struct vas_window *win, char *name, 4498c2ecf20Sopenharmony_ci void *regptr, u64 val) 4508c2ecf20Sopenharmony_ci{ 4518c2ecf20Sopenharmony_ci if (val) 4528c2ecf20Sopenharmony_ci pr_debug("%swin #%d: %s reg %p, val 0x%016llx\n", 4538c2ecf20Sopenharmony_ci win->tx_win ? "Tx" : "Rx", win->winid, name, 4548c2ecf20Sopenharmony_ci regptr, val); 4558c2ecf20Sopenharmony_ci} 4568c2ecf20Sopenharmony_ci 4578c2ecf20Sopenharmony_cistatic inline void write_uwc_reg(struct vas_window *win, char *name, 4588c2ecf20Sopenharmony_ci s32 reg, u64 val) 4598c2ecf20Sopenharmony_ci{ 4608c2ecf20Sopenharmony_ci void *regptr; 4618c2ecf20Sopenharmony_ci 4628c2ecf20Sopenharmony_ci regptr = win->uwc_map + reg; 4638c2ecf20Sopenharmony_ci vas_log_write(win, name, regptr, val); 4648c2ecf20Sopenharmony_ci 4658c2ecf20Sopenharmony_ci out_be64(regptr, val); 4668c2ecf20Sopenharmony_ci} 4678c2ecf20Sopenharmony_ci 4688c2ecf20Sopenharmony_cistatic inline void write_hvwc_reg(struct vas_window *win, char *name, 4698c2ecf20Sopenharmony_ci s32 reg, u64 val) 4708c2ecf20Sopenharmony_ci{ 4718c2ecf20Sopenharmony_ci void *regptr; 4728c2ecf20Sopenharmony_ci 4738c2ecf20Sopenharmony_ci regptr = win->hvwc_map + reg; 4748c2ecf20Sopenharmony_ci vas_log_write(win, name, regptr, val); 4758c2ecf20Sopenharmony_ci 4768c2ecf20Sopenharmony_ci out_be64(regptr, val); 4778c2ecf20Sopenharmony_ci} 4788c2ecf20Sopenharmony_ci 4798c2ecf20Sopenharmony_cistatic inline u64 read_hvwc_reg(struct vas_window *win, 4808c2ecf20Sopenharmony_ci char *name __maybe_unused, s32 reg) 4818c2ecf20Sopenharmony_ci{ 4828c2ecf20Sopenharmony_ci return in_be64(win->hvwc_map+reg); 4838c2ecf20Sopenharmony_ci} 4848c2ecf20Sopenharmony_ci 4858c2ecf20Sopenharmony_ci/* 4868c2ecf20Sopenharmony_ci * Encode/decode the Partition Send Window ID (PSWID) for a window in 4878c2ecf20Sopenharmony_ci * a way that we can uniquely identify any window in the system. i.e. 4888c2ecf20Sopenharmony_ci * we should be able to locate the 'struct vas_window' given the PSWID. 4898c2ecf20Sopenharmony_ci * 4908c2ecf20Sopenharmony_ci * Bits Usage 4918c2ecf20Sopenharmony_ci * 0:7 VAS id (8 bits) 4928c2ecf20Sopenharmony_ci * 8:15 Unused, 0 (3 bits) 4938c2ecf20Sopenharmony_ci * 16:31 Window id (16 bits) 4948c2ecf20Sopenharmony_ci */ 4958c2ecf20Sopenharmony_cistatic inline u32 encode_pswid(int vasid, int winid) 4968c2ecf20Sopenharmony_ci{ 4978c2ecf20Sopenharmony_ci return ((u32)winid | (vasid << (31 - 7))); 4988c2ecf20Sopenharmony_ci} 4998c2ecf20Sopenharmony_ci 5008c2ecf20Sopenharmony_cistatic inline void decode_pswid(u32 pswid, int *vasid, int *winid) 5018c2ecf20Sopenharmony_ci{ 5028c2ecf20Sopenharmony_ci if (vasid) 5038c2ecf20Sopenharmony_ci *vasid = pswid >> (31 - 7) & 0xFF; 5048c2ecf20Sopenharmony_ci 5058c2ecf20Sopenharmony_ci if (winid) 5068c2ecf20Sopenharmony_ci *winid = pswid & 0xFFFF; 5078c2ecf20Sopenharmony_ci} 5088c2ecf20Sopenharmony_ci#endif /* _VAS_H */ 509