1 /* 2 * Copyright 2008 Red Hat, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * on the rights to use, copy, modify, merge, publish, distribute, sub 8 * license, and/or sell copies of the Software, and to permit persons to whom 9 * the Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 */ 22 23 /* all the IO routines for QXL userspace code */ 24 #ifdef HAVE_CONFIG_H 25 #include "config.h" 26 #endif 27 28 #include <unistd.h> 29 #include <errno.h> 30 #include <time.h> 31 #include "qxl.h" 32 33 #ifdef XSPICE 34 #include "spiceqxl_display.h" 35 #endif 36 37 38 #ifndef XSPICE 39 static void 40 qxl_wait_for_io_command (qxl_screen_t *qxl) 41 { 42 struct QXLRam *ram_header; 43 44 ram_header = (void *)((unsigned long)qxl->ram + qxl->rom->ram_header_offset); 45 46 while (!(ram_header->int_pending & 47 (QXL_INTERRUPT_IO_CMD | QXL_INTERRUPT_ERROR))) 48 usleep (1); 49 50 assert(!(ram_header->int_pending & QXL_INTERRUPT_ERROR)); 51 52 ram_header->int_pending &= ~QXL_INTERRUPT_IO_CMD; 53 } 54 55 #if 0 56 static void 57 qxl_wait_for_display_interrupt (qxl_screen_t *qxl) 58 { 59 struct QXLRam *ram_header; 60 61 ram_header = (void *)((unsigned long)qxl->ram + qxl->rom->ram_header_offset); 62 63 while (!(ram_header->int_pending & QXL_INTERRUPT_DISPLAY)) 64 usleep (1); 65 66 ram_header->int_pending &= ~QXL_INTERRUPT_DISPLAY; 67 } 68 69 #endif 70 #endif 71 72 void 73 qxl_update_area (qxl_screen_t *qxl) 74 { 75 #ifndef XSPICE 76 if (qxl->pci->revision >= 3) 77 { 78 ioport_write (qxl, QXL_IO_UPDATE_AREA_ASYNC, 0); 79 qxl_wait_for_io_command (qxl); 80 } 81 else 82 { 83 ioport_write (qxl, QXL_IO_UPDATE_AREA, 0); 84 } 85 #else 86 ioport_write (qxl, QXL_IO_UPDATE_AREA, 0); 87 #endif 88 } 89 90 void 91 qxl_io_memslot_add (qxl_screen_t *qxl, uint8_t id) 92 { 93 #ifndef XSPICE 94 if (qxl->pci->revision >= 3) 95 { 96 ioport_write (qxl, QXL_IO_MEMSLOT_ADD_ASYNC, id); 97 qxl_wait_for_io_command (qxl); 98 } 99 else 100 { 101 ioport_write (qxl, QXL_IO_MEMSLOT_ADD, id); 102 } 103 #else 104 ioport_write (qxl, QXL_IO_MEMSLOT_ADD, id); 105 #endif 106 } 107 108 void 109 qxl_io_create_primary (qxl_screen_t *qxl) 110 { 111 #ifndef XSPICE 112 if (qxl->pci->revision >= 3) 113 { 114 ioport_write (qxl, QXL_IO_CREATE_PRIMARY_ASYNC, 0); 115 qxl_wait_for_io_command (qxl); 116 } 117 else 118 { 119 ioport_write (qxl, QXL_IO_CREATE_PRIMARY, 0); 120 } 121 #else 122 ioport_write (qxl, QXL_IO_CREATE_PRIMARY, 0); 123 #endif 124 qxl->device_primary = QXL_DEVICE_PRIMARY_CREATED; 125 } 126 127 void 128 qxl_io_destroy_primary (qxl_screen_t *qxl) 129 { 130 #ifndef XSPICE 131 if (qxl->pci->revision >= 3) 132 { 133 ioport_write (qxl, QXL_IO_DESTROY_PRIMARY_ASYNC, 0); 134 qxl_wait_for_io_command (qxl); 135 } 136 else 137 { 138 ioport_write (qxl, QXL_IO_DESTROY_PRIMARY, 0); 139 } 140 #else 141 ioport_write (qxl, QXL_IO_DESTROY_PRIMARY, 0); 142 #endif 143 qxl->device_primary = QXL_DEVICE_PRIMARY_NONE; 144 } 145 146 void 147 qxl_io_notify_oom (qxl_screen_t *qxl) 148 { 149 ioport_write (qxl, QXL_IO_NOTIFY_OOM, 0); 150 } 151 152 void 153 qxl_io_flush_surfaces (qxl_screen_t *qxl) 154 { 155 // FIXME: write individual update_area for revision < V10 156 #ifndef XSPICE 157 ioport_write (qxl, QXL_IO_FLUSH_SURFACES_ASYNC, 0); 158 qxl_wait_for_io_command (qxl); 159 #else 160 ioport_write (qxl, QXL_IO_FLUSH_SURFACES_ASYNC, 0); 161 #endif 162 } 163 164 #ifdef QXLDRV_RESIZABLE_SURFACE0 165 void 166 qxl_io_flush_release (qxl_screen_t *qxl) 167 { 168 #ifndef XSPICE 169 int sum = 0; 170 171 sum += qxl_garbage_collect (qxl); 172 ioport_write (qxl, QXL_IO_FLUSH_RELEASE, 0); 173 sum += qxl_garbage_collect (qxl); 174 ErrorF ("%s: collected %d\n", __func__, sum); 175 #else 176 #endif 177 } 178 179 #endif 180 181 void 182 qxl_io_monitors_config_async (qxl_screen_t *qxl) 183 { 184 #ifndef XSPICE 185 if (qxl->pci->revision < 4) 186 return; 187 ioport_write (qxl, QXL_IO_MONITORS_CONFIG_ASYNC, 0); 188 qxl_wait_for_io_command (qxl); 189 #else 190 spiceqxl_display_monitors_config(qxl); 191 #endif 192 } 193 194 195 void 196 qxl_io_destroy_all_surfaces (qxl_screen_t *qxl) 197 { 198 #ifndef XSPICE 199 if (qxl->pci->revision >= 3) 200 { 201 ioport_write (qxl, QXL_IO_DESTROY_ALL_SURFACES_ASYNC, 0); 202 qxl_wait_for_io_command (qxl); 203 } 204 else 205 { 206 ioport_write (qxl, QXL_IO_DESTROY_ALL_SURFACES, 0); 207 } 208 #else 209 ErrorF ("Xspice: error: UNIMPLEMENTED qxl_io_destroy_all_surfaces\n"); 210 #endif 211 qxl->device_primary = QXL_DEVICE_PRIMARY_NONE; 212 } 213