/* set crtc dpms */ static void xilinx_drm_crtc_dpms(struct drm_crtc *base_crtc, int dpms) { struct xilinx_drm_crtc *crtc = to_xilinx_crtc(base_crtc); DRM_DEBUG_KMS("dpms: %d -> %d\n", crtc->dpms, dpms); if (crtc->dpms == dpms) return; crtc->dpms = dpms; switch (dpms) { case DRM_MODE_DPMS_ON: xilinx_drm_plane_dpms(crtc->priv_plane, dpms); if (crtc->rgb2yuv) xilinx_rgb2yuv_enable(crtc->rgb2yuv); if (crtc->cresample) xilinx_cresample_enable(crtc->cresample); xilinx_vtc_enable(crtc->vtc); break; default: xilinx_vtc_disable(crtc->vtc); xilinx_vtc_reset(crtc->vtc); if (crtc->cresample) { xilinx_cresample_disable(crtc->cresample); xilinx_cresample_reset(crtc->cresample); } if (crtc->rgb2yuv) { xilinx_rgb2yuv_disable(crtc->rgb2yuv); xilinx_rgb2yuv_reset(crtc->rgb2yuv); } xilinx_drm_plane_dpms(crtc->priv_plane, dpms); break; } }
/* destroy a plane */ static void xilinx_drm_plane_destroy(struct drm_plane *base_plane) { struct xilinx_drm_plane *plane = to_xilinx_plane(base_plane); unsigned int i; xilinx_drm_plane_dpms(base_plane, DRM_MODE_DPMS_OFF); plane->manager->planes[plane->id] = NULL; drm_plane_cleanup(base_plane); for (i = 0; i < MAX_NUM_SUB_PLANES; i++) if (plane->dma[i].chan) dma_release_channel(plane->dma[i].chan); if (plane->manager->osd) { xilinx_osd_layer_disable(plane->osd_layer); xilinx_osd_layer_put(plane->osd_layer); } if (plane->manager->dp_sub) { xilinx_drm_dp_sub_layer_disable(plane->manager->dp_sub, plane->dp_layer); xilinx_drm_dp_sub_layer_put(plane->manager->dp_sub, plane->dp_layer); } }
/* update a plane. just call mode_set() with bit-shifted values */ static int xilinx_drm_plane_update(struct drm_plane *base_plane, struct drm_crtc *crtc, struct drm_framebuffer *fb, int crtc_x, int crtc_y, unsigned int crtc_w, unsigned int crtc_h, uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h) { int ret; ret = xilinx_drm_plane_mode_set(base_plane, fb, crtc_x, crtc_y, crtc_w, crtc_h, src_x >> 16, src_y >> 16, src_w >> 16, src_h >> 16); if (ret) { DRM_ERROR("failed to mode-set a plane\n"); return ret; } /* make sure a plane is on */ xilinx_drm_plane_dpms(base_plane, DRM_MODE_DPMS_ON); /* apply the new fb addr */ xilinx_drm_plane_commit(base_plane); return 0; }
void xilinx_drm_plane_remove_manager(struct xilinx_drm_plane_manager *manager) { int i; for (i = 0; i < manager->num_planes; i++) { if (manager->planes[i] && !manager->planes[i]->priv) { xilinx_drm_plane_dpms(&manager->planes[i]->base, DRM_MODE_DPMS_OFF); xilinx_drm_plane_destroy(&manager->planes[i]->base); manager->planes[i] = NULL; } } of_node_put(manager->node); }
/* destroy a plane */ static void xilinx_drm_plane_destroy(struct drm_plane *base_plane) { struct xilinx_drm_plane *plane = to_xilinx_plane(base_plane); xilinx_drm_plane_dpms(base_plane, DRM_MODE_DPMS_OFF); plane->manager->planes[plane->id] = NULL; drm_plane_cleanup(base_plane); dma_release_channel(plane->dma.chan); if (plane->manager->osd) { xilinx_osd_layer_disable(plane->osd_layer); xilinx_osd_layer_put(plane->osd_layer); } }
/* disable a plane */ static int xilinx_drm_plane_disable(struct drm_plane *base_plane) { xilinx_drm_plane_dpms(base_plane, DRM_MODE_DPMS_OFF); return 0; }