Esempio n. 1
0
/**************************************************************************//**
\brief Performs exchanging of entry points between application and bootloader.
******************************************************************************/
void flashExchangeEntryPoints(void)
{
  uint32_t appLabel;
  uint32_t tempAddr = FLASH_START_ADDRESS;
  uint32_t itr;
  uint32_t fmrBackup;

  tempAddr = FLASH_END_ADDRESS + BOOT_AREA_SIZE - FLASH_PAGE_SIZE + 1;
  // change application entry point to boot entry point
  for (itr = 0; itr < FLASH_PAGE_SIZE; itr += sizeof(uint32_t))
  {
    if ((FLASH_END_ADDRESS + BOOT_AREA_SIZE - sizeof(uint32_t) + 1) == (tempAddr + itr))
    {  // last flash byte for storing application entry point
      MMIO(tempAddr + itr) = appEntryPoint;
      continue;
    }

    if ((FLASH_END_ADDRESS + BOOT_AREA_SIZE - 2 * sizeof(uint32_t) + 1) == (tempAddr + itr))
    {
      appLabel = MMIO(tempAddr + itr);
      appLabel |= 0xFF000000;
      MMIO(tempAddr + itr) = appLabel;
      continue;
    }

    MMIO(tempAddr + itr) = MMIO(tempAddr + itr); // copy flash page to shadow buffer
  }
  fmrBackup = EFC->EEFC_FMR;
  EFC->EEFC_FMR = (FWS_FOR_WRITE << 8);
  // Perform page erase and write.
  flashWritePage(LAST_PAGE, false);
  EFC->EEFC_FMR = fmrBackup;
}
Esempio n. 2
0
static GLboolean multipass_cliprect( struct gl_context *ctx, GLuint pass )
{
   sisContextPtr smesa = SIS_CONTEXT( ctx );

   if (pass >= smesa->driDrawable->numClipRects) {
      return GL_FALSE;
   } else {
      GLint x1, y1, x2, y2;

      x1 = smesa->driDrawable->pClipRects[pass].x1 - smesa->driDrawable->x;
      y1 = smesa->driDrawable->pClipRects[pass].y1 - smesa->driDrawable->y;
      x2 = smesa->driDrawable->pClipRects[pass].x2 - smesa->driDrawable->x;
      y2 = smesa->driDrawable->pClipRects[pass].y2 - smesa->driDrawable->y;

      if (ctx->Scissor.Enabled) {
         GLint scisy1 = Y_FLIP(ctx->Scissor.Y + ctx->Scissor.Height - 1);
         GLint scisy2 = Y_FLIP(ctx->Scissor.Y);

         if (ctx->Scissor.X > x1)
            x1 = ctx->Scissor.X;
         if (scisy1 > y1)
            y1 = scisy1;
         if (ctx->Scissor.X + ctx->Scissor.Width - 1 < x2)
            x2 = ctx->Scissor.X + ctx->Scissor.Width - 1;
         if (scisy2 < y2)
            y2 = scisy2;
      }

      MMIO(REG_3D_ClipTopBottom, y1 << 13 | y2);
      MMIO(REG_3D_ClipLeftRight, x1 << 13 | x2);
      /* Mark that we clobbered these registers */
      smesa->GlobalFlag |= GFLAG_CLIPPING;
      return GL_TRUE;
   }
}
Esempio n. 3
0
/*!
 * This procedure waits for the next vertical blanking (vertical retrace)
 * period. If the display is already in a vertical blanking period, this
 * procedure exits.
 *
 * Note: A timeout is included to prevent an endless loop.
 *
 * @param display_handle
 *
 * @return FALSE if timed out
 */
static int igd_wait_vblank_plb(igd_display_h display_handle)
{

	return wait_for_vblank_plb(MMIO(display_handle),
		PIPE(display_handle)->pipe_reg);

}  /* wait_vblank */
Esempio n. 4
0
/*!
 *
 * @param display_handle
 * @param palette_entry
 * @param palette_color
 *
 * @return 0 on success
 * @return -IGD_INVAL on failure
 */
static int igd_get_palette_entry_plb(
	igd_display_h display_handle,
	unsigned long palette_entry,
	unsigned long *palette_color)
{
	/* Too Slow For Tracing */

	/* Return if Pipe is not on */
	if(!((1L<<31) & EMGD_READ32(MMIO(display_handle) +
			PIPE(display_handle)->pipe_reg))) {
		return -IGD_INVAL;
	}

	*palette_color = 0xffffff & EMGD_READ32(MMIO(display_handle) +
		PIPE(display_handle)->palette_reg + palette_entry * 4);
	return 0;
}
Esempio n. 5
0
/*!
 *
 * @param display_handle
 * @param palette_entry
 * @param palette_color
 *
 * @return 0 on success
 * @return -IGD_INVAL on failure
 */
static int igd_set_palette_entry_plb(
	igd_display_h display_handle,
	unsigned long palette_entry,
	unsigned long palette_color)
{
	/* Too Slow For Tracing */

	/* Return if Pipe is not on */
	if(!((1L<<31) & EMGD_READ32(MMIO(display_handle) +
			PIPE(display_handle)->pipe_reg))) {
		return -IGD_INVAL;
	}
	/*
	EMGD_DEBUG("%x : %ld : %lx", display_handle,
		palette_entry, palette_color);
	*/
	EMGD_WRITE32(palette_color, MMIO(display_handle) +
		PIPE(display_handle)->palette_reg + palette_entry * 4);

	return 0;
}
Esempio n. 6
0
/**************************************************************************//**
\brief Function to do an atomic erase-write on one page in the flash.

\note The maximum pageAddress must not be exceeded. The maximum number of
      pages can be found in the datasheet.

\param[in] pageAddress Page address to the page to erase/write.
******************************************************************************/
void flashEraseWritePage(uint16_t pageAddress)
{
  // Calculate actual start address of the page.
  uint32_t tableAddress = (uint32_t)pageAddress * (uint32_t)FLASH_PAGE_SIZE;
  uint16_t itr;
  uint32_t *ptr = (uint32_t *)temporaryPageBuffer;

  for (itr = 0; itr < FLASH_PAGE_SIZE; itr += sizeof(uint32_t), ptr++)
  {
    if ((FIRST_PAGE == pageAddress) && (sizeof(uint32_t) == (tableAddress + itr)))
    {
      appEntryPoint = *ptr;
      MMIO(tableAddress + itr) = MMIO(tableAddress + itr);
    }
    else
    {
      MMIO(tableAddress + itr) = *ptr;
    }
  }
  // Perform page erase.
  flashWritePage(pageAddress, false);
}
Esempio n. 7
0
File: sis_tris.c Progetto: aosm/X11
/* Fires a set of vertices that have been written from AGP_StartPtr to
 * AGP_WritePtr, using the smesa->AGPParseSet format.
 */
void
sisFireVertsAGP( sisContextPtr smesa )
{
   if (AGP_WritePtr == AGP_StartPtr)
      return;

   mWait3DCmdQueue(5);
   mEndPrimitive();
   MMIO(REG_3D_AGPCmBase, (long)AGP_StartPtr - (long)smesa->AGPCmdBufBase +
      (long)smesa->AGPCmdBufAddr);
   MMIO(REG_3D_AGPTtDwNum, (((long)AGP_WritePtr - (long)AGP_StartPtr) >> 2) |
      0x50000000);
   MMIO(REG_3D_ParsingSet, smesa->AGPParseSet);
   
   MMIO(REG_3D_AGPCmFire, (GLint)(-1));
   mEndPrimitive();

   *(smesa->pAGPCmdBufNext) = (((long)AGP_WritePtr -
      (long)smesa->AGPCmdBufBase) + 0xf) & ~0xf;
   AGP_StartPtr = AGP_WritePtr;
   sisUpdateAGP( smesa );
}
Esempio n. 8
0
/*!
 * This function programs the Timing registers and clock registers and
 * other control registers for PIPE.
 *
 * @param display
 * @param status
 *
 * @return void
 */
static void program_pipe_plb(igd_display_context_t *display,
	unsigned long status)
{
	unsigned long   timing_reg;
	unsigned long   pipe_conf;
	unsigned long   hactive, vactive;
	igd_timing_info_t  *pTimings;
	unsigned long temp;
#ifndef CONFIG_MICRO
	igd_display_port_t *port;
	int i;
#endif

	EMGD_TRACE_ENTER;
	EMGD_DEBUG("Program Pipe: %s", status?"ENABLE":"DISABLE");
	EMGD_DEBUG("Device power state: D%ld", GET_DEVICE_POWER_STATE(display));

	pipe_conf = device_data->pipe_preserve &
		EMGD_READ32(MMIO(display) + PIPE(display)->pipe_reg);

	/* Reset the plane of this pipe back to NULL, it will be set on the
	 * call to program_plane, which is ok, since program_pipe occurs
	 * before program_plane */
	PIPE(display)->plane = NULL;

	if((status == FALSE) ||
		(GET_DEVICE_POWER_STATE(display) == IGD_POWERSTATE_D3)) {
		/* Disable pipe */
		EMGD_WRITE32(pipe_conf & (~0x80000000),
			MMIO(display) + PIPE(display)->pipe_reg);

		return;
	}

	pTimings = PIPE(display)->timing;

	/*
	 * If the mode is VGA and the PD says it handles all VGA modes without
	 * reprogramming then just set the mode and leave centering off.
	 */
	if(pTimings->mode_info_flags & IGD_MODE_VESA) {
		if (pTimings->mode_number <= VGA_MODE_NUM_MAX) {
			/* Pipe timings and clocks are not used but it must be on anyway */
			EMGD_WRITE32(pipe_conf | 0x80000000,
				MMIO(display) + PIPE(display)->pipe_reg);
			program_pipe_vga_plb(display);
			return;
		} else {
#ifdef CONFIG_MICRO
			set_256_palette(MMIO(display));
#endif
		}
	}

	/* Program dot clock divisors. */
	program_clock_plb(display, PIPE(display)->clock_reg, pTimings->dclk);

	/* Program timing registers for the pipe */
	timing_reg = PIPE(display)->timing_reg;
	if (pTimings->mode_info_flags & IGD_PIXEL_DOUBLE) {
		hactive = (unsigned long)pTimings->width*2 - 1;
	} else {
		hactive = (unsigned long)pTimings->width - 1;
	}

	if (pTimings->mode_info_flags & IGD_LINE_DOUBLE) {
		if (pTimings->mode_info_flags & IGD_SCAN_INTERLACE) {
			vactive = (unsigned long)pTimings->height - 1;
		} else {
			vactive = (unsigned long)pTimings->height*2 - 1;
		}
	} else {
		if (pTimings->mode_info_flags & IGD_SCAN_INTERLACE) {
			vactive = (unsigned long)pTimings->height/2 - 1;
		} else {
			vactive = (unsigned long)pTimings->height - 1;
		}
	}

	/*
	 * DPLL should be on at this point which is required for touching
	 * the palette.
	 */
#ifndef CONFIG_MICRO
	/* reset the palette */
	for (i = 0; i < 256; i++) {
		EMGD_WRITE32(((i<<16) | (i<<8) | i),
			MMIO(display) + PIPE(display)->palette_reg + i*4);
	}

	/* apply color correction */
	port = PORT_OWNER(display);
	for( i = 0; PD_ATTR_LIST_END != port->attributes[i].id; i++ ) {

		if ((PD_ATTR_ID_FB_GAMMA      == (port->attributes[i].id)) ||
			(PD_ATTR_ID_FB_BRIGHTNESS == (port->attributes[i].id)) ||
			(PD_ATTR_ID_FB_BRIGHTNESS == (port->attributes[i].id)))  {

			mode_context->dispatch->full->set_color_correct(display);
		}
	}
#endif

	/*
	 * NOTE: For size reasons the timng table contains unsigned short
	 * values. Don't shift them past 16. Use a temp instead.
	 * All register offsets and bit shift are verified for Napa
	 */
	temp = ((unsigned long)pTimings->htotal << 16) | hactive;
	EMGD_WRITE32(temp, MMIO(display) + timing_reg);

	temp = ((unsigned long)pTimings->hblank_end << 16) |
		(unsigned long)pTimings->hblank_start;
	EMGD_WRITE32(temp, MMIO(display) + timing_reg + 0x04);

	temp = ((unsigned long)pTimings->hsync_end << 16) |
		(unsigned long)pTimings->hsync_start;
	EMGD_WRITE32(temp, MMIO(display) + timing_reg + 0x08);

	temp = ((unsigned long)pTimings->vtotal << 16) | vactive;
	EMGD_WRITE32(temp, MMIO(display) + timing_reg + 0x0C);

	temp = ((unsigned long)pTimings->vblank_end << 16) |
		(unsigned long)pTimings->vblank_start;
	EMGD_WRITE32(temp, MMIO(display) + timing_reg + 0x10);

	temp = ((unsigned long)pTimings->vsync_end << 16) |
		(unsigned long)pTimings->vsync_start;
	EMGD_WRITE32(temp, MMIO(display) + timing_reg + 0x14);

	/*
	 * If there is a linked mode it is either the VGA or a scaled
	 * mode. If it is scaled then we need to use it as the source size.
	 */
	if(pTimings->extn_ptr) {
		igd_timing_info_t *scaled_timings =
			(igd_timing_info_t *)pTimings->extn_ptr;
		if((scaled_timings->mode_info_flags & IGD_MODE_VESA) &&
			(scaled_timings->mode_number <= VGA_MODE_NUM_MAX)) {
			temp = (hactive << 16) | vactive;
		} else {
			temp = (unsigned long)scaled_timings->width  - 1;
			temp = (temp << 16) |
				(unsigned long)(scaled_timings->height - 1);
		}
	} else {
		temp = (hactive << 16) | vactive;
	}
	EMGD_WRITE32(temp, MMIO(display) + timing_reg + 0x1C);

	/* Set other registers */

	/*
	 * FIXME: max_dclk needs to be determined from core clock
	 * at init time. 915 etc has several skus with different
	 * clocks for the same device ID.
	 *
	 */

	/* These values are derived from the Poulsbo B-Spec as
	 * the suggested values */
	WRITE_MMIO_REG (display, FW_BLC1, device_data->fw_blc1);
	WRITE_MMIO_REG (display, FW_BLC2, device_data->fw_blc2);
	WRITE_MMIO_REG (display, FW_BLC3, device_data->fw_blc3);
	WRITE_MMIO_REG (display, FW_BLC_SELF, device_data->fw_self);
	WRITE_MMIO_REG (display, DSP_ARB, device_data->dsp_arb);

	/* The SGX 2D engine can saturate the memory bus and starve
	 * the display engine causing visible screen tearing.
	 * This reduces the priority of the SGX vs. display engine
	 */
	temp = READ_MMIO_REG (display, G_DEBUG);
	WRITE_MMIO_REG (display, G_DEBUG, (temp | (1 << 11)));

	pipe_conf |= PIPE_ENABLE;
	WRITE_MMIO_REG(display, PIPE(display)->pipe_reg, pipe_conf);

	/*
	 * Set the VGA address range to 0xa0000 so that a normal (not VGA)
	 * mode can be accessed through 0xa0000 in a 16bit world.
	 */
	WRITE_AR(MMIO(display), 0x10, 0xb);
	WRITE_VGA(MMIO(display), GR_PORT, 0x06, 0x5);
	WRITE_VGA(MMIO(display), GR_PORT, 0x10, 0x1);

	if(pTimings->extn_ptr) {
		/* This means either internal scaling (LVDS) or centered VGA */
		pTimings = pTimings->extn_ptr;
		if(pTimings->extn_ptr) {
			/* This is both the scaled and centered VGA */
			pTimings = pTimings->extn_ptr;
		}
		if(pTimings->mode_info_flags & IGD_MODE_VESA) {
			if (pTimings->mode_number <= VGA_MODE_NUM_MAX) {
				program_pipe_vga_plb(display);
			} else {
#ifdef CONFIG_MICRO
				set_256_palette(MMIO(display));
#endif
			}
		}
	}

	EMGD_TRACE_EXIT;
	return;
}
Esempio n. 9
0
/*!
 * Program Display Plane Values.
 *
 * @param display Pointer to hardware device instance data
 * @param status
 *
 * @return void
 */
static void program_plane_plb(igd_display_context_t *display,
	unsigned long status)
{
	unsigned long stereo;
	unsigned long stride;
	unsigned long size;
	unsigned long plane_control;
	igd_timing_info_t *timing;
	igd_framebuffer_info_t *fb_info = PLANE(display)->fb_info;
	unsigned long plane_reg = PLANE(display)->plane_reg;
	unsigned long start_addr_reg = DSPAADDR;

	EMGD_TRACE_ENTER;

	EMGD_DEBUG("Program Plane: %s", status?"ENABLE":"DISABLE");
	EMGD_DEBUG("Device power state: D%ld", GET_DEVICE_POWER_STATE(display));

	igd_wait_vblank_plb((igd_display_h)display);

	plane_control = EMGD_READ32(MMIO(display) + plane_reg);
	if(PLANE(display)->plane_reg == DSPACNTR) {
		plane_control &= device_data->plane_a_preserve;
	}
	else { /* if it's plane b or plane c */
		plane_control &= device_data->plane_b_c_preserve;
		start_addr_reg = 0x71184;
	}

	if((status == FALSE) ||
		(GET_DEVICE_POWER_STATE(display) != IGD_POWERSTATE_D0)) {

		/*
		 * Note: The vga programming code does not have an "off". So
		 * when programming the plane to off we make sure VGA is off
		 * as well.
		 */
		disable_vga_plb(MMIO(display));

		/*
		 * To turn off plane A or B, the program have to triger the plane A or B
		 * start register.  Or else, it will not work.
		 */
		EMGD_WRITE32(plane_control, MMIO(display) + plane_reg);
		EMGD_WRITE32(EMGD_READ32(MMIO(display) + start_addr_reg),
			MMIO(display) + start_addr_reg);

		igd_wait_vblank_plb((igd_display_h)display);
		return;
	}
	/*
	 * Note: The very first pass through this function will be with
	 * status false and timings == NULL. Don't use the timings before
	 * the check above.
	 */
	timing = PIPE(display)->timing;
	/* There is a special case code for legacy VGA modes */
	while (timing->extn_ptr) {
		timing = (igd_timing_info_t *)timing->extn_ptr;
	}
	if(MODE_IS_VGA(timing)) {
		program_plane_vga(display, timing);
		return;
	}

	disable_vga_plb(MMIO(display));

	size = (((unsigned long)timing->height - 1)<<16) |
		(unsigned long)(timing->width - 1);

	/* enable plane, select pipe, enable gamma correction logic */
	plane_control |= 0x80000000 | (PIPE(display)->pipe_num<<24);
	PIPE(display)->plane = PLANE(display);
#ifndef CONFIG_MICRO
	plane_control |= (1<<30);
#endif

	/* Here the settings:
	 *   If line + pixel dbling, set 21,20 to 01b, and set Horz Multiply
	 *   If line dbling only,    set 21,20 to 11b
	 *   If pixel dbling only,   set 21,20 to 00b, but set Horz Multiply
	 *   If no doubling,         set 21,20 to 00b (no Horz Multiply)
	 * For pixel doubling
	 *           --> both progressive/interlaced modes
	 * For Line doubling
	 *           --> progressive modes only
	 */

	if (!(timing->mode_info_flags & IGD_SCAN_INTERLACE)) {
		/* Line doubling in progressive mode requires special bits */
		if (timing->mode_info_flags & IGD_LINE_DOUBLE) {
			/* BIT 20 for line & pixel doubling*/
			plane_control |= BIT20;
			/* check later, if no pixel doubling, set bit 21 too*/
		}
	}
	if (timing->mode_info_flags & IGD_PIXEL_DOUBLE) {
		/* Horz pixel multiply must be set for double */
		plane_control |= BIT11;
		/* TODO -> Plba can more than double,
		It can 3X, 4X etc. These arent exposed now */
	}
	else if(plane_control & BIT20){
		/* For line ONLY doubling, set bit 21 also '1' */
		plane_control |= BIT21;
	}

	mode_get_stride_stereo_plb(display, &stride, &stereo, 0);

	/* set color depth */
	switch (IGD_PF_DEPTH(fb_info->pixel_format)) {
	case PF_DEPTH_8:
		plane_control |= BIT27 | BIT30;
		break;
	case PF_DEPTH_16:
		plane_control |= BIT28 | BIT26;
		break;
	default:
	case PF_DEPTH_32:
		plane_control |= BIT28 | BIT27;
		break;
	}

	if(fb_info->flags & IGD_ENABLE_DISPLAY_GAMMA) {
		plane_control |= (BIT30);
	}

	EMGD_DEBUG(" Plane Control = 0x%lx", plane_control);
	EMGD_DEBUG(" Plane Base = 0x%lx", fb_info->visible_offset);
	EMGD_DEBUG(" Plane Pitch = 0x%lx", stride);
	EMGD_DEBUG(" Plane Size = 0x%lx", size);

	EMGD_WRITE32(stride, MMIO(display) + plane_reg + DSP_STRIDE_OFFSET);
	/*
	 * In reality this only exists for plane B. It doesn't seem to hurt
	 * plane A so just do it anyway and save us another case.
	 */
	EMGD_WRITE32(size, MMIO(display) + plane_reg + DSP_SIZE_OFFSET);

	/*EMGD_WRITE32(stereo, MMIO(display) + plane_reg + DSP_STEREO_OFFSET);
		- This register is Reserved ON plba */
	EMGD_WRITE32(fb_info->visible_offset,
		MMIO(display) + plane_reg + DSP_START_OFFSET);

	/* It seems we need push or trigger plane A/B to start to work
	 * on Poulsbo, especially for sDVO port. Let's write plane control
	 * register and start address register at last.
	 */
	EMGD_WRITE32(plane_control, MMIO(display) + plane_reg);
	EMGD_WRITE32(EMGD_READ32(MMIO(display) + start_addr_reg),
		MMIO(display) + start_addr_reg);

	igd_wait_vblank_plb((igd_display_h)display);

	EMGD_TRACE_EXIT;
	return;
}
Esempio n. 10
0
/*!
 * This function sets up planes, pipes, and ports
 * with the configuration passed in and returnes either one
 * or two display handle lists.
 *
 * @param driver_handle from igd_init_driver().
 * @param primary on return, this points to a list of displays.
 * @param primary_ptinfo incoming timing info for the primary.
 * @param primary_fbinfo incoming framebuffer info.
 * @param secondary on return, this points to a list of displays.
 * @param secondary_fbinfo incoming framebuffer info.
 * @param dc display configuration
 * @param flags modify function behavior
 *
 * @return 0 on success
 * @return -IGD_INVAL on failure
 */
int igd_alter_displays(
	igd_driver_h driver_handle,
	igd_display_h *_primary,
	igd_display_info_t *primary_pt_info,
	igd_framebuffer_info_t *primary_fb_info,
	igd_display_h *_secondary,
	igd_display_info_t *secondary_pt_info,
	igd_framebuffer_info_t *secondary_fb_info,
	unsigned long dc,
	unsigned long flags)
{
	igd_context_t *context = (igd_context_t *)driver_handle;
	igd_display_context_t **primary = (igd_display_context_t **)_primary;
	igd_display_context_t **secondary = (igd_display_context_t **)_secondary;
	igd_framebuffer_info_t *fb_info = NULL;
	igd_display_context_t *display = NULL,*tv_display=NULL;
	int p;
	int ret;
	unsigned short tv_port_num=0;
	int p_chng = 1, s_chng = 1;
	unsigned char disable_plane_pipe = 0;
	unsigned long current_dc;

#if 0 /* Ian Elliott is taking this out ... see comment below */
#ifndef CONFIG_MICRO
	igd_framebuffer_info_t *plane_fb_info = NULL;
#endif
#endif /* 0 -- Ian is taking this out */

	EMGD_TRACE_ENTER;

	/*
	 * Make sure the DC is valid
	 *
	 * vBIOS won't be able to do this every time, for now only have
	 * the drivers's do the check.
	 */
#ifndef CONFIG_MICRO
	if (dc && !dsp_valid_dc(dc, 0)) {
		EMGD_ERROR_EXIT("Invalid display configuration: 0x%08lx", dc);
		return -IGD_ERROR_INVAL;
	}
#endif


	/*
	 * Can all display_info's and fb_info's be NULL?  I.E. make this
	 * function do an alloc of display handles only?  If so, then
	 * check for that condition and return without error. Otherwise
	 * return an error.
	 */
	if (dc && (!primary_pt_info && !primary_fb_info) &&
			(!secondary_pt_info && !secondary_fb_info)) {
		EMGD_ERROR_EXIT("Invalid timing and framebuffer info");
		return -IGD_ERROR_INVAL;
	}

#ifndef CONFIG_MICRO
	/* FIXME: GDK Change this to dispatch->idle() */
	if (dsp_wait_rb(mode_context->context) != 0) {
		return -IGD_ERROR_INVAL;
	}
#endif

	/* If seamless request is NOT set , then do reset_plane_pipe_ports
	 * else delay it until we cannot support it.
	 * If seamless is requested by the user and we CAN support it
	 * then we need to make sure reset_plane_pipe_ports is NOT
	 * called. That's the whole point anyway. Not to reset anything
	 * during seamless transition
	 */
	if(mode_context->seamless != TRUE) {

		/* Reset planes/pipes/ports before doing first alter display */
		if (mode_context->first_alter) {
			mode_context->dispatch->reset_plane_pipe_ports(
									mode_context->context);
			mode_context->first_alter = FALSE;
		}
	}

	current_dc = *(context->mod_dispatch.dsp_current_dc);

#ifndef CONFIG_MICRO
	/* Check if platform needs force alter
	* 	to make sure we run tuning code. This
	* 	is for TNC-B0 workaround.*/
	if (mode_context->dispatch->dsp_is_force_alter_required){
		if (mode_context->dispatch-> dsp_is_force_alter_required(context->
						mod_dispatch.dsp_display_list[IGD_DC_PRIMARY(current_dc)],
						current_dc, dc)){
				flags |= IGD_FORCE_ALTER;
		}
	}
#endif

	/*
	 * Turn off the planes, pipes, and ports associated with the current
	 * DC. However, limit the change to the primary if the secondary
	 * display handle is NULL or limit the change to the secondary if the
	 * the pimary display handle is NULL.
	 */
	for (p = 7; p > 0; p--) {
		if (p > 4) {
			display = NULL;
			if (DC_PORT_NUMBER(current_dc, p)) {
				display = context->mod_dispatch.
					dsp_display_list[IGD_DC_SECONDARY(current_dc)];
				s_chng = TIMING_CHANGED(display, dc, current_dc,
						secondary_pt_info, secondary_fb_info,
						(unsigned long)0xfff00000, flags);
			}

			if (s_chng && display && secondary) {
		/* if the port is TV, then don't set the power to S3 as this causes
		 * blank screen and system hang on LVDS on FSDOS, probably because the
		 * external clock needs to be on till the pipes and
		 * DPLLs are off
		 */
				if(PORT(display,DC_PORT_NUMBER(current_dc, p))->pd_type ==
					PD_DISPLAY_TVOUT) {
					tv_display = display;
					tv_port_num = DC_PORT_NUMBER(current_dc, p);
				} else {
					ret = mode_context->dispatch->program_port(display,
					      DC_PORT_NUMBER(current_dc, p), FALSE);
				}
				/* The secondary pipe master */
				if (p == 5) {
					disable_plane_pipe = 1;
				}
			}
		} else {
			display = NULL;
			if (DC_PORT_NUMBER(current_dc, p)) {
				display = context->mod_dispatch.
					dsp_display_list[IGD_DC_PRIMARY(current_dc)];
				p_chng = TIMING_CHANGED(display, dc, current_dc,
						primary_pt_info, primary_fb_info,
						(unsigned long)0x000ffff0, flags);
			}

			if (p_chng && display && primary) {
		/* if the port is TV, then don't set the power to S3 as this causes
		 * blank screen and system hang on LVDS on FSDOS, probably because the
		 * external clock needs to be on till the pipes and
		 * DPLLs are off
		 */
				if(PORT(display,DC_PORT_NUMBER(current_dc, p))->pd_type ==
					PD_DISPLAY_TVOUT) {
					tv_display = display;
					tv_port_num = DC_PORT_NUMBER(current_dc, p);
				} else {
					ret = mode_context->dispatch->program_port(display,
				      DC_PORT_NUMBER(current_dc, p), FALSE);
				}
				/* The primary pipe master */
				if (p == 1) {
					disable_plane_pipe = 1;
				}
			}
		}

		/* Disable plane and pipe after disabling the ports */
		if (disable_plane_pipe) {
			if(mode_context->dispatch->full) {
				mode_context->dispatch->full->program_cursor(display, FALSE);
			}
			mode_context->dispatch->program_plane(display, FALSE);
			mode_context->dispatch->program_pipe(display, FALSE);
			/*pipes and dplls are off, now turn off tv port */
			if(tv_display) {
				ret = mode_context->dispatch->program_port(tv_display,
					tv_port_num, FALSE);
				tv_display = NULL;
			}
			disable_plane_pipe = 0;
		}
	}

#ifndef CONFIG_MICRO
	/* If DC is zero, then return here. A zero dc turns everything off */
	/* This never happens for VBIOS since it only always calls *
	 * alter_displays at the same point with the same valid DC */
	if (!dc) {
		int i;
		mode_context->dispatch->reset_plane_pipe_ports(mode_context->context);
		/* Should de-allocate everything here */
		dsp_alloc(driver_handle, dc, flags);
		/*
		 * FIXME: This should be done inside dsp alloc, mode module does
		 * not own this information.
		 * When dc = 0, set all displays allocated to 0.
		 */
		for (i=0; i<IGD_MAX_PORTS+1; i++) {
			if (context->mod_dispatch.dsp_display_list[i]) {
				context->mod_dispatch.dsp_display_list[i]->allocated = 0;
			}
			context->mod_dispatch.dsp_display_list[i] = NULL;
		}

		return 0;
	}
#endif

	/*
	 * Check the DC (display configuration). If it is the same as the
	 * current configuration, then don't change any allocations, only
	 * modify the framebuffers and timings.
	 */
	if (dc != current_dc) {
		EMGD_DEBUG("Allocate display handles based on DC");

#ifndef CONFIG_MICRO
		if (swap_required(current_dc, dc, primary)) {
			swap_fb_cursor();
		}
#endif
		/*
		 * This function should never be called after VBIOS initialization *
		 * The dsp_alloc is discarded after VBIOS init and is over-  *
		 * written by font tables. Thus in VBIOS IAL, alter_displays *
		 * is never get called with a different DC from the 1st time *
		 */
		dsp_alloc(driver_handle, dc, flags);

	}

	/* Attach the displays to the caller's pointers */
	if (primary) {
		*primary = context->mod_dispatch.dsp_display_list[IGD_DC_PRIMARY(dc)];
#ifndef CONFIG_MICRO
		if (*primary && context->mod_dispatch.alloc_queues) {
			ret = context->mod_dispatch.alloc_queues(driver_handle,
				(*primary)->pipe, flags);
			if (ret) {
				EMGD_ERROR("unable to allocate command queues");
			}
		}
#endif
	}
	if (secondary) {
		EMGD_DEBUG("Attaching display 1 to secondary pointer");
		*secondary = context->mod_dispatch.
			dsp_display_list[IGD_DC_SECONDARY(dc)];
#ifndef CONFIG_MICRO
		if (*secondary && context->mod_dispatch.alloc_queues) {
			ret = context->mod_dispatch.alloc_queues(driver_handle,
				(*secondary)->pipe, flags);
			if (ret) {
				EMGD_ERROR("unable to allocate command queues");
			}
		}
#endif
	}

	/*
	 * Configure the primary display. This configures the timings and the
	 * framebuffer. Once configured, it turns everythying on.
	 */
	if(primary && *primary && (primary_pt_info || primary_fb_info) && p_chng) {
		EMGD_DEBUG("Configure primary timings");
		/* make framebuffer changes */
		if (primary_fb_info) {
			/* set up new frame buffer info */
			fb_info = primary_fb_info;
		} else {
			fb_info = PLANE(*primary)->fb_info;
		}

		ret = configure_display(driver_handle,
				(igd_display_context_t *)(*primary), primary_pt_info,
				fb_info, dc, 0, 4, flags);
		if (ret) {
			EMGD_DEBUG("Primary display disabled.");
		}
	}

	/*
	 * Configure the secondary display. This configures the timings and the
	 * framebuffer. Once configured, it turns everythying on.
	 *
	 * How close is this code to the code for the primary?  Could this
	 * be moved to a separate function?
	 */
	if (secondary != NULL) {

#ifndef CONFIG_MICRO
		/*
		 * In the case where we are in extended or clone and our pipe is not
		 * turned on, we need to turn the pipes on.
		 * We can run into this situation on pre-Cantiga Gen platforms on Linux
		 * where LVDS was the primary display and was assigned PIPE B. Then we
		 * are switching from LVDS to another display and that other display
		 * wants to take PIPE A. In this case PIPE B will be turned on, the
		 * display's new port will take PIPE A and turn on PIPE A.  The second
		 * display thinks it is still PIPE A and nothing has changed for it.
		 * In this case where our pipe is not turned on, we need to let the
		 * system know that something has changed.
		 */
		if ((IGD_DC_CLONE(dc) || IGD_DC_EXTENDED(dc))
			&& !(EMGD_READ32(MMIO(*secondary) + PIPE(*secondary)->pipe_reg)
			& 0x80000000)) {
			s_chng = 1;
		}
#endif

		EMGD_DEBUG("Starting secondary pipe programming");
		if ((*secondary != NULL) && (secondary_pt_info || secondary_fb_info) &&
				s_chng){
			/*
			 * Configure the framebuffer.  For clone, it is the same
			 * as the primary. For DIH, it is a unique fb.
			 */
			EMGD_DEBUG("configure secondary framebuffer");
			if (dc & IGD_DISPLAY_CONFIG_CLONE) {
				fb_info = PLANE(*primary)->fb_info;
			} else {
				if (secondary_fb_info) {
					fb_info = secondary_fb_info;
				} else {
					fb_info = PLANE(*secondary)->fb_info;
				}
			}

			ret = configure_display(driver_handle,
					(igd_display_context_t *)(*secondary), secondary_pt_info,
					fb_info, dc, 4, 7, flags);
			if (ret) {
				EMGD_DEBUG("Secondary display disabled.");
				EMGD_ERROR("Secondary display disabled.");
			}
		}
	} else {
		EMGD_DEBUG("Skipped secondary programming, NULL handle");
	}

	/*
	 * Workaround: wait for Vblank to avoid people accessing display
	 * plane registers before the register is updated properly.
	 */
	if (primary && *primary) {
		EMGD_DEBUG("Wait for vblank on primary display (%p)", primary);
		EMGD_DEBUG("Wait for vblank on primary display (%p)", *primary);
		mode_context->dispatch->wait_vblank(*primary);
	} else if (secondary && *secondary) {
		EMGD_DEBUG("Wait for vblank on secondary display");
		mode_context->dispatch->wait_vblank(*secondary);
	}

	EMGD_TRACE_EXIT;
	return 0;
}
Esempio n. 11
0
int query_ovl2_tnc(igd_display_h display_h,
	unsigned int flags)
{
	igd_display_context_t *display = (igd_display_context_t *)display_h;
	inter_module_dispatch_t *md;
	platform_context_tnc_t * platform;
	os_alarm_t timeout;
	int ret;
	unsigned long pipe_reg, pipe_num;

	EMGD_TRACE_ENTER;

	switch (flags) {
	case IGD_OVL_QUERY_IS_HW_SUPPORTED:
		/* This is the second overlay, so HW overlay is not supported */
		break;

	case IGD_OVL_QUERY_IS_LAST_FLIP_DONE:
		/* If there no sync to wait on, then the last flip is done, and the
		 * Register Update has occured, simply return TRUE (Flip done).
		 */
		if (!ovl_context->sync2) {
			EMGD_DEBUG("Overlay already synced");
			EMGD_TRACE_EXIT;
			return TRUE;
		}

		/* According to the PBL B-spec, there doesnt seem to exist any bit
		 * for Sprite C Flip-Pending status. Testing 0x20AC in code during
		 * virt queue's REG write shows nothing changed for Bit8. Thus, we
		 * are using state of the VBLANK ISR bit as ovl2 flip status.
		 * Assumption is that if were running 2nd overlay, its either clone
		 * display or VEXT in WinCE. In either case, were not doing full screen
		 * FB flipping, so this check should be 'statefully' accurate
		 */
		md = &display->context->mod_dispatch;
		platform = (platform_context_tnc_t *)display->context->
						platform_context;

		pipe_num = PIPE(display)->pipe_num; 
		if(pipe_num){ 
			pipe_reg = PIPEB_STAT; 
		} else { 
			pipe_reg = PIPEA_STAT; 
		} 

		if(md && md->check_flip_pending){
			ret = OS_PTHREAD_MUTEX_LOCK(&platform->flip_mutex);
			if(md->check_flip_pending(MMIO(display), pipe_reg)){
				OS_PTHREAD_MUTEX_UNLOCK(&platform->flip_mutex);
				EMGD_DEBUG("Overlay2 Sync done but Flip not done");
				return FALSE;
			}
			OS_PTHREAD_MUTEX_UNLOCK(&platform->flip_mutex);
		}

		/* Now that we know the last flip is done and the register update is
		 * complete, set the sync to 0 and return TRUE (Flip done). */
		ovl_context->sync2 = FLIP_DONE;
		break;
	case IGD_OVL_QUERY_WAIT_LAST_FLIP_DONE:
		/* Wait for 200 milliseconds for the last flip to complete.  If not
		 * done in that time, there is likely a hardware problem so return
		 * FALSE. */
		timeout = OS_SET_ALARM(200);
		do {
			if (TRUE ==
				query_ovl2_tnc(display_h, IGD_OVL_QUERY_IS_LAST_FLIP_DONE)) {
				EMGD_TRACE_EXIT;
				return TRUE;
			}
		} while (!OS_TEST_ALARM(timeout));
		EMGD_ERROR_EXIT("Timeout waiting for last flip done");
		return FALSE;
		break;
	case IGD_OVL_QUERY_IS_GAMMA_SUPPORTED:
		return TRUE;
		break;
	case IGD_OVL_QUERY_IS_VIDEO_PARAM_SUPPORTED:
		return TRUE;
		break;
	}

	EMGD_TRACE_EXIT;
	return TRUE;
}
Esempio n. 12
0
unsigned int ovl2_send_instr_tnc(
	igd_display_context_t     *display,
	ovl2_reg_tnc_t    *spritec_regs_tnc,
	unsigned int      flags)
{
	unsigned char *mmio = MMIO(display);
	 unsigned long tmp, pipe_reg, pipe_num;
	inter_module_dispatch_t *md;
	platform_context_tnc_t * platform;


	EMGD_TRACE_ENTER;

	/* We dont need the CMD_WAIT_OVL2_TNC instruction coz
	 * our alter_ovl code already querried status
	 * for last flip completion before getting here. See
	 * micro_prepare_ovl2_tnc called by alter_ovl2_tnc.
	 * It calls query overlay before the next flip
	 */

	/*If Overlay+FB Blend is requested and the FB is xRGB
	 *turn on the ARGB format. */
	if(ovl_context->fb_blend_ovl) {
		if((flags & IGD_OVL_ALTER_ON) == IGD_OVL_ALTER_ON) {
			tmp = EMGD_READ32(mmio + PLANE(display)->plane_reg);
			if((tmp & 0x3c000000) == 0x18000000) {
				tmp = tmp & 0xc3FFFFFF;
				EMGD_WRITE32(tmp | 0x1c000000, mmio + PLANE(display)->plane_reg);
				EMGD_READ32(mmio + PLANE(display)->plane_reg);
				tmp = EMGD_READ32(mmio + PLANE(display)->plane_reg + 0x1c);
				EMGD_WRITE32(tmp, mmio + PLANE(display)->plane_reg + 0x1c);
			}
		} else {
			tmp =  EMGD_READ32(mmio + PLANE(display)->plane_reg);
			if((tmp & 0x3c000000) == 0x1c000000) {
				tmp = tmp & 0xc3FFFFFF;
				EMGD_WRITE32(tmp | 0x18000000, mmio + PLANE(display)->plane_reg);
				EMGD_READ32(mmio + PLANE(display)->plane_reg);
				tmp = EMGD_READ32(mmio + PLANE(display)->plane_reg + 0x1c);
				EMGD_WRITE32(tmp, mmio + PLANE(display)->plane_reg + 0x1c);
				OS_SLEEP(100);
			}
		}
	}

	/* Send a load register instruction to write the Plane C sprite address
	 * which is the trigger register.
	 * This is an instruction, so it happens after blend, and since it
	 * is an instruction, we do not have to poll waiting for it. */
	EMGD_WRITE32(spritec_regs_tnc->start, mmio + 0x7219C);

	/* Since the ISR bit 0x100 actually doesnt work,
	 * we need to setup a trigger for a VBLANK event
	 * on Pipe-B to guarantee that the Sprite-C had
	 * actually completed its last flip.
	 * (ISR bit was tested on Poulsbo D2 by capturing
	 * timestamps of quick successive alter_overlays..
	 * checked ISR bit directly after the write to Sprite
	 * C Address register in process_vqueue handling..
	 * the ISR bit never changed
	 */

	md = &display->context->mod_dispatch;
	platform = (platform_context_tnc_t *)display->context->
					platform_context;

	pipe_num = PIPE(display)->pipe_num; 
    
	if(pipe_num){ 
		pipe_reg = PIPEB_STAT; 
	} else { 
		pipe_reg = PIPEA_STAT; 
	} 

	if(md && md->set_flip_pending){
		OS_PTHREAD_MUTEX_LOCK(&platform->flip_mutex);
		md->set_flip_pending(MMIO(display), pipe_reg);
		OS_PTHREAD_MUTEX_UNLOCK(&platform->flip_mutex);
	}

	ovl_context->sync2 = WAIT_FOR_FLIP;

	EMGD_TRACE_EXIT;
	return IGD_SUCCESS;
}
Esempio n. 13
0
void
sis_update_texture_state (sisContextPtr smesa)
{
   __GLSiSHardware *prev = &smesa->prev;

   mWait3DCmdQueue (55);
   if (smesa->clearTexCache || (smesa->GlobalFlag & GFLAG_TEXTUREADDRESS)) {
      MMIO(REG_3D_TEnable, prev->hwCapEnable | MASK_TextureCacheClear);
      MMIO(REG_3D_TEnable, prev->hwCapEnable);
      smesa->clearTexCache = GL_FALSE;
   }

   /* Texture Setting */
   if (smesa->GlobalFlag & CFLAG_TEXTURERESET)
      MMIO(REG_3D_TextureSet, prev->texture[0].hwTextureSet);

   if (smesa->GlobalFlag & GFLAG_TEXTUREMIPMAP)
      MMIO(REG_3D_TextureMip, prev->texture[0].hwTextureMip);

  /*
  MMIO(REG_3D_TextureTransparencyColorHigh, prev->texture[0].hwTextureClrHigh);
  MMIO(REG_3D_TextureTransparencyColorLow, prev->texture[0].hwTextureClrLow);
  */

   if (smesa->GlobalFlag & GFLAG_TEXBORDERCOLOR)
      MMIO(REG_3D_TextureBorderColor, prev->texture[0].hwTextureBorderColor);

   if (smesa->GlobalFlag & GFLAG_TEXTUREADDRESS) {
      switch ((prev->texture[0].hwTextureSet & MASK_TextureLevel) >> 8)
      {
      case 11:
         MMIO(REG_3D_TextureAddress11, prev->texture[0].texOffset11);
      case 10:
         MMIO(REG_3D_TextureAddress10, prev->texture[0].texOffset10);
         MMIO(REG_3D_TexturePitch10, prev->texture[0].texPitch10);
      case 9:
         MMIO(REG_3D_TextureAddress9, prev->texture[0].texOffset9);
      case 8:
         MMIO(REG_3D_TextureAddress8, prev->texture[0].texOffset8);
         MMIO(REG_3D_TexturePitch8, prev->texture[0].texPitch89);
      case 7:
         MMIO(REG_3D_TextureAddress7, prev->texture[0].texOffset7);
      case 6:
         MMIO(REG_3D_TextureAddress6, prev->texture[0].texOffset6);
         MMIO(REG_3D_TexturePitch6, prev->texture[0].texPitch67);
      case 5:
         MMIO(REG_3D_TextureAddress5, prev->texture[0].texOffset5);
      case 4:
         MMIO(REG_3D_TextureAddress4, prev->texture[0].texOffset4);
         MMIO(REG_3D_TexturePitch4, prev->texture[0].texPitch45);
      case 3:
         MMIO(REG_3D_TextureAddress3, prev->texture[0].texOffset3);
      case 2:
         MMIO(REG_3D_TextureAddress2, prev->texture[0].texOffset2);
         MMIO(REG_3D_TexturePitch2, prev->texture[0].texPitch23);
      case 1:
         MMIO(REG_3D_TextureAddress1, prev->texture[0].texOffset1);
      case 0:
	  MMIO(REG_3D_TextureAddress0, prev->texture[0].texOffset0);
	  MMIO(REG_3D_TexturePitch0, prev->texture[0].texPitch01);
      }
   }
   if (smesa->GlobalFlag & CFLAG_TEXTURERESET_1)
      MMIO(REG_3D_Texture1Set, prev->texture[1].hwTextureSet);
   if (smesa->GlobalFlag & GFLAG_TEXTUREMIPMAP_1)
      MMIO(REG_3D_Texture1Mip, prev->texture[1].hwTextureMip);

   if (smesa->GlobalFlag & GFLAG_TEXBORDERCOLOR_1) {
      MMIO(REG_3D_Texture1BorderColor,
	    prev->texture[1].hwTextureBorderColor);
   }
   if (smesa->GlobalFlag & GFLAG_TEXTUREADDRESS_1) {
      switch ((prev->texture[1].hwTextureSet & MASK_TextureLevel) >> 8)
      {
      case 11:
         MMIO(REG_3D_Texture1Address11, prev->texture[1].texOffset11);
      case 10:
         MMIO(REG_3D_Texture1Address10, prev->texture[1].texOffset10);
         MMIO(REG_3D_Texture1Pitch10, prev->texture[1].texPitch10);
      case 9:
         MMIO(REG_3D_Texture1Address9, prev->texture[1].texOffset9);
      case 8:
         MMIO(REG_3D_Texture1Address8, prev->texture[1].texOffset8);
         MMIO(REG_3D_Texture1Pitch8, prev->texture[1].texPitch89);
      case 7:
         MMIO(REG_3D_Texture1Address7, prev->texture[1].texOffset7);
      case 6:
         MMIO(REG_3D_Texture1Address6, prev->texture[1].texOffset6);
         MMIO(REG_3D_Texture1Pitch6, prev->texture[1].texPitch67);
      case 5:
         MMIO(REG_3D_Texture1Address5, prev->texture[1].texOffset5);
      case 4:
         MMIO(REG_3D_Texture1Address4, prev->texture[1].texOffset4);
         MMIO(REG_3D_Texture1Pitch4, prev->texture[1].texPitch45);
      case 3:
         MMIO(REG_3D_Texture1Address3, prev->texture[1].texOffset3);
      case 2:
         MMIO(REG_3D_Texture1Address2, prev->texture[1].texOffset2);
         MMIO(REG_3D_Texture1Pitch2, prev->texture[1].texPitch23);
      case 1:
         MMIO(REG_3D_Texture1Address1, prev->texture[1].texOffset1);
      case 0:
         MMIO(REG_3D_Texture1Address0, prev->texture[1].texOffset0);
         MMIO(REG_3D_Texture1Pitch0, prev->texture[1].texPitch01);
      }
   }

   /* texture environment */
   if (smesa->GlobalFlag & GFLAG_TEXTUREENV) {
      MMIO(REG_3D_TextureBlendFactor, prev->hwTexEnvColor);
      MMIO(REG_3D_TextureColorBlendSet0, prev->hwTexBlendColor0);
      MMIO(REG_3D_TextureAlphaBlendSet0, prev->hwTexBlendAlpha0);
   }
   if (smesa->GlobalFlag & GFLAG_TEXTUREENV_1) {
      MMIO(REG_3D_TextureBlendFactor, prev->hwTexEnvColor);
      MMIO(REG_3D_TextureColorBlendSet1, prev->hwTexBlendColor1);
      MMIO(REG_3D_TextureAlphaBlendSet1, prev->hwTexBlendAlpha1);
   }

   smesa->GlobalFlag &= ~GFLAG_TEXTURE_STATES;
}
Esempio n. 14
0
void
sis_update_render_state( sisContextPtr smesa )
{
   __GLSiSHardware *prev = &smesa->prev;

   mWait3DCmdQueue (45);

   if (smesa->GlobalFlag & GFLAG_ENABLESETTING) {
      if (!smesa->clearTexCache) {
	 MMIO(REG_3D_TEnable, prev->hwCapEnable);
      } else {
	 MMIO(REG_3D_TEnable, prev->hwCapEnable | MASK_TextureCacheClear);
	 MMIO(REG_3D_TEnable, prev->hwCapEnable);
	 smesa->clearTexCache = GL_FALSE;
      }
   }

   if (smesa->GlobalFlag & GFLAG_ENABLESETTING2)
      MMIO(REG_3D_TEnable2, prev->hwCapEnable2);

   /* Z Setting */
   if (smesa->GlobalFlag & GFLAG_ZSETTING)
   {
      MMIO(REG_3D_ZSet, prev->hwZ);
      MMIO(REG_3D_ZStWriteMask, prev->hwZMask);
      MMIO(REG_3D_ZAddress, prev->hwOffsetZ);
   }

   /* Alpha Setting */
   if (smesa->GlobalFlag & GFLAG_ALPHASETTING)
      MMIO(REG_3D_AlphaSet, prev->hwAlpha);

   if (smesa->GlobalFlag & GFLAG_DESTSETTING) {
      MMIO(REG_3D_DstSet, prev->hwDstSet);
      MMIO(REG_3D_DstAlphaWriteMask, prev->hwDstMask);
      MMIO(REG_3D_DstAddress, prev->hwOffsetDest);
   }

   /* Line Setting */
#if 0
   if (smesa->GlobalFlag & GFLAG_LINESETTING) 
      MMIO(REG_3D_LinePattern, prev->hwLinePattern);
#endif

   /* Fog Setting */
   if (smesa->GlobalFlag & GFLAG_FOGSETTING)
   {
      MMIO(REG_3D_FogSet, prev->hwFog);
      MMIO(REG_3D_FogInverseDistance, prev->hwFogInverse);
      MMIO(REG_3D_FogFarDistance, prev->hwFogFar);
      MMIO(REG_3D_FogFactorDensity, prev->hwFogDensity);
   }

   /* Stencil Setting */
   if (smesa->GlobalFlag & GFLAG_STENCILSETTING) {
      MMIO(REG_3D_StencilSet, prev->hwStSetting);
      MMIO(REG_3D_StencilSet2, prev->hwStSetting2);
   }

   /* Miscellaneous Setting */
   if (smesa->GlobalFlag & GFLAG_DSTBLEND)
      MMIO(REG_3D_DstBlendMode, prev->hwDstSrcBlend);
   if (smesa->GlobalFlag & GFLAG_CLIPPING) {
      MMIO(REG_3D_ClipTopBottom, prev->clipTopBottom);
      MMIO(REG_3D_ClipLeftRight, prev->clipLeftRight);
   }

  smesa->GlobalFlag &= ~GFLAG_RENDER_STATES;
}
Esempio n. 15
0
unsigned int ovl2_send_instr_plb(
	igd_display_context_t     *display,
	ovl2_reg_plb_t    *spritec_regs_plb,
	unsigned int      flags)
{
	unsigned char * mmio = MMIO(display);
	unsigned long tmp;
	inter_module_dispatch_t *md;
	platform_context_plb_t * platform;
	unsigned int pipe_num;
	unsigned long pipe_reg;
	int ret;

	EMGD_TRACE_ENTER;

	/* We dont need the CMD_WAIT_OVL2_PLB instruction coz
	 * our alter_ovl code already querried status
	 * for last flip completion before getting here. See
	 * micro_prepare_ovl2_plb called by alter_ovl2_plb.
	 * It calls query overlay before the next flip
	 */


	/*
	 * If Overlay + FB Blend is requested and the FB is xRGB
	 * turn on the ARGB format.
	 */
	if(ovl_context->fb_blend_ovl) {
		if ((flags & IGD_OVL_ALTER_ON) != IGD_OVL_ALTER_ON) {
			tmp = EMGD_READ32(mmio +  PLANE(display)->plane_reg);
			if((tmp & 0x3c000000) == 0x1c000000) {
				tmp = tmp & 0xc3FFFFFF;
				EMGD_WRITE32(tmp | 0x18000000, mmio +  PLANE(display)->plane_reg);
				tmp = EMGD_READ32(mmio + PLANE(display)->plane_reg + 4);
				EMGD_WRITE32(tmp, mmio + PLANE(display)->plane_reg + 4);
				OS_SLEEP(100);
			}
		} else {
			tmp = EMGD_READ32(mmio +  PLANE(display)->plane_reg);
			if((tmp & 0x3c000000) == 0x18000000) {
				EMGD_WRITE32(tmp | 0x1c000000, mmio +  PLANE(display)->plane_reg);
				tmp = EMGD_READ32(mmio + PLANE(display)->plane_reg + 4);
				EMGD_WRITE32(tmp, mmio + PLANE(display)->plane_reg + 4);
			}
		}
	}


	/* Send a load register instruction to write the Plane C sprite address
	 * which is the trigger register.
	 * This is an instruction, so it happens after blend, and since it
	 * is an instruction, we do not have to poll waiting for it. */
	EMGD_WRITE32(spritec_regs_plb->start, mmio + 0x72184);

	md = &display->context->mod_dispatch;
	platform = (platform_context_plb_t *)display->context->
			platform_context;

	pipe_num = PIPE(display)->pipe_num;

	if(pipe_num){
		pipe_reg = 0x71024;
	} else {
		pipe_reg = 0x70024;
	}

        if(md && md->set_flip_pending){
                /* For second overlay, Poulsbo has no ISR bit
	         * to reflect the flip pending for Display
                 * Sprite C. So we use Pipe-B vblank status
                 * as a substitute
                 */
                ret = OS_PTHREAD_MUTEX_LOCK(&platform->flip_mutex);
                md->set_flip_pending(MMIO(display), pipe_reg);
                OS_PTHREAD_MUTEX_UNLOCK(&platform->flip_mutex);
        }

	ovl_context->sync2 = 0;

	display->context->dispatch.sync(display,
		IGD_PRIORITY_NORMAL,
		&ovl_context->sync2,
		IGD_SYNC_NONBLOCK);

	EMGD_TRACE_EXIT;
	return IGD_SUCCESS;
}