1117N/A/*
1385N/A * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
1117N/A *
1117N/A * Permission is hereby granted, free of charge, to any person obtaining a
1117N/A * copy of this software and associated documentation files (the "Software"),
1117N/A * to deal in the Software without restriction, including without limitation
1117N/A * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1117N/A * and/or sell copies of the Software, and to permit persons to whom the
1117N/A * Software is furnished to do so, subject to the following conditions:
1117N/A *
1117N/A * The above copyright notice and this permission notice (including the next
1117N/A * paragraph) shall be included in all copies or substantial portions of the
1117N/A * Software.
1117N/A *
1117N/A * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1117N/A * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1117N/A * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
1117N/A * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1117N/A * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
1117N/A * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
1117N/A * DEALINGS IN THE SOFTWARE.
1117N/A */
1117N/A
1385N/A#include "libvtsSUNWast.h"
1117N/A
1385N/Ahrtime_t ast_loop_time = (hrtime_t)10 * NANOSEC; /* time to busy wait */
1117N/A
1117N/A
1385N/Aint
1385N/Aast_map_mem(
1385N/A register return_packet *const rp,
1385N/A register int const test)
1117N/A{
1385N/A register int const pagesize = getpagesize();
1117N/A
1385N/A if (ast_get_pci_info() != 0) {
1385N/A gfx_vts_set_message(rp, 1, test, "get pci info failed");
1385N/A return (-1);
1385N/A }
1117N/A
1385N/A
1385N/A ast_info.ast_fb_size = (ast_info.ast_fb_size + pagesize - 1) /
1385N/A pagesize * pagesize;
1117N/A
1385N/A /*
1385N/A * Map framebuffer
1385N/A */
1117N/A
1385N/A if (ast_map_fb() != 0) {
1385N/A gfx_vts_set_message(rp, 1, test, "map framebuffer failed");
1385N/A return (-1);
1385N/A }
1385N/A
1117N/A
1385N/A ast_info.ast_mmio_size = (ast_info.ast_mmio_size + pagesize - 1) /
1385N/A pagesize * pagesize;
1117N/A
1385N/A /*
1385N/A * Map MMIO
1385N/A */
1385N/A if (ast_map_mmio() != 0) {
1385N/A gfx_vts_set_message(rp, 1, test, "map MMIO failed");
1385N/A return (-1);
1385N/A }
1117N/A
1385N/A return (0);
1117N/A}
1117N/A
1117N/A
1385N/Aint
1385N/Aast_get_pci_info(
1385N/A void)
1117N/A{
1385N/A struct gfx_pci_cfg pciconfig;
1385N/A int i;
1385N/A uint_t bar;
1385N/A uint_t bar_hi;
1385N/A offset_t mem_base[6];
1385N/A offset_t io_base[6];
1385N/A int type[6];
1385N/A uchar_t pots;
1117N/A
1385N/A if (ioctl(ast_info.ast_fd, GFX_IOCTL_GET_PCI_CONFIG,
1385N/A &pciconfig) != 0) {
1385N/A return (-1);
1385N/A }
1117N/A
1385N/A ast_info.ast_vendor = pciconfig.VendorID;
1385N/A ast_info.ast_device = pciconfig.DeviceID;
1117N/A
1385N/A for (i = 0; i < 6; i++) {
1385N/A type[i] = 0;
1385N/A mem_base[i] = 0;
1385N/A io_base[i] = 0;
1117N/A }
1117N/A
1385N/A for (i = 0; i < 6; i++) {
1385N/A bar = pciconfig.bar[i];
1385N/A if (bar != 0) {
1385N/A if (bar & PCI_MAP_IO) {
1385N/A io_base[i] = PCIGETIO(bar);
1385N/A type[i] = bar & PCI_MAP_IO_ATTR_MASK;
1385N/A } else {
1385N/A type[i] = bar & PCI_MAP_MEMORY_ATTR_MASK;
1385N/A mem_base[i] = PCIGETMEMORY(bar);
1385N/A if (PCI_MAP_IS64BITMEM(bar)) {
1385N/A if (i == 5) {
1385N/A mem_base[i] = 0;
1385N/A } else {
1385N/A bar_hi = pciconfig.bar[i+1];
1385N/A mem_base[i] |=
1385N/A ((offset_t)bar_hi << 32);
1385N/A ++i;
1385N/A }
1385N/A }
1385N/A }
1385N/A }
1117N/A }
1117N/A
1385N/A ast_info.ast_fb_addr = mem_base[0] & 0xfff00000;
1385N/A ast_info.ast_fb_size = 0;
1385N/A
1385N/A ast_info.ast_mmio_addr = mem_base[1] & 0xffff0000;
1385N/A ast_info.ast_mmio_size = AST_MMIO_SIZE;
1385N/A
1385N/A ast_info.ast_relocate_io = io_base[2];
1385N/A
1385N/A if (ast_open_key() != 0)
1385N/A return (-1);
1385N/A
1385N/A if (ast_get_index_reg(&pots, CRTC_PORT, 0xAA) != 0)
1385N/A return (-1);
1385N/A
1385N/A switch (pots & 0x03) {
1385N/A case 0x00:
1385N/A ast_info.ast_fb_size = AST_VRAM_SIZE_08M;
1385N/A break;
1385N/A
1385N/A case 0x01:
1385N/A ast_info.ast_fb_size = AST_VRAM_SIZE_16M;
1385N/A break;
1117N/A
1385N/A case 0x02:
1385N/A ast_info.ast_fb_size = AST_VRAM_SIZE_32M;
1385N/A break;
1385N/A
1385N/A case 0x03:
1385N/A ast_info.ast_fb_size = AST_VRAM_SIZE_64M;
1385N/A break;
1385N/A }
1117N/A
1385N/A if (gfx_vts_debug_mask & VTS_DEBUG) {
1385N/A printf("ast_vendor = 0x%04x, ast_device = 0x%04x\n",
1385N/A ast_info.ast_vendor, ast_info.ast_device);
1385N/A printf("ast_fb_addr 0x%llx, ast_fb_size 0x%lx\n",
1385N/A (unsigned long long)ast_info.ast_fb_addr,
1385N/A (unsigned long)ast_info.ast_fb_size);
1385N/A printf("ast_mmio_addr 0x%llx, ast_mmio_size 0x%lx\n",
1385N/A (unsigned long long)ast_info.ast_mmio_addr,
1385N/A (unsigned long)ast_info.ast_mmio_size);
1385N/A printf("ast_relocate_io 0x%llx\n",
1385N/A (unsigned long long)ast_info.ast_relocate_io);
1385N/A }
1385N/A
1385N/A return (0);
1117N/A}
1117N/A
1117N/Aint
1385N/Aast_map_mmio(
1385N/A void)
1117N/A{
1385N/A register void *ptr;
1117N/A
1385N/A if (ast_info.ast_mmio_ptr == NULL) {
1385N/A ptr = mmap(NULL, ast_info.ast_mmio_size,
1385N/A PROT_READ | PROT_WRITE, MAP_SHARED,
1385N/A ast_info.ast_fd, ast_info.ast_mmio_addr);
1117N/A
1385N/A if (ptr == MAP_FAILED)
1385N/A return (-1);
1117N/A }
1117N/A
1385N/A ast_info.ast_mmio_ptr = (uchar_t *)ptr;
1117N/A
1385N/A if (gfx_vts_debug_mask & VTS_DEBUG)
1385N/A printf("ast_mmio_ptr = 0x%llx\n",
1385N/A (unsigned long long)ast_info.ast_mmio_ptr);
1117N/A
1385N/A return (0);
1117N/A}
1117N/A
1117N/A
1385N/Aint
1385N/Aast_map_fb(
1385N/A void)
1117N/A{
1385N/A register void *ptr;
1117N/A
1385N/A if (ast_info.ast_fb_ptr == NULL) {
1385N/A ptr = mmap(NULL, ast_info.ast_fb_size,
1385N/A PROT_READ | PROT_WRITE, MAP_SHARED,
1385N/A ast_info.ast_fd, ast_info.ast_fb_addr);
1117N/A
1385N/A if (ptr == MAP_FAILED)
1385N/A return (-1);
1117N/A
1385N/A ast_info.ast_fb_ptr = (uchar_t *)ptr;
1117N/A }
1117N/A
1385N/A if (gfx_vts_debug_mask & VTS_DEBUG)
1385N/A printf("ast_fb_ptr = 0x%llx\n",
1385N/A (unsigned long long)ast_info.ast_fb_ptr);
1117N/A
1385N/A return (0);
1117N/A}
1117N/A
1117N/A
1385N/Aint
1385N/Aast_init_info(
1385N/A register return_packet *const rp,
1385N/A register int const test)
1117N/A{
1385N/A register uint_t mode;
1385N/A register uint_t width;
1385N/A register uint_t height;
1385N/A register uint_t depth;
1385N/A register uint_t pixelsize;
1385N/A register uint_t offset;
1385N/A register uint_t memsize;
1385N/A uchar_t save_gctl;
1385N/A uchar_t misc;
1385N/A uchar_t hde;
1385N/A uchar_t ovf;
1385N/A uchar_t vde;
1385N/A uchar_t off;
1385N/A uchar_t undloc;
1385N/A uchar_t modectl;
1385N/A uchar_t pcicr3;
1385N/A uchar_t ecm;
1385N/A uchar_t xhovf;
1385N/A uchar_t xvovf;
1385N/A uchar_t offovf;
1385N/A unsigned int status = 0;
1117N/A
1385N/A /*
1385N/A * first check if the hardware is already initialized.
1385N/A * If not, abort
1385N/A */
1385N/A if (ioctl(ast_info.ast_fd, AST_GET_STATUS_FLAGS, &status) != 0) {
1385N/A gfx_vts_set_message(rp, 1, test,
1385N/A "AST_GET_STATUS_FLAGS failed");
1385N/A return (-1);
1385N/A }
1117N/A
1385N/A if (!(status & AST_STATUS_HW_INITIALIZED)) {
1385N/A gfx_vts_set_message(rp, 1, test,
1385N/A "AST_GET_STATUS_FLAGS not initialized");
1385N/A return (-1);
1385N/A }
1117N/A
1385N/A if (ast_open_key() != 0) {
1385N/A gfx_vts_set_message(rp, 1, test, "unable to open key");
1385N/A return (-1);
1385N/A }
1385N/A
1385N/A if (ast_get_reg(&save_gctl, GR_PORT) != 0) {
1385N/A gfx_vts_set_message(rp, 1, test,
1385N/A "unable to get the gctl index");
1385N/A return (-1);
1385N/A }
1117N/A
1385N/A if (ast_get_index_reg(&misc, GR_PORT, 0x06) != 0) {
1385N/A gfx_vts_set_message(rp, 1, test, "unable to get the misc");
1385N/A return (-1);
1385N/A }
1117N/A
1385N/A if (ast_set_reg(GR_PORT, save_gctl) != 0) {
1385N/A gfx_vts_set_message(rp, 1, test,
1385N/A "unable to set the gctl index");
1385N/A return (-1);
1385N/A }
1117N/A
1385N/A if (ast_get_index_reg(&hde, CRTC_PORT, 0x01) != 0) {
1385N/A gfx_vts_set_message(rp, 1, test, "unable to get the hde");
1385N/A return (-1);
1385N/A }
1385N/A
1385N/A if (ast_get_index_reg(&ovf, CRTC_PORT, 0x07) != 0) {
1385N/A gfx_vts_set_message(rp, 1, test, "unable to get the ovf");
1385N/A return (-1);
1385N/A }
1385N/A
1385N/A if (ast_get_index_reg(&vde, CRTC_PORT, 0x12) != 0) {
1385N/A gfx_vts_set_message(rp, 1, test, "unable to get the vde");
1385N/A return (-1);
1385N/A }
1385N/A
1385N/A if (ast_get_index_reg(&off, CRTC_PORT, 0x13) != 0) {
1385N/A gfx_vts_set_message(rp, 1, test, "unable to get the offset");
1385N/A return (-1);
1385N/A }
1385N/A
1385N/A if (ast_get_index_reg(&undloc, CRTC_PORT, 0x14) != 0) {
1385N/A gfx_vts_set_message(rp, 1, test, "unable to get the undloc");
1385N/A return (-1);
1385N/A }
1385N/A
1385N/A if (ast_get_index_reg(&modectl, CRTC_PORT, 0x17) != 0) {
1385N/A gfx_vts_set_message(rp, 1, test, "unable to get the modectl");
1385N/A return (-1);
1117N/A }
1117N/A
1385N/A if (ast_get_index_reg(&pcicr3, CRTC_PORT, 0xa2) != 0) {
1385N/A gfx_vts_set_message(rp, 1, test, "unable to get the pcicr3");
1385N/A return (-1);
1385N/A }
1117N/A
1385N/A if (ast_get_index_reg(&ecm, CRTC_PORT, 0xa3) != 0) {
1385N/A gfx_vts_set_message(rp, 1, test, "unable to get the ecm");
1385N/A return (-1);
1385N/A }
1117N/A
1385N/A if (ast_get_index_reg(&xhovf, CRTC_PORT, 0xac) != 0) {
1385N/A gfx_vts_set_message(rp, 1, test, "unable to get the xhovf");
1385N/A return (-1);
1385N/A }
1117N/A
1385N/A if (ast_get_index_reg(&xvovf, CRTC_PORT, 0xae) != 0) {
1385N/A gfx_vts_set_message(rp, 1, test, "unable to get the xvovf");
1385N/A return (-1);
1117N/A }
1385N/A
1385N/A if (ast_get_index_reg(&offovf, CRTC_PORT, 0xb0) != 0) {
1385N/A gfx_vts_set_message(rp, 1, test, "unable to get the offovf");
1385N/A return (-1);
1385N/A }
1117N/A
1385N/A width = (((((uint_t)xhovf & 0x4) >> 2 << 8) |
1385N/A (uint_t)hde) + 1) << 3;
1117N/A
1385N/A height = ((((uint_t)xvovf & 0x2) >> 1 << 10) |
1385N/A (((uint_t)ovf & 0x40) >> 6 << 9) |
1385N/A (((uint_t)ovf & 0x02) >> 1 << 8) |
1385N/A (uint_t)vde) + 1;
1117N/A
1385N/A offset = (((uint_t)offovf & 0x3f) << 8) | (uint_t)off;
1385N/A
1385N/A memsize = (undloc & 0x40) ? 4 :
1385N/A ((modectl & 0x40) ? 1 : 2);
1117N/A
1385N/A if (!(misc & 0x01)) {
1385N/A if (!(ecm & 0x01)) {
1385N/A mode = VIS_TEXT;
1385N/A depth = 4;
1385N/A width /= 8;
1385N/A height /= 16;
1385N/A pixelsize = 2;
1385N/A } else {
1385N/A mode = VIS_PIXEL;
1385N/A depth = 8;
1385N/A pixelsize = 1;
1385N/A }
1385N/A } else {
1385N/A mode = VIS_PIXEL;
1385N/A
1385N/A switch (ecm & 0xf) {
1385N/A case 0x01:
1385N/A /* enable enhanced 256 color display mode */
1385N/A depth = 8;
1385N/A pixelsize = 1;
1385N/A break;
1117N/A
1385N/A case 0x02:
1385N/A /* enable 15-bpp high color display mode (rgb:555) */
1385N/A depth = 15;
1385N/A pixelsize = 2;
1385N/A break;
1117N/A
1385N/A case 0x04:
1385N/A /* enable 16-bpp high color display mode (rgb:565) */
1385N/A depth = 16;
1385N/A pixelsize = 2;
1385N/A break;
1117N/A
1385N/A case 0x08:
1385N/A /* enable 32-bpp true color display mode (argb:8888) */
1385N/A depth = 32;
1385N/A pixelsize = 4;
1385N/A break;
1385N/A
1385N/A default:
1385N/A gfx_vts_set_message(rp, 1, test, "invalid ecm");
1385N/A return (-1);
1385N/A }
1117N/A }
1385N/A
1385N/A ast_info.ast_mode = mode;
1385N/A ast_info.ast_width = width;
1385N/A ast_info.ast_height = height;
1385N/A ast_info.ast_depth = depth;
1385N/A ast_info.ast_pixelsize = pixelsize;
1385N/A ast_info.ast_linesize = offset * memsize * 2;
1117N/A
1385N/A switch (pcicr3 & 0xc0) {
1385N/A case 0x00: /* little endian */
1385N/A case 0x40:
1385N/A ast_info.ast_endian = 0;
1117N/A break;
1385N/A
1385N/A case 0x80: /* big endian 32 */
1385N/A ast_info.ast_endian = 2;
1117N/A break;
1385N/A
1385N/A case 0xc0: /* big endian 16 */
1385N/A ast_info.ast_endian = 1;
1117N/A break;
1117N/A }
1117N/A
1385N/A if (gfx_vts_debug_mask & VTS_DEBUG) {
1385N/A printf("width=%d height=%d depth=%d pitch=%d\n",
1385N/A ast_info.ast_width, ast_info.ast_height,
1385N/A ast_info.ast_depth, ast_info.ast_linesize);
1117N/A }
1117N/A
1385N/A return (0);
1117N/A}
1117N/A
1385N/A
1385N/Aint
1385N/Aast_init_graphics(
1385N/A void)
1117N/A{
1385N/A unsigned int ulData;
1385N/A register int status = 0;
1385N/A
1385N/A /*
1385N/A * Enable MMIO
1385N/A */
1385N/A
1385N/A if (ast_get_index_reg(&ast_info.ast_pcicr2, CRTC_PORT, 0xA1) != 0)
1385N/A return (-1);
1385N/A
1385N/A if (ast_set_index_reg(CRTC_PORT, 0xA1, 0x4) != 0)
1385N/A return (-1);
1385N/A
1385N/A ast_info.ast_remap_base = ast_mmio_read32(0xF004);
1385N/A ast_info.ast_prot_key = ast_mmio_read32(0xF000);
1385N/A if (ast_get_index_reg(&ast_info.ast_misc_control, CRTC_PORT, 0xA4) != 0)
1385N/A return (-1);
1385N/A
1385N/A ast_mmio_write32(0xF004, 0x1e6e0000);
1385N/A ast_mmio_write32(0xF000, 0x1);
1385N/A
1385N/A ulData = ast_mmio_read32(0x1200c);
1385N/A ast_mmio_write32(0x1200c, ulData & 0xFFFFFFFD);
1385N/A
1385N/A if (!(ast_info.ast_misc_control & 0x01)) {
1385N/A if (ast_set_index_reg(CRTC_PORT, 0xA4,
1385N/A ast_info.ast_misc_control | 0x01) != 0)
1385N/A return (-1);
1385N/A status = 1;
1117N/A }
1117N/A
1385N/A if (!ast_wait_idle())
1385N/A return (-1);
1117N/A
1385N/A ast_info.ast_queue = ast_mmio_read32(MMIOREG_QUEUE);
1385N/A ast_info.ast_dst_base = ast_mmio_read32(MMIOREG_DST_BASE);
1385N/A ast_info.ast_dst_pitch = ast_mmio_read32(MMIOREG_DST_PITCH);
1385N/A ast_info.ast_dst_xy = ast_mmio_read32(MMIOREG_DST_XY);
1385N/A ast_info.ast_line_err = ast_mmio_read32(MMIOREG_LINE_ERR);
1385N/A ast_info.ast_rect_xy = ast_mmio_read32(MMIOREG_RECT_XY);
1385N/A ast_info.ast_fg = ast_mmio_read32(MMIOREG_FG);
1385N/A ast_info.ast_bg = ast_mmio_read32(MMIOREG_BG);
1385N/A ast_info.ast_mono1 = ast_mmio_read32(MMIOREG_MONO1);
1385N/A ast_info.ast_mono2 = ast_mmio_read32(MMIOREG_MONO2);
1385N/A ast_info.ast_clip1 = ast_mmio_read32(MMIOREG_CLIP1);
1385N/A ast_info.ast_clip2 = ast_mmio_read32(MMIOREG_CLIP2);
1117N/A
1385N/A if (!(ast_info.ast_queue & QUEUE_MEMORY_MAP)) {
1385N/A ast_mmio_write32(MMIOREG_QUEUE,
1385N/A ast_info.ast_queue | QUEUE_MEMORY_MAP);
1385N/A status = 1;
1117N/A }
1117N/A
1385N/A if (!ast_store_mmio(MMIOREG_CLIP1,
1385N/A ((0 & MASK_CLIP) << 16) |
1385N/A (0 & MASK_CLIP)))
1385N/A return (-1);
1117N/A
1385N/A if (!ast_store_mmio(MMIOREG_CLIP2,
1385N/A ((ast_info.ast_width & MASK_CLIP) << 16) |
1385N/A (ast_info.ast_height & MASK_CLIP)))
1385N/A return (-1);
1117N/A
1385N/A return (status);
1117N/A}
1117N/A
1117N/A
1117N/Aint
1385N/Aast_finish_graphics(
1385N/A void)
1117N/A{
1385N/A register int status = 0;
1117N/A
1385N/A ast_store_mmio(MMIOREG_DST_BASE, ast_info.ast_dst_base);
1385N/A ast_store_mmio(MMIOREG_DST_PITCH, ast_info.ast_dst_pitch);
1385N/A ast_store_mmio(MMIOREG_DST_XY, ast_info.ast_dst_xy);
1385N/A ast_store_mmio(MMIOREG_LINE_ERR, ast_info.ast_line_err);
1385N/A ast_store_mmio(MMIOREG_RECT_XY, ast_info.ast_rect_xy);
1385N/A ast_store_mmio(MMIOREG_FG, ast_info.ast_fg);
1385N/A ast_store_mmio(MMIOREG_BG, ast_info.ast_bg);
1385N/A ast_store_mmio(MMIOREG_MONO1, ast_info.ast_mono1);
1385N/A ast_store_mmio(MMIOREG_MONO2, ast_info.ast_mono2);
1385N/A ast_store_mmio(MMIOREG_CLIP1, ast_info.ast_clip1);
1385N/A ast_store_mmio(MMIOREG_CLIP2, ast_info.ast_clip2);
1385N/A
1385N/A ast_store_mmio(MMIOREG_QUEUE, ast_info.ast_queue);
1385N/A
1385N/A if (!(ast_info.ast_misc_control & 0x01)) {
1385N/A if (ast_set_index_reg(CRTC_PORT,
1385N/A 0xA4, ast_info.ast_misc_control) != 0)
1385N/A status = -1;
1385N/A else
1385N/A status = 1;
1117N/A }
1117N/A
1385N/A ast_mmio_write32(0xF004, ast_info.ast_remap_base);
1385N/A ast_mmio_write32(0xF000, ast_info.ast_prot_key);
1117N/A
1385N/A if (ast_set_index_reg(CRTC_PORT, 0xA1, ast_info.ast_pcicr2) != 0)
1385N/A status = -1;
1385N/A
1385N/A return (status);
1117N/A}
1117N/A
1385N/A
1117N/Aint
1385N/Aast_save_palet(
1385N/A void)
1117N/A{
1385N/A register uint_t coloron;
1385N/A register int status = 1;
1385N/A uchar_t junk;
1117N/A
1385N/A for (coloron = 0; coloron < 256; coloron++) {
1385N/A if (ast_set_reg(DAC_INDEX_READ, coloron) != 0)
1385N/A status = -1;
1117N/A
1385N/A if (ast_get_reg(&junk, SEQ_PORT) != 0)
1385N/A status = -1;
1117N/A
1385N/A if (ast_get_reg(&ast_info.ast_red[coloron], DAC_DATA) != 0)
1385N/A status = -1;
1385N/A
1385N/A if (ast_get_reg(&junk, SEQ_PORT) != 0)
1385N/A status = -1;
1385N/A
1385N/A if (ast_get_reg(&ast_info.ast_green[coloron], DAC_DATA) != 0)
1385N/A status = -1;
1385N/A
1385N/A if (ast_get_reg(&junk, SEQ_PORT) != 0)
1385N/A status = -1;
1385N/A
1385N/A if (ast_get_reg(&ast_info.ast_blue[coloron], DAC_DATA) != 0)
1385N/A status = -1;
1385N/A
1385N/A if (ast_get_reg(&junk, SEQ_PORT) != 0)
1385N/A status = -1;
1117N/A }
1117N/A
1385N/A return (status);
1117N/A}
1117N/A
1117N/A
1117N/Aint
1385N/Aast_set_palet(
1385N/A void)
1117N/A{
1385N/A register uint_t coloron;
1385N/A register int status = 1;
1385N/A register uint_t maxdac;
1385N/A uchar_t ramdac_ctrl;
1385N/A uchar_t new_red[256];
1385N/A uchar_t new_green[256];
1385N/A uchar_t new_blue[256];
1385N/A uchar_t junk;
1385N/A
1385N/A if (ast_get_index_reg(&ramdac_ctrl, CRTC_PORT, 0xA8) != 0)
1385N/A return (-1);
1385N/A
1385N/A maxdac = (ramdac_ctrl & 0x2) ? 255 : 63;
1385N/A
1385N/A switch (ast_info.ast_depth) {
1385N/A case 8: /* 3, 3, 2 */
1385N/A for (coloron = 0; coloron < 256; coloron++) {
1385N/A new_red[coloron] =
1385N/A (uint8_t)(((coloron >> 5) & 0x7) * maxdac / 7);
1385N/A new_green[coloron] =
1385N/A (uint8_t)(((coloron >> 2) & 0x7) * maxdac / 7);
1385N/A new_blue[coloron] =
1385N/A (uint8_t)((coloron & 0x3) * maxdac / 3);
1385N/A }
1385N/A break;
1385N/A
1385N/A case 15: /* 5, 5, 5 */
1385N/A for (coloron = 0; coloron < 256; coloron++) {
1385N/A new_red[coloron] =
1385N/A (uint8_t)((coloron / 8) * maxdac / 31);
1385N/A new_green[coloron] =
1385N/A (uint8_t)((coloron / 8) * maxdac / 31);
1385N/A new_blue[coloron] =
1385N/A (uint8_t)((coloron / 8) * maxdac / 31);
1385N/A }
1385N/A break;
1385N/A
1385N/A case 16: /* 5, 6, 5 */
1385N/A for (coloron = 0; coloron < 256; coloron++) {
1385N/A new_red[coloron] =
1385N/A (uint8_t)((coloron / 8) * maxdac / 31);
1385N/A new_green[coloron] =
1385N/A (uint8_t)((coloron / 4) * maxdac / 63);
1385N/A new_blue[coloron] =
1385N/A (uint8_t)((coloron / 8) * maxdac / 31);
1385N/A }
1385N/A break;
1385N/A
1385N/A default: /* 8, 8, 8 */
1385N/A for (coloron = 0; coloron < 256; coloron++) {
1385N/A new_red[coloron] =
1385N/A (uint8_t)(coloron * maxdac / 255);
1385N/A new_green[coloron] =
1385N/A (uint8_t)(coloron * maxdac / 255);
1385N/A new_blue[coloron] =
1385N/A (uint8_t)(coloron * maxdac / 255);
1385N/A }
1385N/A break;
1385N/A }
1385N/A
1385N/A /* Don't set the palet if it matches what we will set. */
1117N/A
1385N/A for (coloron = 0; coloron < 256; coloron++) {
1385N/A if ((ast_info.ast_red[coloron] != new_red[coloron]) ||
1385N/A (ast_info.ast_green[coloron] != new_green[coloron]) ||
1385N/A (ast_info.ast_blue[coloron] != new_blue[coloron]))
1385N/A break;
1385N/A }
1385N/A
1385N/A if (coloron == 256)
1385N/A return (0);
1385N/A
1385N/A ast_info.ast_palet_changed = 1;
1385N/A
1385N/A for (coloron = 0; coloron < 256; coloron++) {
1385N/A if (ast_set_reg(DAC_INDEX_WRITE, coloron) != 0)
1385N/A status = -1;
1385N/A
1385N/A if (ast_get_reg(&junk, SEQ_PORT) != 0)
1385N/A status = -1;
1385N/A
1385N/A if (ast_set_reg(DAC_DATA, new_red[coloron]) != 0)
1385N/A status = -1;
1385N/A
1385N/A if (ast_get_reg(&junk, SEQ_PORT) != 0)
1385N/A status = -1;
1385N/A
1385N/A if (ast_set_reg(DAC_DATA, new_green[coloron]) != 0)
1385N/A status = -1;
1385N/A
1385N/A if (ast_get_reg(&junk, SEQ_PORT) != 0)
1385N/A status = -1;
1385N/A
1385N/A if (ast_set_reg(DAC_DATA, new_blue[coloron]) != 0)
1385N/A status = -1;
1117N/A
1385N/A if (ast_get_reg(&junk, SEQ_PORT) != 0)
1385N/A status = -1;
1385N/A }
1385N/A
1385N/A return (status);
1385N/A}
1385N/A
1385N/A
1385N/Aint
1385N/Aast_restore_palet(
1385N/A void)
1385N/A{
1385N/A register uint_t coloron;
1385N/A register int status = 1;
1385N/A uchar_t junk;
1385N/A
1385N/A if (!ast_info.ast_palet_changed)
1385N/A return (0);
1385N/A
1385N/A for (coloron = 0; coloron < 256; coloron++) {
1385N/A if (ast_set_reg(DAC_INDEX_WRITE, coloron) != 0)
1385N/A status = -1;
1385N/A
1385N/A if (ast_get_reg(&junk, SEQ_PORT) != 0)
1385N/A status = -1;
1385N/A
1385N/A if (ast_set_reg(DAC_DATA, ast_info.ast_red[coloron]) != 0)
1385N/A status = -1;
1385N/A
1385N/A if (ast_get_reg(&junk, SEQ_PORT) != 0)
1385N/A status = -1;
1385N/A
1385N/A if (ast_set_reg(DAC_DATA, ast_info.ast_green[coloron]) != 0)
1385N/A status = -1;
1117N/A
1385N/A if (ast_get_reg(&junk, SEQ_PORT) != 0)
1385N/A status = -1;
1385N/A
1385N/A if (ast_set_reg(DAC_DATA, ast_info.ast_blue[coloron]) != 0)
1385N/A status = -1;
1385N/A
1385N/A if (ast_get_reg(&junk, SEQ_PORT) != 0)
1385N/A status = -1;
1385N/A }
1385N/A
1385N/A ast_info.ast_palet_changed = 0;
1385N/A return (status);
1385N/A}
1385N/A
1385N/A
1385N/Auint_t
1385N/Aast_color(
1385N/A register uint_t const red,
1385N/A register uint_t const green,
1385N/A register uint_t const blue)
1385N/A{
1385N/A register uint_t value;
1117N/A
1385N/A switch (ast_info.ast_depth) {
1385N/A case 8: /* 3, 3, 2 */
1385N/A value = ((red >> 5) & 0x7) << 5;
1385N/A value |= ((green >> 5) & 0x7) << 2;
1385N/A value |= (blue >> 6) & 0x3;
1385N/A break;
1385N/A
1385N/A case 15: /* 5, 5, 5 */
1385N/A value = ((red >> 3) & 0x1f) << 10;
1385N/A value |= ((green >> 3) & 0x1f) << 5;
1385N/A value |= (blue >> 3) & 0x1f;
1385N/A break;
1385N/A
1385N/A case 16: /* 5, 6, 5 */
1385N/A value = ((red >> 3) & 0x1f) << 11;
1385N/A value |= ((green >> 2) & 0x3f) << 5;
1385N/A value |= (blue >> 3) & 0x1f;
1385N/A break;
1385N/A
1385N/A default: /* 8, 8, 8 */
1385N/A value = (red & 0xff) << 16;
1385N/A value |= (green & 0xff) << 8;
1385N/A value |= blue & 0xff;
1117N/A break;
1385N/A }
1385N/A
1385N/A return (value);
1385N/A}
1385N/A
1385N/A
1385N/Aint
1385N/Aast_open_key(
1385N/A void)
1385N/A{
1385N/A if (ast_set_index_reg(CRTC_PORT, 0x80, 0xA8) != 0)
1385N/A return (-1);
1385N/A return (0);
1385N/A}
1385N/A
1385N/A
1385N/Aint
1385N/Aast_fill_solid_rect(
1385N/A register uint_t const x1,
1385N/A register uint_t const y1,
1385N/A register uint_t const x2,
1385N/A register uint_t const y2,
1385N/A register uint_t const fg)
1385N/A{
1385N/A register uint_t cmdreg;
1385N/A
1385N/A cmdreg = CMD_BITBLT | CMD_PAT_FGCOLOR | 0xf000;
1385N/A switch (ast_info.ast_pixelsize) {
1385N/A case 1:
1385N/A cmdreg |= CMD_COLOR_08;
1117N/A break;
1385N/A case 2:
1385N/A cmdreg |= CMD_COLOR_16;
1385N/A break;
1385N/A case 3:
1385N/A case 4:
1385N/A default:
1385N/A cmdreg |= CMD_COLOR_32;
1117N/A break;
1385N/A }
1385N/A
1385N/A if (!ast_store_mmio(MMIOREG_DST_PITCH,
1385N/A (ast_info.ast_linesize << 16) | MASK_DST_HEIGHT))
1385N/A return (0);
1385N/A
1385N/A if (!ast_store_mmio(MMIOREG_FG, fg))
1385N/A return (0);
1385N/A
1385N/A if (!ast_store_mmio(MMIOREG_DST_BASE, 0))
1385N/A return (0);
1385N/A
1385N/A if (!ast_store_mmio(MMIOREG_DST_XY,
1385N/A (x1 << 16) | y1))
1385N/A return (0);
1385N/A
1385N/A if (!ast_store_mmio(MMIOREG_RECT_XY,
1385N/A ((x2 - x1) << 16) | (y2 - y1)))
1385N/A return (0);
1385N/A
1385N/A if (!ast_store_mmio(MMIOREG_CMD, cmdreg))
1385N/A return (0);
1385N/A
1385N/A return (1);
1385N/A}
1385N/A
1385N/A
1385N/Aint
1385N/Aast_fill_pattern_rect(
1385N/A register uint_t const x1,
1385N/A register uint_t const y1,
1385N/A register uint_t const x2,
1385N/A register uint_t const y2,
1385N/A register uint_t const bg,
1385N/A register uint_t const fg,
1385N/A register uint64_t const pat)
1385N/A{
1385N/A register uint_t cmdreg;
1385N/A
1385N/A cmdreg = CMD_BITBLT | CMD_PAT_MONOMASK | 0xf000;
1385N/A switch (ast_info.ast_pixelsize) {
1385N/A case 1:
1385N/A cmdreg |= CMD_COLOR_08;
1117N/A break;
1385N/A case 2:
1385N/A cmdreg |= CMD_COLOR_16;
1385N/A break;
1385N/A case 3:
1385N/A case 4:
1117N/A default:
1385N/A cmdreg |= CMD_COLOR_32;
1117N/A break;
1117N/A }
1117N/A
1385N/A if (!ast_store_mmio(MMIOREG_DST_PITCH,
1385N/A (ast_info.ast_linesize << 16) | MASK_DST_HEIGHT))
1385N/A return (0);
1385N/A
1385N/A if (!ast_store_mmio(MMIOREG_FG, fg))
1385N/A return (0);
1385N/A
1385N/A if (!ast_store_mmio(MMIOREG_BG, bg))
1385N/A return (0);
1385N/A
1385N/A if (!ast_store_mmio(MMIOREG_MONO1, (uint_t)(pat >> 32)))
1385N/A return (0);
1385N/A
1385N/A if (!ast_store_mmio(MMIOREG_MONO2, (uint_t)pat))
1385N/A return (0);
1385N/A
1385N/A if (!ast_store_mmio(MMIOREG_DST_BASE, 0))
1385N/A return (0);
1385N/A
1385N/A if (!ast_store_mmio(MMIOREG_DST_XY,
1385N/A (x1 << 16) | y1))
1385N/A return (0);
1385N/A
1385N/A if (!ast_store_mmio(MMIOREG_RECT_XY,
1385N/A ((x2 - x1) << 16) | (y2 - y1)))
1385N/A return (0);
1385N/A
1385N/A if (!ast_store_mmio(MMIOREG_CMD, cmdreg))
1385N/A return (0);
1385N/A
1385N/A return (1);
1385N/A}
1385N/A
1385N/A
1385N/Aint
1385N/Aast_draw_solid_line(
1385N/A register uint_t const x1,
1385N/A register uint_t const y1,
1385N/A register uint_t const x2,
1385N/A register uint_t const y2,
1385N/A register uint_t const fg)
1385N/A{
1385N/A register uint_t cmdreg;
1385N/A register uint_t GAbsX;
1385N/A register uint_t GAbsY;
1385N/A register uint_t MM;
1385N/A register uint_t mm;
1385N/A register int err;
1385N/A register int k1;
1385N/A register int k2;
1385N/A register int xm;
1385N/A
1385N/A cmdreg = 0xf000 | CMD_LINEDRAW | CMD_ENABLE_CLIP |
1385N/A CMD_NOT_DRAW_LAST_PIXEL;
1385N/A switch (ast_info.ast_pixelsize) {
1385N/A case 1:
1385N/A cmdreg |= CMD_COLOR_08;
1385N/A break;
1385N/A case 2:
1385N/A cmdreg |= CMD_COLOR_16;
1385N/A break;
1385N/A case 3:
1385N/A case 4:
1385N/A default:
1385N/A cmdreg |= CMD_COLOR_32;
1385N/A break;
1117N/A }
1117N/A
1385N/A if (x1 < x2)
1385N/A GAbsX = x2 - x1;
1385N/A else
1385N/A GAbsX = x1 - x2;
1385N/A
1385N/A if (y1 < y2)
1385N/A GAbsY = y2 - y1;
1385N/A else
1385N/A GAbsY = y1 - y2;
1385N/A
1385N/A if (GAbsX >= GAbsY) {
1385N/A MM = GAbsX;
1385N/A mm = GAbsY;
1385N/A xm = 1;
1385N/A } else {
1385N/A MM = GAbsY;
1385N/A mm = GAbsX;
1385N/A xm = 0;
1385N/A }
1385N/A
1385N/A if (x1 >= x2)
1385N/A cmdreg |= CMD_X_DEC;
1385N/A
1385N/A if (y1 >= y2)
1385N/A cmdreg |= CMD_Y_DEC;
1385N/A
1385N/A err = (int)(2 * mm) - (int)MM;
1385N/A k1 = 2 * mm;
1385N/A k2 = (int)(2 * mm) - (int)(2 * MM);
1117N/A
1385N/A if (!ast_store_mmio(MMIOREG_DST_BASE, 0))
1385N/A return (0);
1385N/A
1385N/A if (!ast_store_mmio(MMIOREG_DST_PITCH,
1385N/A (ast_info.ast_linesize << 16) | MASK_DST_HEIGHT))
1385N/A return (0);
1385N/A
1385N/A if (!ast_store_mmio(MMIOREG_FG, fg))
1385N/A return (0);
1385N/A
1385N/A if (!ast_store_mmio(MMIOREG_LINE_XY,
1385N/A (x1 << 16) | y1))
1385N/A return (0);
1117N/A
1385N/A if (!ast_store_mmio(MMIOREG_LINE_ERR,
1385N/A (xm << 24) | (err & MASK_LINE_ERR)))
1385N/A return (0);
1385N/A
1385N/A if (!ast_store_mmio(MMIOREG_LINE_WIDTH,
1385N/A (MM & MASK_LINE_WIDTH) << 16))
1385N/A return (0);
1385N/A
1385N/A if (!ast_store_mmio(MMIOREG_LINE_K1,
1385N/A (k1 & MASK_LINE_K1)))
1385N/A return (0);
1385N/A
1385N/A if (!ast_store_mmio(MMIOREG_LINE_K2,
1385N/A (k2 & MASK_LINE_K2)))
1385N/A return (0);
1385N/A
1385N/A if (!ast_store_mmio(MMIOREG_CMD, cmdreg))
1385N/A return (0);
1385N/A
1385N/A return (1);
1117N/A}
1117N/A
1117N/Aint
1385N/Aast_unmap_mem(
1385N/A register return_packet *const rp,
1385N/A register int const test)
1117N/A{
1385N/A if (ast_unmap_fb() != 0) {
1385N/A gfx_vts_set_message(rp, 1, test, "unmap framebuffer failed");
1385N/A return (-1);
1385N/A }
1385N/A
1385N/A if (ast_unmap_mmio() != 0) {
1385N/A gfx_vts_set_message(rp, 1, test, "unmap MMIO failed");
1385N/A return (-1);
1385N/A }
1385N/A
1385N/A return (0);
1385N/A}
1385N/A
1117N/A
1385N/Aint
1385N/Aast_unmap_fb(
1385N/A void)
1385N/A{
1385N/A register int status;
1385N/A
1385N/A if (ast_info.ast_fb_ptr == NULL)
1385N/A return (0);
1385N/A
1385N/A status = munmap((char *)ast_info.ast_fb_ptr, ast_info.ast_fb_size);
1385N/A ast_info.ast_fb_ptr = NULL;
1385N/A
1385N/A return (status);
1385N/A}
1117N/A
1117N/A
1385N/Aint
1385N/Aast_unmap_mmio(
1385N/A void)
1385N/A{
1385N/A register int status;
1117N/A
1385N/A if (ast_info.ast_mmio_ptr == NULL)
1385N/A return (0);
1117N/A
1385N/A status = munmap((char *)ast_info.ast_mmio_ptr,
1385N/A ast_info.ast_mmio_size);
1385N/A ast_info.ast_mmio_ptr = NULL;
1117N/A
1385N/A return (status);
1385N/A}
1385N/A
1117N/A
1117N/A
1385N/Aint
1385N/Aast_store_mmio(
1385N/A register uint_t const port,
1385N/A register uint_t const value)
1385N/A{
1385N/A register uint_t readvalue;
1385N/A register hrtime_t starttime;
1385N/A register hrtime_t curtime;
1385N/A register hrtime_t endtime;
1385N/A register ulong_t count = 0;
1385N/A
1385N/A ast_mmio_write32(port, value);
1385N/A readvalue = ast_mmio_read32(port);
1385N/A
1385N/A if (readvalue == value)
1385N/A return (1);
1117N/A
1385N/A starttime = gethrtime();
1385N/A endtime = starttime + ast_loop_time;
1385N/A
1385N/A do {
1385N/A count++;
1385N/A ast_mmio_write32(port, value);
1385N/A readvalue = ast_mmio_read32(port);
1117N/A
1385N/A if (readvalue == value)
1385N/A return (1);
1385N/A curtime = gethrtime();
1385N/A } while (curtime < endtime);
1117N/A
1385N/A ast_mmio_write32(port, value);
1385N/A readvalue = ast_mmio_read32(port);
1385N/A
1385N/A if (readvalue == value)
1385N/A return (1);
1385N/A
1385N/A return (0);
1117N/A}
1117N/A
1117N/Aint
1385N/Aast_get_index_reg(
1385N/A register uchar_t *const valueptr,
1385N/A register uchar_t const offset,
1385N/A register uchar_t const index)
1385N/A{
1385N/A if (ast_set_reg(offset, index) != 0)
1385N/A return (-1);
1385N/A
1385N/A if (ast_get_reg(valueptr, offset + 1) != 0)
1385N/A return (-1);
1385N/A
1385N/A return (0);
1385N/A}
1385N/A
1385N/A
1385N/Aint
1385N/Aast_set_index_reg(
1385N/A register uchar_t const offset,
1385N/A register uchar_t const index,
1385N/A register uchar_t const value)
1385N/A{
1385N/A if (ast_set_reg(offset, index) != 0)
1385N/A return (-1);
1385N/A
1385N/A if (ast_set_reg(offset + 1, value) != 0)
1385N/A return (-1);
1385N/A
1385N/A return (0);
1385N/A}
1385N/A
1385N/A
1385N/Aint
1385N/Aast_get_reg(
1385N/A register uchar_t *const valueptr,
1385N/A register uchar_t const offset)
1117N/A{
1385N/A ast_io_reg io_reg;
1385N/A
1385N/A io_reg.offset = offset;
1385N/A io_reg.value = (uchar_t)-1;
1385N/A
1385N/A if (ioctl(ast_info.ast_fd, AST_GET_IO_REG, &io_reg) != 0)
1385N/A return (-1);
1385N/A
1385N/A *valueptr = io_reg.value;
1385N/A return (0);
1385N/A}
1385N/A
1385N/A
1385N/Aint
1385N/Aast_set_reg(
1385N/A register uchar_t const offset,
1385N/A register uchar_t const value)
1385N/A{
1385N/A ast_io_reg io_reg;
1385N/A
1385N/A io_reg.offset = offset;
1385N/A io_reg.value = value;
1385N/A
1385N/A if (ioctl(ast_info.ast_fd, AST_SET_IO_REG, &io_reg) != 0)
1385N/A return (-1);
1385N/A
1385N/A return (0);
1385N/A}
1385N/A
1385N/A
1385N/Auint_t
1385N/Aast_mmio_read32(
1385N/A register uint_t const port)
1385N/A{
1385N/A register uint_t volatile const *const addr =
1385N/A (uint_t volatile const *) (ast_info.ast_mmio_ptr + port);
1385N/A register uint_t value;
1385N/A
1385N/A union {
1385N/A uint_t l;
1385N/A ushort_t w[2];
1385N/A uchar_t b[4];
1385N/A } data;
1385N/A
1385N/A data.l = *addr;
1117N/A
1385N/A switch (ast_info.ast_endian) {
1385N/A case 0: /* little endian */
1385N/A value = ((uint_t)data.b[3] << 24) |
1385N/A ((uint_t)data.b[2] << 16) |
1385N/A ((uint_t)data.b[1] << 8) |
1385N/A (uint_t)data.b[0];
1385N/A break;
1385N/A
1385N/A case 1: /* big endian 16 */
1385N/A case 2: /* big endian 32 */
1385N/A value = ((uint_t)data.b[0] << 24) |
1385N/A ((uint_t)data.b[1] << 16) |
1385N/A ((uint_t)data.b[2] << 8) |
1385N/A (uint_t)data.b[3];
1385N/A break;
1385N/A }
1385N/A
1385N/A return (value);
1385N/A}
1385N/A
1385N/A
1385N/A
1385N/Avoid
1385N/Aast_mmio_write32(
1385N/A register uint_t const port,
1385N/A register uint_t const val)
1385N/A{
1385N/A register uint_t volatile *const addr =
1385N/A (uint_t volatile *) (ast_info.ast_mmio_ptr + port);
1385N/A register uint_t value;
1385N/A
1385N/A union {
1385N/A uint_t l;
1385N/A ushort_t w[2];
1385N/A uchar_t b[4];
1385N/A } data;
1385N/A
1385N/A data.l = val;
1117N/A
1385N/A switch (ast_info.ast_endian) {
1385N/A case 0: /* little endian */
1385N/A value = ((uint_t)data.b[3] << 24) |
1385N/A ((uint_t)data.b[2] << 16) |
1385N/A ((uint_t)data.b[1] << 8) |
1385N/A (uint_t)data.b[0];
1385N/A break;
1385N/A
1385N/A case 1: /* big endian 16 */
1385N/A case 2: /* big endian 32 */
1385N/A value = ((uint_t)data.b[0] << 24) |
1385N/A ((uint_t)data.b[1] << 16) |
1385N/A ((uint_t)data.b[2] << 8) |
1385N/A (uint_t)data.b[3];
1385N/A break;
1385N/A }
1385N/A
1385N/A *addr = value;
1385N/A}
1385N/A
1117N/A
1385N/Aint
1385N/Aast_wait_idle(
1385N/A void)
1385N/A{
1385N/A register hrtime_t starttime;
1385N/A register hrtime_t curtime;
1385N/A register hrtime_t endtime;
1385N/A register ulong_t count = 0;
1385N/A
1385N/A if (!(ast_mmio_read32(MMIOREG_STAT) & STAT_BUSY))
1385N/A return (1);
1385N/A
1385N/A starttime = gethrtime();
1385N/A endtime = starttime + ast_loop_time;
1385N/A
1385N/A do {
1385N/A count++;
1385N/A if (!(ast_mmio_read32(MMIOREG_STAT) & STAT_BUSY))
1385N/A return (1);
1385N/A curtime = gethrtime();
1385N/A } while (curtime < endtime);
1385N/A
1385N/A if (!(ast_mmio_read32(MMIOREG_STAT) & STAT_BUSY))
1385N/A return (1);
1385N/A
1385N/A return (0);
1117N/A}