Exemplo n.º 1
0
/**
 *	psbfb_copyarea_accel	-	copyarea acceleration for /dev/fb
 *	@info: our framebuffer
 *	@a: copyarea parameters from the framebuffer core
 *
 *	Perform a 2D copy via the accelerator
 */
static void psbfb_copyarea_accel(struct fb_info *info,
				 const struct fb_copyarea *a)
{
	struct psb_fbdev *fbdev = info->par;
	struct psb_framebuffer *psbfb = &fbdev->pfb;
	struct drm_device *dev = psbfb->base.dev;
	struct drm_framebuffer *fb = fbdev->psb_fb_helper.fb;
	struct drm_psb_private *dev_priv = dev->dev_private;
	uint32_t offset;
	uint32_t stride;
	uint32_t src_format;
	uint32_t dst_format;

	if (!fb)
		return;

	offset = psbfb->gtt->offset;
	stride = fb->pitches[0];

	switch (fb->depth) {
	case 8:
		src_format = PSB_2D_SRC_332RGB;
		dst_format = PSB_2D_DST_332RGB;
		break;
	case 15:
		src_format = PSB_2D_SRC_555RGB;
		dst_format = PSB_2D_DST_555RGB;
		break;
	case 16:
		src_format = PSB_2D_SRC_565RGB;
		dst_format = PSB_2D_DST_565RGB;
		break;
	case 24:
	case 32:
		/* this is wrong but since we don't do blending its okay */
		src_format = PSB_2D_SRC_8888ARGB;
		dst_format = PSB_2D_DST_8888ARGB;
		break;
	default:
		/* software fallback */
		cfb_copyarea(info, a);
		return;
	}

	if (!gma_power_begin(dev, false)) {
		cfb_copyarea(info, a);
		return;
	}
	psb_accel_2d_copy(dev_priv,
			  offset, stride, src_format,
			  offset, stride, dst_format,
			  a->sx, a->sy, a->dx, a->dy, a->width, a->height);
	gma_power_end(dev);
}
Exemplo n.º 2
0
static void
nouveau_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *image)
{
	struct nouveau_fbdev *nfbdev = info->par;
	struct drm_device *dev = nfbdev->dev;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	int ret;

	if (info->state != FBINFO_STATE_RUNNING)
		return;

	ret = -ENODEV;
	if (!in_interrupt() && !(info->flags & FBINFO_HWACCEL_DISABLED) &&
	    mutex_trylock(&dev_priv->channel->mutex)) {
		if (dev_priv->card_type < NV_50)
			ret = nv04_fbcon_copyarea(info, image);
		else
		if (dev_priv->card_type < NV_C0)
			ret = nv50_fbcon_copyarea(info, image);
		else
			ret = nvc0_fbcon_copyarea(info, image);
		mutex_unlock(&dev_priv->channel->mutex);
	}

	if (ret == 0)
		return;

	if (ret != -ENODEV)
		nouveau_fbcon_gpu_lockup(info);
	cfb_copyarea(info, image);
}
Exemplo n.º 3
0
static void
nv04_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region)
{
	struct nouveau_fbcon_par *par = info->par;
	struct drm_device *dev = par->dev;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_channel *chan = dev_priv->channel;

	if (info->state != FBINFO_STATE_RUNNING)
		return;

	if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 4)) {
		nouveau_fbcon_gpu_lockup(info);
	}

	if (info->flags & FBINFO_HWACCEL_DISABLED) {
		cfb_copyarea(info, region);
		return;
	}

	BEGIN_RING(chan, NvSubImageBlit, 0x0300, 3);
	OUT_RING(chan, (region->sy << 16) | region->sx);
	OUT_RING(chan, (region->dy << 16) | region->dx);
	OUT_RING(chan, (region->height << 16) | region->width);
	FIRE_RING(chan);
}
Exemplo n.º 4
0
static void hvfb_cfb_copyarea(struct fb_info *p,
			      const struct fb_copyarea *area)
{
	struct hvfb_par *par = p->par;

	cfb_copyarea(p, area);
	if (par->synchronous_fb)
		synthvid_update(p);
}
Exemplo n.º 5
0
void psbfb_copyarea(struct fb_info *info,
			   const struct fb_copyarea *region)
{
	if (unlikely(info->state != FBINFO_STATE_RUNNING))
		return;

	if (info->flags & FBINFO_HWACCEL_DISABLED)
		return cfb_copyarea(info, region);

	/* psb_check_power_state(dev, PSB_DEVICE_SGX); */
	psbfb_copyarea_accel(info, region);
	/* Need to power back off here for MRST FIXMEAC */
}
Exemplo n.º 6
0
/**
 *	psbfb_copyarea	-	2D copy interface
 *	@info: our framebuffer
 *	@region: region to copy
 *
 *	Copy an area of the framebuffer console either by the accelerator
 *	or directly using the cfb helpers according to the request
 */
void psbfb_copyarea(struct fb_info *info,
			   const struct fb_copyarea *region)
{
	if (unlikely(info->state != FBINFO_STATE_RUNNING))
		return;

	/* Avoid the 8 pixel erratum */
	if (region->width == 8 || region->height == 8 ||
		(info->flags & FBINFO_HWACCEL_DISABLED))
		return cfb_copyarea(info, region);

	psbfb_copyarea_accel(info, region);
}
Exemplo n.º 7
0
void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
{
	struct atyfb_par *par = (struct atyfb_par *) info->par;
	u32 dy = area->dy, sy = area->sy, direction = DST_LAST_PEL;
	u32 sx = area->sx, dx = area->dx, width = area->width, rotation = 0;

	if (par->asleep)
		return;
	if (!area->width || !area->height)
		return;
	if (!par->accel_flags) {
		cfb_copyarea(info, area);
		return;
	}

	if (info->var.bits_per_pixel == 24) {
		/* In 24 bpp, the engine is in 8 bpp - this requires that all */
		/* horizontal coordinates and widths must be adjusted */
		sx *= 3;
		dx *= 3;
		width *= 3;
	}

	if (area->sy < area->dy) {
		dy += area->height - 1;
		sy += area->height - 1;
	} else
		direction |= DST_Y_TOP_TO_BOTTOM;

	if (sx < dx) {
		dx += width - 1;
		sx += width - 1;
	} else
		direction |= DST_X_LEFT_TO_RIGHT;

	if (info->var.bits_per_pixel == 24) {
		rotation = rotation24bpp(dx, direction);
	}

	wait_for_fifo(4, par);
	aty_st_le32(DP_SRC, FRGD_SRC_BLIT, par);
	aty_st_le32(SRC_Y_X, (sx << 16) | sy, par);
	aty_st_le32(SRC_HEIGHT1_WIDTH1, (width << 16) | area->height, par);
	aty_st_le32(DST_CNTL, direction | rotation, par);
	draw_rect(dx, dy, width, area->height, par);
}
Exemplo n.º 8
0
void i810fb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
{
	struct i810fb_par *par = info->par;
	u32 sx, sy, dx, dy, pitch, width, height, src, dest, xdir;

	if (!info->var.accel_flags || par->dev_flags & LOCKUP ||
	    par->depth == 4) {
		cfb_copyarea(info, region);
		return;
	}

	dx = region->dx * par->depth;
	sx = region->sx * par->depth;
	width = region->width * par->depth;
	sy = region->sy;
	dy = region->dy;
	height = region->height;

	if (dx <= sx) {
		xdir = INCREMENT;
	}
	else {
		xdir = DECREMENT;
		sx += width - 1;
		dx += width - 1;
	}
	if (dy <= sy) {
		pitch = info->fix.line_length;
	}
	else {
		pitch = (-(info->fix.line_length)) & 0xFFFF;
		sy += height - 1;
		dy += height - 1;
	}
	src = info->fix.smem_start + (sy * info->fix.line_length) + sx;
	dest = info->fix.smem_start + (dy * info->fix.line_length) + dx;

	source_copy_blit(width, height, pitch, xdir, src, dest,
			 PAT_COPY_ROP, par->blit_bpp, info);
}