tools.c revision 1247
1247N/A/*
1247N/A * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
1247N/A *
1247N/A * Permission is hereby granted, free of charge, to any person obtaining a
1247N/A * copy of this software and associated documentation files (the "Software"),
1247N/A * to deal in the Software without restriction, including without limitation
1247N/A * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1247N/A * and/or sell copies of the Software, and to permit persons to whom the
1247N/A * Software is furnished to do so, subject to the following conditions:
1247N/A *
1247N/A * The above copyright notice and this permission notice (including the next
1247N/A * paragraph) shall be included in all copies or substantial portions of the
1247N/A * Software.
1247N/A *
1247N/A * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1247N/A * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1247N/A * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
1247N/A * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1247N/A * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
1247N/A * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
1247N/A * DEALINGS IN THE SOFTWARE.
1247N/A */
1247N/A
1247N/A#include "libvtsSUNWmga.h" /* Common VTS library definitions */
1247N/A
1247N/Ahrtime_t mga_loop_time = (hrtime_t) 10 * NANOSEC; /* time to busy wait */
1247N/A
1247N/A#if !defined(_BIG_ENDIAN)
1247N/Aint mga_big_endian = 0;
1247N/A#else /* defined(_BIG_ENDIAN) */
1247N/Aint mga_big_endian = 1;
1247N/A#endif /* defined(_BIG_ENDIAN) */
1247N/A
1247N/Aint
1247N/Amga_map_mem(
1247N/A register return_packet *const rp,
1247N/A register int const test)
1247N/A{
1247N/A if (mga_get_pci_info() != 0) {
1247N/A gfx_vts_set_message(rp, 1, test, "get pci info failed");
1247N/A return (-1);
1247N/A }
1247N/A
1247N/A if (mga_map_fb() != 0) {
1247N/A gfx_vts_set_message(rp, 1, test, "map framebuffer failed");
1247N/A return (-1);
1247N/A }
1247N/A
1247N/A if (mga_map_control() != 0) {
1247N/A gfx_vts_set_message(rp, 1, test, "map control failed");
1247N/A return (-1);
1247N/A }
1247N/A
1247N/A if (mga_map_iload() != 0) {
1247N/A gfx_vts_set_message(rp, 1, test, "map iload failed");
1247N/A return (-1);
1247N/A }
1247N/A
1247N/A return (0);
1247N/A}
1247N/A
1247N/Aint
1247N/Amga_get_pci_info(
1247N/A void)
1247N/A{
1247N/A struct gfx_pci_cfg pciconfig;
1247N/A
1247N/A if (ioctl(mga_info.mga_fd, GFX_IOCTL_GET_PCI_CONFIG,
1247N/A &pciconfig) != 0)
1247N/A return (-1);
1247N/A
1247N/A mga_info.mga_vendor = pciconfig.VendorID;
1247N/A mga_info.mga_device = pciconfig.DeviceID;
1247N/A
1247N/A mga_info.mga_fb_addr = pciconfig.bar[0] & PCI_BASE_M_ADDR_M;
1247N/A mga_info.mga_fb_size = MGASIZE_FB;
1247N/A
1247N/A mga_info.mga_control_addr = pciconfig.bar[1] & PCI_BASE_M_ADDR_M;
1247N/A mga_info.mga_control_size = MGASIZE_CONTROL;
1247N/A
1247N/A mga_info.mga_iload_addr = pciconfig.bar[2] & PCI_BASE_M_ADDR_M;
1247N/A mga_info.mga_iload_size = MGASIZE_ILOAD;
1247N/A
1247N/A if (gfx_vts_debug_mask & VTS_DEBUG) {
1247N/A printf("mga_vendor = 0x%04x, mga_device = 0x%04x\n",
1247N/A mga_info.mga_vendor, mga_info.mga_device);
1247N/A printf("fb_addr = 0x%08llx, mga_fb_size = 0x%08lx\n",
1247N/A (unsigned long long) mga_info.mga_fb_addr,
1247N/A (unsigned long) mga_info.mga_fb_size);
1247N/A printf("control_addr = 0x%08llx, mga_control_size = 0x%08lx\n",
1247N/A (unsigned long long) mga_info.mga_control_addr,
1247N/A (unsigned long) mga_info.mga_control_size);
1247N/A printf("iload_addr = 0x%08llx, mga_iload_size = 0x%08lx\n",
1247N/A (unsigned long long) mga_info.mga_iload_addr,
1247N/A (unsigned long) mga_info.mga_iload_size);
1247N/A }
1247N/A
1247N/A return (0);
1247N/A}
1247N/A
1247N/Aint
1247N/Amga_map_fb(
1247N/A void)
1247N/A{
1247N/A register void *ptr;
1247N/A
1247N/A if (mga_info.mga_fb_ptr == NULL) {
1247N/A ptr = mmap(NULL, mga_info.mga_fb_size,
1247N/A PROT_READ | PROT_WRITE, MAP_SHARED,
1247N/A mga_info.mga_fd, mga_info.mga_fb_addr);
1247N/A
1247N/A if (ptr == MAP_FAILED)
1247N/A return (-1);
1247N/A
1247N/A mga_info.mga_fb_ptr = (char *) ptr;
1247N/A }
1247N/A
1247N/A if (gfx_vts_debug_mask & VTS_DEBUG)
1247N/A printf("mga_fb_ptr = 0x%llx\n",
1247N/A (unsigned long long) mga_info.mga_fb_ptr);
1247N/A
1247N/A return (0);
1247N/A}
1247N/A
1247N/Aint
1247N/Amga_map_control(
1247N/A void)
1247N/A{
1247N/A register void *ptr;
1247N/A
1247N/A if (mga_info.mga_control_ptr == NULL) {
1247N/A ptr = mmap(NULL, mga_info.mga_control_size,
1247N/A PROT_READ | PROT_WRITE, MAP_SHARED,
1247N/A mga_info.mga_fd, mga_info.mga_control_addr);
1247N/A
1247N/A if (ptr == MAP_FAILED)
1247N/A return (-1);
1247N/A }
1247N/A
1247N/A mga_info.mga_control_ptr = (mga_t volatile *) ptr;
1247N/A
1247N/A if (gfx_vts_debug_mask & VTS_DEBUG)
1247N/A printf("mga_control_ptr = 0x%llx\n",
1247N/A (unsigned long long) mga_info.mga_control_ptr);
1247N/A
1247N/A return (0);
1247N/A}
1247N/A
1247N/Aint
1247N/Amga_map_iload(
1247N/A void)
1247N/A{
1247N/A register void *ptr;
1247N/A
1247N/A if (mga_info.mga_iload_ptr == NULL) {
1247N/A ptr = mmap(NULL, mga_info.mga_iload_size,
1247N/A PROT_READ | PROT_WRITE, MAP_SHARED,
1247N/A mga_info.mga_fd, mga_info.mga_iload_addr);
1247N/A
1247N/A if (ptr == MAP_FAILED)
1247N/A return (-1);
1247N/A }
1247N/A
1247N/A mga_info.mga_iload_ptr = (char volatile *) ptr;
1247N/A
1247N/A if (gfx_vts_debug_mask & VTS_DEBUG)
1247N/A printf("mga_iload_ptr = 0x%llx\n",
1247N/A (unsigned long long) mga_info.mga_iload_ptr);
1247N/A
1247N/A return (0);
1247N/A}
1247N/A
1247N/Aint
1247N/Amga_init_info(
1247N/A register return_packet *const rp,
1247N/A register int const test)
1247N/A{
1247N/A register mga_t volatile *mgaptr;
1247N/A
1247N/A if (mga_get_fb_size() == 0) {
1247N/A gfx_vts_set_message(rp, 1, test, "get fb size failed");
1247N/A return (-1);
1247N/A }
1247N/A
1247N/A if (mga_get_screen_size() == 0) {
1247N/A gfx_vts_set_message(rp, 1, test, "get resolution failed");
1247N/A return (-1);
1247N/A }
1247N/A
1247N/A mgaptr = mga_info.mga_control_ptr;
1247N/A mga_info.mga_opmode = mga_get_uint32(&mgaptr->mga_opmode);
1247N/A
1247N/A return (0);
1247N/A}
1247N/A
1247N/A#define MGA_FB_STEP (16 * 1024)
1247N/A
1247N/Asize_t
1247N/Amga_get_fb_size(
1247N/A void)
1247N/A{
1247N/A register uint32_t volatile *fbptr;
1247N/A register size_t offset;
1247N/A register uint32_t word;
1247N/A
1247N/A for (offset = 0, fbptr = (uint32_t volatile *) mga_info.mga_fb_ptr;
1247N/A offset < mga_info.mga_fb_size;
1247N/A offset += MGA_FB_STEP, fbptr += MGA_FB_STEP / sizeof (uint32_t)) {
1247N/A word = *fbptr;
1247N/A *fbptr = ~word;
1247N/A if (*fbptr != ~word) {
1247N/A *fbptr = word;
1247N/A break;
1247N/A }
1247N/A *fbptr = word;
1247N/A if (*fbptr != word)
1247N/A break;
1247N/A }
1247N/A
1247N/A mga_info.mga_fb_real_size = offset;
1247N/A
1247N/A if (gfx_vts_debug_mask & VTS_DEBUG)
1247N/A printf("mga_fb_real_size = %lu\n", (unsigned long) offset);
1247N/A
1247N/A return (offset);
1247N/A}
1247N/A
1247N/A
1247N/Aint
1247N/Amga_get_screen_size(
1247N/A void)
1247N/A{
1247N/A register mga_t volatile *const mgaptr = mga_info.mga_control_ptr;
1247N/A register uint8_t save_crtc_index;
1247N/A register uint8_t save_crtcext_index;
1247N/A register uint8_t save_palwtadd;
1247N/A register uint8_t save_gctl_index;
1247N/A register uint8_t miscout;
1247N/A register uint8_t horiz_total;
1247N/A register uint8_t horiz_display_end;
1247N/A register uint8_t vert_total;
1247N/A register uint8_t vert_display_end;
1247N/A register uint8_t overflow;
1247N/A register uint8_t offset;
1247N/A register uint8_t addr_gen_ext;
1247N/A register uint8_t hor_counter_ext;
1247N/A register uint8_t vert_counter_ext;
1247N/A register uint8_t xmulctrl;
1247N/A register uint8_t misc;
1247N/A register uint8_t graphic_mode;
1247N/A register uint8_t miscellaneous;
1247N/A register uint32_t freq;
1247N/A register uint8_t m;
1247N/A register uint8_t n;
1247N/A register uint8_t p;
1247N/A register uint_t mode;
1247N/A register uint_t width;
1247N/A register uint_t height;
1247N/A register uint_t depth;
1247N/A register uint_t pixelsize;
1247N/A register uint_t pclk;
1247N/A register uint_t htotal;
1247N/A register uint_t vtotal;
1247N/A register uint_t hz;
1247N/A register uint_t pitch;
1247N/A
1247N/A /* Get the miscellaneous output register */
1247N/A
1247N/A miscout = mgaptr->mga_miscout_read;
1247N/A
1247N/A /* Save the crtc index. */
1247N/A
1247N/A save_crtc_index = mgaptr->mga_crtc_index;
1247N/A
1247N/A /* Get the horizontal total */
1247N/A
1247N/A mgaptr->mga_crtc_index = MGA_CRTC_HORIZ_TOTAL;
1247N/A horiz_total = mgaptr->mga_crtc_data;
1247N/A
1247N/A /* Get the horizontal display end. */
1247N/A
1247N/A mgaptr->mga_crtc_index = MGA_CRTC_HORIZ_DISPLAY_END;
1247N/A horiz_display_end = mgaptr->mga_crtc_data;
1247N/A
1247N/A /* Get the vertical total */
1247N/A
1247N/A mgaptr->mga_crtc_index = MGA_CRTC_VERT_TOTAL;
1247N/A vert_total = mgaptr->mga_crtc_data;
1247N/A
1247N/A /* Get the vertical display end. */
1247N/A
1247N/A mgaptr->mga_crtc_index = MGA_CRTC_VERT_DISPLAY_END;
1247N/A vert_display_end = mgaptr->mga_crtc_data;
1247N/A
1247N/A /* Get the overflow */
1247N/A
1247N/A mgaptr->mga_crtc_index = MGA_CRTC_OVERFLOW;
1247N/A overflow = mgaptr->mga_crtc_data;
1247N/A
1247N/A /* Get the offset */
1247N/A
1247N/A mgaptr->mga_crtc_index = MGA_CRTC_OFFSET;
1247N/A offset = mgaptr->mga_crtc_data;
1247N/A
1247N/A /* Restore the crtc index. */
1247N/A
1247N/A mgaptr->mga_crtc_index = save_crtc_index;
1247N/A
1247N/A /* Save the crtcext index. */
1247N/A
1247N/A save_crtcext_index = mgaptr->mga_crtcext_index;
1247N/A
1247N/A /* Get the address generator extensions */
1247N/A
1247N/A mgaptr->mga_crtcext_index = MGA_CRTCEXT_ADDR_GEN_EXT;
1247N/A addr_gen_ext = mgaptr->mga_crtcext_data;
1247N/A
1247N/A /* Get the horizontal counter extensions */
1247N/A
1247N/A mgaptr->mga_crtcext_index = MGA_CRTCEXT_HOR_COUNT_EXT;
1247N/A hor_counter_ext = mgaptr->mga_crtcext_data;
1247N/A
1247N/A /* Get the vertical counter extensions */
1247N/A
1247N/A mgaptr->mga_crtcext_index = MGA_CRTCEXT_VERT_COUNT_EXT;
1247N/A vert_counter_ext = mgaptr->mga_crtcext_data;
1247N/A
1247N/A /* Get the miscellaneous register */
1247N/A
1247N/A mgaptr->mga_crtcext_index = MGA_CRTCEXT_MISC;
1247N/A misc = mgaptr->mga_crtcext_data;
1247N/A
1247N/A /* Restore the crtcext index. */
1247N/A
1247N/A mgaptr->mga_crtcext_index = save_crtcext_index;
1247N/A
1247N/A /* Save the dac index. */
1247N/A
1247N/A save_palwtadd = mgaptr->mga_palwtadd;
1247N/A
1247N/A /* Get the multiplex control. */
1247N/A
1247N/A mgaptr->mga_palwtadd = MGA_XDATA_XMULCTRL;
1247N/A xmulctrl = mgaptr->mga_x_datareg;
1247N/A
1247N/A /* Get the appropriate clock values */
1247N/A
1247N/A switch (miscout & MGA_MISCOUT_CLKSEL_MASK) {
1247N/A case MGA_MISCOUT_CLKSEL_25MHZ: /* 0x00 */
1247N/A freq = MGA_XPIXPLLPA_REFCLK;
1247N/A
1247N/A /* Get pixpllam register */
1247N/A
1247N/A mgaptr->mga_palwtadd = MGA_XDATA_XPIXPLLAM;
1247N/A m = mgaptr->mga_x_datareg;
1247N/A
1247N/A /* Get pixpllan register */
1247N/A
1247N/A mgaptr->mga_palwtadd = MGA_XDATA_XPIXPLLAN;
1247N/A n = mgaptr->mga_x_datareg;
1247N/A
1247N/A /* Get pixpllap register */
1247N/A
1247N/A mgaptr->mga_palwtadd = MGA_XDATA_XPIXPLLAP;
1247N/A p = mgaptr->mga_x_datareg;
1247N/A break;
1247N/A
1247N/A case MGA_MISCOUT_CLKSEL_28MHZ: /* 0x04 */
1247N/A freq = MGA_XPIXPLLPB_REFCLK;
1247N/A
1247N/A /* Get pixpllbm register */
1247N/A
1247N/A mgaptr->mga_palwtadd = MGA_XDATA_XPIXPLLBM;
1247N/A m = mgaptr->mga_x_datareg;
1247N/A
1247N/A /* Get pixpllbn register */
1247N/A
1247N/A mgaptr->mga_palwtadd = MGA_XDATA_XPIXPLLBN;
1247N/A n = mgaptr->mga_x_datareg;
1247N/A
1247N/A /* Get pixpllbp register */
1247N/A
1247N/A mgaptr->mga_palwtadd = MGA_XDATA_XPIXPLLBP;
1247N/A p = mgaptr->mga_x_datareg;
1247N/A break;
1247N/A
1247N/A case MGA_MISCOUT_CLKSEL_MGAPIXEL0: /* 0x08 */
1247N/A case MGA_MISCOUT_CLKSEL_MGAPIXEL1: /* 0x0c */
1247N/A freq = MGA_XPIXPLLPC_REFCLK_G200E;
1247N/A
1247N/A /* Get pixpllcm register */
1247N/A
1247N/A mgaptr->mga_palwtadd = MGA_XDATA_XPIXPLLCM;
1247N/A m = mgaptr->mga_x_datareg;
1247N/A
1247N/A /* Get pixpllcn register */
1247N/A
1247N/A mgaptr->mga_palwtadd = MGA_XDATA_XPIXPLLCN;
1247N/A n = mgaptr->mga_x_datareg;
1247N/A
1247N/A /* Get pixpllcp register */
1247N/A
1247N/A mgaptr->mga_palwtadd = MGA_XDATA_XPIXPLLCP;
1247N/A p = mgaptr->mga_x_datareg;
1247N/A break;
1247N/A }
1247N/A
1247N/A /* Restore the dac index. */
1247N/A
1247N/A mgaptr->mga_palwtadd = save_palwtadd;
1247N/A
1247N/A /* Save the gctl index. */
1247N/A
1247N/A save_gctl_index = mgaptr->mga_gctl_index;
1247N/A
1247N/A /* Get the graphic mode register. */
1247N/A
1247N/A mgaptr->mga_gctl_index = MGA_GCTL_GRAPHIC_MODE;
1247N/A graphic_mode = mgaptr->mga_gctl_data;
1247N/A
1247N/A /* Get the miscellaneous register */
1247N/A
1247N/A mgaptr->mga_gctl_index = MGA_GCTL_MISCELLANEOUS;
1247N/A miscellaneous = mgaptr->mga_gctl_data;
1247N/A
1247N/A /* Restore the gctl index. */
1247N/A
1247N/A mgaptr->mga_gctl_index = save_gctl_index;
1247N/A
1247N/A /* Compute the width. */
1247N/A
1247N/A width = ((uint_t) horiz_display_end + 1) * 8;
1247N/A
1247N/A /* Compute the height. */
1247N/A
1247N/A height = (uint_t) vert_display_end;
1247N/A height |= (((uint_t) overflow >>
1247N/A MGA_CRTC_OVERFLOW_VDISPEND8_SHIFT) & 1) << 8;
1247N/A height |= (((uint_t) overflow >>
1247N/A MGA_CRTC_OVERFLOW_VDISPEND9_SHIFT) & 1) << 9;
1247N/A height |= (((uint_t) vert_counter_ext >>
1247N/A MGA_CRTCEXT_VCOUNT_VDISPEND10_SHIFT) & 1) << 10;
1247N/A height++;
1247N/A
1247N/A if (addr_gen_ext & MGA_CRTCEXT_ADDR_GEN_INTERLACE)
1247N/A height *= 2;
1247N/A
1247N/A if (!(misc & MGA_CRTCEXT_MISC_MGAMODE)) {
1247N/A if (!(miscellaneous & MGA_GCTL_MISC_GCGRMODE)) {
1247N/A mode = VIS_TEXT;
1247N/A depth = 4;
1247N/A width /= 8;
1247N/A height /= 16;
1247N/A pixelsize = 2;
1247N/A
1247N/A } else {
1247N/A mode = VIS_PIXEL;
1247N/A if (!(graphic_mode & MGA_GCTL_GRMODE_MODE256))
1247N/A depth = 4;
1247N/A else
1247N/A depth = 8;
1247N/A pixelsize = 1;
1247N/A }
1247N/A
1247N/A } else {
1247N/A mode = VIS_PIXEL;
1247N/A
1247N/A /* Compute the depth. */
1247N/A
1247N/A switch (xmulctrl & MGA_XMULCTRL_DEPTH_MASK) {
1247N/A case MGA_XMULCTRL_DEPTH_8BPP: /* 0x00 */
1247N/A depth = 8;
1247N/A pixelsize = 1;
1247N/A break;
1247N/A
1247N/A case MGA_XMULCTRL_DEPTH_15BPP_1BPP_OVERLAY: /* 0x01 */
1247N/A depth = 15;
1247N/A pixelsize = 2;
1247N/A break;
1247N/A
1247N/A case MGA_XMULCTRL_DEPTH_16BPP: /* 0x02 */
1247N/A depth = 16;
1247N/A pixelsize = 2;
1247N/A break;
1247N/A
1247N/A case MGA_XMULCTRL_DEPTH_24BPP: /* 0x03 */
1247N/A depth = 24;
1247N/A pixelsize = 3;
1247N/A break;
1247N/A
1247N/A case MGA_XMULCTRL_DEPTH_32BPP_8BPP_OVERLAY: /* 0x04 */
1247N/A case MGA_XMULCTRL_DEPTH_32BPP_8BPP_UNUSED: /* 0x07 */
1247N/A depth = 32;
1247N/A pixelsize = 4;
1247N/A break;
1247N/A
1247N/A default:
1247N/A return (0);
1247N/A }
1247N/A }
1247N/A
1247N/A pclk = (unsigned long long) freq *
1247N/A (unsigned long long) (n + 1) /
1247N/A (unsigned long long) ((m & MGA_XPIXPLLM_MASK) + 1) /
1247N/A (unsigned long long) ((p & MGA_XPIXPLLP_PIXPLLP_MASK) + 1);
1247N/A
1247N/A htotal = ((horiz_total |
1247N/A ((hor_counter_ext & MGA_CRTCEXT_HCOUNT_HTOTAL8) << 8)) + 5) * 8;
1247N/A
1247N/A vtotal = (vert_total |
1247N/A ((overflow & MGA_CRTC_OVERFLOW_VTOTAL8) << 8) |
1247N/A (((overflow >> MGA_CRTC_OVERFLOW_VTOTAL9_SHIFT) & 1) << 9) |
1247N/A ((vert_counter_ext & MGA_CRTCEXT_VCOUNT_VTOTAL10_11) << 10)) + 2;
1247N/A
1247N/A hz = (pclk + (htotal * vtotal / 2)) / (htotal * vtotal);
1247N/A
1247N/A pitch = ((((addr_gen_ext & MGA_CRTCEXT_ADDR_GEN_OFFSET8_9) >>
1247N/A MGA_CRTCEXT_ADDR_GEN_OFFSET8_9_SHIFT) << 8) + offset) * 8 * 2;
1247N/A
1247N/A mga_info.mga_mode = mode;
1247N/A mga_info.mga_width = width;
1247N/A mga_info.mga_height = height;
1247N/A mga_info.mga_depth = depth;
1247N/A mga_info.mga_hz = hz;
1247N/A mga_info.mga_pixelsize = pixelsize;
1247N/A mga_info.mga_linesize = pitch;
1247N/A
1247N/A return (1);
1247N/A}
1247N/A
1247N/A
1247N/Aint
1247N/Amga_mgamode(
1247N/A void)
1247N/A{
1247N/A register mga_t volatile *const mgaptr = mga_info.mga_control_ptr;
1247N/A register uint8_t crtcext_index;
1247N/A register uint8_t misc;
1247N/A
1247N/A /* Save the crtcext index. */
1247N/A
1247N/A crtcext_index = mgaptr->mga_crtcext_index;
1247N/A
1247N/A /* Get the miscellaneous register */
1247N/A
1247N/A mgaptr->mga_crtcext_index = MGA_CRTCEXT_MISC;
1247N/A misc = mgaptr->mga_crtcext_data;
1247N/A
1247N/A /* Restore the crtcext index. */
1247N/A
1247N/A mgaptr->mga_crtcext_index = crtcext_index;
1247N/A
1247N/A if (!(misc & MGA_CRTCEXT_MISC_MGAMODE))
1247N/A return (0);
1247N/A else
1247N/A return (1);
1247N/A}
1247N/A
1247N/Aint
1247N/Amga_init_graphics(
1247N/A void)
1247N/A{
1247N/A register mga_t volatile *const mgaptr = mga_info.mga_control_ptr;
1247N/A register uint32_t maccess;
1247N/A register uint32_t opmode = MGA_OPMODE_DIRDATASIZ_8BPP;
1247N/A static short endian = 1;
1247N/A
1247N/A if (!mga_wait_fifo(11))
1247N/A return (0);
1247N/A
1247N/A switch (mga_info.mga_depth) {
1247N/A case 8:
1247N/A maccess = MGA_MACCESS_PWIDTH_PW8;
1247N/A break;
1247N/A
1247N/A case 15:
1247N/A case 16:
1247N/A maccess = MGA_MACCESS_PWIDTH_PW16;
1247N/A if (!*(char const *)&endian) /* big endian */
1247N/A opmode = MGA_OPMODE_DIRDATASIZ_16BPP;
1247N/A break;
1247N/A
1247N/A case 24:
1247N/A maccess = MGA_MACCESS_PWIDTH_PW24;
1247N/A break;
1247N/A
1247N/A case 32:
1247N/A maccess = MGA_MACCESS_PWIDTH_PW32;
1247N/A if (!*(char const *)&endian) /* big endian */
1247N/A opmode = MGA_OPMODE_DIRDATASIZ_32BPP;
1247N/A break;
1247N/A }
1247N/A
1247N/A mga_put_uint32(&mgaptr->mga_maccess, maccess);
1247N/A mga_put_uint32(&mgaptr->mga_opmode, opmode);
1247N/A mga_put_uint32(&mgaptr->mga_pitch, mga_info.mga_linesize /
1247N/A mga_info.mga_pixelsize);
1247N/A mga_put_uint32(&mgaptr->mga_dstorg, 0);
1247N/A mga_put_uint32(&mgaptr->mga_ydstorg, 0);
1247N/A mga_put_uint32(&mgaptr->mga_cxbndry, (mga_info.mga_width - 1) << 16);
1247N/A mga_put_uint32(&mgaptr->mga_ytop, 0);
1247N/A mga_put_uint32(&mgaptr->mga_ybot, (mga_info.mga_height - 1) *
1247N/A mga_info.mga_linesize);
1247N/A mga_put_uint32(&mgaptr->mga_plnwt, 0xffffffff);
1247N/A mga_put_uint32(&mgaptr->mga_fcol, 0);
1247N/A mga_put_uint32(&mgaptr->mga_bcol, 0xffffffff);
1247N/A
1247N/A return (1);
1247N/A}
1247N/A
1247N/A
1247N/Avoid
1247N/Amga_save_palet(
1247N/A void)
1247N/A{
1247N/A register mga_t volatile *const mgaptr = mga_info.mga_control_ptr;
1247N/A register uint_t coloron;
1247N/A register uint8_t const save_palrdadd = mgaptr->mga_palrdadd;
1247N/A
1247N/A mgaptr->mga_palrdadd = 0;
1247N/A
1247N/A for (coloron = 0; coloron < 256; coloron++) {
1247N/A mga_info.mga_red[coloron] = mgaptr->mga_paldata;
1247N/A mga_info.mga_green[coloron] = mgaptr->mga_paldata;
1247N/A mga_info.mga_blue[coloron] = mgaptr->mga_paldata;
1247N/A }
1247N/A
1247N/A mgaptr->mga_palrdadd = save_palrdadd;
1247N/A}
1247N/A
1247N/A
1247N/Aint
1247N/Amga_set_palet(
1247N/A void)
1247N/A{
1247N/A register mga_t volatile *const mgaptr = mga_info.mga_control_ptr;
1247N/A register uint_t coloron;
1247N/A register uint8_t save_palwtadd;
1247N/A uchar_t new_red[256];
1247N/A uchar_t new_green[256];
1247N/A uchar_t new_blue[256];
1247N/A
1247N/A switch (mga_info.mga_depth) {
1247N/A case 8: /* 3, 3, 2 */
1247N/A for (coloron = 0; coloron < 256; coloron++) {
1247N/A new_red[coloron] =
1247N/A (uint8_t)(((coloron >> 5) & 0x7) * 255 / 7);
1247N/A new_green[coloron] =
1247N/A (uint8_t)(((coloron >> 2) & 0x7) * 255 / 7);
1247N/A new_blue[coloron] =
1247N/A (uint8_t)((coloron & 0x3) * 255 / 3);
1247N/A }
1247N/A break;
1247N/A
1247N/A case 15: /* 5, 5, 5 */
1247N/A for (coloron = 0; coloron < 256; coloron++) {
1247N/A new_red[coloron] =
1247N/A (uint8_t)((coloron & 0x1f) * 255 / 31);
1247N/A new_green[coloron] =
1247N/A (uint8_t)((coloron & 0x1f) * 255 / 31);
1247N/A new_blue[coloron] =
1247N/A (uint8_t)((coloron & 0x1f) * 255 / 31);
1247N/A }
1247N/A break;
1247N/A
1247N/A case 16: /* 5, 6, 5 */
1247N/A for (coloron = 0; coloron < 256; coloron++) {
1247N/A new_red[coloron] =
1247N/A (uint8_t)((coloron & 0x1f) * 255 / 31);
1247N/A new_green[coloron] =
1247N/A (uint8_t)((coloron & 0x3f) * 255 / 63);
1247N/A new_blue[coloron] =
1247N/A (uint8_t)((coloron & 0x1f) * 255 / 31);
1247N/A }
1247N/A break;
1247N/A
1247N/A default: /* 8, 8, 8 */
1247N/A for (coloron = 0; coloron < 256; coloron++) {
1247N/A new_red[coloron] = (uint8_t) coloron;
1247N/A new_green[coloron] = (uint8_t) coloron;
1247N/A new_blue[coloron] = (uint8_t) coloron;
1247N/A }
1247N/A break;
1247N/A }
1247N/A
1247N/A /* Don't set the palet if it matches what we will set. */
1247N/A
1247N/A for (coloron = 0; coloron < 256; coloron++) {
1247N/A if ((mga_info.mga_red[coloron] != new_red[coloron]) ||
1247N/A (mga_info.mga_green[coloron] != new_green[coloron]) ||
1247N/A (mga_info.mga_blue[coloron] != new_blue[coloron]))
1247N/A break;
1247N/A }
1247N/A
1247N/A if (coloron == 256)
1247N/A return (0);
1247N/A
1247N/A mga_info.mga_palet_changed = 1;
1247N/A save_palwtadd = mgaptr->mga_palwtadd;
1247N/A
1247N/A mgaptr->mga_palwtadd = 0;
1247N/A
1247N/A for (coloron = 0; coloron < 256; coloron++) {
1247N/A mgaptr->mga_paldata = new_red[coloron];
1247N/A mgaptr->mga_paldata = new_green[coloron];
1247N/A mgaptr->mga_paldata = new_blue[coloron];
1247N/A }
1247N/A
1247N/A mgaptr->mga_palwtadd = save_palwtadd;
1247N/A return (1);
1247N/A}
1247N/A
1247N/A
1247N/Aint
1247N/Amga_restore_palet(
1247N/A void)
1247N/A{
1247N/A register mga_t volatile *const mgaptr = mga_info.mga_control_ptr;
1247N/A register uint_t coloron;
1247N/A register uint8_t save_palwtadd;
1247N/A
1247N/A if (!mga_info.mga_palet_changed)
1247N/A return (0);
1247N/A
1247N/A save_palwtadd = mgaptr->mga_palwtadd;
1247N/A
1247N/A mgaptr->mga_palwtadd = 0;
1247N/A
1247N/A for (coloron = 0; coloron < 256; coloron++) {
1247N/A mgaptr->mga_paldata = mga_info.mga_red[coloron];
1247N/A mgaptr->mga_paldata = mga_info.mga_green[coloron];
1247N/A mgaptr->mga_paldata = mga_info.mga_blue[coloron];
1247N/A }
1247N/A
1247N/A mgaptr->mga_palwtadd = save_palwtadd;
1247N/A
1247N/A mga_info.mga_palet_changed = 0;
1247N/A return (1);
1247N/A}
1247N/A
1247N/A
1247N/Auint_t
1247N/Amga_color(
1247N/A register uint_t const red,
1247N/A register uint_t const green,
1247N/A register uint_t const blue)
1247N/A{
1247N/A register uint_t value;
1247N/A
1247N/A switch (mga_info.mga_depth) {
1247N/A case 8: /* 3, 3, 2 */
1247N/A value = ((red >> 5) & 0x7) << 5;
1247N/A value |= ((green >> 5) & 0x7) << 2;
1247N/A value |= (blue >> 6) & 0x3;
1247N/A break;
1247N/A
1247N/A case 15: /* 5, 5, 5 */
1247N/A value = ((red >> 3) & 0x1f) << 10;
1247N/A value |= ((green >> 3) & 0x1f) << 5;
1247N/A value |= (blue >> 3) & 0x1f;
1247N/A break;
1247N/A
1247N/A case 16: /* 5, 6, 5 */
1247N/A value = ((red >> 3) & 0x1f) << 11;
1247N/A value |= ((green >> 2) & 0x3f) << 5;
1247N/A value |= (blue >> 3) & 0x1f;
1247N/A break;
1247N/A
1247N/A default: /* 8, 8, 8 */
1247N/A value = (red & 0xff) << 16;
1247N/A value |= (green & 0xff) << 8;
1247N/A value |= blue & 0xff;
1247N/A break;
1247N/A }
1247N/A
1247N/A return (value);
1247N/A}
1247N/A
1247N/Avoid
1247N/Amga_finish_graphics(
1247N/A void)
1247N/A{
1247N/A register mga_t volatile *const mgaptr = mga_info.mga_control_ptr;
1247N/A
1247N/A mga_put_uint32(&mgaptr->mga_opmode, mga_info.mga_opmode);
1247N/A}
1247N/A
1247N/A
1247N/Aint
1247N/Amga_fill_solid_rect(
1247N/A register int const x1,
1247N/A register int const y1,
1247N/A register int const x2,
1247N/A register int const y2,
1247N/A register uint_t const fg)
1247N/A{
1247N/A register mga_t volatile *const mgaptr = mga_info.mga_control_ptr;
1247N/A
1247N/A if (!mga_wait_fifo(5))
1247N/A return (0);
1247N/A
1247N/A mga_put_uint32(&mgaptr->mga_fcol, fg);
1247N/A mga_put_uint32(&mgaptr->mga_plnwt, 0xffffffff);
1247N/A mga_put_uint32(&mgaptr->mga_dwgctl,
1247N/A MGA_DWGCTL_BOP_COPY | MGA_DWGCTL_SHFTZERO |
1247N/A MGA_DWGCTL_SGNZERO | MGA_DWGCTL_ARZERO |
1247N/A MGA_DWGCTL_SOLID | MGA_DWGCTL_ZMODE_NOZCMP |
1247N/A MGA_DWGCTL_ATYPE_RPL | MGA_DWGCTL_OPCOD_TRAP);
1247N/A mga_put_uint32(&mgaptr->mga_fxbndry,
1247N/A (x2 << 16) | (x1 & 0xffff));
1247N/A mga_put_uint32(&mgaptr->mga_draw_ydstlen,
1247N/A (y1 << 16) | ((y2 - y1) & 0xffff));
1247N/A
1247N/A return (1);
1247N/A}
1247N/A
1247N/A
1247N/Aint
1247N/Amga_fill_pattern_rect(
1247N/A register int const x1,
1247N/A register int const y1,
1247N/A register int const x2,
1247N/A register int const y2,
1247N/A register uint_t const bg,
1247N/A register uint_t const fg,
1247N/A register uint64_t const pat)
1247N/A{
1247N/A register mga_t volatile *const mgaptr = mga_info.mga_control_ptr;
1247N/A register int const width = x2 - x1;
1247N/A register int const height = y2 - y1;
1247N/A register int x;
1247N/A register int y;
1247N/A register uint32_t value;
1247N/A register uint32_t iloadon = 0;
1247N/A register uint32_t volatile *iloadptr =
1247N/A (uint32_t volatile *) mga_info.mga_iload_ptr;
1247N/A register int status;
1247N/A
1247N/A if (!mga_wait_fifo(11))
1247N/A return (0);
1247N/A
1247N/A mga_put_uint32(&mgaptr->mga_opmode, MGA_OPMODE_DIRDATASIZ_8BPP |
1247N/A MGA_OPMODE_DMADATASIZ_8BPP | MGA_OPMODE_DMAMOD_BLIT);
1247N/A mga_put_uint32(&mgaptr->mga_plnwt, 0xffffffff);
1247N/A mga_put_uint32(&mgaptr->mga_shift, 0);
1247N/A mga_put_uint32(&mgaptr->mga_bcol, bg);
1247N/A mga_put_uint32(&mgaptr->mga_fcol, fg);
1247N/A mga_put_uint32(&mgaptr->mga_dwgctl,
1247N/A MGA_DWGCTL_BLTMOD_BMONOLEF | MGA_DWGCTL_BOP_COPY |
1247N/A MGA_DWGCTL_SHFTZERO | MGA_DWGCTL_SGNZERO |
1247N/A MGA_DWGCTL_ZMODE_NOZCMP | MGA_DWGCTL_LINEAR |
1247N/A MGA_DWGCTL_ATYPE_RSTR | MGA_DWGCTL_OPCOD_ILOAD);
1247N/A mga_put_uint32(&mgaptr->mga_ar0, ((width + 31) / 32 * 32) *
1247N/A height - 1);
1247N/A mga_put_uint32(&mgaptr->mga_ar3, 0);
1247N/A mga_put_uint32(&mgaptr->mga_ar5, (width + 31) / 32);
1247N/A mga_put_uint32(&mgaptr->mga_fxbndry,
1247N/A ((x2 - 1) << 16) | (x1 & 0xffff));
1247N/A mga_put_uint32(&mgaptr->mga_draw_ydstlen,
1247N/A (y1 << 16) | (height & 0xffff));
1247N/A
1247N/A for (y = 0; y < height; y++) {
1247N/A value = 0;
1247N/A
1247N/A for (x = 0; x < width; x++) {
1247N/A value |= ((pat >> (((y + y1) & 7) * 8 +
1247N/A ((x + x1) & 7))) & 1) << (x & 0x1f);
1247N/A
1247N/A if ((x & 0x1f) == 0x1f || x == width - 1) {
1247N/A mga_put_uint32(iloadptr, value);
1247N/A
1247N/A iloadon += sizeof (uint32_t);
1247N/A if (iloadon < mga_info.mga_iload_size)
1247N/A iloadptr++;
1247N/A else {
1247N/A iloadon = 0;
1247N/A iloadptr = (uint32_t volatile *)
1247N/A mga_info.mga_iload_ptr;
1247N/A }
1247N/A value = 0;
1247N/A }
1247N/A }
1247N/A }
1247N/A
1247N/A status = mga_wait_idle();
1247N/A return (status);
1247N/A}
1247N/A
1247N/A
1247N/Aint
1247N/Amga_draw_solid_line(
1247N/A register int const x1,
1247N/A register int const y1,
1247N/A register int const x2,
1247N/A register int const y2,
1247N/A register uint_t const fg)
1247N/A{
1247N/A register mga_t volatile *const mgaptr = mga_info.mga_control_ptr;
1247N/A
1247N/A if (!mga_wait_fifo(5))
1247N/A return (0);
1247N/A
1247N/A mga_put_uint32(&mgaptr->mga_fcol, fg);
1247N/A mga_put_uint32(&mgaptr->mga_plnwt, 0xffffffff);
1247N/A mga_put_uint32(&mgaptr->mga_dwgctl,
1247N/A MGA_DWGCTL_BOP_COPY | MGA_DWGCTL_SOLID |
1247N/A MGA_DWGCTL_ZMODE_NOZCMP | MGA_DWGCTL_ATYPE_RPL |
1247N/A MGA_DWGCTL_OPCOD_AUTOLINE_CLOSE);
1247N/A mga_put_uint32(&mgaptr->mga_xystrt, x1 | (y1 << 16));
1247N/A mga_put_uint32(&mgaptr->mga_draw_xyend, x2 | (y2 << 16));
1247N/A
1247N/A return (1);
1247N/A}
1247N/A
1247N/A
1247N/Aint
1247N/Amga_wait_fifo(
1247N/A register int const fifocount)
1247N/A{
1247N/A register mga_t volatile *const mgaptr = mga_info.mga_control_ptr;
1247N/A register uint32_t fifostatus;
1247N/A register hrtime_t starttime;
1247N/A register hrtime_t curtime;
1247N/A register hrtime_t endtime;
1247N/A register ulong_t count = 0;
1247N/A
1247N/A starttime = gethrtime();
1247N/A endtime = starttime + mga_loop_time;
1247N/A
1247N/A do {
1247N/A count++;
1247N/A fifostatus = mga_get_uint32(&mgaptr->mga_fifostatus);
1247N/A if ((fifostatus & MGA_FIFOSTATUS_FIFOCOUNT_MASK) >= fifocount)
1247N/A break;
1247N/A curtime = gethrtime();
1247N/A } while (curtime < endtime);
1247N/A
1247N/A if ((fifostatus & MGA_FIFOSTATUS_FIFOCOUNT_MASK) < fifocount) {
1247N/A count++;
1247N/A fifostatus = mga_get_uint32(&mgaptr->mga_fifostatus);
1247N/A }
1247N/A
1247N/A if ((fifostatus & MGA_FIFOSTATUS_FIFOCOUNT_MASK) < fifocount)
1247N/A return (0);
1247N/A
1247N/A return (1);
1247N/A}
1247N/A
1247N/A
1247N/Aint
1247N/Amga_wait_idle(
1247N/A void)
1247N/A{
1247N/A register mga_t volatile *const mgaptr = mga_info.mga_control_ptr;
1247N/A register uint32_t fifostatus;
1247N/A register hrtime_t starttime;
1247N/A register hrtime_t curtime;
1247N/A register hrtime_t endtime;
1247N/A register ulong_t count = 0;
1247N/A
1247N/A starttime = gethrtime();
1247N/A endtime = starttime + mga_loop_time;
1247N/A
1247N/A do {
1247N/A count++;
1247N/A fifostatus = mga_get_uint32(&mgaptr->mga_fifostatus);
1247N/A if (fifostatus & MGA_FIFOSTATUS_BEMPTY)
1247N/A break;
1247N/A curtime = gethrtime();
1247N/A } while (curtime < endtime);
1247N/A
1247N/A if (!(fifostatus & MGA_FIFOSTATUS_BEMPTY)) {
1247N/A count++;
1247N/A fifostatus = mga_get_uint32(&mgaptr->mga_fifostatus);
1247N/A }
1247N/A
1247N/A if (!(fifostatus & MGA_FIFOSTATUS_BEMPTY))
1247N/A return (0);
1247N/A
1247N/A return (1);
1247N/A}
1247N/A
1247N/A
1247N/Aint
1247N/Amga_unmap_mem(
1247N/A register return_packet *const rp,
1247N/A register int const test)
1247N/A{
1247N/A if (mga_unmap_fb() != 0) {
1247N/A gfx_vts_set_message(rp, 1, test, "unmap framebuffer failed");
1247N/A return (-1);
1247N/A }
1247N/A
1247N/A if (mga_unmap_control() != 0) {
1247N/A gfx_vts_set_message(rp, 1, test, "unmap control failed");
1247N/A return (-1);
1247N/A }
1247N/A
1247N/A if (mga_unmap_iload() != 0) {
1247N/A gfx_vts_set_message(rp, 1, test, "unmap iload failed");
1247N/A return (-1);
1247N/A }
1247N/A
1247N/A return (0);
1247N/A}
1247N/A
1247N/Aint
1247N/Amga_unmap_fb(
1247N/A void)
1247N/A{
1247N/A register int status;
1247N/A
1247N/A if (mga_info.mga_fb_ptr == NULL)
1247N/A return (0);
1247N/A
1247N/A status = munmap((char *) mga_info.mga_fb_ptr, mga_info.mga_fb_size);
1247N/A mga_info.mga_fb_ptr = NULL;
1247N/A
1247N/A return (status);
1247N/A}
1247N/A
1247N/A
1247N/Aint
1247N/Amga_unmap_control(
1247N/A void)
1247N/A{
1247N/A register int status;
1247N/A
1247N/A if (mga_info.mga_control_ptr == NULL)
1247N/A return (0);
1247N/A
1247N/A status = munmap((char *) mga_info.mga_control_ptr,
1247N/A mga_info.mga_control_size);
1247N/A mga_info.mga_control_ptr = NULL;
1247N/A
1247N/A return (status);
1247N/A}
1247N/A
1247N/A
1247N/Aint
1247N/Amga_unmap_iload(
1247N/A void)
1247N/A{
1247N/A register int status;
1247N/A
1247N/A if (mga_info.mga_iload_ptr == NULL)
1247N/A return (0);
1247N/A
1247N/A status = munmap((char *) mga_info.mga_iload_ptr,
1247N/A mga_info.mga_iload_size);
1247N/A mga_info.mga_iload_ptr = NULL;
1247N/A
1247N/A return (status);
1247N/A}
1247N/A
1247N/Auint32_t
1247N/Amga_get_uint32(
1247N/A register uint32_t volatile const *const uint32ptr)
1247N/A{
1247N/A register uint32_t value = *uint32ptr;
1247N/A
1247N/A if (!mga_big_endian)
1247N/A return (value);
1247N/A
1247N/A else
1247N/A return (((value & 0xff) << 24) |
1247N/A ((value & 0xff00) << 8) |
1247N/A ((value & 0xff0000) >> 8) |
1247N/A ((value & 0xff000000) >> 24));
1247N/A}
1247N/A
1247N/Avoid
1247N/Amga_put_uint32(
1247N/A register uint32_t volatile *const uint32ptr,
1247N/A register uint32_t const value)
1247N/A{
1247N/A register uint32_t newvalue;
1247N/A
1247N/A if (!mga_big_endian)
1247N/A newvalue = value;
1247N/A else
1247N/A newvalue = ((value & 0xff) << 24) |
1247N/A ((value & 0xff00) << 8) |
1247N/A ((value & 0xff0000) >> 8) |
1247N/A ((value & 0xff000000) >> 24);
1247N/A
1247N/A *uint32ptr = newvalue;
1247N/A}