1d514b0f3Smrg/* 2d514b0f3Smrg * Copyright 2011 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/** \file spiceqxl_driver.c 24d514b0f3Smrg * \author Alon Levy <alevy@redhat.com> 25d514b0f3Smrg * 26d514b0f3Smrg * most of the code is still in qxl_driver.c, but for clarity parts are moved 27d514b0f3Smrg * here, and only used / compiled if XSPICE is defined 28d514b0f3Smrg */ 29d514b0f3Smrg#ifdef HAVE_CONFIG_H 30d514b0f3Smrg#include "config.h" 31d514b0f3Smrg#endif 32d514b0f3Smrg 33d514b0f3Smrg#include "qxl.h" 34d514b0f3Smrg#include "spiceqxl_driver.h" 35d514b0f3Smrg 36d514b0f3Smrg#define SPICE_ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 37d514b0f3Smrg 38d514b0f3Smrg#define QXL_MODE_EX(x_res, y_res) \ 39d514b0f3Smrg QXL_MODE_16_32(x_res, y_res, 0), \ 40d514b0f3Smrg QXL_MODE_16_32(y_res, x_res, 1), \ 41d514b0f3Smrg QXL_MODE_16_32(x_res, y_res, 2), \ 42d514b0f3Smrg QXL_MODE_16_32(y_res, x_res, 3) 43d514b0f3Smrg 44d514b0f3Smrg#define QXL_MODE_16_32(x_res, y_res, orientation) \ 45d514b0f3Smrg QXL_MODE(x_res, y_res, 16, orientation), \ 46d514b0f3Smrg QXL_MODE(x_res, y_res, 32, orientation) 47d514b0f3Smrg 48d514b0f3Smrg#define QXL_MODE(_x, _y, _b, _o) \ 49d514b0f3Smrg { .x_res = _x, \ 50d514b0f3Smrg .y_res = _y, \ 51d514b0f3Smrg .bits = _b, \ 52d514b0f3Smrg .stride = (_x) * (_b) / 8, \ 53d514b0f3Smrg .x_mili = PIXEL_SIZE * (_x), \ 54d514b0f3Smrg .y_mili = PIXEL_SIZE * (_y), \ 55d514b0f3Smrg .orientation = _o, \ 56d514b0f3Smrg } 57d514b0f3Smrg 58d514b0f3Smrg#define PIXEL_SIZE 0.2936875 //1280x1024 is 14.8" x 11.9" 59d514b0f3Smrg 60d514b0f3Smrg#define ALIGN(x, y) (((x)+(y)-1) & ~((y)-1)) 61d514b0f3Smrg 62d514b0f3Smrgstatic QXLMode qxl_modes[] = { 63d514b0f3Smrg QXL_MODE_EX(640, 480), 64d514b0f3Smrg QXL_MODE_EX(800, 480), 65d514b0f3Smrg QXL_MODE_EX(800, 600), 66d514b0f3Smrg QXL_MODE_EX(832, 624), 67d514b0f3Smrg QXL_MODE_EX(960, 640), 68d514b0f3Smrg QXL_MODE_EX(1024, 600), 69d514b0f3Smrg QXL_MODE_EX(1024, 768), 70d514b0f3Smrg QXL_MODE_EX(1152, 864), 71d514b0f3Smrg QXL_MODE_EX(1152, 870), 72d514b0f3Smrg QXL_MODE_EX(1280, 720), 73d514b0f3Smrg QXL_MODE_EX(1280, 760), 74d514b0f3Smrg QXL_MODE_EX(1280, 768), 75d514b0f3Smrg QXL_MODE_EX(1280, 800), 76d514b0f3Smrg QXL_MODE_EX(1280, 960), 77d514b0f3Smrg QXL_MODE_EX(1280, 1024), 78d514b0f3Smrg QXL_MODE_EX(1360, 768), 79d514b0f3Smrg QXL_MODE_EX(1366, 768), 80d514b0f3Smrg QXL_MODE_EX(1400, 1050), 81d514b0f3Smrg QXL_MODE_EX(1440, 900), 82d514b0f3Smrg QXL_MODE_EX(1600, 900), 83d514b0f3Smrg QXL_MODE_EX(1600, 1200), 84d514b0f3Smrg QXL_MODE_EX(1680, 1050), 85d514b0f3Smrg QXL_MODE_EX(1920, 1080), 86d514b0f3Smrg QXL_MODE_EX(1920, 1200), 87d514b0f3Smrg QXL_MODE_EX(1920, 1440), 88d514b0f3Smrg QXL_MODE_EX(2048, 1536), 89d514b0f3Smrg QXL_MODE_EX(2560, 1440), 90d514b0f3Smrg QXL_MODE_EX(2560, 1600), 91d514b0f3Smrg QXL_MODE_EX(3840, 1080), 92d514b0f3Smrg QXL_MODE_EX(2560, 2048), 93d514b0f3Smrg QXL_MODE_EX(2800, 2100), 94d514b0f3Smrg QXL_MODE_EX(3200, 2400), 95d514b0f3Smrg QXL_MODE_EX(5760, 1080), 96d514b0f3Smrg QXL_MODE_EX(7680, 1080), 97d514b0f3Smrg 98d514b0f3Smrg}; 99d514b0f3Smrg 100d514b0f3Smrg 101d514b0f3Smrg// TODO - reuse code from qxl.c? 102d514b0f3Smrgvoid init_qxl_rom(qxl_screen_t* qxl, uint32_t rom_size) 103d514b0f3Smrg{ 104d514b0f3Smrg QXLRom *rom = qxl->rom; 105d514b0f3Smrg struct QXLModes *modes = (struct QXLModes *)(rom + 1); 106d514b0f3Smrg uint32_t ram_header_size; 107d514b0f3Smrg uint32_t num_pages; 108d514b0f3Smrg uint32_t fb; 109d514b0f3Smrg int i, m; 110d514b0f3Smrg 111d514b0f3Smrg memset(rom, 0, rom_size); 112d514b0f3Smrg 113d514b0f3Smrg rom->magic = QXL_ROM_MAGIC; 114d514b0f3Smrg rom->id = 0; // TODO - multihead? 115d514b0f3Smrg rom->log_level = 3; 116d514b0f3Smrg rom->modes_offset = (sizeof(QXLRom)); 117d514b0f3Smrg 118d514b0f3Smrg rom->slot_gen_bits = MEMSLOT_GENERATION_BITS; 119d514b0f3Smrg rom->slot_id_bits = MEMSLOT_SLOT_BITS; 120d514b0f3Smrg rom->slots_start = 0; 121d514b0f3Smrg rom->slots_end = 1; 122d514b0f3Smrg rom->n_surfaces = (NUM_SURFACES); 123d514b0f3Smrg 124d514b0f3Smrg for (i = 0, m = 0; i < (SPICE_ARRAY_SIZE(qxl_modes)); i++) { 125d514b0f3Smrg fb = qxl_modes[i].y_res * qxl_modes[i].stride; 126d514b0f3Smrg if (fb > qxl->surface0_size) 127d514b0f3Smrg continue; 128d514b0f3Smrg 129d514b0f3Smrg modes->modes[m].id = m; 130d514b0f3Smrg modes->modes[m].x_res = qxl_modes[i].x_res; 131d514b0f3Smrg modes->modes[m].y_res = qxl_modes[i].y_res; 132d514b0f3Smrg modes->modes[m].bits = qxl_modes[i].bits; 133d514b0f3Smrg modes->modes[m].stride = qxl_modes[i].stride; 134d514b0f3Smrg modes->modes[m].x_mili = qxl_modes[i].x_mili; 135d514b0f3Smrg modes->modes[m].y_mili = qxl_modes[i].y_mili; 136d514b0f3Smrg modes->modes[m].orientation = qxl_modes[i].orientation; 137d514b0f3Smrg 138d514b0f3Smrg m++; 139d514b0f3Smrg } 140d514b0f3Smrg modes->n_modes = m; 141d514b0f3Smrg 142d514b0f3Smrg ram_header_size = ALIGN(sizeof(struct QXLRam), 4096); 143d514b0f3Smrg num_pages = qxl->vram_size; 144d514b0f3Smrg num_pages -= ram_header_size; 145d514b0f3Smrg num_pages -= qxl->surface0_size; 146d514b0f3Smrg num_pages = num_pages / TARGET_PAGE_SIZE; 147d514b0f3Smrg 148d514b0f3Smrg rom->draw_area_offset = 0; 149d514b0f3Smrg rom->surface0_area_size = qxl->surface0_size; 150d514b0f3Smrg rom->pages_offset = rom->surface0_area_size; 151d514b0f3Smrg rom->num_pages = num_pages; 152d514b0f3Smrg rom->ram_header_offset = qxl->vram_size - ram_header_size; 153d514b0f3Smrg 154d514b0f3Smrg qxl->shadow_rom = *qxl->rom; // TODO - do we need this? 155d514b0f3Smrg} 156