static int mdp4_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) { struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); struct mdp4_kms *mdp4_kms = get_kms(crtc); enum mdp4_dma dma = mdp4_crtc->dma; mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_POS(dma), MDP4_DMA_CURSOR_POS_X(x) | MDP4_DMA_CURSOR_POS_Y(y)); return 0; }
/* called from IRQ to update cursor related registers (if needed). The * cursor registers, other than x/y position, appear not to be double * buffered, and changing them other than from vblank seems to trigger * underflow. */ static void update_cursor(struct drm_crtc *crtc) { struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); struct mdp4_kms *mdp4_kms = get_kms(crtc); enum mdp4_dma dma = mdp4_crtc->dma; unsigned long flags; spin_lock_irqsave(&mdp4_crtc->cursor.lock, flags); if (mdp4_crtc->cursor.stale) { struct drm_gem_object *next_bo = mdp4_crtc->cursor.next_bo; struct drm_gem_object *prev_bo = mdp4_crtc->cursor.scanout_bo; uint32_t iova = mdp4_crtc->cursor.next_iova; if (next_bo) { /* take a obj ref + iova ref when we start scanning out: */ drm_gem_object_reference(next_bo); msm_gem_get_iova_locked(next_bo, mdp4_kms->id, &iova); /* enable cursor: */ mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_SIZE(dma), MDP4_DMA_CURSOR_SIZE_WIDTH(mdp4_crtc->cursor.width) | MDP4_DMA_CURSOR_SIZE_HEIGHT(mdp4_crtc->cursor.height)); mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_BASE(dma), iova); mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_BLEND_CONFIG(dma), MDP4_DMA_CURSOR_BLEND_CONFIG_FORMAT(CURSOR_ARGB) | MDP4_DMA_CURSOR_BLEND_CONFIG_CURSOR_EN); } else { /* disable cursor: */ mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_BASE(dma), mdp4_kms->blank_cursor_iova); } /* and drop the iova ref + obj rev when done scanning out: */ if (prev_bo) drm_flip_work_queue(&mdp4_crtc->unref_cursor_work, prev_bo); mdp4_crtc->cursor.scanout_bo = next_bo; mdp4_crtc->cursor.stale = false; } mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_POS(dma), MDP4_DMA_CURSOR_POS_X(mdp4_crtc->cursor.x) | MDP4_DMA_CURSOR_POS_Y(mdp4_crtc->cursor.y)); spin_unlock_irqrestore(&mdp4_crtc->cursor.lock, flags); }