Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.17-rc3 195 lines 4.9 kB view raw
1/* 2 * Copyright (C) STMicroelectronics SA 2014 3 * Authors: Benjamin Gaignard <benjamin.gaignard@st.com> 4 * Fabien Dessenne <fabien.dessenne@st.com> 5 * for STMicroelectronics. 6 * License terms: GNU General Public License (GPL), version 2 7 */ 8 9#include "sti_compositor.h" 10#include "sti_drm_drv.h" 11#include "sti_drm_plane.h" 12#include "sti_vtg.h" 13 14enum sti_layer_desc sti_layer_default_zorder[] = { 15 STI_GDP_0, 16 STI_VID_0, 17 STI_GDP_1, 18 STI_VID_1, 19 STI_GDP_2, 20 STI_GDP_3, 21}; 22 23/* (Background) < GDP0 < VID0 < GDP1 < VID1 < GDP2 < GDP3 < (ForeGround) */ 24 25static int 26sti_drm_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, 27 struct drm_framebuffer *fb, int crtc_x, int crtc_y, 28 unsigned int crtc_w, unsigned int crtc_h, 29 uint32_t src_x, uint32_t src_y, 30 uint32_t src_w, uint32_t src_h) 31{ 32 struct sti_layer *layer = to_sti_layer(plane); 33 struct sti_mixer *mixer = to_sti_mixer(crtc); 34 int res; 35 36 DRM_DEBUG_KMS("CRTC:%d (%s) drm plane:%d (%s) drm fb:%d\n", 37 crtc->base.id, sti_mixer_to_str(mixer), 38 plane->base.id, sti_layer_to_str(layer), fb->base.id); 39 DRM_DEBUG_KMS("(%dx%d)@(%d,%d)\n", crtc_w, crtc_h, crtc_x, crtc_y); 40 41 res = sti_mixer_set_layer_depth(mixer, layer); 42 if (res) { 43 DRM_ERROR("Can not set layer depth\n"); 44 return res; 45 } 46 47 /* src_x are in 16.16 format. */ 48 res = sti_layer_prepare(layer, fb, &crtc->mode, mixer->id, 49 crtc_x, crtc_y, crtc_w, crtc_h, 50 src_x >> 16, src_y >> 16, 51 src_w >> 16, src_h >> 16); 52 if (res) { 53 DRM_ERROR("Layer prepare failed\n"); 54 return res; 55 } 56 57 res = sti_layer_commit(layer); 58 if (res) { 59 DRM_ERROR("Layer commit failed\n"); 60 return res; 61 } 62 63 res = sti_mixer_set_layer_status(mixer, layer, true); 64 if (res) { 65 DRM_ERROR("Can not enable layer at mixer\n"); 66 return res; 67 } 68 69 return 0; 70} 71 72static int sti_drm_disable_plane(struct drm_plane *plane) 73{ 74 struct sti_layer *layer; 75 struct sti_mixer *mixer; 76 int lay_res, mix_res; 77 78 if (!plane->crtc) { 79 DRM_DEBUG_DRIVER("drm plane:%d not enabled\n", plane->base.id); 80 return 0; 81 } 82 layer = to_sti_layer(plane); 83 mixer = to_sti_mixer(plane->crtc); 84 85 DRM_DEBUG_DRIVER("CRTC:%d (%s) drm plane:%d (%s)\n", 86 plane->crtc->base.id, sti_mixer_to_str(mixer), 87 plane->base.id, sti_layer_to_str(layer)); 88 89 /* Disable layer at mixer level */ 90 mix_res = sti_mixer_set_layer_status(mixer, layer, false); 91 if (mix_res) 92 DRM_ERROR("Can not disable layer at mixer\n"); 93 94 /* Wait a while to be sure that a Vsync event is received */ 95 msleep(WAIT_NEXT_VSYNC_MS); 96 97 /* Then disable layer itself */ 98 lay_res = sti_layer_disable(layer); 99 if (lay_res) 100 DRM_ERROR("Layer disable failed\n"); 101 102 if (lay_res || mix_res) 103 return -EINVAL; 104 105 return 0; 106} 107 108static void sti_drm_plane_destroy(struct drm_plane *plane) 109{ 110 DRM_DEBUG_DRIVER("\n"); 111 112 sti_drm_disable_plane(plane); 113 drm_plane_cleanup(plane); 114} 115 116static int sti_drm_plane_set_property(struct drm_plane *plane, 117 struct drm_property *property, 118 uint64_t val) 119{ 120 struct drm_device *dev = plane->dev; 121 struct sti_drm_private *private = dev->dev_private; 122 struct sti_layer *layer = to_sti_layer(plane); 123 124 DRM_DEBUG_DRIVER("\n"); 125 126 if (property == private->plane_zorder_property) { 127 layer->zorder = val; 128 return 0; 129 } 130 131 return -EINVAL; 132} 133 134static struct drm_plane_funcs sti_drm_plane_funcs = { 135 .update_plane = sti_drm_update_plane, 136 .disable_plane = sti_drm_disable_plane, 137 .destroy = sti_drm_plane_destroy, 138 .set_property = sti_drm_plane_set_property, 139}; 140 141static void sti_drm_plane_attach_zorder_property(struct drm_plane *plane, 142 uint64_t default_val) 143{ 144 struct drm_device *dev = plane->dev; 145 struct sti_drm_private *private = dev->dev_private; 146 struct drm_property *prop; 147 struct sti_layer *layer = to_sti_layer(plane); 148 149 prop = private->plane_zorder_property; 150 if (!prop) { 151 prop = drm_property_create_range(dev, 0, "zpos", 0, 152 GAM_MIXER_NB_DEPTH_LEVEL - 1); 153 if (!prop) 154 return; 155 156 private->plane_zorder_property = prop; 157 } 158 159 drm_object_attach_property(&plane->base, prop, default_val); 160 layer->zorder = default_val; 161} 162 163struct drm_plane *sti_drm_plane_init(struct drm_device *dev, 164 struct sti_layer *layer, 165 unsigned int possible_crtcs, 166 enum drm_plane_type type) 167{ 168 int err, i; 169 uint64_t default_zorder = 0; 170 171 err = drm_universal_plane_init(dev, &layer->plane, possible_crtcs, 172 &sti_drm_plane_funcs, 173 sti_layer_get_formats(layer), 174 sti_layer_get_nb_formats(layer), type); 175 if (err) { 176 DRM_ERROR("Failed to initialize plane\n"); 177 return NULL; 178 } 179 180 for (i = 0; i < ARRAY_SIZE(sti_layer_default_zorder); i++) 181 if (sti_layer_default_zorder[i] == layer->desc) 182 break; 183 184 default_zorder = i; 185 186 if (type == DRM_PLANE_TYPE_OVERLAY) 187 sti_drm_plane_attach_zorder_property(&layer->plane, 188 default_zorder); 189 190 DRM_DEBUG_DRIVER("drm plane:%d mapped to %s with zorder:%llu\n", 191 layer->plane.base.id, 192 sti_layer_to_str(layer), default_zorder); 193 194 return &layer->plane; 195}