/** * 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); }
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); }
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); }
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); }
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 */ }
/** * 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); }
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); }
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); }