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