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