open-src/app/gfx-utils/sun-src/vts/efb/tools.c
changeset 1368 475ce9398539
parent 1117 629ac4b133bc
--- a/open-src/app/gfx-utils/sun-src/vts/efb/tools.c	Wed Sep 18 11:01:17 2013 -0700
+++ b/open-src/app/gfx-utils/sun-src/vts/efb/tools.c	Tue Sep 24 14:01:59 2013 -0700
@@ -1,6 +1,5 @@
-
 /*
- * Copyright (c) 2006, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -22,318 +21,753 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
-#include <sys/types.h>
-#include <stdio.h>
-#include <sys/mman.h>
-
-#include "gfx_common.h"		/* GFX Common definitions */
-#include "graphicstest.h"
 #include "libvtsSUNWefb.h"	/* Common VTS library definitions */
-
-#include "X11/Xlib.h"
-#include "gfx_vts.h"		/* VTS Graphics Test common routines */
 #include "efb.h"
 
 
 int
-efb_get_pci_info(int fd, struct pci_info *pciInfo)
+efb_map_mem(
+    register return_packet *const rp,
+    register int const test)
 {
-	struct gfx_pci_cfg pciCfg;
-	int i;
-	unsigned int bar;
+	register int const pagesize = getpagesize();
+
+	if (efb_get_pci_info() != 0) {
+		gfx_vts_set_message(rp, 1, test, "get pci info failed");
+		return (-1);
+	}
 
-	if (ioctl(fd, GFX_IOCTL_GET_PCI_CONFIG, &pciCfg) == -1) {
-		return -1;
+	/*
+	 * Map MMIO
+	 */
+	efb_info.efb_mmio_size = (efb_info.efb_mmio_size + pagesize - 1) /
+	    pagesize * pagesize;
+
+	if (efb_map_mmio() != 0) {
+		gfx_vts_set_message(rp, 1, test, "map MMIO failed");
+		return (-1);
 	}
 
-        pciInfo->deviceID = pciCfg.DeviceID;
+	switch (efb_info.efb_device) {
+	case 20825:
+	case 20830:
+	case 23396:
+		efb_info.efb_fb_size = REGR(RADEON_CONFIG_MEMSIZE);
+		break;
+	default:
+		efb_info.efb_fb_size = REGR(R600_CONFIG_MEMSIZE);
+		break;
+	}
+	efb_info.efb_fb_size = (efb_info.efb_fb_size + (pagesize - 1)) /
+	    pagesize * pagesize;
+
+	/*
+	 * Map framebuffer
+	 */
+
+	if (efb_map_fb() != 0) {
+		gfx_vts_set_message(rp, 1, test, "map framebuffer failed");
+		return (-1);
+	}
+
+	return (0);
+}
+
+int
+efb_get_pci_info(
+    void)
+{
+	struct gfx_pci_cfg pciconfig;
+	int i;
+	uint_t bar;
+	uint_t bar_hi;
+	offset_t mem_base[6];
+	offset_t io_base[6];
+	int type[6];
+
+	if (ioctl(efb_info.efb_fd, GFX_IOCTL_GET_PCI_CONFIG,
+	    &pciconfig) != 0) {
+		return (-1);
+	}
+
+	efb_info.efb_vendor = pciconfig.VendorID;
+	efb_info.efb_device = pciconfig.DeviceID;
 
 	for (i = 0; i < 6; i++) {
-	    bar = pciCfg.bar[i];
-	    if (bar != 0) {
-		if (bar & PCI_MAP_IO) {
-		    pciInfo->ioBase[i] = PCIGETIO(bar);
-		    pciInfo->type[i] = bar & PCI_MAP_IO_ATTR_MASK;
-		} else {
-		    pciInfo->type[i] = bar & PCI_MAP_MEMORY_ATTR_MASK;
-		    pciInfo->memBase[i] = PCIGETMEMORY(bar);
-		    if (PCI_MAP_IS64BITMEM(bar)) {
-			if (i == 5) {
-			    pciInfo->memBase[i] = 0;
+		type[i] = 0;
+		mem_base[i] = 0;
+		io_base[i] = 0;
+	}
+
+	for (i = 0; i < 6; i++) {
+		bar = pciconfig.bar[i];
+		if (bar != 0) {
+			if (bar & PCI_MAP_IO) {
+				io_base[i] = PCIGETIO(bar);
+				type[i] = bar & PCI_MAP_IO_ATTR_MASK;
 			} else {
-			    int bar_hi = pciCfg.bar[i+1];
-			    pciInfo->memBase[i] |= (bar_hi << 32);
-			    ++i;
+				type[i] = bar & PCI_MAP_MEMORY_ATTR_MASK;
+				mem_base[i] = PCIGETMEMORY(bar);
+				if (PCI_MAP_IS64BITMEM(bar)) {
+					if (i == 5) {
+						mem_base[i] = 0;
+					} else {
+						bar_hi = pciconfig.bar[i+1];
+						mem_base[i] |=
+						    ((offset_t)bar_hi << 32);
+						++i;
+					}
+				}
 			}
-		    }
-		    pciInfo->size[i] = EFB_REG_SIZE_LOG2;
 		}
-	    }
 	}
 
-	return 0;
+	efb_info.efb_fb_addr = mem_base[0] & 0xfff00000;
+	efb_info.efb_fb_size = 0;
+
+	efb_info.efb_mmio_addr = mem_base[2] & 0xffff0000;
+	efb_info.efb_mmio_size = 1 << EFB_REG_SIZE_LOG2;
+
+	if (gfx_vts_debug_mask & VTS_DEBUG) {
+		printf("efb_vendor = 0x%04x, efb_device = 0x%04x\n",
+		    efb_info.efb_vendor, efb_info.efb_device);
+		printf("efb_fb_addr 0x%llx, efb_fb_size 0x%lx\n",
+		    (unsigned long long)efb_info.efb_fb_addr,
+		    (unsigned long)efb_info.efb_fb_size);
+		printf("efb_mmio_addr 0x%llx, efb_mmio_size 0x%lx\n",
+		    (unsigned long long)efb_info.efb_mmio_addr,
+		    (unsigned long)efb_info.efb_mmio_size);
+	}
+
+	return (0);
+}
+
+int
+efb_map_mmio(
+    void)
+{
+	register void *ptr;
+
+	if (efb_info.efb_mmio_ptr == NULL) {
+		ptr = mmap(NULL, efb_info.efb_mmio_size,
+		    PROT_READ | PROT_WRITE, MAP_SHARED,
+		    efb_info.efb_fd, efb_info.efb_mmio_addr);
+
+		if (ptr == MAP_FAILED)
+			return (-1);
+	}
+
+	efb_info.efb_mmio_ptr = (uchar_t *)ptr;
+
+	if (gfx_vts_debug_mask & VTS_DEBUG)
+		printf("efb_mmio_ptr = 0x%llx\n",
+		    (unsigned long long)efb_info.efb_mmio_ptr);
+
+	return (0);
 }
 
 int
-efb_get_mem_info(struct pci_info *pci_info, struct efb_info *pEFB) 
+efb_map_fb(
+    void)
 {
-	unsigned char reg;
+	register void *ptr;
+
+	if (efb_info.efb_fb_ptr == NULL) {
+		ptr = mmap(NULL, efb_info.efb_fb_size,
+		    PROT_READ | PROT_WRITE, MAP_SHARED,
+		    efb_info.efb_fd, efb_info.efb_fb_addr);
+
+		if (ptr == MAP_FAILED)
+			return (-1);
+
+		efb_info.efb_fb_ptr = (uchar_t *)ptr;
+	}
+
+	if (gfx_vts_debug_mask & VTS_DEBUG)
+		printf("efb_fb_ptr = 0x%llx\n",
+		    (unsigned long long)efb_info.efb_fb_ptr);
+
+	return (0);
+}
+
 
-	pEFB->FBPhysAddr = pci_info->memBase[0] & 0xfff00000;
-	pEFB->FBMapSize = 0;
+int
+efb_init_info(
+    register return_packet *const rp,
+    register int const test)
+{
+	register uint32_t crtc_h_total_disp;
+	register uint32_t crtc_v_total_disp;
+	register uint32_t crtc_gen_cntl;
+	register uint32_t crtc_pitch;
+	register uint_t width;
+	register uint_t height;
+	register uint_t depth;
+	register uint_t pixelsize;
+	register uint_t pitch;
+
+	/* Get the gen cntl */
+
+	crtc_gen_cntl = REGR(CRTC_GEN_CNTL);
+
+	/* Get the horizontal total display end */
+
+	crtc_h_total_disp = REGR(CRTC_H_TOTAL_DISP);
+
+	/* Get the vertical total display end */
 
-	pEFB->MMIOPhysAddr = pci_info->memBase[2] & 0xffff0000;
-	pEFB->MMIOMapSize =  1 << pci_info->size[2];
+	crtc_v_total_disp = REGR(CRTC_V_TOTAL_DISP);
+
+	/* Get the pitch */
+
+	crtc_pitch = REGR(CRTC_PITCH);
+
+	/* Compute the width. */
+
+	width = (((crtc_h_total_disp & CRTC_H_TOTAL_DISP__CRTC_H_DISP_MASK) >>
+	    CRTC_H_TOTAL_DISP__CRTC_H_DISP__SHIFT) + 1) * 8;
+
+	/* Compute the height. */
+
+	height = ((crtc_v_total_disp & CRTC_V_TOTAL_DISP__CRTC_V_DISP_MASK) >>
+	    CRTC_V_TOTAL_DISP__CRTC_V_DISP__SHIFT) + 1;
+
+	if (crtc_gen_cntl & CRTC_GEN_CNTL__CRTC_INTERLACE_EN_MASK)
+		height *= 2;
+
+	/* Compute the pitch */
+
+	pitch = crtc_pitch & CRTC_PITCH__CRTC_PITCH_MASK;
+
+	/* Compute the depth. */
+
+	switch ((crtc_gen_cntl & CRTC_GEN_CNTL__CRTC_PIX_WIDTH_MASK) >>
+	    CRTC_GEN_CNTL__CRTC_PIX_WIDTH__SHIFT) {
 
-	pEFB->RelocateIO = pci_info->ioBase[1];
+	case 2:
+		depth = 8;
+		pixelsize = 1;
+		pitch *= 8;
+		break;
+
+	case 3:
+		depth = 15;
+		pixelsize = 2;
+		pitch *= 16;
+		break;
+
+	case 4:
+		depth = 16;
+		pixelsize = 2;
+		pitch *= 16;
+		break;
 
-	pEFB->ChipSet = pci_info->deviceID;
+	case 5:
+		depth = 24;
+		pixelsize = 3;
+		pitch *= 24;
+		break;
+
+	case 6:
+		depth = 32;
+		pixelsize = 4;
+		pitch *= 32;
+		break;
+
+	default:
+		gfx_vts_set_message(rp, 1, test, "unsupported depth");
+		return (-1);
+	}
+
+	efb_info.efb_width = width;
+	efb_info.efb_height = height;
+	efb_info.efb_depth = depth;
+	efb_info.efb_pixelsize = pixelsize;
+	efb_info.efb_linesize = pitch;
 
-#ifdef DEBUG
-	printf("FBPhysAddr=0x%x FBMapSize=0x%x\n", pEFB->FBPhysAddr, pEFB->FBMapSize);
-	printf("MMIOPhysAddr=0x%x MMIOMapSize=0x%x\n", pEFB->MMIOPhysAddr, pEFB->MMIOMapSize);
-	printf("RelocateIO=0x%x\n", pEFB->RelocateIO);
-#endif
+	if (gfx_vts_debug_mask & VTS_DEBUG) {
+		printf("width=%d height=%d depth=%d pitch=%d\n",
+		    efb_info.efb_width, efb_info.efb_height,
+		    efb_info.efb_depth, efb_info.efb_linesize);
+	}
+	return (0);
+}
+
+int
+efb_unmap_mem(
+    register return_packet *const rp,
+    register int const test)
+{
+	if (efb_unmap_fb() != 0) {
+		gfx_vts_set_message(rp, 1, test, "unmap framebuffer failed");
+		return (-1);
+	}
 
-	return 0;
+	if (efb_unmap_mmio() != 0) {
+		gfx_vts_set_message(rp, 1, test, "unmap MMIO failed");
+		return (-1);
+	}
+
+	return (0);
+}
+
+
+int
+efb_unmap_fb(
+    void)
+{
+	register int status;
+
+	if (efb_info.efb_fb_ptr == NULL)
+		return (0);
+
+	status = munmap((char *)efb_info.efb_fb_ptr, efb_info.efb_fb_size);
+	efb_info.efb_fb_ptr = NULL;
+
+	return (status);
 }
 
 
 int
-efb_init_info(struct efb_info *pEFB)
+efb_unmap_mmio(
+    void)
 {
-	unsigned int v, v2;
-	unsigned int status = 0;
-
-        
-#if 0
-	/* 
-	 * first check if the hardware is already initialized.
-	 * If not, abort
-	 */
-	ioctl(pEFB->fd, EFB_GET_STATUS_FLAGS, &status);
-	if (!(status & EFB_STATUS_HW_INITIALIZED))
-		return -1;
-#endif
-
+	register int status;
 
-        v = REGR(CRTC_GEN_CNTL);
-	v2 = (v & CRTC_GEN_CNTL__CRTC_PIX_WIDTH_MASK) >> CRTC_GEN_CNTL__CRTC_PIX_WIDTH__SHIFT;
-	if (v2 <= 2)
-        	pEFB->bitsPerPixel = 8;
-	else if (v2 <= 4)
-		pEFB->bitsPerPixel = 16;
-	else 
-		pEFB->bitsPerPixel = 32;
-
-
-        v = REGR(CRTC_H_TOTAL_DISP);
-	v2 = (v & CRTC_H_TOTAL_DISP__CRTC_H_DISP_MASK) >> CRTC_H_TOTAL_DISP__CRTC_H_DISP__SHIFT;
-	pEFB->screenWidth = (v2 + 1) * 8;
+	if (efb_info.efb_mmio_ptr == NULL)
+		return (0);
 
-        v = REGR(CRTC_V_TOTAL_DISP);
-	v2 = (v & CRTC_V_TOTAL_DISP__CRTC_V_DISP_MASK) >> CRTC_V_TOTAL_DISP__CRTC_V_DISP__SHIFT;
-	pEFB->screenHeight = (v2 + 1);
-	pEFB->screenPitch = pEFB->screenWidth * pEFB->bitsPerPixel / 8;
-
+	status = munmap((char *)efb_info.efb_mmio_ptr,
+	    efb_info.efb_mmio_size);
+	efb_info.efb_mmio_ptr = NULL;
 
-	pEFB->fbLocation = REGR(RADEON_MC_FB_LOCATION);
-
-#ifdef DEBUG
-	printf("bpp=%d width=%d height=%d pitch=%d fbLoc=0x%x\n", 
-		pEFB->bitsPerPixel, pEFB->screenWidth, pEFB->screenHeight, pEFB->screenPitch, 
-		pEFB->fbLocation);
-#endif
-	return 0;
+	return (status);
 }
 
 int
-efb_map_mem(struct efb_info *pEFB, return_packet *rp, int test)
+efb_init_graphics(void)
 {
-        struct pci_info  pci_info;
-        int              pageSize, size;
-	int		 fd = pEFB->fd;
+	uint_t pitch_offset;
+	uint_t pitch;
+	uint_t offset;
+	uint_t gmc_bpp;
+	uint_t v;
+
+	switch (efb_info.efb_depth) {
+	case 8:
+		gmc_bpp = GMC_DST_8BPP;
+		break;
+	case 15:
+		gmc_bpp = GMC_DST_15BPP;
+		break;
+
+	case 16:
+		gmc_bpp = GMC_DST_16BPP;
+		break;
+
+	case 24:
+		gmc_bpp = GMC_DST_24BPP;
+		break;
+
+	case 32:
+		gmc_bpp = GMC_DST_32BPP;
+		break;
+	}
+
+	offset = REGR(CRTC_OFFSET) & 0x7ffffff;
+	pitch = REGR(CRTC_PITCH) & 0x7ff;
+
+	pitch = pitch * 8;	/* was in groups of 8 pixels */
+
+	pitch_offset =
+	    ((pitch * efb_info.efb_pixelsize / 64) << 22) |
+	    (offset / 1024);
+
+	/*
+	 * Initialize GUI engine
+	 */
+	if (!efb_wait_idle())
+		return (0);
 
-        if (efb_get_pci_info(fd, &pci_info) == -1) {
-            TraceMessage(VTS_DEBUG, __func__, "get pci info failed\n");
-            gfx_vts_set_message(rp, 1, test, "get pci info failed");
-            return -1;
-        }
+	if (!efb_wait_fifo(5))
+		return (0);
+
+	REGW(DEFAULT_PITCH_OFFSET, pitch_offset);
+	REGW(RADEON_DST_PITCH_OFFSET, pitch_offset);
+	REGW(RADEON_SRC_PITCH_OFFSET, pitch_offset);
+
+	REGW(DEFAULT_SC_BOTTOM_RIGHT,
+	    (efb_info.efb_height << 16) | (efb_info.efb_width));
+
+	v = (GMC_SRC_PITCH_OFFSET_DEFAULT |
+	    GMC_DST_PITCH_OFFSET_LEAVE |
+	    GMC_SRC_CLIP_DEFAULT |
+	    GMC_DST_CLIP_DEFAULT |
+	    GMC_BRUSH_SOLIDCOLOR |
+	    gmc_bpp |
+	    GMC_SRC_DSTCOLOR |
+	    RADEON_ROP3_P |
+	    GMC_WRITE_MASK_LEAVE);
+
+	REGW(RADEON_DP_GUI_MASTER_CNTL, v);
+
+#ifdef DEBUG
+	printf("v=0x%x\n", v);
+#endif
+	return (1);
+}
+
+
+void
+efb_save_palet(
+    void)
+{
+	register uint_t coloron;
+	register uint_t const save_palette_index =
+	    REGR(RADEON_PALETTE_INDEX);
+
+	REGW(RADEON_PALETTE_INDEX, 0);
+
+	for (coloron = 0; coloron < 256; coloron++)
+		efb_info.efb_palet[coloron] = REGR(RADEON_PALETTE_30_DATA);
+
+	REGW(RADEON_PALETTE_INDEX, save_palette_index);
+}
 
 
-        if (efb_get_mem_info(&pci_info, pEFB) == -1) {
-            TraceMessage(VTS_DEBUG, __func__, "get mem info failed\n");
-            gfx_vts_set_message(rp, 1, test, "get mem info failed");
-            return -1;
-        }
+int
+efb_set_palet(
+    void)
+{
+	register uint_t coloron;
+	register uint_t save_palette_index;
+	uint_t new_red;
+	uint_t new_green;
+	uint_t new_blue;
+	uint_t new_palet[256];
 
-        /*
-         * Map MMIO
-         */
-        pageSize = getpagesize();
-        size = pEFB->MMIOMapSize + (pageSize - 1) & (~(pageSize - 1));
-
-        pEFB->MMIOvaddr = (unsigned char *)mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED,
-                                        fd, pEFB->MMIOPhysAddr);
+	switch (efb_info.efb_depth) {
+	case 8:	/* 3, 3, 2 */
+		for (coloron = 0; coloron < 256; coloron++) {
+			new_red = ((coloron >> 5) & 0x7) * 1023 / 7;
+			new_green = ((coloron >> 2) & 0x7) * 1023 / 7;
+			new_blue = (coloron & 0x3) * 1023 / 3;
+			new_palet[coloron] =
+			    (new_red <<
+			    PALETTE_30_DATA__PALETTE_DATA_R__SHIFT) |
+			    (new_green <<
+			    PALETTE_30_DATA__PALETTE_DATA_G__SHIFT) |
+			    (new_blue <<
+			    PALETTE_30_DATA__PALETTE_DATA_B__SHIFT);
+		}
+		break;
 
-        if (pEFB->MMIOvaddr == MAP_FAILED) {
-            TraceMessage(VTS_DEBUG, __func__, "map MMIO failed\n");
-            gfx_vts_set_message(rp, 1, test, "map MMIO failed");
-            return -1;
-        }
-
-
+	case 15:	/* 5, 5, 5 */
+		for (coloron = 0; coloron < 256; coloron++) {
+			new_red = (coloron / 8) * 1023 / 31;
+			new_green = (coloron / 8) * 1023 / 31;
+			new_blue = (coloron / 8) * 1023 / 31;
+			new_palet[coloron] =
+			    (new_red <<
+			    PALETTE_30_DATA__PALETTE_DATA_R__SHIFT) |
+			    (new_green <<
+			    PALETTE_30_DATA__PALETTE_DATA_G__SHIFT) |
+			    (new_blue <<
+			    PALETTE_30_DATA__PALETTE_DATA_B__SHIFT);
+		}
+		break;
 
-	switch (pEFB->ChipSet) {
-	case 20825:
-	case 20830:
-	case 23396:
-		pEFB->FBMapSize = REGR(RADEON_CONFIG_MEMSIZE);
+	case 16:	/* 5, 6, 5 */
+		for (coloron = 0; coloron < 256; coloron++) {
+			new_red = (coloron / 8) * 1023 / 31;
+			new_green = (coloron / 4) * 1023 / 63;
+			new_blue = (coloron / 8) * 1023 / 31;
+			new_palet[coloron] =
+			    (new_red <<
+			    PALETTE_30_DATA__PALETTE_DATA_R__SHIFT) |
+			    (new_green <<
+			    PALETTE_30_DATA__PALETTE_DATA_G__SHIFT) |
+			    (new_blue <<
+			    PALETTE_30_DATA__PALETTE_DATA_B__SHIFT);
+		}
 		break;
-	default:
-		pEFB->FBMapSize = REGR(R600_CONFIG_MEMSIZE);
+
+	default:	/* 8, 8, 8 */
+		for (coloron = 0; coloron < 256; coloron++) {
+			new_red = (coloron * 1023) / 255;
+			new_green = (coloron * 1023) / 255;
+			new_blue = (coloron * 1023) / 255;
+			new_palet[coloron] =
+			    (new_red <<
+			    PALETTE_30_DATA__PALETTE_DATA_R__SHIFT) |
+			    (new_green <<
+			    PALETTE_30_DATA__PALETTE_DATA_G__SHIFT) |
+			    (new_blue <<
+			    PALETTE_30_DATA__PALETTE_DATA_B__SHIFT);
+		}
 		break;
 	}
-	
 
-        /*
-         * Map framebuffer
-         */
-        pageSize = getpagesize();
-        size = pEFB->FBMapSize + (pageSize - 1) & (~(pageSize - 1));
+	/* Don't set the palet if it matches what we will set. */
 
-        pEFB->FBvaddr = (unsigned char *)mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED,
-                                        fd, pEFB->FBPhysAddr);
+	for (coloron = 0; coloron < 256; coloron++) {
+		if ((efb_info.efb_palet[coloron] &
+		    (PALETTE_30_DATA__PALETTE_DATA_R_MASK |
+		    PALETTE_30_DATA__PALETTE_DATA_G_MASK |
+		    PALETTE_30_DATA__PALETTE_DATA_B_MASK)) !=
+		    (new_palet[coloron] &
+		    (PALETTE_30_DATA__PALETTE_DATA_R_MASK |
+		    PALETTE_30_DATA__PALETTE_DATA_G_MASK |
+		    PALETTE_30_DATA__PALETTE_DATA_B_MASK)))
+			break;
+	}
 
-        if (pEFB->FBvaddr == MAP_FAILED) {
-            TraceMessage(VTS_DEBUG, __func__, "map framebuffer failed\n");
-            gfx_vts_set_message(rp, 1, test, "map framebuffer failed");
-            return -1;
-        }
+	if (coloron == 256)
+		return (0);
+
+	efb_info.efb_palet_changed = 1;
+	save_palette_index = REGR(RADEON_PALETTE_INDEX);
 
+	REGW(RADEON_PALETTE_INDEX, 0);
 
-	return 0;
+	for (coloron = 0; coloron < 256; coloron++)
+		REGW(RADEON_PALETTE_30_DATA, new_palet[coloron]);
+
+	REGW(RADEON_PALETTE_INDEX, save_palette_index);
+	return (1);
 }
 
 int
-efb_unmap_mem(struct efb_info *pEFB, return_packet *rp, int test)
+efb_restore_palet(
+    void)
 {
-        /*
-         * Unmap Frame Buffer
-         */
+	register uint_t coloron;
+	register uint_t save_palette_index;
+
+	if (!efb_info.efb_palet_changed)
+		return (0);
+
+	save_palette_index = REGR(RADEON_PALETTE_INDEX);
+
+	REGW(RADEON_PALETTE_INDEX, 0);
+
+	for (coloron = 0; coloron < 256; coloron++)
+		REGW(RADEON_PALETTE_30_DATA, efb_info.efb_palet[coloron]);
+
+	REGW(RADEON_PALETTE_INDEX, save_palette_index);
+
+	efb_info.efb_palet_changed = 0;
+	return (1);
+}
+
 
-        if (munmap((void *)pEFB->FBvaddr, pEFB->FBMapSize) == -1) {
-            TraceMessage(VTS_DEBUG, __func__, "unmap framebuffer failed\n");
-            gfx_vts_set_message(rp, 1, test, "unmap framebuffer failed");
-            return -1;
-        }
+uint_t
+efb_color(
+    register uint_t const red,
+    register uint_t const green,
+    register uint_t const blue)
+{
+	register uint_t value;
+
+	switch (efb_info.efb_depth) {
+	case 8:	/* 3, 3, 2 */
+		value = ((red >> 5) & 0x7) << 5;
+		value |= ((green >> 5) & 0x7) << 2;
+		value |= (blue >> 6) & 0x3;
+		break;
 
-        if (munmap((void *)pEFB->MMIOvaddr, pEFB->MMIOMapSize) == -1) {
-            TraceMessage(VTS_DEBUG, __func__, "unmap MMIO failed\n");
-            gfx_vts_set_message(rp, 1, test, "unmap MMIO failed");
-            return -1;
-        }
+	case 15:	/* 5, 5, 5 */
+		value = ((red >> 3) & 0x1f) << 10;
+		value |= ((green >> 3) & 0x1f) << 5;
+		value |= (blue >> 3) & 0x1f;
+		break;
 
-	return 0;
+	case 16:	/* 5, 6, 5 */
+		value = ((red >> 3) & 0x1f) << 11;
+		value |= ((green >> 2) & 0x3f) << 5;
+		value |= (blue >> 3) & 0x1f;
+		break;
+
+	default:	/* 8, 8, 8 */
+		value = (red & 0xff) << 16;
+		value |= (green & 0xff) << 8;
+		value |= blue & 0xff;
+		break;
+	}
+
+	return (value);
 }
 
 
-#define MASK    RBBM_STATUS__CMDFIFO_AVAIL_MASK
-
-uint32_t
-getBPPValue (int bpp)
+int
+efb_fill_solid_rect(
+    register uint_t const x1,
+    register uint_t const y1,
+    register uint_t const x2,
+    register uint_t const y2,
+    register uint_t const fg)
 {
-	switch (bpp) {
-            case 8:     return (DST_8BPP);
-            case 15:    return (DST_15BPP);
-            case 16:    return (DST_16BPP);
-            case 32:    return (DST_32BPP);
-            default:    return (0);
-    	}
+	register int width;
+	register int height;
+
+	width  = x2 - x1;
+	height = y2 - y1;
+
+	if ((width <= 0) || (height <= 0)) {
+#ifdef DEBUG
+		printf("x1=%d x2=%d y1=%d y2=%d\n", x1, x2, y1, y2);
+#endif
+		return (0);
+	}
+
+	if (!efb_wait_fifo(5))
+		return (0);
+
+	REGW(RADEON_DP_WRITE_MASK, 0xffffffff);
+	REGW(RADEON_DP_CNTL,
+	    (RADEON_DST_X_LEFT_TO_RIGHT | RADEON_DST_Y_TOP_TO_BOTTOM));
+
+	REGW(RADEON_DP_BRUSH_FRGD_CLR, fg);
+	REGW(DST_Y_X,  (x1 << DST_Y_X__DST_X__SHIFT) |
+	    (y1 << DST_Y_X__DST_Y__SHIFT));
+	REGW(DST_WIDTH_HEIGHT,
+	    (height << DST_WIDTH_HEIGHT__DST_HEIGHT__SHIFT) |
+	    (width << DST_WIDTH_HEIGHT__DST_WIDTH__SHIFT));
+
+	return (1);
 }
 
-void 
-efb_flush_pixel_cache(struct efb_info *pEFB)
+int
+efb_draw_solid_line(
+    register uint_t const x1,
+    register uint_t const y1,
+    register uint_t const x2,
+    register uint_t const y2,
+    register uint_t const fg)
 {
-	int i ;
+	if (!efb_wait_fifo(5))
+		return (0);
+
+	REGW(RADEON_DP_WRITE_MASK, 0xffffffff);
+	REGW(RADEON_DP_CNTL,
+	    (RADEON_DST_X_LEFT_TO_RIGHT | RADEON_DST_Y_TOP_TO_BOTTOM));
 
-	// initiate flush
-	REGW(RADEON_RB2D_DSTCACHE_CTLSTAT, REGR(RADEON_RB2D_DSTCACHE_CTLSTAT) | 0xf);
+	REGW(RADEON_DP_BRUSH_FRGD_CLR, fg);
+	REGW(DST_LINE_START,
+	    (x1 << DST_LINE_START__DST_START_X__SHIFT) |
+	    (y1 << DST_LINE_START__DST_START_Y__SHIFT));
+	REGW(DST_LINE_END,
+	    (x2 << DST_LINE_END__DST_END_X__SHIFT) |
+	    (y2 << DST_LINE_END__DST_END_Y__SHIFT));
+
+	return (1);
+}	/* line() */
 
-	// check for completion but limit looping to 16384 reads
-	i = 16384;
-	while((REGR(RADEON_RB2D_DSTCACHE_CTLSTAT) & RADEON_RB2D_DC_BUSY) == RADEON_RB2D_DC_BUSY &&
-                --i >= 0 ) ;
+int
+efb_flush_pixel_cache(
+    void)
+{
+	register int i;
+
+	/* initiate flush */
+	REGW(RADEON_RB2D_DSTCACHE_CTLSTAT,
+	    REGR(RADEON_RB2D_DSTCACHE_CTLSTAT) | 0xf);
+
+	/* check for completion but limit looping to 16384 reads */
+	for (i = 16384; i > 0; i--) {
+		if ((REGR(RADEON_RB2D_DSTCACHE_CTLSTAT) &
+		    (uint_t)RADEON_RB2D_DC_BUSY) != (uint_t)RADEON_RB2D_DC_BUSY)
+			break;
+	}
+	return ((REGR(RADEON_RB2D_DSTCACHE_CTLSTAT) &
+	    (uint_t)RADEON_RB2D_DC_BUSY) != (uint_t)RADEON_RB2D_DC_BUSY);
 }
 
-void 
-efb_reset_engine (struct efb_info *pEFB)
+void
+efb_reset_engine(
+    void)
 {
-	uint32_t save_genresetcntl, save_clockcntlindex, save_mclkcntl;
-	long term_count;
+	register uint_t save_genresetcntl;
+	register uint_t save_clockcntlindex;
+	static ulong_t term_count;
 
-	efb_flush_pixel_cache(pEFB) ;
+	efb_flush_pixel_cache();
 
 	save_clockcntlindex = REGR(RADEON_CLOCK_CNTL_INDEX);
 
-	// save GEN_RESET_CNTL register
+	/* save GEN_RESET_CNTL register */
 	save_genresetcntl = REGR(RADEON_DISP_MISC_CNTL);
 
-	// reset by setting bit, add read delay, then clear bit, 
-	// add read delay
+	/* reset by setting bit, add read delay, then clear bit, */
+	/* add read delay */
 	REGW(RADEON_DISP_MISC_CNTL, save_genresetcntl |
-      	     RADEON_DISP_MISC_CNTL__SOFT_RESET_GRPH_PP);
+	    RADEON_DISP_MISC_CNTL__SOFT_RESET_GRPH_PP);
 	REGR(RADEON_DISP_MISC_CNTL);
 	REGW(RADEON_DISP_MISC_CNTL, save_genresetcntl &
-             ~(RADEON_DISP_MISC_CNTL__SOFT_RESET_GRPH_PP));
+	    ~(RADEON_DISP_MISC_CNTL__SOFT_RESET_GRPH_PP));
 	REGR(RADEON_DISP_MISC_CNTL);
 
-	// restore the two registers we changed
+	/* restore the two registers we changed */
 	REGW(RADEON_CLOCK_CNTL_INDEX, save_clockcntlindex);
 	REGW(RADEON_DISP_MISC_CNTL, save_genresetcntl);
 
-	term_count++;     // for monitoring engine hangs
-}
-
-void 
-efb_wait_for_fifo(struct efb_info *pEFB, int c)
-{
-	uint32_t i;
-	long limit;
-
-	/* First a short loop, just in case fifo clears out quickly */
-	for(limit=100; (REGR(RBBM_STATUS) & MASK) < c && --limit > 0; ) ;
-
-	if((REGR(RBBM_STATUS) & MASK) < c ) {
-    		hrtime_t timeout = gethrtime() + (hrtime_t)3000000000;
-            	while((REGR(RBBM_STATUS) & MASK) < c && 
-					gethrtime() < timeout )
-        	    yield();
-
-       	    	if((REGR(RBBM_STATUS) & MASK) < c )
-      	    	    efb_reset_engine(pEFB) ;
-	}
+	term_count++;	/* for monitoring engine hangs */
 }
 
-void 
-efb_wait_for_idle(struct efb_info *pEFB)
+int
+efb_wait_fifo(
+    register int const c)
 {
-	uint32_t i;
-	long limit;
+	register int limit;
+	register hrtime_t timeout;
 
-	efb_wait_for_fifo(pEFB, 64) ;
-
-	for(limit=10000; (REGR(RBBM_STATUS) & GUI_ACTIVE) && --limit > 0; ) ;
+	/* First a short loop, just in case fifo clears out quickly */
+	for (limit = 100; limit >= 0; limit--) {
+		if ((REGR(RBBM_STATUS) &
+		    RBBM_STATUS__CMDFIFO_AVAIL_MASK) >= c)
+			break;
+	}
 
-	if( REGR(RBBM_STATUS) & GUI_ACTIVE ) {
-    	    hrtime_t timeout = gethrtime() + (hrtime_t)3000000000;
-    	    while( (REGR(RBBM_STATUS) & GUI_ACTIVE) && 
-				gethrtime() < timeout )
-        	yield();
-
-            if( (REGR(RBBM_STATUS) & GUI_ACTIVE) != 0 )
-      		efb_reset_engine(pEFB) ;
+	if ((REGR(RBBM_STATUS) & RBBM_STATUS__CMDFIFO_AVAIL_MASK) < c) {
+		timeout = gethrtime() + 3 * (hrtime_t)1000000000;
+		while (gethrtime() < timeout) {
+			if ((REGR(RBBM_STATUS) &
+			    RBBM_STATUS__CMDFIFO_AVAIL_MASK) >= c)
+				break;
+			yield();
+		}
+		if ((REGR(RBBM_STATUS) &
+		    RBBM_STATUS__CMDFIFO_AVAIL_MASK) < c)
+			efb_reset_engine();
 	}
+	return ((REGR(RBBM_STATUS) &
+	    RBBM_STATUS__CMDFIFO_AVAIL_MASK) >= c);
 }
 
+int
+efb_wait_idle(
+    void)
+{
+	register int limit;
+	register hrtime_t timeout;
 
+	efb_wait_fifo(64);
+
+	for (limit = 10000; limit > 0; limit--) {
+		if (!(REGR(RBBM_STATUS) & GUI_ACTIVE))
+			break;
+	}
+
+	if (REGR(RBBM_STATUS) & GUI_ACTIVE) {
+		timeout = gethrtime() + 3 * (hrtime_t)1000000000;
+		while (gethrtime() < timeout) {
+			if (!(REGR(RBBM_STATUS) & GUI_ACTIVE))
+				break;
+			yield();
+		}
+
+		if ((REGR(RBBM_STATUS) & GUI_ACTIVE) != 0)
+			efb_reset_engine();
+	}
+	return ((REGR(RBBM_STATUS) & GUI_ACTIVE) == 0);
+}