void GGI_kgi_mach64_gcchanged(struct ggi_visual *vis, int mask) { if(mask & GGI_GCCHANGED_FG){ MACH64_CHECK(vis, 2); MACH64_WRITE(vis, MACH64_DP_FRGD_CLR); MACH64_WRITE(vis, LIBGGI_GC_FGCOLOR(vis)); } if(mask & GGI_GCCHANGED_BG){ MACH64_CHECK(vis, 2); MACH64_WRITE(vis, MACH64_DP_BKGD_CLR); MACH64_WRITE(vis, LIBGGI_GC_BGCOLOR(vis)); } }
irqreturn_t mach64_driver_irq_handler(DRM_IRQ_ARGS) { struct drm_device *dev = arg; drm_mach64_private_t *dev_priv = dev->dev_private; int status; status = MACH64_READ(MACH64_CRTC_INT_CNTL); /* VBLANK interrupt */ if (status & MACH64_CRTC_VBLANK_INT) { /* Mask off all interrupt ack bits before setting the ack bit, since * there may be other handlers outside the DRM. * * NOTE: On mach64, you need to keep the enable bits set when doing * the ack, despite what the docs say about not acking and enabling * in a single write. */ MACH64_WRITE(MACH64_CRTC_INT_CNTL, (status & ~MACH64_CRTC_INT_ACKS) | MACH64_CRTC_VBLANK_INT); atomic_inc(&dev_priv->vbl_received); drm_handle_vblank(dev, 0); return IRQ_HANDLED; } return IRQ_NONE; }
static void mach64_disable_vblank_local(struct drm_device * dev, int crtc) { drm_mach64_private_t *dev_priv = dev->dev_private; u32 status = MACH64_READ(MACH64_CRTC_INT_CNTL); if (crtc != 0) { DRM_ERROR("tried to disable vblank on non-existent crtc %d\n", crtc); return; } DRM_DEBUG("before disable vblank CRTC_INT_CTNL: 0x%08x\n", status); /* Disable and clear VBLANK interrupt */ MACH64_WRITE(MACH64_CRTC_INT_CNTL, (status & ~MACH64_CRTC_VBLANK_INT_EN) | MACH64_CRTC_VBLANK_INT); }
int mach64_enable_vblank(struct drm_device * dev, int crtc) { drm_mach64_private_t *dev_priv = dev->dev_private; u32 status = MACH64_READ(MACH64_CRTC_INT_CNTL); if (crtc != 0) { DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", crtc); return -EINVAL; } DRM_DEBUG("before enable vblank CRTC_INT_CTNL: 0x%08x\n", status); /* Turn on VBLANK interrupt */ MACH64_WRITE(MACH64_CRTC_INT_CNTL, MACH64_READ(MACH64_CRTC_INT_CNTL) | MACH64_CRTC_VBLANK_INT_EN); return 0; }
int GGI_kgi_mach64_drawbox(ggi_visual *vis, int x, int y, int w, int h) { MACH64_CHECK(vis, 6); MACH64_WRITE(vis, MACH64_DST_CNTL); MACH64_WRITE(vis, 0x00000003); MACH64_WRITE(vis, MACH64_DST_X_Y); MACH64_WRITE(vis, ((x << MACH64_BA_DST_XShift) & MACH64_BA_DST_XMask) | ((y << MACH64_BA_DST_YShift) & MACH64_BA_DST_YMask)); MACH64_WRITE(vis, MACH64_DST_WIDTH_HEIGHT); MACH64_WRITE(vis, ((w << MACH64_BB_DST_WIDTHShift) & MACH64_BB_DST_WIDTHMask) | ((h << MACH64_BB_DST_HEIGHTShift) & MACH64_BB_DST_HEIGHTMask)); return 0; }
int GGI_kgi_mach64_copybox(ggi_visual *vis, int x, int y, int w, int h, int nx, int ny) { uint32_t direction = MACH64_4C_DST_LAST_PEL; if ((w < 1) || (h < 1)) return 0; if (y < ny) { y += h-1; ny += h-1; } else direction |= MACH64_4C_DST_Y_DIR; if (x < nx) { x += w-1; nx += w-1; } else direction |= MACH64_4C_DST_X_DIR; MACH64_CHECK(vis, 12); MACH64_WRITE(vis, MACH64_DP_SRC); MACH64_WRITE(vis, 0x3 << MACH64_B6_DP_FRGD_SRCShift); MACH64_WRITE(vis, MACH64_DST_CNTL); MACH64_WRITE(vis, direction); MACH64_WRITE(vis, MACH64_SRC_Y_X); MACH64_WRITE(vis, (x << MACH64_63_SRC_XShift) | y); MACH64_WRITE(vis, MACH64_SRC_HEIGHT1_WIDTH1); MACH64_WRITE(vis, (w << MACH64_66_SRC_WIDTH1Shift) | h); MACH64_WRITE(vis, MACH64_DST_Y_X); MACH64_WRITE(vis, (nx << MACH64_43_DST_XShift) | ny); MACH64_WRITE(vis, MACH64_DST_HEIGHT_WIDTH); MACH64_WRITE(vis, (w << MACH64_46_DST_WIDTHShift) | h); return 0; }