1 1.2 riastrad /* $NetBSD: qxl_kms.c,v 1.3 2021/12/18 23:45:42 riastradh Exp $ */ 2 1.2 riastrad 3 1.1 riastrad /* 4 1.1 riastrad * Copyright 2013 Red Hat Inc. 5 1.1 riastrad * 6 1.1 riastrad * Permission is hereby granted, free of charge, to any person obtaining a 7 1.1 riastrad * copy of this software and associated documentation files (the "Software"), 8 1.1 riastrad * to deal in the Software without restriction, including without limitation 9 1.1 riastrad * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 1.1 riastrad * and/or sell copies of the Software, and to permit persons to whom the 11 1.1 riastrad * Software is furnished to do so, subject to the following conditions: 12 1.1 riastrad * 13 1.1 riastrad * The above copyright notice and this permission notice shall be included in 14 1.1 riastrad * all copies or substantial portions of the Software. 15 1.1 riastrad * 16 1.1 riastrad * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 1.1 riastrad * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 1.1 riastrad * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 1.1 riastrad * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 1.1 riastrad * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 1.1 riastrad * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 1.1 riastrad * OTHER DEALINGS IN THE SOFTWARE. 23 1.1 riastrad * 24 1.1 riastrad * Authors: Dave Airlie 25 1.1 riastrad * Alon Levy 26 1.1 riastrad */ 27 1.1 riastrad 28 1.2 riastrad #include <sys/cdefs.h> 29 1.2 riastrad __KERNEL_RCSID(0, "$NetBSD: qxl_kms.c,v 1.3 2021/12/18 23:45:42 riastradh Exp $"); 30 1.2 riastrad 31 1.3 riastrad #include <linux/io-mapping.h> 32 1.3 riastrad #include <linux/pci.h> 33 1.3 riastrad 34 1.3 riastrad #include <drm/drm_drv.h> 35 1.3 riastrad #include <drm/drm_probe_helper.h> 36 1.3 riastrad 37 1.1 riastrad #include "qxl_drv.h" 38 1.1 riastrad #include "qxl_object.h" 39 1.1 riastrad 40 1.1 riastrad int qxl_log_level; 41 1.1 riastrad 42 1.1 riastrad static bool qxl_check_device(struct qxl_device *qdev) 43 1.1 riastrad { 44 1.1 riastrad struct qxl_rom *rom = qdev->rom; 45 1.1 riastrad 46 1.1 riastrad if (rom->magic != 0x4f525851) { 47 1.1 riastrad DRM_ERROR("bad rom signature %x\n", rom->magic); 48 1.1 riastrad return false; 49 1.1 riastrad } 50 1.1 riastrad 51 1.1 riastrad DRM_INFO("Device Version %d.%d\n", rom->id, rom->update_id); 52 1.1 riastrad DRM_INFO("Compression level %d log level %d\n", rom->compression_level, 53 1.1 riastrad rom->log_level); 54 1.1 riastrad DRM_INFO("%d io pages at offset 0x%x\n", 55 1.1 riastrad rom->num_io_pages, rom->pages_offset); 56 1.1 riastrad DRM_INFO("%d byte draw area at offset 0x%x\n", 57 1.1 riastrad rom->surface0_area_size, rom->draw_area_offset); 58 1.1 riastrad 59 1.1 riastrad qdev->vram_size = rom->surface0_area_size; 60 1.1 riastrad DRM_INFO("RAM header offset: 0x%x\n", rom->ram_header_offset); 61 1.1 riastrad return true; 62 1.1 riastrad } 63 1.1 riastrad 64 1.3 riastrad static void setup_hw_slot(struct qxl_device *qdev, struct qxl_memslot *slot) 65 1.1 riastrad { 66 1.1 riastrad qdev->ram_header->mem_slot.mem_start = slot->start_phys_addr; 67 1.3 riastrad qdev->ram_header->mem_slot.mem_end = slot->start_phys_addr + slot->size; 68 1.3 riastrad qxl_io_memslot_add(qdev, qdev->rom->slots_start + slot->index); 69 1.1 riastrad } 70 1.1 riastrad 71 1.3 riastrad static void setup_slot(struct qxl_device *qdev, 72 1.3 riastrad struct qxl_memslot *slot, 73 1.3 riastrad unsigned int slot_index, 74 1.3 riastrad const char *slot_name, 75 1.3 riastrad unsigned long start_phys_addr, 76 1.3 riastrad unsigned long size) 77 1.1 riastrad { 78 1.1 riastrad uint64_t high_bits; 79 1.1 riastrad 80 1.3 riastrad slot->index = slot_index; 81 1.3 riastrad slot->name = slot_name; 82 1.1 riastrad slot->start_phys_addr = start_phys_addr; 83 1.3 riastrad slot->size = size; 84 1.1 riastrad 85 1.3 riastrad setup_hw_slot(qdev, slot); 86 1.1 riastrad 87 1.1 riastrad slot->generation = qdev->rom->slot_generation; 88 1.3 riastrad high_bits = (qdev->rom->slots_start + slot->index) 89 1.3 riastrad << qdev->rom->slot_gen_bits; 90 1.1 riastrad high_bits |= slot->generation; 91 1.3 riastrad high_bits <<= (64 - (qdev->rom->slot_gen_bits + qdev->rom->slot_id_bits)); 92 1.1 riastrad slot->high_bits = high_bits; 93 1.3 riastrad 94 1.3 riastrad DRM_INFO("slot %d (%s): base 0x%08lx, size 0x%08lx, gpu_offset 0x%lx\n", 95 1.3 riastrad slot->index, slot->name, 96 1.3 riastrad (unsigned long)slot->start_phys_addr, 97 1.3 riastrad (unsigned long)slot->size, 98 1.3 riastrad (unsigned long)slot->gpu_offset); 99 1.1 riastrad } 100 1.1 riastrad 101 1.1 riastrad void qxl_reinit_memslots(struct qxl_device *qdev) 102 1.1 riastrad { 103 1.3 riastrad setup_hw_slot(qdev, &qdev->main_slot); 104 1.3 riastrad setup_hw_slot(qdev, &qdev->surfaces_slot); 105 1.1 riastrad } 106 1.1 riastrad 107 1.1 riastrad static void qxl_gc_work(struct work_struct *work) 108 1.1 riastrad { 109 1.1 riastrad struct qxl_device *qdev = container_of(work, struct qxl_device, gc_work); 110 1.3 riastrad 111 1.1 riastrad qxl_garbage_collect(qdev); 112 1.1 riastrad } 113 1.1 riastrad 114 1.3 riastrad int qxl_device_init(struct qxl_device *qdev, 115 1.3 riastrad struct drm_driver *drv, 116 1.3 riastrad struct pci_dev *pdev) 117 1.1 riastrad { 118 1.1 riastrad int r, sb; 119 1.1 riastrad 120 1.3 riastrad r = drm_dev_init(&qdev->ddev, drv, &pdev->dev); 121 1.3 riastrad if (r) { 122 1.3 riastrad pr_err("Unable to init drm dev"); 123 1.3 riastrad goto error; 124 1.3 riastrad } 125 1.3 riastrad 126 1.3 riastrad qdev->ddev.pdev = pdev; 127 1.3 riastrad pci_set_drvdata(pdev, &qdev->ddev); 128 1.3 riastrad qdev->ddev.dev_private = qdev; 129 1.1 riastrad 130 1.1 riastrad mutex_init(&qdev->gem.mutex); 131 1.1 riastrad mutex_init(&qdev->update_area_mutex); 132 1.1 riastrad mutex_init(&qdev->release_mutex); 133 1.1 riastrad mutex_init(&qdev->surf_evict_mutex); 134 1.3 riastrad qxl_gem_init(qdev); 135 1.1 riastrad 136 1.1 riastrad qdev->rom_base = pci_resource_start(pdev, 2); 137 1.1 riastrad qdev->rom_size = pci_resource_len(pdev, 2); 138 1.1 riastrad qdev->vram_base = pci_resource_start(pdev, 0); 139 1.1 riastrad qdev->io_base = pci_resource_start(pdev, 3); 140 1.1 riastrad 141 1.1 riastrad qdev->vram_mapping = io_mapping_create_wc(qdev->vram_base, pci_resource_len(pdev, 0)); 142 1.3 riastrad if (!qdev->vram_mapping) { 143 1.3 riastrad pr_err("Unable to create vram_mapping"); 144 1.3 riastrad r = -ENOMEM; 145 1.3 riastrad goto error; 146 1.3 riastrad } 147 1.1 riastrad 148 1.1 riastrad if (pci_resource_len(pdev, 4) > 0) { 149 1.1 riastrad /* 64bit surface bar present */ 150 1.1 riastrad sb = 4; 151 1.1 riastrad qdev->surfaceram_base = pci_resource_start(pdev, sb); 152 1.1 riastrad qdev->surfaceram_size = pci_resource_len(pdev, sb); 153 1.1 riastrad qdev->surface_mapping = 154 1.1 riastrad io_mapping_create_wc(qdev->surfaceram_base, 155 1.1 riastrad qdev->surfaceram_size); 156 1.1 riastrad } 157 1.1 riastrad if (qdev->surface_mapping == NULL) { 158 1.1 riastrad /* 64bit surface bar not present (or mapping failed) */ 159 1.1 riastrad sb = 1; 160 1.1 riastrad qdev->surfaceram_base = pci_resource_start(pdev, sb); 161 1.1 riastrad qdev->surfaceram_size = pci_resource_len(pdev, sb); 162 1.1 riastrad qdev->surface_mapping = 163 1.1 riastrad io_mapping_create_wc(qdev->surfaceram_base, 164 1.1 riastrad qdev->surfaceram_size); 165 1.3 riastrad if (!qdev->surface_mapping) { 166 1.3 riastrad pr_err("Unable to create surface_mapping"); 167 1.3 riastrad r = -ENOMEM; 168 1.3 riastrad goto vram_mapping_free; 169 1.3 riastrad } 170 1.1 riastrad } 171 1.1 riastrad 172 1.1 riastrad DRM_DEBUG_KMS("qxl: vram %llx-%llx(%dM %dk), surface %llx-%llx(%dM %dk, %s)\n", 173 1.1 riastrad (unsigned long long)qdev->vram_base, 174 1.1 riastrad (unsigned long long)pci_resource_end(pdev, 0), 175 1.1 riastrad (int)pci_resource_len(pdev, 0) / 1024 / 1024, 176 1.1 riastrad (int)pci_resource_len(pdev, 0) / 1024, 177 1.1 riastrad (unsigned long long)qdev->surfaceram_base, 178 1.1 riastrad (unsigned long long)pci_resource_end(pdev, sb), 179 1.1 riastrad (int)qdev->surfaceram_size / 1024 / 1024, 180 1.1 riastrad (int)qdev->surfaceram_size / 1024, 181 1.1 riastrad (sb == 4) ? "64bit" : "32bit"); 182 1.1 riastrad 183 1.1 riastrad qdev->rom = ioremap(qdev->rom_base, qdev->rom_size); 184 1.1 riastrad if (!qdev->rom) { 185 1.1 riastrad pr_err("Unable to ioremap ROM\n"); 186 1.3 riastrad r = -ENOMEM; 187 1.3 riastrad goto surface_mapping_free; 188 1.1 riastrad } 189 1.1 riastrad 190 1.3 riastrad if (!qxl_check_device(qdev)) { 191 1.3 riastrad r = -ENODEV; 192 1.3 riastrad goto rom_unmap; 193 1.3 riastrad } 194 1.1 riastrad 195 1.1 riastrad r = qxl_bo_init(qdev); 196 1.1 riastrad if (r) { 197 1.1 riastrad DRM_ERROR("bo init failed %d\n", r); 198 1.3 riastrad goto rom_unmap; 199 1.1 riastrad } 200 1.1 riastrad 201 1.1 riastrad qdev->ram_header = ioremap(qdev->vram_base + 202 1.1 riastrad qdev->rom->ram_header_offset, 203 1.1 riastrad sizeof(*qdev->ram_header)); 204 1.3 riastrad if (!qdev->ram_header) { 205 1.3 riastrad DRM_ERROR("Unable to ioremap RAM header\n"); 206 1.3 riastrad r = -ENOMEM; 207 1.3 riastrad goto bo_fini; 208 1.3 riastrad } 209 1.1 riastrad 210 1.1 riastrad qdev->command_ring = qxl_ring_create(&(qdev->ram_header->cmd_ring_hdr), 211 1.1 riastrad sizeof(struct qxl_command), 212 1.1 riastrad QXL_COMMAND_RING_SIZE, 213 1.1 riastrad qdev->io_base + QXL_IO_NOTIFY_CMD, 214 1.1 riastrad false, 215 1.1 riastrad &qdev->display_event); 216 1.3 riastrad if (!qdev->command_ring) { 217 1.3 riastrad DRM_ERROR("Unable to create command ring\n"); 218 1.3 riastrad r = -ENOMEM; 219 1.3 riastrad goto ram_header_unmap; 220 1.3 riastrad } 221 1.1 riastrad 222 1.1 riastrad qdev->cursor_ring = qxl_ring_create( 223 1.1 riastrad &(qdev->ram_header->cursor_ring_hdr), 224 1.1 riastrad sizeof(struct qxl_command), 225 1.1 riastrad QXL_CURSOR_RING_SIZE, 226 1.1 riastrad qdev->io_base + QXL_IO_NOTIFY_CMD, 227 1.1 riastrad false, 228 1.1 riastrad &qdev->cursor_event); 229 1.1 riastrad 230 1.3 riastrad if (!qdev->cursor_ring) { 231 1.3 riastrad DRM_ERROR("Unable to create cursor ring\n"); 232 1.3 riastrad r = -ENOMEM; 233 1.3 riastrad goto command_ring_free; 234 1.3 riastrad } 235 1.3 riastrad 236 1.1 riastrad qdev->release_ring = qxl_ring_create( 237 1.1 riastrad &(qdev->ram_header->release_ring_hdr), 238 1.1 riastrad sizeof(uint64_t), 239 1.1 riastrad QXL_RELEASE_RING_SIZE, 0, true, 240 1.1 riastrad NULL); 241 1.1 riastrad 242 1.3 riastrad if (!qdev->release_ring) { 243 1.3 riastrad DRM_ERROR("Unable to create release ring\n"); 244 1.3 riastrad r = -ENOMEM; 245 1.3 riastrad goto cursor_ring_free; 246 1.3 riastrad } 247 1.1 riastrad 248 1.1 riastrad idr_init(&qdev->release_idr); 249 1.1 riastrad spin_lock_init(&qdev->release_idr_lock); 250 1.2 riastrad spin_lock_init(&qdev->release_lock); 251 1.1 riastrad 252 1.1 riastrad idr_init(&qdev->surf_id_idr); 253 1.1 riastrad spin_lock_init(&qdev->surf_id_idr_lock); 254 1.1 riastrad 255 1.1 riastrad mutex_init(&qdev->async_io_mutex); 256 1.1 riastrad 257 1.1 riastrad /* reset the device into a known state - no memslots, no primary 258 1.1 riastrad * created, no surfaces. */ 259 1.1 riastrad qxl_io_reset(qdev); 260 1.1 riastrad 261 1.1 riastrad /* must initialize irq before first async io - slot creation */ 262 1.1 riastrad r = qxl_irq_init(qdev); 263 1.3 riastrad if (r) { 264 1.3 riastrad DRM_ERROR("Unable to init qxl irq\n"); 265 1.3 riastrad goto release_ring_free; 266 1.3 riastrad } 267 1.1 riastrad 268 1.1 riastrad /* 269 1.1 riastrad * Note that virtual is surface0. We rely on the single ioremap done 270 1.1 riastrad * before. 271 1.1 riastrad */ 272 1.3 riastrad setup_slot(qdev, &qdev->main_slot, 0, "main", 273 1.3 riastrad (unsigned long)qdev->vram_base, 274 1.3 riastrad (unsigned long)qdev->rom->ram_header_offset); 275 1.3 riastrad setup_slot(qdev, &qdev->surfaces_slot, 1, "surfaces", 276 1.3 riastrad (unsigned long)qdev->surfaceram_base, 277 1.3 riastrad (unsigned long)qdev->surfaceram_size); 278 1.1 riastrad 279 1.1 riastrad INIT_WORK(&qdev->gc_work, qxl_gc_work); 280 1.1 riastrad 281 1.3 riastrad return 0; 282 1.1 riastrad 283 1.3 riastrad release_ring_free: 284 1.3 riastrad qxl_ring_free(qdev->release_ring); 285 1.3 riastrad cursor_ring_free: 286 1.3 riastrad qxl_ring_free(qdev->cursor_ring); 287 1.3 riastrad command_ring_free: 288 1.3 riastrad qxl_ring_free(qdev->command_ring); 289 1.3 riastrad ram_header_unmap: 290 1.3 riastrad iounmap(qdev->ram_header); 291 1.3 riastrad bo_fini: 292 1.3 riastrad qxl_bo_fini(qdev); 293 1.3 riastrad rom_unmap: 294 1.3 riastrad iounmap(qdev->rom); 295 1.3 riastrad surface_mapping_free: 296 1.3 riastrad io_mapping_free(qdev->surface_mapping); 297 1.3 riastrad vram_mapping_free: 298 1.3 riastrad io_mapping_free(qdev->vram_mapping); 299 1.3 riastrad error: 300 1.3 riastrad return r; 301 1.1 riastrad } 302 1.1 riastrad 303 1.3 riastrad void qxl_device_fini(struct qxl_device *qdev) 304 1.1 riastrad { 305 1.3 riastrad qxl_bo_unref(&qdev->current_release_bo[0]); 306 1.3 riastrad qxl_bo_unref(&qdev->current_release_bo[1]); 307 1.3 riastrad flush_work(&qdev->gc_work); 308 1.1 riastrad qxl_ring_free(qdev->command_ring); 309 1.1 riastrad qxl_ring_free(qdev->cursor_ring); 310 1.1 riastrad qxl_ring_free(qdev->release_ring); 311 1.3 riastrad qxl_gem_fini(qdev); 312 1.1 riastrad qxl_bo_fini(qdev); 313 1.1 riastrad io_mapping_free(qdev->surface_mapping); 314 1.1 riastrad io_mapping_free(qdev->vram_mapping); 315 1.1 riastrad iounmap(qdev->ram_header); 316 1.1 riastrad iounmap(qdev->rom); 317 1.1 riastrad qdev->rom = NULL; 318 1.1 riastrad } 319