📄 ffb_context.c
字号:
upa_writel(ctx->auxclip1max, &ffb->auxclip[1].max); upa_writel(ctx->auxclip2min, &ffb->auxclip[2].min); upa_writel(ctx->auxclip2max, &ffb->auxclip[2].max); upa_writel(ctx->auxclip3min, &ffb->auxclip[3].min); upa_writel(ctx->auxclip3max, &ffb->auxclip[3].max); upa_writel(ctx->lpat, &ffb->lpat); /* Line Pattern */ upa_writel(ctx->fontxy, &ffb->fontxy); /* XY Font Coordinate */ upa_writel(ctx->fontw, &ffb->fontw); /* Font Width */ upa_writel(ctx->fontinc, &ffb->fontinc); /* Font X/Y Increment */ /* These registers/features only exist on FFB2 and later chips. */ if (fpriv->ffb_type >= ffb2_prototype) { upa_writel(ctx->dcss1, &ffb->dcss1); /* Depth Cue Scale Slope 1 */ upa_writel(ctx->dcss2, &ffb->dcss2); /* Depth Cue Scale Slope 2 */ upa_writel(ctx->dcss3, &ffb->dcss2); /* Depth Cue Scale Slope 3 */ upa_writel(ctx->dcs2, &ffb->dcs2); /* Depth Cue Scale 2 */ upa_writel(ctx->dcs3, &ffb->dcs3); /* Depth Cue Scale 3 */ upa_writel(ctx->dcs4, &ffb->dcs4); /* Depth Cue Scale 4 */ upa_writel(ctx->dcd2, &ffb->dcd2); /* Depth Cue Depth 2 */ upa_writel(ctx->dcd3, &ffb->dcd3); /* Depth Cue Depth 3 */ upa_writel(ctx->dcd4, &ffb->dcd4); /* Depth Cue Depth 4 */ /* And stencil/stencilctl only exists on FFB2+ and later * due to the introduction of 3DRAM-III. */ if (fpriv->ffb_type == ffb2_vertical_plus || fpriv->ffb_type == ffb2_horizontal_plus) { /* Unfortunately, there is a hardware bug on * the FFB2+ chips which prevents a normal write * to the stencil control register from working * as it should. * * The state controlled by the FFB stencilctl register * really gets transferred to the per-buffer instances * of the stencilctl register in the 3DRAM chips. * * The bug is that FFB does not update buffer C correctly, * so we have to do it by hand for them. */ /* This will update buffers A and B. */ upa_writel(ctx->stencil, &ffb->stencil); upa_writel(ctx->stencilctl, &ffb->stencilctl); /* Force FFB to use buffer C 3dram regs. */ upa_writel(0x80000000, &ffb->fbc); upa_writel((ctx->stencilctl | 0x80000), &ffb->rawstencilctl); /* Now restore the correct FBC controls. */ upa_writel(ctx->fbc, &ffb->fbc); } } /* Restore the 32x32 area pattern. */ for (i = 0; i < 32; i++) upa_writel(ctx->area_pattern[i], &ffb->pattern[i]); /* Finally, stash away the User Constol/Status Register. * The only state we really preserve here is the picking * control. */ upa_writel((ctx->ucsr & 0xf0000), &ffb->ucsr);}#define FFB_UCSR_FB_BUSY 0x01000000#define FFB_UCSR_RP_BUSY 0x02000000#define FFB_UCSR_ALL_BUSY (FFB_UCSR_RP_BUSY|FFB_UCSR_FB_BUSY)static void FFBWait(ffb_fbcPtr ffb){ int limit = 100000; do { u32 regval = upa_readl(&ffb->ucsr); if ((regval & FFB_UCSR_ALL_BUSY) == 0) break; } while (--limit);}int ffb_driver_context_switch(drm_device_t * dev, int old, int new){ ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;#ifdef DRM_DMA_HISTOGRAM dev->ctx_start = get_cycles();#endif DRM_DEBUG("Context switch from %d to %d\n", old, new); if (new == dev->last_context || dev->last_context == 0) { dev->last_context = new; return 0; } FFBWait(fpriv->regs); ffb_save_context(fpriv, old); ffb_restore_context(fpriv, old, new); FFBWait(fpriv->regs); dev->last_context = new; return 0;}int ffb_driver_resctx(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg){ drm_ctx_res_t res; drm_ctx_t ctx; int i; DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS); if (copy_from_user(&res, (drm_ctx_res_t __user *) arg, sizeof(res))) return -EFAULT; if (res.count >= DRM_RESERVED_CONTEXTS) { memset(&ctx, 0, sizeof(ctx)); for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) { ctx.handle = i; if (copy_to_user(&res.contexts[i], &i, sizeof(i))) return -EFAULT; } } res.count = DRM_RESERVED_CONTEXTS; if (copy_to_user((drm_ctx_res_t __user *) arg, &res, sizeof(res))) return -EFAULT; return 0;}int ffb_driver_addctx(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg){ drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; drm_ctx_t ctx; int idx; if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx))) return -EFAULT; idx = DRM(alloc_queue) (dev, (ctx.flags & _DRM_CONTEXT_2DONLY)); if (idx < 0) return -ENFILE; DRM_DEBUG("%d\n", ctx.handle); ctx.handle = idx; if (copy_to_user((drm_ctx_t __user *) arg, &ctx, sizeof(ctx))) return -EFAULT; return 0;}int ffb_driver_modctx(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg){ drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private; struct ffb_hw_context *hwctx; drm_ctx_t ctx; int idx; if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx))) return -EFAULT; idx = ctx.handle; if (idx <= 0 || idx >= FFB_MAX_CTXS) return -EINVAL; hwctx = fpriv->hw_state[idx - 1]; if (hwctx == NULL) return -EINVAL; if ((ctx.flags & _DRM_CONTEXT_2DONLY) == 0) hwctx->is_2d_only = 0; else hwctx->is_2d_only = 1; return 0;}int ffb_driver_getctx(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg){ drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private; struct ffb_hw_context *hwctx; drm_ctx_t ctx; int idx; if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx))) return -EFAULT; idx = ctx.handle; if (idx <= 0 || idx >= FFB_MAX_CTXS) return -EINVAL; hwctx = fpriv->hw_state[idx - 1]; if (hwctx == NULL) return -EINVAL; if (hwctx->is_2d_only != 0) ctx.flags = _DRM_CONTEXT_2DONLY; else ctx.flags = 0; if (copy_to_user((drm_ctx_t __user *) arg, &ctx, sizeof(ctx))) return -EFAULT; return 0;}int ffb_driver_switchctx(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg){ drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; drm_ctx_t ctx; if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx))) return -EFAULT; DRM_DEBUG("%d\n", ctx.handle); return ffb_driver_context_switch(dev, dev->last_context, ctx.handle);}int ffb_driver_newctx(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg){ drm_ctx_t ctx; if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx))) return -EFAULT; DRM_DEBUG("%d\n", ctx.handle); return 0;}int ffb_driver_rmctx(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg){ drm_ctx_t ctx; drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private; int idx; if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx))) return -EFAULT; DRM_DEBUG("%d\n", ctx.handle); idx = ctx.handle - 1; if (idx < 0 || idx >= FFB_MAX_CTXS) return -EINVAL; kfree(fpriv->hw_state[idx]); fpriv->hw_state[idx] = NULL; return 0;}void ffb_set_context_ioctls(void){ DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)].func = ffb_driver_addctx; DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)].func = ffb_driver_rmctx; DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)].func = ffb_driver_modctx; DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)].func = ffb_driver_getctx; DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)].func = ffb_driver_switchctx; DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)].func = ffb_driver_newctx; DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)].func = ffb_driver_resctx;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -