18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * IBM PowerPC Virtual I/O Infrastructure Support.
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (c) 2003 IBM Corp.
68c2ecf20Sopenharmony_ci *  Dave Engebretsen engebret@us.ibm.com
78c2ecf20Sopenharmony_ci *  Santiago Leon santil@us.ibm.com
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#ifndef _ASM_POWERPC_VIO_H
118c2ecf20Sopenharmony_ci#define _ASM_POWERPC_VIO_H
128c2ecf20Sopenharmony_ci#ifdef __KERNEL__
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#include <linux/errno.h>
158c2ecf20Sopenharmony_ci#include <linux/device.h>
168c2ecf20Sopenharmony_ci#include <linux/dma-mapping.h>
178c2ecf20Sopenharmony_ci#include <linux/mod_devicetable.h>
188c2ecf20Sopenharmony_ci#include <linux/scatterlist.h>
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci#include <asm/hvcall.h>
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ci/*
238c2ecf20Sopenharmony_ci * Architecture-specific constants for drivers to
248c2ecf20Sopenharmony_ci * extract attributes of the device using vio_get_attribute()
258c2ecf20Sopenharmony_ci */
268c2ecf20Sopenharmony_ci#define VETH_MAC_ADDR "local-mac-address"
278c2ecf20Sopenharmony_ci#define VETH_MCAST_FILTER_SIZE "ibm,mac-address-filters"
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci/* End architecture-specific constants */
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci#define h_vio_signal(ua, mode) \
328c2ecf20Sopenharmony_ci  plpar_hcall_norets(H_VIO_SIGNAL, ua, mode)
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci#define VIO_IRQ_DISABLE		0UL
358c2ecf20Sopenharmony_ci#define VIO_IRQ_ENABLE		1UL
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci/*
388c2ecf20Sopenharmony_ci * VIO CMO minimum entitlement for all devices and spare entitlement
398c2ecf20Sopenharmony_ci */
408c2ecf20Sopenharmony_ci#define VIO_CMO_MIN_ENT 1562624
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ciextern struct bus_type vio_bus_type;
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_cistruct iommu_table;
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci/*
478c2ecf20Sopenharmony_ci * Platform Facilities Option (PFO)-specific data
488c2ecf20Sopenharmony_ci */
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci/* Starting unit address for PFO devices on the VIO BUS */
518c2ecf20Sopenharmony_ci#define VIO_BASE_PFO_UA	0x50000000
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci/**
548c2ecf20Sopenharmony_ci * vio_pfo_op - PFO operation parameters
558c2ecf20Sopenharmony_ci *
568c2ecf20Sopenharmony_ci * @flags: h_call subfunctions and modifiers
578c2ecf20Sopenharmony_ci * @in: Input data block logical real address
588c2ecf20Sopenharmony_ci * @inlen: If non-negative, the length of the input data block.  If negative,
598c2ecf20Sopenharmony_ci *	the length of the input data descriptor list in bytes.
608c2ecf20Sopenharmony_ci * @out: Output data block logical real address
618c2ecf20Sopenharmony_ci * @outlen: If non-negative, the length of the input data block.  If negative,
628c2ecf20Sopenharmony_ci *	the length of the input data descriptor list in bytes.
638c2ecf20Sopenharmony_ci * @csbcpb: Logical real address of the 4k naturally-aligned storage block
648c2ecf20Sopenharmony_ci *	containing the CSB & optional FC field specific CPB
658c2ecf20Sopenharmony_ci * @timeout: # of milliseconds to retry h_call, 0 for no timeout.
668c2ecf20Sopenharmony_ci * @hcall_err: pointer to return the h_call return value, else NULL
678c2ecf20Sopenharmony_ci */
688c2ecf20Sopenharmony_cistruct vio_pfo_op {
698c2ecf20Sopenharmony_ci	u64 flags;
708c2ecf20Sopenharmony_ci	s64 in;
718c2ecf20Sopenharmony_ci	s64 inlen;
728c2ecf20Sopenharmony_ci	s64 out;
738c2ecf20Sopenharmony_ci	s64 outlen;
748c2ecf20Sopenharmony_ci	u64 csbcpb;
758c2ecf20Sopenharmony_ci	void *done;
768c2ecf20Sopenharmony_ci	unsigned long handle;
778c2ecf20Sopenharmony_ci	unsigned int timeout;
788c2ecf20Sopenharmony_ci	long hcall_err;
798c2ecf20Sopenharmony_ci};
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci/* End PFO specific data */
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_cienum vio_dev_family {
848c2ecf20Sopenharmony_ci	VDEVICE,	/* The OF node is a child of /vdevice */
858c2ecf20Sopenharmony_ci	PFO,		/* The OF node is a child of /ibm,platform-facilities */
868c2ecf20Sopenharmony_ci};
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci/**
898c2ecf20Sopenharmony_ci * vio_dev - This structure is used to describe virtual I/O devices.
908c2ecf20Sopenharmony_ci *
918c2ecf20Sopenharmony_ci * @desired: set from return of driver's get_desired_dma() function
928c2ecf20Sopenharmony_ci * @entitled: bytes of IO data that has been reserved for this device.
938c2ecf20Sopenharmony_ci * @allocated: bytes of IO data currently in use by the device.
948c2ecf20Sopenharmony_ci * @allocs_failed: number of DMA failures due to insufficient entitlement.
958c2ecf20Sopenharmony_ci */
968c2ecf20Sopenharmony_cistruct vio_dev {
978c2ecf20Sopenharmony_ci	const char *name;
988c2ecf20Sopenharmony_ci	const char *type;
998c2ecf20Sopenharmony_ci	uint32_t unit_address;
1008c2ecf20Sopenharmony_ci	uint32_t resource_id;
1018c2ecf20Sopenharmony_ci	unsigned int irq;
1028c2ecf20Sopenharmony_ci	struct {
1038c2ecf20Sopenharmony_ci		size_t desired;
1048c2ecf20Sopenharmony_ci		size_t entitled;
1058c2ecf20Sopenharmony_ci		size_t allocated;
1068c2ecf20Sopenharmony_ci		atomic_t allocs_failed;
1078c2ecf20Sopenharmony_ci	} cmo;
1088c2ecf20Sopenharmony_ci	enum vio_dev_family family;
1098c2ecf20Sopenharmony_ci	struct device dev;
1108c2ecf20Sopenharmony_ci};
1118c2ecf20Sopenharmony_ci
1128c2ecf20Sopenharmony_cistruct vio_driver {
1138c2ecf20Sopenharmony_ci	const char *name;
1148c2ecf20Sopenharmony_ci	const struct vio_device_id *id_table;
1158c2ecf20Sopenharmony_ci	int (*probe)(struct vio_dev *dev, const struct vio_device_id *id);
1168c2ecf20Sopenharmony_ci	int (*remove)(struct vio_dev *dev);
1178c2ecf20Sopenharmony_ci	/* A driver must have a get_desired_dma() function to
1188c2ecf20Sopenharmony_ci	 * be loaded in a CMO environment if it uses DMA.
1198c2ecf20Sopenharmony_ci	 */
1208c2ecf20Sopenharmony_ci	unsigned long (*get_desired_dma)(struct vio_dev *dev);
1218c2ecf20Sopenharmony_ci	const struct dev_pm_ops *pm;
1228c2ecf20Sopenharmony_ci	struct device_driver driver;
1238c2ecf20Sopenharmony_ci};
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ciextern int __vio_register_driver(struct vio_driver *drv, struct module *owner,
1268c2ecf20Sopenharmony_ci				 const char *mod_name);
1278c2ecf20Sopenharmony_ci/*
1288c2ecf20Sopenharmony_ci * vio_register_driver must be a macro so that KBUILD_MODNAME can be expanded
1298c2ecf20Sopenharmony_ci */
1308c2ecf20Sopenharmony_ci#define vio_register_driver(driver)		\
1318c2ecf20Sopenharmony_ci	__vio_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)
1328c2ecf20Sopenharmony_ciextern void vio_unregister_driver(struct vio_driver *drv);
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_ciextern int vio_cmo_entitlement_update(size_t);
1358c2ecf20Sopenharmony_ciextern void vio_cmo_set_dev_desired(struct vio_dev *viodev, size_t desired);
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ciextern void vio_unregister_device(struct vio_dev *dev);
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_ciextern int vio_h_cop_sync(struct vio_dev *vdev, struct vio_pfo_op *op);
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_cistruct device_node;
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_ciextern struct vio_dev *vio_register_device_node(
1448c2ecf20Sopenharmony_ci		struct device_node *node_vdev);
1458c2ecf20Sopenharmony_ciextern const void *vio_get_attribute(struct vio_dev *vdev, char *which,
1468c2ecf20Sopenharmony_ci		int *length);
1478c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC_PSERIES
1488c2ecf20Sopenharmony_ciextern struct vio_dev *vio_find_node(struct device_node *vnode);
1498c2ecf20Sopenharmony_ciextern int vio_enable_interrupts(struct vio_dev *dev);
1508c2ecf20Sopenharmony_ciextern int vio_disable_interrupts(struct vio_dev *dev);
1518c2ecf20Sopenharmony_ci#else
1528c2ecf20Sopenharmony_cistatic inline int vio_enable_interrupts(struct vio_dev *dev)
1538c2ecf20Sopenharmony_ci{
1548c2ecf20Sopenharmony_ci	return 0;
1558c2ecf20Sopenharmony_ci}
1568c2ecf20Sopenharmony_ci#endif
1578c2ecf20Sopenharmony_ci
1588c2ecf20Sopenharmony_cistatic inline struct vio_driver *to_vio_driver(struct device_driver *drv)
1598c2ecf20Sopenharmony_ci{
1608c2ecf20Sopenharmony_ci	return container_of(drv, struct vio_driver, driver);
1618c2ecf20Sopenharmony_ci}
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_cistatic inline struct vio_dev *to_vio_dev(struct device *dev)
1648c2ecf20Sopenharmony_ci{
1658c2ecf20Sopenharmony_ci	return container_of(dev, struct vio_dev, dev);
1668c2ecf20Sopenharmony_ci}
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_ci#endif /* __KERNEL__ */
1698c2ecf20Sopenharmony_ci#endif /* _ASM_POWERPC_VIO_H */
170