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