From 5b7c4cabbb65f5c469464da6c5f614cbd7f730f2 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 21 Feb 2023 18:24:12 -0800 Subject: Merge tag 'net-next-6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next Pull networking updates from Jakub Kicinski: "Core: - Add dedicated kmem_cache for typical/small skb->head, avoid having to access struct page at kfree time, and improve memory use. - Introduce sysctl to set default RPS configuration for new netdevs. - Define Netlink protocol specification format which can be used to describe messages used by each family and auto-generate parsers. Add tools for generating kernel data structures and uAPI headers. - Expose all net/core sysctls inside netns. - Remove 4s sleep in netpoll if carrier is instantly detected on boot. - Add configurable limit of MDB entries per port, and port-vlan. - Continue populating drop reasons throughout the stack. - Retire a handful of legacy Qdiscs and classifiers. Protocols: - Support IPv4 big TCP (TSO frames larger than 64kB). - Add IP_LOCAL_PORT_RANGE socket option, to control local port range on socket by socket basis. - Track and report in procfs number of MPTCP sockets used. - Support mixing IPv4 and IPv6 flows in the in-kernel MPTCP path manager. - IPv6: don't check net.ipv6.route.max_size and rely on garbage collection to free memory (similarly to IPv4). - Support Penultimate Segment Pop (PSP) flavor in SRv6 (RFC8986). - ICMP: add per-rate limit counters. - Add support for user scanning requests in ieee802154. - Remove static WEP support. - Support minimal Wi-Fi 7 Extremely High Throughput (EHT) rate reporting. - WiFi 7 EHT channel puncturing support (client & AP). BPF: - Add a rbtree data structure following the "next-gen data structure" precedent set by recently added linked list, that is, by using kfunc + kptr instead of adding a new BPF map type. - Expose XDP hints via kfuncs with initial support for RX hash and timestamp metadata. - Add BPF_F_NO_TUNNEL_KEY extension to bpf_skb_set_tunnel_key to better support decap on GRE tunnel devices not operating in collect metadata. - Improve x86 JIT's codegen for PROBE_MEM runtime error checks. - Remove the need for trace_printk_lock for bpf_trace_printk and bpf_trace_vprintk helpers. - Extend libbpf's bpf_tracing.h support for tracing arguments of kprobes/uprobes and syscall as a special case. - Significantly reduce the search time for module symbols by livepatch and BPF. - Enable cpumasks to be used as kptrs, which is useful for tracing programs tracking which tasks end up running on which CPUs in different time intervals. - Add support for BPF trampoline on s390x and riscv64. - Add capability to export the XDP features supported by the NIC. - Add __bpf_kfunc tag for marking kernel functions as kfuncs. - Add cgroup.memory=nobpf kernel parameter option to disable BPF memory accounting for container environments. Netfilter: - Remove the CLUSTERIP target. It has been marked as obsolete for years, and we still have WARN splats wrt races of the out-of-band /proc interface installed by this target. - Add 'destroy' commands to nf_tables. They are identical to the existing 'delete' commands, but do not return an error if the referenced object (set, chain, rule...) did not exist. Driver API: - Improve cpumask_local_spread() locality to help NICs set the right IRQ affinity on AMD platforms. - Separate C22 and C45 MDIO bus transactions more clearly. - Introduce new DCB table to control DSCP rewrite on egress. - Support configuration of Physical Layer Collision Avoidance (PLCA) Reconciliation Sublayer (RS) (802.3cg-2019). Modern version of shared medium Ethernet. - Support for MAC Merge layer (IEEE 802.3-2018 clause 99). Allowing preemption of low priority frames by high priority frames. - Add support for controlling MACSec offload using netlink SET. - Rework devlink instance refcounts to allow registration and de-registration under the instance lock. Split the code into multiple files, drop some of the unnecessarily granular locks and factor out common parts of netlink operation handling. - Add TX frame aggregation parameters (for USB drivers). - Add a new attr TCA_EXT_WARN_MSG to report TC (offload) warning messages with notifications for debug. - Allow offloading of UDP NEW connections via act_ct. - Add support for per action HW stats in TC. - Support hardware miss to TC action (continue processing in SW from a specific point in the action chain). - Warn if old Wireless Extension user space interface is used with modern cfg80211/mac80211 drivers. Do not support Wireless Extensions for Wi-Fi 7 devices at all. Everyone should switch to using nl80211 interface instead. - Improve the CAN bit timing configuration. Use extack to return error messages directly to user space, update the SJW handling, including the definition of a new default value that will benefit CAN-FD controllers, by increasing their oscillator tolerance. New hardware / drivers: - Ethernet: - nVidia BlueField-3 support (control traffic driver) - Ethernet support for imx93 SoCs - Motorcomm yt8531 gigabit Ethernet PHY - onsemi NCN26000 10BASE-T1S PHY (with support for PLCA) - Microchip LAN8841 PHY (incl. cable diagnostics and PTP) - Amlogic gxl MDIO mux - WiFi: - RealTek RTL8188EU (rtl8xxxu) - Qualcomm Wi-Fi 7 devices (ath12k) - CAN: - Renesas R-Car V4H Drivers: - Bluetooth: - Set Per Platform Antenna Gain (PPAG) for Intel controllers. - Ethernet NICs: - Intel (1G, igc): - support TSN / Qbv / packet scheduling features of i226 model - Intel (100G, ice): - use GNSS subsystem instead of TTY - multi-buffer XDP support - extend support for GPIO pins to E823 devices - nVidia/Mellanox: - update the shared buffer configuration on PFC commands - implement PTP adjphase function for HW offset control - TC support for Geneve and GRE with VF tunnel offload - more efficient crypto key management method - multi-port eswitch support - Netronome/Corigine: - add DCB IEEE support - support IPsec offloading for NFP3800 - Freescale/NXP (enetc): - support XDP_REDIRECT for XDP non-linear buffers - improve reconfig, avoid link flap and waiting for idle - support MAC Merge layer - Other NICs: - sfc/ef100: add basic devlink support for ef100 - ionic: rx_push mode operation (writing descriptors via MMIO) - bnxt: use the auxiliary bus abstraction for RDMA - r8169: disable ASPM and reset bus in case of tx timeout - cpsw: support QSGMII mode for J721e CPSW9G - cpts: support pulse-per-second output - ngbe: add an mdio bus driver - usbnet: optimize usbnet_bh() by avoiding unnecessary queuing - r8152: handle devices with FW with NCM support - amd-xgbe: support 10Mbps, 2.5GbE speeds and rx-adaptation - virtio-net: support multi buffer XDP - virtio/vsock: replace virtio_vsock_pkt with sk_buff - tsnep: XDP support - Ethernet high-speed switches: - nVidia/Mellanox (mlxsw): - add support for latency TLV (in FW control messages) - Microchip (sparx5): - separate explicit and implicit traffic forwarding rules, make the implicit rules always active - add support for egress DSCP rewrite - IS0 VCAP support (Ingress Classification) - IS2 VCAP filters (protos, L3 addrs, L4 ports, flags, ToS etc.) - ES2 VCAP support (Egress Access Control) - support for Per-Stream Filtering and Policing (802.1Q, 8.6.5.1) - Ethernet embedded switches: - Marvell (mv88e6xxx): - add MAB (port auth) offload support - enable PTP receive for mv88e6390 - NXP (ocelot): - support MAC Merge layer - support for the the vsc7512 internal copper phys - Microchip: - lan9303: convert to PHYLINK - lan966x: support TC flower filter statistics - lan937x: PTP support for KSZ9563/KSZ8563 and LAN937x - lan937x: support Credit Based Shaper configuration - ksz9477: support Energy Efficient Ethernet - other: - qca8k: convert to regmap read/write API, use bulk operations - rswitch: Improve TX timestamp accuracy - Intel WiFi (iwlwifi): - EHT (Wi-Fi 7) rate reporting - STEP equalizer support: transfer some STEP (connection to radio on platforms with integrated wifi) related parameters from the BIOS to the firmware. - Qualcomm 802.11ax WiFi (ath11k): - IPQ5018 support - Fine Timing Measurement (FTM) responder role support - channel 177 support - MediaTek WiFi (mt76): - per-PHY LED support - mt7996: EHT (Wi-Fi 7) support - Wireless Ethernet Dispatch (WED) reset support - switch to using page pool allocator - RealTek WiFi (rtw89): - support new version of Bluetooth co-existance - Mobile: - rmnet: support TX aggregation" * tag 'net-next-6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next: (1872 commits) page_pool: add a comment explaining the fragment counter usage net: ethtool: fix __ethtool_dev_mm_supported() implementation ethtool: pse-pd: Fix double word in comments xsk: add linux/vmalloc.h to xsk.c sefltests: netdevsim: wait for devlink instance after netns removal selftest: fib_tests: Always cleanup before exit net/mlx5e: Align IPsec ASO result memory to be as required by hardware net/mlx5e: TC, Set CT miss to the specific ct action instance net/mlx5e: Rename CHAIN_TO_REG to MAPPED_OBJ_TO_REG net/mlx5: Refactor tc miss handling to a single function net/mlx5: Kconfig: Make tc offload depend on tc skb extension net/sched: flower: Support hardware miss to tc action net/sched: flower: Move filter handle initialization earlier net/sched: cls_api: Support hardware miss to tc action net/sched: Rename user cookie and act cookie sfc: fix builds without CONFIG_RTC_LIB sfc: clean up some inconsistent indentings net/mlx4_en: Introduce flexible array to silence overflow warning net: lan966x: Fix possible deadlock inside PTP net/ulp: Remove redundant ->clone() test in inet_clone_ulp(). ... --- drivers/gpu/drm/nouveau/include/nvkm/core/client.h | 40 ++++ drivers/gpu/drm/nouveau/include/nvkm/core/debug.h | 12 ++ drivers/gpu/drm/nouveau/include/nvkm/core/device.h | 151 +++++++++++++++ drivers/gpu/drm/nouveau/include/nvkm/core/engine.h | 55 ++++++ drivers/gpu/drm/nouveau/include/nvkm/core/enum.h | 22 +++ drivers/gpu/drm/nouveau/include/nvkm/core/event.h | 77 ++++++++ drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h | 210 +++++++++++++++++++++ .../gpu/drm/nouveau/include/nvkm/core/firmware.h | 77 ++++++++ drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h | 43 +++++ drivers/gpu/drm/nouveau/include/nvkm/core/intr.h | 73 +++++++ drivers/gpu/drm/nouveau/include/nvkm/core/ioctl.h | 8 + drivers/gpu/drm/nouveau/include/nvkm/core/layout.h | 54 ++++++ drivers/gpu/drm/nouveau/include/nvkm/core/memory.h | 123 ++++++++++++ drivers/gpu/drm/nouveau/include/nvkm/core/mm.h | 78 ++++++++ drivers/gpu/drm/nouveau/include/nvkm/core/object.h | 79 ++++++++ drivers/gpu/drm/nouveau/include/nvkm/core/oclass.h | 31 +++ drivers/gpu/drm/nouveau/include/nvkm/core/oproxy.h | 23 +++ drivers/gpu/drm/nouveau/include/nvkm/core/option.h | 19 ++ drivers/gpu/drm/nouveau/include/nvkm/core/os.h | 57 ++++++ drivers/gpu/drm/nouveau/include/nvkm/core/pci.h | 15 ++ drivers/gpu/drm/nouveau/include/nvkm/core/ramht.h | 30 +++ drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h | 95 ++++++++++ drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h | 56 ++++++ 23 files changed, 1428 insertions(+) create mode 100644 drivers/gpu/drm/nouveau/include/nvkm/core/client.h create mode 100644 drivers/gpu/drm/nouveau/include/nvkm/core/debug.h create mode 100644 drivers/gpu/drm/nouveau/include/nvkm/core/device.h create mode 100644 drivers/gpu/drm/nouveau/include/nvkm/core/engine.h create mode 100644 drivers/gpu/drm/nouveau/include/nvkm/core/enum.h create mode 100644 drivers/gpu/drm/nouveau/include/nvkm/core/event.h create mode 100644 drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h create mode 100644 drivers/gpu/drm/nouveau/include/nvkm/core/firmware.h create mode 100644 drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h create mode 100644 drivers/gpu/drm/nouveau/include/nvkm/core/intr.h create mode 100644 drivers/gpu/drm/nouveau/include/nvkm/core/ioctl.h create mode 100644 drivers/gpu/drm/nouveau/include/nvkm/core/layout.h create mode 100644 drivers/gpu/drm/nouveau/include/nvkm/core/memory.h create mode 100644 drivers/gpu/drm/nouveau/include/nvkm/core/mm.h create mode 100644 drivers/gpu/drm/nouveau/include/nvkm/core/object.h create mode 100644 drivers/gpu/drm/nouveau/include/nvkm/core/oclass.h create mode 100644 drivers/gpu/drm/nouveau/include/nvkm/core/oproxy.h create mode 100644 drivers/gpu/drm/nouveau/include/nvkm/core/option.h create mode 100644 drivers/gpu/drm/nouveau/include/nvkm/core/os.h create mode 100644 drivers/gpu/drm/nouveau/include/nvkm/core/pci.h create mode 100644 drivers/gpu/drm/nouveau/include/nvkm/core/ramht.h create mode 100644 drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h create mode 100644 drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h (limited to 'drivers/gpu/drm/nouveau/include/nvkm/core') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/client.h b/drivers/gpu/drm/nouveau/include/nvkm/core/client.h new file mode 100644 index 000000000..0d9fc741a --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/client.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: MIT */ +#ifndef __NVKM_CLIENT_H__ +#define __NVKM_CLIENT_H__ +#define nvkm_client(p) container_of((p), struct nvkm_client, object) +#include + +struct nvkm_client { + struct nvkm_object object; + char name[32]; + u64 device; + u32 debug; + + struct rb_root objroot; + + void *data; + int (*event)(u64 token, void *argv, u32 argc); + + struct list_head umem; + spinlock_t lock; +}; + +int nvkm_client_new(const char *name, u64 device, const char *cfg, const char *dbg, + int (*)(u64, void *, u32), struct nvkm_client **); +struct nvkm_client *nvkm_client_search(struct nvkm_client *, u64 handle); + +/* logging for client-facing objects */ +#define nvif_printk(o,l,p,f,a...) do { \ + const struct nvkm_object *_object = (o); \ + const struct nvkm_client *_client = _object->client; \ + if (_client->debug >= NV_DBG_##l) \ + printk(KERN_##p "nouveau: %s:%08x:%08x: "f, _client->name, \ + _object->handle, _object->oclass, ##a); \ +} while(0) +#define nvif_fatal(o,f,a...) nvif_printk((o), FATAL, CRIT, f, ##a) +#define nvif_error(o,f,a...) nvif_printk((o), ERROR, ERR, f, ##a) +#define nvif_debug(o,f,a...) nvif_printk((o), DEBUG, INFO, f, ##a) +#define nvif_trace(o,f,a...) nvif_printk((o), TRACE, INFO, f, ##a) +#define nvif_info(o,f,a...) nvif_printk((o), INFO, INFO, f, ##a) +#define nvif_ioctl(o,f,a...) nvif_trace((o), "ioctl: "f, ##a) +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/debug.h b/drivers/gpu/drm/nouveau/include/nvkm/core/debug.h new file mode 100644 index 000000000..b4a9c7d99 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/debug.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: MIT */ +#ifndef __NVKM_DEBUG_H__ +#define __NVKM_DEBUG_H__ +#define NV_DBG_FATAL 0 +#define NV_DBG_ERROR 1 +#define NV_DBG_WARN 2 +#define NV_DBG_INFO 3 +#define NV_DBG_DEBUG 4 +#define NV_DBG_TRACE 5 +#define NV_DBG_PARANOIA 6 +#define NV_DBG_SPAM 7 +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h new file mode 100644 index 000000000..f65b5009a --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h @@ -0,0 +1,151 @@ +/* SPDX-License-Identifier: MIT */ +#ifndef __NVKM_DEVICE_H__ +#define __NVKM_DEVICE_H__ +#include +#include +enum nvkm_subdev_type; + +enum nvkm_device_type { + NVKM_DEVICE_PCI, + NVKM_DEVICE_AGP, + NVKM_DEVICE_PCIE, + NVKM_DEVICE_TEGRA, +}; + +struct nvkm_device { + const struct nvkm_device_func *func; + const struct nvkm_device_quirk *quirk; + struct device *dev; + enum nvkm_device_type type; + u64 handle; + const char *name; + const char *cfgopt; + const char *dbgopt; + + struct list_head head; + struct mutex mutex; + int refcount; + + void __iomem *pri; + + u32 debug; + + const struct nvkm_device_chip *chip; + enum { + NV_04 = 0x04, + NV_10 = 0x10, + NV_11 = 0x11, + NV_20 = 0x20, + NV_30 = 0x30, + NV_40 = 0x40, + NV_50 = 0x50, + NV_C0 = 0xc0, + NV_E0 = 0xe0, + GM100 = 0x110, + GP100 = 0x130, + GV100 = 0x140, + TU100 = 0x160, + GA100 = 0x170, + } card_type; + u32 chipset; + u8 chiprev; + u32 crystal; + + struct { + struct notifier_block nb; + } acpi; + +#define NVKM_LAYOUT_ONCE(type,data,ptr) data *ptr; +#define NVKM_LAYOUT_INST(type,data,ptr,cnt) data *ptr[cnt]; +#include +#undef NVKM_LAYOUT_INST +#undef NVKM_LAYOUT_ONCE + struct list_head subdev; + + struct { + struct list_head intr; + struct list_head prio[NVKM_INTR_PRIO_NR]; + spinlock_t lock; + int irq; + bool alloc; + bool armed; + bool legacy_done; + } intr; +}; + +struct nvkm_subdev *nvkm_device_subdev(struct nvkm_device *, int type, int inst); +struct nvkm_engine *nvkm_device_engine(struct nvkm_device *, int type, int inst); + +struct nvkm_device_func { + struct nvkm_device_pci *(*pci)(struct nvkm_device *); + struct nvkm_device_tegra *(*tegra)(struct nvkm_device *); + void *(*dtor)(struct nvkm_device *); + int (*preinit)(struct nvkm_device *); + int (*init)(struct nvkm_device *); + void (*fini)(struct nvkm_device *, bool suspend); + int (*irq)(struct nvkm_device *); + resource_size_t (*resource_addr)(struct nvkm_device *, unsigned bar); + resource_size_t (*resource_size)(struct nvkm_device *, unsigned bar); + bool cpu_coherent; +}; + +struct nvkm_device_quirk { + u8 tv_pin_mask; + u8 tv_gpio; +}; + +struct nvkm_device_chip { + const char *name; +#define NVKM_LAYOUT_ONCE(type,data,ptr,...) \ + struct { \ + u32 inst; \ + int (*ctor)(struct nvkm_device *, enum nvkm_subdev_type, int inst, data **); \ + } ptr; +#define NVKM_LAYOUT_INST(A...) NVKM_LAYOUT_ONCE(A) +#include +#undef NVKM_LAYOUT_INST +#undef NVKM_LAYOUT_ONCE +}; + +struct nvkm_device *nvkm_device_find(u64 name); +int nvkm_device_list(u64 *name, int size); + +/* privileged register interface accessor macros */ +#define nvkm_rd08(d,a) ioread8((d)->pri + (a)) +#define nvkm_rd16(d,a) ioread16_native((d)->pri + (a)) +#define nvkm_rd32(d,a) ioread32_native((d)->pri + (a)) +#define nvkm_wr08(d,a,v) iowrite8((v), (d)->pri + (a)) +#define nvkm_wr16(d,a,v) iowrite16_native((v), (d)->pri + (a)) +#define nvkm_wr32(d,a,v) iowrite32_native((v), (d)->pri + (a)) +#define nvkm_mask(d,a,m,v) ({ \ + struct nvkm_device *_device = (d); \ + u32 _addr = (a), _temp = nvkm_rd32(_device, _addr); \ + nvkm_wr32(_device, _addr, (_temp & ~(m)) | (v)); \ + _temp; \ +}) + +void nvkm_device_del(struct nvkm_device **); + +struct nvkm_device_oclass { + int (*ctor)(struct nvkm_device *, const struct nvkm_oclass *, + void *data, u32 size, struct nvkm_object **); + struct nvkm_sclass base; +}; + +extern const struct nvkm_sclass nvkm_udevice_sclass; + +/* device logging */ +#define nvdev_printk_(d,l,p,f,a...) do { \ + const struct nvkm_device *_device = (d); \ + if (_device->debug >= (l)) \ + dev_##p(_device->dev, f, ##a); \ +} while(0) +#define nvdev_printk(d,l,p,f,a...) nvdev_printk_((d), NV_DBG_##l, p, f, ##a) +#define nvdev_fatal(d,f,a...) nvdev_printk((d), FATAL, crit, f, ##a) +#define nvdev_error(d,f,a...) nvdev_printk((d), ERROR, err, f, ##a) +#define nvdev_warn(d,f,a...) nvdev_printk((d), WARN, notice, f, ##a) +#define nvdev_info(d,f,a...) nvdev_printk((d), INFO, info, f, ##a) +#define nvdev_debug(d,f,a...) nvdev_printk((d), DEBUG, info, f, ##a) +#define nvdev_trace(d,f,a...) nvdev_printk((d), TRACE, info, f, ##a) +#define nvdev_spam(d,f,a...) nvdev_printk((d), SPAM, dbg, f, ##a) +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/engine.h b/drivers/gpu/drm/nouveau/include/nvkm/core/engine.h new file mode 100644 index 000000000..b67b9c1a6 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/engine.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: MIT */ +#ifndef __NVKM_ENGINE_H__ +#define __NVKM_ENGINE_H__ +#define nvkm_engine(p) container_of((p), struct nvkm_engine, subdev) +#include +struct nvkm_fifo_chan; +struct nvkm_fb_tile; + +extern const struct nvkm_subdev_func nvkm_engine; + +struct nvkm_engine { + const struct nvkm_engine_func *func; + struct nvkm_subdev subdev; + spinlock_t lock; +}; + +struct nvkm_engine_func { + void *(*dtor)(struct nvkm_engine *); + void (*preinit)(struct nvkm_engine *); + int (*oneinit)(struct nvkm_engine *); + int (*info)(struct nvkm_engine *, u64 mthd, u64 *data); + int (*init)(struct nvkm_engine *); + int (*fini)(struct nvkm_engine *, bool suspend); + int (*reset)(struct nvkm_engine *); + void (*intr)(struct nvkm_engine *); + void (*tile)(struct nvkm_engine *, int region, struct nvkm_fb_tile *); + bool (*chsw_load)(struct nvkm_engine *); + + struct { + int (*sclass)(struct nvkm_oclass *, int index, + const struct nvkm_device_oclass **); + } base; + + struct { + int (*cclass)(struct nvkm_fifo_chan *, + const struct nvkm_oclass *, + struct nvkm_object **); + int (*sclass)(struct nvkm_oclass *, int index); + } fifo; + + const struct nvkm_object_func *cclass; + struct nvkm_sclass sclass[]; +}; + +int nvkm_engine_ctor(const struct nvkm_engine_func *, struct nvkm_device *, + enum nvkm_subdev_type, int inst, bool enable, struct nvkm_engine *); +int nvkm_engine_new_(const struct nvkm_engine_func *, struct nvkm_device *, + enum nvkm_subdev_type, int, bool enable, struct nvkm_engine **); + +struct nvkm_engine *nvkm_engine_ref(struct nvkm_engine *); +void nvkm_engine_unref(struct nvkm_engine **); +int nvkm_engine_reset(struct nvkm_engine *); +void nvkm_engine_tile(struct nvkm_engine *, int region); +bool nvkm_engine_chsw_load(struct nvkm_engine *); +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/enum.h b/drivers/gpu/drm/nouveau/include/nvkm/core/enum.h new file mode 100644 index 000000000..070462be3 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/enum.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: MIT */ +#ifndef __NVKM_ENUM_H__ +#define __NVKM_ENUM_H__ +#include + +struct nvkm_enum { + u32 value; + const char *name; + const void *data; + u32 data2; + int inst; +}; + +const struct nvkm_enum *nvkm_enum_find(const struct nvkm_enum *, u32 value); + +struct nvkm_bitfield { + u32 mask; + const char *name; +}; + +void nvkm_snprintbf(char *, int, const struct nvkm_bitfield *, u32 value); +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/event.h b/drivers/gpu/drm/nouveau/include/nvkm/core/event.h new file mode 100644 index 000000000..82b267c11 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/event.h @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: MIT */ +#ifndef __NVKM_EVENT_H__ +#define __NVKM_EVENT_H__ +#include +struct nvkm_object; +struct nvkm_oclass; +struct nvkm_uevent; + +struct nvkm_event { + const struct nvkm_event_func *func; + struct nvkm_subdev *subdev; + + int types_nr; + int index_nr; + + spinlock_t refs_lock; + spinlock_t list_lock; + int *refs; + + struct list_head ntfy; +}; + +struct nvkm_event_func { + void (*init)(struct nvkm_event *, int type, int index); + void (*fini)(struct nvkm_event *, int type, int index); +}; + +int __nvkm_event_init(const struct nvkm_event_func *func, struct nvkm_subdev *, int types_nr, + int index_nr, struct nvkm_event *); + +/* Each nvkm_event needs its own lockdep class due to inter-dependencies, to + * prevent lockdep false-positives. + * + * Inlining the spinlock initialisation ensures each is unique. + */ +static __always_inline int +nvkm_event_init(const struct nvkm_event_func *func, struct nvkm_subdev *subdev, + int types_nr, int index_nr, struct nvkm_event *event) +{ + spin_lock_init(&event->refs_lock); + spin_lock_init(&event->list_lock); + return __nvkm_event_init(func, subdev, types_nr, index_nr, event); +} + +void nvkm_event_fini(struct nvkm_event *); + +#define NVKM_EVENT_KEEP 0 +#define NVKM_EVENT_DROP 1 +struct nvkm_event_ntfy; +typedef int (*nvkm_event_func)(struct nvkm_event_ntfy *, u32 bits); + +struct nvkm_event_ntfy { + struct nvkm_event *event; + int id; + u32 bits; + bool wait; + nvkm_event_func func; + + atomic_t allowed; + bool running; + + struct list_head head; +}; + +void nvkm_event_ntfy(struct nvkm_event *, int id, u32 bits); +bool nvkm_event_ntfy_valid(struct nvkm_event *, int id, u32 bits); +void nvkm_event_ntfy_add(struct nvkm_event *, int id, u32 bits, bool wait, nvkm_event_func, + struct nvkm_event_ntfy *); +void nvkm_event_ntfy_del(struct nvkm_event_ntfy *); +void nvkm_event_ntfy_allow(struct nvkm_event_ntfy *); +void nvkm_event_ntfy_block(struct nvkm_event_ntfy *); + +typedef int (*nvkm_uevent_func)(struct nvkm_object *, u64 token, u32 bits); + +int nvkm_uevent_new(const struct nvkm_oclass *, void *argv, u32 argc, struct nvkm_object **); +int nvkm_uevent_add(struct nvkm_uevent *, struct nvkm_event *, int id, u32 bits, nvkm_uevent_func); +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h b/drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h new file mode 100644 index 000000000..b857cf142 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h @@ -0,0 +1,210 @@ +#ifndef __NVKM_FALCON_H__ +#define __NVKM_FALCON_H__ +#include +#include + +enum nvkm_falcon_mem { + IMEM, + DMEM, + EMEM, +}; + +static inline const char * +nvkm_falcon_mem(enum nvkm_falcon_mem mem) +{ + switch (mem) { + case IMEM: return "imem"; + case DMEM: return "dmem"; + case EMEM: return "emem"; + default: + WARN_ON(1); + return "?mem"; + } +} + +struct nvkm_falcon_func_pio { + int min; + int max; + void (*wr_init)(struct nvkm_falcon *, u8 port, bool sec, u32 mem_base); + void (*wr)(struct nvkm_falcon *, u8 port, const u8 *img, int len, u16 tag); + void (*rd_init)(struct nvkm_falcon *, u8 port, u32 mem_base); + void (*rd)(struct nvkm_falcon *, u8 port, const u8 *img, int len); +}; + +struct nvkm_falcon_func_dma { + int (*init)(struct nvkm_falcon *, u64 dma_addr, int xfer_len, + enum nvkm_falcon_mem, bool sec, u32 *cmd); + void (*xfer)(struct nvkm_falcon *, u32 mem_base, u32 dma_base, u32 cmd); + bool (*done)(struct nvkm_falcon *); +}; + +int nvkm_falcon_ctor(const struct nvkm_falcon_func *, struct nvkm_subdev *owner, + const char *name, u32 addr, struct nvkm_falcon *); +void nvkm_falcon_dtor(struct nvkm_falcon *); +int nvkm_falcon_reset(struct nvkm_falcon *); +int nvkm_falcon_pio_wr(struct nvkm_falcon *, const u8 *img, u32 img_base, u8 port, + enum nvkm_falcon_mem mem_type, u32 mem_base, int len, u16 tag, bool sec); +int nvkm_falcon_pio_rd(struct nvkm_falcon *, u8 port, enum nvkm_falcon_mem type, u32 mem_base, + const u8 *img, u32 img_base, int len); +int nvkm_falcon_dma_wr(struct nvkm_falcon *, const u8 *img, u64 dma_addr, u32 dma_base, + enum nvkm_falcon_mem mem_type, u32 mem_base, int len, bool sec); + +int gm200_flcn_reset_wait_mem_scrubbing(struct nvkm_falcon *); +int gm200_flcn_disable(struct nvkm_falcon *); +int gm200_flcn_enable(struct nvkm_falcon *); +void gm200_flcn_bind_inst(struct nvkm_falcon *, int, u64); +int gm200_flcn_bind_stat(struct nvkm_falcon *, bool); +extern const struct nvkm_falcon_func_pio gm200_flcn_imem_pio; +extern const struct nvkm_falcon_func_pio gm200_flcn_dmem_pio; +void gm200_flcn_tracepc(struct nvkm_falcon *); + +int gp102_flcn_reset_eng(struct nvkm_falcon *); +extern const struct nvkm_falcon_func_pio gp102_flcn_emem_pio; + +int ga102_flcn_select(struct nvkm_falcon *); +int ga102_flcn_reset_prep(struct nvkm_falcon *); +int ga102_flcn_reset_wait_mem_scrubbing(struct nvkm_falcon *); +extern const struct nvkm_falcon_func_dma ga102_flcn_dma; + +void nvkm_falcon_v1_load_imem(struct nvkm_falcon *, + void *, u32, u32, u16, u8, bool); +void nvkm_falcon_v1_load_dmem(struct nvkm_falcon *, void *, u32, u32, u8); +void nvkm_falcon_v1_start(struct nvkm_falcon *); + +#define FLCN_PRINTK(f,l,p,fmt,a...) ({ \ + if ((f)->owner->name != (f)->name) \ + nvkm_printk___((f)->owner, (f)->user, NV_DBG_##l, p, "%s:"fmt, (f)->name, ##a); \ + else \ + nvkm_printk___((f)->owner, (f)->user, NV_DBG_##l, p, fmt, ##a); \ +}) +#define FLCN_DBG(f,fmt,a...) FLCN_PRINTK((f), DEBUG, info, " "fmt"\n", ##a) +#define FLCN_ERR(f,fmt,a...) FLCN_PRINTK((f), ERROR, err, " "fmt"\n", ##a) +#define FLCN_ERRON(f,c,fmt,a...) \ + ({ bool _cond = (c); _cond ? FLCN_ERR(f, fmt, ##a) : FLCN_DBG(f, fmt, ##a); _cond; }) + + +struct nvkm_falcon_fw { + const struct nvkm_falcon_fw_func { + int (*signature)(struct nvkm_falcon_fw *, u32 *sig_base_src); + int (*reset)(struct nvkm_falcon_fw *); + int (*setup)(struct nvkm_falcon_fw *); + int (*load)(struct nvkm_falcon_fw *); + int (*load_bld)(struct nvkm_falcon_fw *); + int (*boot)(struct nvkm_falcon_fw *, + u32 *mbox0, u32 *mbox1, u32 mbox0_ok, u32 irqsclr); + } *func; + struct nvkm_firmware fw; + + u32 sig_base_prd; + u32 sig_base_dbg; + u32 sig_base_img; + u32 sig_size; + int sig_nr; + u8 *sigs; + u32 fuse_ver; + u32 engine_id; + u32 ucode_id; + + u32 nmem_base_img; + u32 nmem_base; + u32 nmem_size; + + u32 imem_base_img; + u32 imem_base; + u32 imem_size; + + u32 dmem_base_img; + u32 dmem_base; + u32 dmem_size; + u32 dmem_sign; + + u8 *boot; + u32 boot_size; + u32 boot_addr; + + struct nvkm_falcon *falcon; + struct nvkm_memory *inst; + struct nvkm_vmm *vmm; + struct nvkm_vma *vma; +}; + +int nvkm_falcon_fw_ctor(const struct nvkm_falcon_fw_func *, const char *name, struct nvkm_device *, + bool bl, const void *src, u32 len, struct nvkm_falcon *, + struct nvkm_falcon_fw *); +int nvkm_falcon_fw_ctor_hs(const struct nvkm_falcon_fw_func *, const char *name, + struct nvkm_subdev *, const char *bl, const char *img, int ver, + struct nvkm_falcon *falcon, struct nvkm_falcon_fw *fw); +int nvkm_falcon_fw_ctor_hs_v2(const struct nvkm_falcon_fw_func *, const char *name, + struct nvkm_subdev *, const char *img, int ver, struct nvkm_falcon *, + struct nvkm_falcon_fw *); +int nvkm_falcon_fw_sign(struct nvkm_falcon_fw *, u32 sig_base_img, u32 sig_size, const u8 *sigs, + int sig_nr_prd, u32 sig_base_prd, int sig_nr_dbg, u32 sig_base_dbg); +int nvkm_falcon_fw_patch(struct nvkm_falcon_fw *); +void nvkm_falcon_fw_dtor(struct nvkm_falcon_fw *); +int nvkm_falcon_fw_oneinit(struct nvkm_falcon_fw *, struct nvkm_falcon *, struct nvkm_vmm *, + struct nvkm_memory *inst); +int nvkm_falcon_fw_boot(struct nvkm_falcon_fw *, struct nvkm_subdev *user, + bool release, u32 *pmbox0, u32 *pmbox1, u32 mbox0_ok, u32 irqsclr); + +extern const struct nvkm_falcon_fw_func gm200_flcn_fw; +int gm200_flcn_fw_signature(struct nvkm_falcon_fw *, u32 *); +int gm200_flcn_fw_reset(struct nvkm_falcon_fw *); +int gm200_flcn_fw_load(struct nvkm_falcon_fw *); +int gm200_flcn_fw_boot(struct nvkm_falcon_fw *, u32 *, u32 *, u32, u32); + +int ga100_flcn_fw_signature(struct nvkm_falcon_fw *, u32 *); + +extern const struct nvkm_falcon_fw_func ga102_flcn_fw; +int ga102_flcn_fw_load(struct nvkm_falcon_fw *); +int ga102_flcn_fw_boot(struct nvkm_falcon_fw *, u32 *, u32 *, u32, u32); + +#define FLCNFW_PRINTK(f,l,p,fmt,a...) FLCN_PRINTK((f)->falcon, l, p, "%s: "fmt, (f)->fw.name, ##a) +#define FLCNFW_DBG(f,fmt,a...) FLCNFW_PRINTK((f), DEBUG, info, fmt"\n", ##a) +#define FLCNFW_ERR(f,fmt,a...) FLCNFW_PRINTK((f), ERROR, err, fmt"\n", ##a) + +/** + * struct nvfw_falcon_msg - header for all messages + * + * @unit_id: id of firmware process that sent the message + * @size: total size of message + * @ctrl_flags: control flags + * @seq_id: used to match a message from its corresponding command + */ +struct nvfw_falcon_msg { + u8 unit_id; + u8 size; + u8 ctrl_flags; + u8 seq_id; +}; + +#define nvfw_falcon_cmd nvfw_falcon_msg +#define NV_FALCON_CMD_UNIT_ID_REWIND 0x00 + +struct nvkm_falcon_qmgr; +int nvkm_falcon_qmgr_new(struct nvkm_falcon *, struct nvkm_falcon_qmgr **); +void nvkm_falcon_qmgr_del(struct nvkm_falcon_qmgr **); + +typedef int +(*nvkm_falcon_qmgr_callback)(void *priv, struct nvfw_falcon_msg *); + +struct nvkm_falcon_cmdq; +int nvkm_falcon_cmdq_new(struct nvkm_falcon_qmgr *, const char *name, + struct nvkm_falcon_cmdq **); +void nvkm_falcon_cmdq_del(struct nvkm_falcon_cmdq **); +void nvkm_falcon_cmdq_init(struct nvkm_falcon_cmdq *, + u32 index, u32 offset, u32 size); +void nvkm_falcon_cmdq_fini(struct nvkm_falcon_cmdq *); +int nvkm_falcon_cmdq_send(struct nvkm_falcon_cmdq *, struct nvfw_falcon_cmd *, + nvkm_falcon_qmgr_callback, void *priv, + unsigned long timeout_jiffies); + +struct nvkm_falcon_msgq; +int nvkm_falcon_msgq_new(struct nvkm_falcon_qmgr *, const char *name, + struct nvkm_falcon_msgq **); +void nvkm_falcon_msgq_del(struct nvkm_falcon_msgq **); +void nvkm_falcon_msgq_init(struct nvkm_falcon_msgq *, + u32 index, u32 offset, u32 size); +bool nvkm_falcon_msgq_empty(struct nvkm_falcon_msgq *); +int nvkm_falcon_msgq_recv_initmsg(struct nvkm_falcon_msgq *, void *, u32 size); +void nvkm_falcon_msgq_recv(struct nvkm_falcon_msgq *); +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/firmware.h b/drivers/gpu/drm/nouveau/include/nvkm/core/firmware.h new file mode 100644 index 000000000..d4e507e25 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/firmware.h @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: MIT */ +#ifndef __NVKM_FIRMWARE_H__ +#define __NVKM_FIRMWARE_H__ +#include +#include +#include + +struct nvkm_firmware { + const struct nvkm_firmware_func { + enum nvkm_firmware_type { + NVKM_FIRMWARE_IMG_RAM, + NVKM_FIRMWARE_IMG_DMA, + } type; + } *func; + const char *name; + struct nvkm_device *device; + + int len; + u8 *img; + u64 phys; + + struct nvkm_firmware_mem { + struct nvkm_memory memory; + struct scatterlist sgl; + } mem; +}; + +int nvkm_firmware_ctor(const struct nvkm_firmware_func *, const char *name, struct nvkm_device *, + const void *ptr, int len, struct nvkm_firmware *); +void nvkm_firmware_dtor(struct nvkm_firmware *); + +int nvkm_firmware_get(const struct nvkm_subdev *, const char *fwname, int ver, + const struct firmware **); +void nvkm_firmware_put(const struct firmware *); + +int nvkm_firmware_load_blob(const struct nvkm_subdev *subdev, const char *path, + const char *name, int ver, struct nvkm_blob *); +int nvkm_firmware_load_name(const struct nvkm_subdev *subdev, const char *path, + const char *name, int ver, + const struct firmware **); + +#define nvkm_firmware_load(s,l,o,p...) ({ \ + struct nvkm_subdev *_s = (s); \ + const char *_opts = (o); \ + char _option[32]; \ + typeof(l[0]) *_list = (l), *_next, *_fwif = NULL; \ + int _ver, _fwv, _ret = 0; \ + \ + snprintf(_option, sizeof(_option), "Nv%sFw", _opts); \ + _ver = nvkm_longopt(_s->device->cfgopt, _option, -2); \ + if (_ver >= -1) { \ + for (_next = _list; !_fwif && _next->load; _next++) { \ + if (_next->version == _ver) \ + _fwif = _next; \ + } \ + _ret = _fwif ? 0 : -EINVAL; \ + } \ + \ + if (_ret == 0) { \ + snprintf(_option, sizeof(_option), "Nv%sFwVer", _opts); \ + _fwv = _fwif ? _fwif->version : -1; \ + _ver = nvkm_longopt(_s->device->cfgopt, _option, _fwv); \ + for (_next = _fwif ? _fwif : _list; _next->load; _next++) { \ + _fwv = (_ver >= 0) ? _ver : _next->version; \ + _ret = _next->load(p, _fwv, _next); \ + if (_ret == 0 || _ver >= 0) { \ + _fwif = _next; \ + break; \ + } \ + } \ + } \ + \ + if (_ret) \ + _fwif = ERR_PTR(_ret); \ + _fwif; \ +}) +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h b/drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h new file mode 100644 index 000000000..0f515ec28 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: MIT */ +#ifndef __NVKM_GPUOBJ_H__ +#define __NVKM_GPUOBJ_H__ +#include +#include + +#define NVOBJ_FLAG_ZERO_ALLOC 0x00000001 +#define NVOBJ_FLAG_HEAP 0x00000004 + +struct nvkm_gpuobj { + union { + const struct nvkm_gpuobj_func *func; + const struct nvkm_gpuobj_func *ptrs; + }; + struct nvkm_gpuobj *parent; + struct nvkm_memory *memory; + struct nvkm_mm_node *node; + + u64 addr; + u32 size; + struct nvkm_mm heap; + + void __iomem *map; +}; + +struct nvkm_gpuobj_func { + void *(*acquire)(struct nvkm_gpuobj *); + void (*release)(struct nvkm_gpuobj *); + u32 (*rd32)(struct nvkm_gpuobj *, u32 offset); + void (*wr32)(struct nvkm_gpuobj *, u32 offset, u32 data); + int (*map)(struct nvkm_gpuobj *, u64 offset, struct nvkm_vmm *, + struct nvkm_vma *, void *argv, u32 argc); +}; + +int nvkm_gpuobj_new(struct nvkm_device *, u32 size, int align, bool zero, + struct nvkm_gpuobj *parent, struct nvkm_gpuobj **); +void nvkm_gpuobj_del(struct nvkm_gpuobj **); +int nvkm_gpuobj_wrap(struct nvkm_memory *, struct nvkm_gpuobj **); +void nvkm_gpuobj_memcpy_to(struct nvkm_gpuobj *dst, u32 dstoffset, void *src, + u32 length); +void nvkm_gpuobj_memcpy_from(void *dst, struct nvkm_gpuobj *src, u32 srcoffset, + u32 length); +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/intr.h b/drivers/gpu/drm/nouveau/include/nvkm/core/intr.h new file mode 100644 index 000000000..a003d6a54 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/intr.h @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: MIT */ +#ifndef __NVKM_INTR_H__ +#define __NVKM_INTR_H__ +#include +struct nvkm_device; +struct nvkm_subdev; + +enum nvkm_intr_prio { + NVKM_INTR_PRIO_VBLANK = 0, + NVKM_INTR_PRIO_NORMAL, + NVKM_INTR_PRIO_NR +}; + +enum nvkm_intr_type { + NVKM_INTR_SUBDEV = -1, /* lookup vector by requesting subdev, in mapping table. */ + NVKM_INTR_VECTOR_0 = 0, +}; + +struct nvkm_intr { + const struct nvkm_intr_func { + bool (*pending)(struct nvkm_intr *); + void (*unarm)(struct nvkm_intr *); + void (*rearm)(struct nvkm_intr *); + void (*block)(struct nvkm_intr *, int leaf, u32 mask); + void (*allow)(struct nvkm_intr *, int leaf, u32 mask); + void (*reset)(struct nvkm_intr *, int leaf, u32 mask); + } *func; + const struct nvkm_intr_data { + int type; /* enum nvkm_subdev_type (+ve), enum nvkm_intr_type (-ve) */ + int inst; + int leaf; + u32 mask; /* 0-terminated. */ + bool legacy; /* auto-create "legacy" nvkm_subdev_intr() handler */ + } *data; + + struct nvkm_subdev *subdev; + int leaves; + u32 *stat; + u32 *mask; + + struct list_head head; +}; + +void nvkm_intr_ctor(struct nvkm_device *); +void nvkm_intr_dtor(struct nvkm_device *); +int nvkm_intr_install(struct nvkm_device *); +void nvkm_intr_unarm(struct nvkm_device *); +void nvkm_intr_rearm(struct nvkm_device *); + +int nvkm_intr_add(const struct nvkm_intr_func *, const struct nvkm_intr_data *, + struct nvkm_subdev *, int leaves, struct nvkm_intr *); +void nvkm_intr_block(struct nvkm_subdev *, enum nvkm_intr_type); +void nvkm_intr_allow(struct nvkm_subdev *, enum nvkm_intr_type); + +struct nvkm_inth; +typedef irqreturn_t (*nvkm_inth_func)(struct nvkm_inth *); + +struct nvkm_inth { + struct nvkm_intr *intr; + int leaf; + u32 mask; + nvkm_inth_func func; + + atomic_t allowed; + + struct list_head head; +}; + +int nvkm_inth_add(struct nvkm_intr *, enum nvkm_intr_type, enum nvkm_intr_prio, + struct nvkm_subdev *, nvkm_inth_func, struct nvkm_inth *); +void nvkm_inth_allow(struct nvkm_inth *); +void nvkm_inth_block(struct nvkm_inth *); +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/ioctl.h b/drivers/gpu/drm/nouveau/include/nvkm/core/ioctl.h new file mode 100644 index 000000000..f52918a43 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/ioctl.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: MIT */ +#ifndef __NVKM_IOCTL_H__ +#define __NVKM_IOCTL_H__ +#include +struct nvkm_client; + +int nvkm_ioctl(struct nvkm_client *, void *, u32, void **); +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/layout.h b/drivers/gpu/drm/nouveau/include/nvkm/core/layout.h new file mode 100644 index 000000000..58108dea5 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/layout.h @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: MIT */ +NVKM_LAYOUT_ONCE(NVKM_SUBDEV_TOP , struct nvkm_top , top) +NVKM_LAYOUT_ONCE(NVKM_SUBDEV_GSP , struct nvkm_gsp , gsp) +NVKM_LAYOUT_ONCE(NVKM_SUBDEV_VFN , struct nvkm_vfn , vfn) +NVKM_LAYOUT_ONCE(NVKM_SUBDEV_PCI , struct nvkm_pci , pci) +NVKM_LAYOUT_ONCE(NVKM_SUBDEV_VBIOS , struct nvkm_bios , bios) +NVKM_LAYOUT_ONCE(NVKM_SUBDEV_DEVINIT , struct nvkm_devinit , devinit) +NVKM_LAYOUT_ONCE(NVKM_SUBDEV_PRIVRING, struct nvkm_subdev , privring) +NVKM_LAYOUT_ONCE(NVKM_SUBDEV_GPIO , struct nvkm_gpio , gpio) +NVKM_LAYOUT_ONCE(NVKM_SUBDEV_I2C , struct nvkm_i2c , i2c) +NVKM_LAYOUT_ONCE(NVKM_SUBDEV_FUSE , struct nvkm_fuse , fuse) +NVKM_LAYOUT_ONCE(NVKM_SUBDEV_MXM , struct nvkm_subdev , mxm) +NVKM_LAYOUT_ONCE(NVKM_SUBDEV_MC , struct nvkm_mc , mc) +NVKM_LAYOUT_ONCE(NVKM_SUBDEV_BUS , struct nvkm_bus , bus) +NVKM_LAYOUT_ONCE(NVKM_SUBDEV_TIMER , struct nvkm_timer , timer) +NVKM_LAYOUT_ONCE(NVKM_SUBDEV_INSTMEM , struct nvkm_instmem , imem) +NVKM_LAYOUT_ONCE(NVKM_SUBDEV_FB , struct nvkm_fb , fb) +NVKM_LAYOUT_ONCE(NVKM_SUBDEV_LTC , struct nvkm_ltc , ltc) +NVKM_LAYOUT_ONCE(NVKM_SUBDEV_MMU , struct nvkm_mmu , mmu) +NVKM_LAYOUT_ONCE(NVKM_SUBDEV_BAR , struct nvkm_bar , bar) +NVKM_LAYOUT_ONCE(NVKM_SUBDEV_FAULT , struct nvkm_fault , fault) +NVKM_LAYOUT_ONCE(NVKM_SUBDEV_ACR , struct nvkm_acr , acr) +NVKM_LAYOUT_ONCE(NVKM_SUBDEV_PMU , struct nvkm_pmu , pmu) +NVKM_LAYOUT_ONCE(NVKM_SUBDEV_VOLT , struct nvkm_volt , volt) +NVKM_LAYOUT_ONCE(NVKM_SUBDEV_ICCSENSE, struct nvkm_iccsense, iccsense) +NVKM_LAYOUT_ONCE(NVKM_SUBDEV_THERM , struct nvkm_therm , therm) +NVKM_LAYOUT_ONCE(NVKM_SUBDEV_CLK , struct nvkm_clk , clk) +NVKM_LAYOUT_INST(NVKM_SUBDEV_IOCTRL , struct nvkm_subdev , ioctrl, 3) +NVKM_LAYOUT_ONCE(NVKM_SUBDEV_FLA , struct nvkm_subdev , fla) + +NVKM_LAYOUT_ONCE(NVKM_ENGINE_BSP , struct nvkm_engine , bsp) +NVKM_LAYOUT_INST(NVKM_ENGINE_CE , struct nvkm_engine , ce, 10) +NVKM_LAYOUT_ONCE(NVKM_ENGINE_CIPHER , struct nvkm_engine , cipher) +NVKM_LAYOUT_ONCE(NVKM_ENGINE_DISP , struct nvkm_disp , disp) +NVKM_LAYOUT_ONCE(NVKM_ENGINE_DMAOBJ , struct nvkm_dma , dma) +NVKM_LAYOUT_ONCE(NVKM_ENGINE_FIFO , struct nvkm_fifo , fifo) +NVKM_LAYOUT_ONCE(NVKM_ENGINE_GR , struct nvkm_gr , gr) +NVKM_LAYOUT_ONCE(NVKM_ENGINE_IFB , struct nvkm_engine , ifb) +NVKM_LAYOUT_ONCE(NVKM_ENGINE_ME , struct nvkm_engine , me) +NVKM_LAYOUT_ONCE(NVKM_ENGINE_MPEG , struct nvkm_engine , mpeg) +NVKM_LAYOUT_ONCE(NVKM_ENGINE_MSENC , struct nvkm_engine , msenc) +NVKM_LAYOUT_ONCE(NVKM_ENGINE_MSPDEC , struct nvkm_engine , mspdec) +NVKM_LAYOUT_ONCE(NVKM_ENGINE_MSPPP , struct nvkm_engine , msppp) +NVKM_LAYOUT_ONCE(NVKM_ENGINE_MSVLD , struct nvkm_engine , msvld) +NVKM_LAYOUT_INST(NVKM_ENGINE_NVDEC , struct nvkm_nvdec , nvdec, 5) +NVKM_LAYOUT_INST(NVKM_ENGINE_NVENC , struct nvkm_nvenc , nvenc, 3) +NVKM_LAYOUT_ONCE(NVKM_ENGINE_NVJPG , struct nvkm_engine , nvjpg) +NVKM_LAYOUT_ONCE(NVKM_ENGINE_OFA , struct nvkm_engine , ofa) +NVKM_LAYOUT_ONCE(NVKM_ENGINE_PM , struct nvkm_pm , pm) +NVKM_LAYOUT_ONCE(NVKM_ENGINE_SEC , struct nvkm_engine , sec) +NVKM_LAYOUT_ONCE(NVKM_ENGINE_SEC2 , struct nvkm_sec2 , sec2) +NVKM_LAYOUT_ONCE(NVKM_ENGINE_SW , struct nvkm_sw , sw) +NVKM_LAYOUT_ONCE(NVKM_ENGINE_VIC , struct nvkm_engine , vic) +NVKM_LAYOUT_ONCE(NVKM_ENGINE_VP , struct nvkm_engine , vp) diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h b/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h new file mode 100644 index 000000000..d3b6a68dd --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h @@ -0,0 +1,123 @@ +/* SPDX-License-Identifier: MIT */ +#ifndef __NVKM_MEMORY_H__ +#define __NVKM_MEMORY_H__ +#include +struct nvkm_device; +struct nvkm_vma; +struct nvkm_vmm; + +struct nvkm_tags { + struct nvkm_mm_node *mn; + refcount_t refcount; +}; + +enum nvkm_memory_target { + NVKM_MEM_TARGET_INST, /* instance memory */ + NVKM_MEM_TARGET_VRAM, /* video memory */ + NVKM_MEM_TARGET_HOST, /* coherent system memory */ + NVKM_MEM_TARGET_NCOH, /* non-coherent system memory */ +}; + +struct nvkm_memory { + const struct nvkm_memory_func *func; + const struct nvkm_memory_ptrs *ptrs; + struct kref kref; + struct nvkm_tags *tags; +}; + +struct nvkm_memory_func { + void *(*dtor)(struct nvkm_memory *); + enum nvkm_memory_target (*target)(struct nvkm_memory *); + u8 (*page)(struct nvkm_memory *); + u64 (*bar2)(struct nvkm_memory *); + u64 (*addr)(struct nvkm_memory *); + u64 (*size)(struct nvkm_memory *); + void (*boot)(struct nvkm_memory *, struct nvkm_vmm *); + void __iomem *(*acquire)(struct nvkm_memory *); + void (*release)(struct nvkm_memory *); + int (*map)(struct nvkm_memory *, u64 offset, struct nvkm_vmm *, + struct nvkm_vma *, void *argv, u32 argc); + int (*kmap)(struct nvkm_memory *, struct nvkm_memory **); +}; + +struct nvkm_memory_ptrs { + u32 (*rd32)(struct nvkm_memory *, u64 offset); + void (*wr32)(struct nvkm_memory *, u64 offset, u32 data); +}; + +void nvkm_memory_ctor(const struct nvkm_memory_func *, struct nvkm_memory *); +int nvkm_memory_new(struct nvkm_device *, enum nvkm_memory_target, + u64 size, u32 align, bool zero, struct nvkm_memory **); +struct nvkm_memory *nvkm_memory_ref(struct nvkm_memory *); +void nvkm_memory_unref(struct nvkm_memory **); +int nvkm_memory_tags_get(struct nvkm_memory *, struct nvkm_device *, u32 tags, + void (*clear)(struct nvkm_device *, u32, u32), + struct nvkm_tags **); +void nvkm_memory_tags_put(struct nvkm_memory *, struct nvkm_device *, + struct nvkm_tags **); + +#define nvkm_memory_target(p) (p)->func->target(p) +#define nvkm_memory_page(p) (p)->func->page(p) +#define nvkm_memory_bar2(p) (p)->func->bar2(p) +#define nvkm_memory_addr(p) (p)->func->addr(p) +#define nvkm_memory_size(p) (p)->func->size(p) +#define nvkm_memory_boot(p,v) (p)->func->boot((p),(v)) +#define nvkm_memory_map(p,o,vm,va,av,ac) \ + (p)->func->map((p),(o),(vm),(va),(av),(ac)) +#define nvkm_memory_kmap(p,i) ((p)->func->kmap ? (p)->func->kmap((p), (i)) : -ENOSYS) + +/* accessor macros - kmap()/done() must bracket use of the other accessor + * macros to guarantee correct behaviour across all chipsets + */ +#define nvkm_kmap(o) (o)->func->acquire(o) +#define nvkm_done(o) (o)->func->release(o) + +#define nvkm_ro32(o,a) (o)->ptrs->rd32((o), (a)) +#define nvkm_wo32(o,a,d) (o)->ptrs->wr32((o), (a), (d)) +#define nvkm_mo32(o,a,m,d) ({ \ + u32 _addr = (a), _data = nvkm_ro32((o), _addr); \ + nvkm_wo32((o), _addr, (_data & ~(m)) | (d)); \ + _data; \ +}) + +#define nvkm_wo64(o,a,d) do { \ + u64 __a = (a), __d = (d); \ + nvkm_wo32((o), __a + 0, lower_32_bits(__d)); \ + nvkm_wo32((o), __a + 4, upper_32_bits(__d)); \ +} while(0) + +#define nvkm_robj(o,a,p,s) do { \ + u32 _addr = (a), _size = (s) >> 2, *_data = (void *)(p); \ + while (_size--) { \ + *(_data++) = nvkm_ro32((o), _addr); \ + _addr += 4; \ + } \ +} while(0) + +#define nvkm_wobj(o,a,p,s) do { \ + u32 _addr = (a), _size = (s) >> 2, *_data = (void *)(p); \ + while (_size--) { \ + nvkm_wo32((o), _addr, *(_data++)); \ + _addr += 4; \ + } \ +} while(0) + +#define nvkm_fill(t,s,o,a,d,c) do { \ + u64 _a = (a), _c = (c), _d = (d), _o = _a >> s, _s = _c << s; \ + u##t __iomem *_m = nvkm_kmap(o); \ + if (likely(_m)) { \ + if (_d) { \ + while (_c--) \ + iowrite##t##_native(_d, &_m[_o++]); \ + } else { \ + memset_io(&_m[_o], _d, _s); \ + } \ + } else { \ + for (; _c; _c--, _a += BIT(s)) \ + nvkm_wo##t((o), _a, _d); \ + } \ + nvkm_done(o); \ +} while(0) +#define nvkm_fo32(o,a,d,c) nvkm_fill(32, 2, (o), (a), (d), (c)) +#define nvkm_fo64(o,a,d,c) nvkm_fill(64, 3, (o), (a), (d), (c)) +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/mm.h b/drivers/gpu/drm/nouveau/include/nvkm/core/mm.h new file mode 100644 index 000000000..4ecfbde88 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/mm.h @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: MIT */ +#ifndef __NVKM_MM_H__ +#define __NVKM_MM_H__ +#include + +struct nvkm_mm_node { + struct list_head nl_entry; + struct list_head fl_entry; + struct nvkm_mm_node *next; + +#define NVKM_MM_HEAP_ANY 0x00 + u8 heap; +#define NVKM_MM_TYPE_NONE 0x00 +#define NVKM_MM_TYPE_HOLE 0xff + u8 type; + u32 offset; + u32 length; +}; + +struct nvkm_mm { + struct list_head nodes; + struct list_head free; + + u32 block_size; + int heap_nodes; +}; + +static inline bool +nvkm_mm_initialised(struct nvkm_mm *mm) +{ + return mm->heap_nodes; +} + +int nvkm_mm_init(struct nvkm_mm *, u8 heap, u32 offset, u32 length, u32 block); +int nvkm_mm_fini(struct nvkm_mm *); +int nvkm_mm_head(struct nvkm_mm *, u8 heap, u8 type, u32 size_max, + u32 size_min, u32 align, struct nvkm_mm_node **); +int nvkm_mm_tail(struct nvkm_mm *, u8 heap, u8 type, u32 size_max, + u32 size_min, u32 align, struct nvkm_mm_node **); +void nvkm_mm_free(struct nvkm_mm *, struct nvkm_mm_node **); +void nvkm_mm_dump(struct nvkm_mm *, const char *); + +static inline u32 +nvkm_mm_heap_size(struct nvkm_mm *mm, u8 heap) +{ + struct nvkm_mm_node *node; + u32 size = 0; + list_for_each_entry(node, &mm->nodes, nl_entry) { + if (node->heap == heap) + size += node->length; + } + return size; +} + +static inline bool +nvkm_mm_contiguous(struct nvkm_mm_node *node) +{ + return !node->next; +} + +static inline u32 +nvkm_mm_addr(struct nvkm_mm_node *node) +{ + if (WARN_ON(!nvkm_mm_contiguous(node))) + return 0; + return node->offset; +} + +static inline u32 +nvkm_mm_size(struct nvkm_mm_node *node) +{ + u32 size = 0; + do { + size += node->length; + } while ((node = node->next)); + return size; +} +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/object.h b/drivers/gpu/drm/nouveau/include/nvkm/core/object.h new file mode 100644 index 000000000..ed1f66360 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/object.h @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: MIT */ +#ifndef __NVKM_OBJECT_H__ +#define __NVKM_OBJECT_H__ +#include +struct nvkm_event; +struct nvkm_gpuobj; +struct nvkm_uevent; + +struct nvkm_object { + const struct nvkm_object_func *func; + struct nvkm_client *client; + struct nvkm_engine *engine; + s32 oclass; + u32 handle; + + struct list_head head; + struct list_head tree; + u8 route; + u64 token; + u64 object; + struct rb_node node; +}; + +enum nvkm_object_map { + NVKM_OBJECT_MAP_IO, + NVKM_OBJECT_MAP_VA +}; + +struct nvkm_object_func { + void *(*dtor)(struct nvkm_object *); + int (*init)(struct nvkm_object *); + int (*fini)(struct nvkm_object *, bool suspend); + int (*mthd)(struct nvkm_object *, u32 mthd, void *data, u32 size); + int (*ntfy)(struct nvkm_object *, u32 mthd, struct nvkm_event **); + int (*map)(struct nvkm_object *, void *argv, u32 argc, + enum nvkm_object_map *, u64 *addr, u64 *size); + int (*unmap)(struct nvkm_object *); + int (*rd08)(struct nvkm_object *, u64 addr, u8 *data); + int (*rd16)(struct nvkm_object *, u64 addr, u16 *data); + int (*rd32)(struct nvkm_object *, u64 addr, u32 *data); + int (*wr08)(struct nvkm_object *, u64 addr, u8 data); + int (*wr16)(struct nvkm_object *, u64 addr, u16 data); + int (*wr32)(struct nvkm_object *, u64 addr, u32 data); + int (*bind)(struct nvkm_object *, struct nvkm_gpuobj *, int align, + struct nvkm_gpuobj **); + int (*sclass)(struct nvkm_object *, int index, struct nvkm_oclass *); + int (*uevent)(struct nvkm_object *, void *argv, u32 argc, struct nvkm_uevent *); +}; + +void nvkm_object_ctor(const struct nvkm_object_func *, + const struct nvkm_oclass *, struct nvkm_object *); +int nvkm_object_new_(const struct nvkm_object_func *, + const struct nvkm_oclass *, void *data, u32 size, + struct nvkm_object **); +int nvkm_object_new(const struct nvkm_oclass *, void *data, u32 size, + struct nvkm_object **); +void nvkm_object_del(struct nvkm_object **); +void *nvkm_object_dtor(struct nvkm_object *); +int nvkm_object_init(struct nvkm_object *); +int nvkm_object_fini(struct nvkm_object *, bool suspend); +int nvkm_object_mthd(struct nvkm_object *, u32 mthd, void *data, u32 size); +int nvkm_object_ntfy(struct nvkm_object *, u32 mthd, struct nvkm_event **); +int nvkm_object_map(struct nvkm_object *, void *argv, u32 argc, + enum nvkm_object_map *, u64 *addr, u64 *size); +int nvkm_object_unmap(struct nvkm_object *); +int nvkm_object_rd08(struct nvkm_object *, u64 addr, u8 *data); +int nvkm_object_rd16(struct nvkm_object *, u64 addr, u16 *data); +int nvkm_object_rd32(struct nvkm_object *, u64 addr, u32 *data); +int nvkm_object_wr08(struct nvkm_object *, u64 addr, u8 data); +int nvkm_object_wr16(struct nvkm_object *, u64 addr, u16 data); +int nvkm_object_wr32(struct nvkm_object *, u64 addr, u32 data); +int nvkm_object_bind(struct nvkm_object *, struct nvkm_gpuobj *, int align, + struct nvkm_gpuobj **); + +bool nvkm_object_insert(struct nvkm_object *); +void nvkm_object_remove(struct nvkm_object *); +struct nvkm_object *nvkm_object_search(struct nvkm_client *, u64 object, + const struct nvkm_object_func *); +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/oclass.h b/drivers/gpu/drm/nouveau/include/nvkm/core/oclass.h new file mode 100644 index 000000000..8e1b945d3 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/oclass.h @@ -0,0 +1,31 @@ +#ifndef __NVKM_OCLASS_H__ +#define __NVKM_OCLASS_H__ +#include +#include +struct nvkm_oclass; +struct nvkm_object; + +struct nvkm_sclass { + int minver; + int maxver; + s32 oclass; + const struct nvkm_object_func *func; + int (*ctor)(const struct nvkm_oclass *, void *data, u32 size, + struct nvkm_object **); +}; + +struct nvkm_oclass { + int (*ctor)(const struct nvkm_oclass *, void *data, u32 size, + struct nvkm_object **); + struct nvkm_sclass base; + const void *priv; + const void *engn; + u32 handle; + u8 route; + u64 token; + u64 object; + struct nvkm_client *client; + struct nvkm_object *parent; + struct nvkm_engine *engine; +}; +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/oproxy.h b/drivers/gpu/drm/nouveau/include/nvkm/core/oproxy.h new file mode 100644 index 000000000..0e70a9afb --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/oproxy.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: MIT */ +#ifndef __NVKM_OPROXY_H__ +#define __NVKM_OPROXY_H__ +#define nvkm_oproxy(p) container_of((p), struct nvkm_oproxy, base) +#include + +struct nvkm_oproxy { + const struct nvkm_oproxy_func *func; + struct nvkm_object base; + struct nvkm_object *object; +}; + +struct nvkm_oproxy_func { + void (*dtor[2])(struct nvkm_oproxy *); + int (*init[2])(struct nvkm_oproxy *); + int (*fini[2])(struct nvkm_oproxy *, bool suspend); +}; + +void nvkm_oproxy_ctor(const struct nvkm_oproxy_func *, + const struct nvkm_oclass *, struct nvkm_oproxy *); +int nvkm_oproxy_new_(const struct nvkm_oproxy_func *, + const struct nvkm_oclass *, struct nvkm_oproxy **); +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/option.h b/drivers/gpu/drm/nouveau/include/nvkm/core/option.h new file mode 100644 index 000000000..6882eb7c7 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/option.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: MIT */ +#ifndef __NVKM_OPTION_H__ +#define __NVKM_OPTION_H__ +#include + +const char *nvkm_stropt(const char *optstr, const char *opt, int *len); +bool nvkm_boolopt(const char *optstr, const char *opt, bool value); +long nvkm_longopt(const char *optstr, const char *opt, long value); +int nvkm_dbgopt(const char *optstr, const char *sub); + +/* compares unterminated string 'str' with zero-terminated string 'cmp' */ +static inline int +strncasecmpz(const char *str, const char *cmp, size_t len) +{ + if (strlen(cmp) != len) + return len; + return strncasecmp(str, cmp, len); +} +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/os.h b/drivers/gpu/drm/nouveau/include/nvkm/core/os.h new file mode 100644 index 000000000..4486d9862 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/os.h @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: MIT */ +#ifndef __NVKM_OS_H__ +#define __NVKM_OS_H__ +#include + +#ifdef __BIG_ENDIAN +#define ioread16_native ioread16be +#define iowrite16_native iowrite16be +#define ioread32_native ioread32be +#define iowrite32_native iowrite32be +#else +#define ioread16_native ioread16 +#define iowrite16_native iowrite16 +#define ioread32_native ioread32 +#define iowrite32_native iowrite32 +#endif + +#define iowrite64_native(v,p) do { \ + u32 __iomem *_p = (u32 __iomem *)(p); \ + u64 _v = (v); \ + iowrite32_native(lower_32_bits(_v), &_p[0]); \ + iowrite32_native(upper_32_bits(_v), &_p[1]); \ +} while(0) + +struct nvkm_blob { + void *data; + u32 size; +}; + +static inline void +nvkm_blob_dtor(struct nvkm_blob *blob) +{ + kfree(blob->data); + blob->data = NULL; + blob->size = 0; +} + +#define nvkm_list_find_next(p,h,m,c) ({ \ + typeof(p) _p = NULL; \ + list_for_each_entry_continue(p, (h), m) { \ + if (c) { \ + _p = p; \ + break; \ + } \ + } \ + _p; \ +}) +#define nvkm_list_find(p,h,m,c) \ + (p = container_of((h), typeof(*p), m), nvkm_list_find_next(p, (h), m, (c))) +#define nvkm_list_foreach(p,h,m,c) \ + for (p = nvkm_list_find(p, (h), m, (c)); p; p = nvkm_list_find_next(p, (h), m, (c))) + +/*FIXME: remove after */ +#define nvkm_fifo_chan nvkm_chan +#define nvkm_fifo_chan_func nvkm_chan_func +#define nvkm_fifo_cgrp nvkm_cgrp +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/pci.h b/drivers/gpu/drm/nouveau/include/nvkm/core/pci.h new file mode 100644 index 000000000..b4b5df3e1 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/pci.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: MIT */ +#ifndef __NVKM_DEVICE_PCI_H__ +#define __NVKM_DEVICE_PCI_H__ +#include + +struct nvkm_device_pci { + struct nvkm_device device; + struct pci_dev *pdev; + bool suspend; +}; + +int nvkm_device_pci_new(struct pci_dev *, const char *cfg, const char *dbg, + bool detect, bool mmio, u64 subdev_mask, + struct nvkm_device **); +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/ramht.h b/drivers/gpu/drm/nouveau/include/nvkm/core/ramht.h new file mode 100644 index 000000000..bc2d1dccc --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/ramht.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: MIT */ +#ifndef __NVKM_RAMHT_H__ +#define __NVKM_RAMHT_H__ +#include +struct nvkm_object; + +struct nvkm_ramht_data { + struct nvkm_gpuobj *inst; + int chid; + u32 handle; +}; + +struct nvkm_ramht { + struct nvkm_device *device; + struct nvkm_gpuobj *parent; + struct nvkm_gpuobj *gpuobj; + int size; + int bits; + struct nvkm_ramht_data data[]; +}; + +int nvkm_ramht_new(struct nvkm_device *, u32 size, u32 align, + struct nvkm_gpuobj *, struct nvkm_ramht **); +void nvkm_ramht_del(struct nvkm_ramht **); +int nvkm_ramht_insert(struct nvkm_ramht *, struct nvkm_object *, + int chid, int addr, u32 handle, u32 context); +void nvkm_ramht_remove(struct nvkm_ramht *, int cookie); +struct nvkm_gpuobj * +nvkm_ramht_search(struct nvkm_ramht *, int chid, u32 handle); +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h b/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h new file mode 100644 index 000000000..bce6e1ba0 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h @@ -0,0 +1,95 @@ +/* SPDX-License-Identifier: MIT */ +#ifndef __NVKM_SUBDEV_H__ +#define __NVKM_SUBDEV_H__ +#include + +enum nvkm_subdev_type { +#define NVKM_LAYOUT_ONCE(t,s,p,...) t, +#define NVKM_LAYOUT_INST NVKM_LAYOUT_ONCE +#include +#undef NVKM_LAYOUT_INST +#undef NVKM_LAYOUT_ONCE + NVKM_SUBDEV_NR +}; + +struct nvkm_subdev { + const struct nvkm_subdev_func *func; + struct nvkm_device *device; + enum nvkm_subdev_type type; + int inst; + + char name[16]; + u32 debug; + + struct { + refcount_t refcount; + struct mutex mutex; + bool enabled; + } use; + + struct nvkm_inth inth; + + struct list_head head; + void **pself; + bool oneinit; +}; + +struct nvkm_subdev_func { + void *(*dtor)(struct nvkm_subdev *); + int (*preinit)(struct nvkm_subdev *); + int (*oneinit)(struct nvkm_subdev *); + int (*info)(struct nvkm_subdev *, u64 mthd, u64 *data); + int (*init)(struct nvkm_subdev *); + int (*fini)(struct nvkm_subdev *, bool suspend); + void (*intr)(struct nvkm_subdev *); +}; + +extern const char *nvkm_subdev_type[NVKM_SUBDEV_NR]; +int nvkm_subdev_new_(const struct nvkm_subdev_func *, struct nvkm_device *, enum nvkm_subdev_type, + int inst, struct nvkm_subdev **); +void __nvkm_subdev_ctor(const struct nvkm_subdev_func *, struct nvkm_device *, + enum nvkm_subdev_type, int inst, struct nvkm_subdev *); + +static inline void +nvkm_subdev_ctor(const struct nvkm_subdev_func *func, struct nvkm_device *device, + enum nvkm_subdev_type type, int inst, struct nvkm_subdev *subdev) +{ + __nvkm_subdev_ctor(func, device, type, inst, subdev); + mutex_init(&subdev->use.mutex); +} + +void nvkm_subdev_disable(struct nvkm_device *, enum nvkm_subdev_type, int inst); +void nvkm_subdev_del(struct nvkm_subdev **); +int nvkm_subdev_ref(struct nvkm_subdev *); +void nvkm_subdev_unref(struct nvkm_subdev *); +int nvkm_subdev_preinit(struct nvkm_subdev *); +int nvkm_subdev_oneinit(struct nvkm_subdev *); +int nvkm_subdev_init(struct nvkm_subdev *); +int nvkm_subdev_fini(struct nvkm_subdev *, bool suspend); +int nvkm_subdev_info(struct nvkm_subdev *, u64, u64 *); +void nvkm_subdev_intr(struct nvkm_subdev *); + +/* subdev logging */ +#define nvkm_printk_ok(s,u,l) \ + ((CONFIG_NOUVEAU_DEBUG >= (l)) && ((s)->debug >= (l) || ((u) && (u)->debug >= (l)))) +#define nvkm_printk___(s,u,l,p,f,a...) do { \ + if (nvkm_printk_ok((s), (u), (l))) { \ + if ((u) && (u) != (s)) \ + dev_##p((s)->device->dev, "%s(%s):"f, (s)->name, (u)->name, ##a); \ + else \ + dev_##p((s)->device->dev, "%s:"f, (s)->name, ##a); \ + } \ +} while(0) +#define nvkm_printk__(s,l,p,f,a...) nvkm_printk___((s), (s), (l), p, f, ##a) +#define nvkm_printk_(s,l,p,f,a...) nvkm_printk__((s), (l), p, " "f, ##a) +#define nvkm_printk(s,l,p,f,a...) nvkm_printk_((s), NV_DBG_##l, p, f, ##a) +#define nvkm_fatal(s,f,a...) nvkm_printk((s), FATAL, crit, f, ##a) +#define nvkm_error(s,f,a...) nvkm_printk((s), ERROR, err, f, ##a) +#define nvkm_warn(s,f,a...) nvkm_printk((s), WARN, notice, f, ##a) +#define nvkm_info(s,f,a...) nvkm_printk((s), INFO, info, f, ##a) +#define nvkm_debug(s,f,a...) nvkm_printk((s), DEBUG, info, f, ##a) +#define nvkm_trace(s,f,a...) nvkm_printk((s), TRACE, info, f, ##a) +#define nvkm_spam(s,f,a...) nvkm_printk((s), SPAM, dbg, f, ##a) + +#define nvkm_error_ratelimited(s,f,a...) nvkm_printk((s), ERROR, err_ratelimited, f, ##a) +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h b/drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h new file mode 100644 index 000000000..ccee53d4e --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: MIT */ +#ifndef __NVKM_DEVICE_TEGRA_H__ +#define __NVKM_DEVICE_TEGRA_H__ +#include +#include + +struct nvkm_device_tegra { + const struct nvkm_device_tegra_func *func; + struct nvkm_device device; + struct platform_device *pdev; + + struct reset_control *rst; + struct clk *clk; + struct clk *clk_ref; + struct clk *clk_pwr; + + struct regulator *vdd; + + struct { + /* + * Protects accesses to mm from subsystems + */ + struct mutex mutex; + + struct nvkm_mm mm; + struct iommu_domain *domain; + unsigned long pgshift; + } iommu; + + int gpu_speedo; + int gpu_speedo_id; +}; + +struct nvkm_device_tegra_func { + /* + * If an IOMMU is used, indicates which address bit will trigger a + * IOMMU translation when set (when this bit is not set, IOMMU is + * bypassed). A value of 0 means an IOMMU is never used. + */ + u8 iommu_bit; + /* + * Whether the chip requires a reference clock + */ + bool require_ref_clk; + /* + * Whether the chip requires the VDD regulator + */ + bool require_vdd; +}; + +int nvkm_device_tegra_new(const struct nvkm_device_tegra_func *, + struct platform_device *, + const char *cfg, const char *dbg, + bool detect, bool mmio, u64 subdev_mask, + struct nvkm_device **); +#endif -- cgit v1.2.3