1 /* SPDX-License-Identifier: MIT */ 2 #ifndef __NVKM_DEVICE_H__ 3 #define __NVKM_DEVICE_H__ 4 #include <core/oclass.h> 5 #include <core/suspend_state.h> 6 #include <core/intr.h> 7 enum nvkm_subdev_type; 8 9 enum nvkm_device_type { 10 NVKM_DEVICE_PCI, 11 NVKM_DEVICE_AGP, 12 NVKM_DEVICE_PCIE, 13 NVKM_DEVICE_TEGRA, 14 }; 15 16 struct nvkm_device { 17 const struct nvkm_device_func *func; 18 const struct nvkm_device_quirk *quirk; 19 struct device *dev; 20 enum nvkm_device_type type; 21 u64 handle; 22 const char *name; 23 const char *cfgopt; 24 const char *dbgopt; 25 26 struct list_head head; 27 struct mutex mutex; 28 int refcount; 29 30 void __iomem *pri; 31 32 u32 debug; 33 34 const struct nvkm_device_chip *chip; 35 enum { 36 NV_04 = 0x04, 37 NV_10 = 0x10, 38 NV_11 = 0x11, 39 NV_20 = 0x20, 40 NV_30 = 0x30, 41 NV_40 = 0x40, 42 NV_50 = 0x50, 43 NV_C0 = 0xc0, 44 NV_E0 = 0xe0, 45 GM100 = 0x110, 46 GP100 = 0x130, 47 GV100 = 0x140, 48 TU100 = 0x160, 49 GA100 = 0x170, 50 GH100 = 0x180, 51 AD100 = 0x190, 52 GB10x = 0x1a0, 53 GB20x = 0x1b0, 54 } card_type; 55 u32 chipset; 56 u8 chiprev; 57 u32 crystal; 58 59 struct { 60 struct notifier_block nb; 61 } acpi; 62 63 #define NVKM_LAYOUT_ONCE(type,data,ptr) data *ptr; 64 #define NVKM_LAYOUT_INST(type,data,ptr,cnt) data *ptr[cnt]; 65 #include <core/layout.h> 66 #undef NVKM_LAYOUT_INST 67 #undef NVKM_LAYOUT_ONCE 68 struct list_head subdev; 69 70 struct { 71 struct list_head intr; 72 struct list_head prio[NVKM_INTR_PRIO_NR]; 73 spinlock_t lock; 74 int irq; 75 bool alloc; 76 bool armed; 77 bool legacy_done; 78 } intr; 79 }; 80 81 struct nvkm_subdev *nvkm_device_subdev(struct nvkm_device *, int type, int inst); 82 struct nvkm_engine *nvkm_device_engine(struct nvkm_device *, int type, int inst); 83 84 enum nvkm_bar_id { 85 NVKM_BAR_INVALID = 0, 86 NVKM_BAR0_PRI, 87 NVKM_BAR1_FB, 88 NVKM_BAR2_INST, 89 }; 90 91 struct nvkm_device_func { 92 struct nvkm_device_pci *(*pci)(struct nvkm_device *); 93 struct nvkm_device_tegra *(*tegra)(struct nvkm_device *); 94 void *(*dtor)(struct nvkm_device *); 95 int (*preinit)(struct nvkm_device *); 96 int (*init)(struct nvkm_device *); 97 void (*fini)(struct nvkm_device *, enum nvkm_suspend_state suspend); 98 int (*irq)(struct nvkm_device *); 99 resource_size_t (*resource_addr)(struct nvkm_device *, enum nvkm_bar_id); 100 resource_size_t (*resource_size)(struct nvkm_device *, enum nvkm_bar_id); 101 bool cpu_coherent; 102 }; 103 104 struct nvkm_device_quirk { 105 u8 tv_pin_mask; 106 u8 tv_gpio; 107 }; 108 109 struct nvkm_device_chip { 110 const char *name; 111 #define NVKM_LAYOUT_ONCE(type,data,ptr,...) \ 112 struct { \ 113 u32 inst; \ 114 int (*ctor)(struct nvkm_device *, enum nvkm_subdev_type, int inst, data **); \ 115 } ptr; 116 #define NVKM_LAYOUT_INST(A...) NVKM_LAYOUT_ONCE(A) 117 #include <core/layout.h> 118 #undef NVKM_LAYOUT_INST 119 #undef NVKM_LAYOUT_ONCE 120 }; 121 122 struct nvkm_device *nvkm_device_find(u64 name); 123 124 /* privileged register interface accessor macros */ 125 #define nvkm_rd08(d,a) ioread8((d)->pri + (a)) 126 #define nvkm_rd16(d,a) ioread16_native((d)->pri + (a)) 127 #define nvkm_rd32(d,a) ioread32_native((d)->pri + (a)) 128 #define nvkm_wr08(d,a,v) iowrite8((v), (d)->pri + (a)) 129 #define nvkm_wr16(d,a,v) iowrite16_native((v), (d)->pri + (a)) 130 #define nvkm_wr32(d,a,v) iowrite32_native((v), (d)->pri + (a)) 131 #define nvkm_mask(d,a,m,v) ({ \ 132 struct nvkm_device *_device = (d); \ 133 u32 _addr = (a), _temp = nvkm_rd32(_device, _addr); \ 134 nvkm_wr32(_device, _addr, (_temp & ~(m)) | (v)); \ 135 _temp; \ 136 }) 137 138 #define NVKM_RD32_(p,o,dr) nvkm_rd32((p), (o) + (dr)) 139 #define NVKM_RD32(p,A...) DRF_RV(NVKM_RD32_, (p), 0, ##A) 140 141 void nvkm_device_del(struct nvkm_device **); 142 143 struct nvkm_device_oclass { 144 int (*ctor)(struct nvkm_device *, const struct nvkm_oclass *, 145 void *data, u32 size, struct nvkm_object **); 146 struct nvkm_sclass base; 147 }; 148 149 extern const struct nvkm_sclass nvkm_udevice_sclass; 150 151 /* device logging */ 152 #define nvdev_printk_(d,l,p,f,a...) do { \ 153 const struct nvkm_device *_device = (d); \ 154 if (_device->debug >= (l)) \ 155 dev_##p(_device->dev, f, ##a); \ 156 } while(0) 157 #define nvdev_printk(d,l,p,f,a...) nvdev_printk_((d), NV_DBG_##l, p, f, ##a) 158 #define nvdev_fatal(d,f,a...) nvdev_printk((d), FATAL, crit, f, ##a) 159 #define nvdev_error(d,f,a...) nvdev_printk((d), ERROR, err, f, ##a) 160 #define nvdev_warn(d,f,a...) nvdev_printk((d), WARN, notice, f, ##a) 161 #define nvdev_info(d,f,a...) nvdev_printk((d), INFO, info, f, ##a) 162 #define nvdev_debug(d,f,a...) nvdev_printk((d), DEBUG, info, f, ##a) 163 #define nvdev_trace(d,f,a...) nvdev_printk((d), TRACE, info, f, ##a) 164 #define nvdev_spam(d,f,a...) nvdev_printk((d), SPAM, dbg, f, ##a) 165 #endif 166