--- 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);
+}