static int mtk_plane_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) { struct drm_framebuffer *fb = state->fb; struct drm_crtc_state *crtc_state; struct drm_rect clip = { 0, }; if (!fb) return 0; if (!mtk_fb_get_gem_obj(fb)) { DRM_DEBUG_KMS("buffer is null\n"); return -EFAULT; } if (!state->crtc) return 0; crtc_state = drm_atomic_get_crtc_state(state->state, state->crtc); if (IS_ERR(crtc_state)) return PTR_ERR(crtc_state); clip.x2 = crtc_state->mode.hdisplay; clip.y2 = crtc_state->mode.vdisplay; return drm_atomic_helper_check_plane_state(state, crtc_state, &clip, DRM_PLANE_HELPER_NO_SCALING, DRM_PLANE_HELPER_NO_SCALING, true, true); }
static void mtk_plane_atomic_update(struct drm_plane *plane, struct drm_plane_state *old_state) { struct mtk_plane_state *state = to_mtk_plane_state(plane->state); struct drm_crtc *crtc = plane->state->crtc; struct drm_framebuffer *fb = plane->state->fb; struct drm_gem_object *gem; struct mtk_drm_gem_obj *mtk_gem; unsigned int pitch, format; dma_addr_t addr; if (!crtc || WARN_ON(!fb)) return; gem = mtk_fb_get_gem_obj(fb); mtk_gem = to_mtk_gem_obj(gem); addr = mtk_gem->dma_addr; pitch = fb->pitches[0]; format = fb->format->format; addr += (plane->state->src.x1 >> 16) * fb->format->cpp[0]; addr += (plane->state->src.y1 >> 16) * pitch; state->pending.enable = true; state->pending.pitch = pitch; state->pending.format = format; state->pending.addr = addr; state->pending.x = plane->state->dst.x1; state->pending.y = plane->state->dst.y1; state->pending.width = drm_rect_width(&plane->state->dst); state->pending.height = drm_rect_height(&plane->state->dst); wmb(); /* Make sure the above parameters are set before update */ state->pending.dirty = true; }
/* * Wait for any exclusive fence in fb's gem object's reservation object. * * Returns -ERESTARTSYS if interrupted, else 0. */ int mtk_fb_wait(struct drm_framebuffer *fb) { struct drm_gem_object *gem; struct reservation_object *resv; long ret; if (!fb) return 0; gem = mtk_fb_get_gem_obj(fb); if (!gem || !gem->dma_buf || !gem->dma_buf->resv) return 0; resv = gem->dma_buf->resv; ret = reservation_object_wait_timeout_rcu(resv, false, true, MAX_SCHEDULE_TIMEOUT); /* MAX_SCHEDULE_TIMEOUT on success, -ERESTARTSYS if interrupted */ if (WARN_ON(ret < 0)) return ret; return 0; }