1 /* 2 * Copyright (C) 2014 Intel Corporation 3 * 4 * DRM universal plane helper functions 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the next 14 * paragraph) shall be included in all copies or substantial portions of the 15 * Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 * SOFTWARE. 24 */ 25 26 #include <linux/list.h> 27 #include <drm/drmP.h> 28 #include <drm/drm_rect.h> 29 #include <drm/drm_plane_helper.h> 30 31 #define SUBPIXEL_MASK 0xffff 32 33 /* 34 * This is the minimal list of formats that seem to be safe for modeset use 35 * with all current DRM drivers. Most hardware can actually support more 36 * formats than this and drivers may specify a more accurate list when 37 * creating the primary plane. However drivers that still call 38 * drm_plane_init() will use this minimal format list as the default. 39 */ 40 static const uint32_t safe_modeset_formats[] = { 41 DRM_FORMAT_XRGB8888, 42 DRM_FORMAT_ARGB8888, 43 }; 44 45 /* 46 * Returns the connectors currently associated with a CRTC. This function 47 * should be called twice: once with a NULL connector list to retrieve 48 * the list size, and once with the properly allocated list to be filled in. 49 */ 50 static int get_connectors_for_crtc(struct drm_crtc *crtc, 51 struct drm_connector **connector_list, 52 int num_connectors) 53 { 54 struct drm_device *dev = crtc->dev; 55 struct drm_connector *connector; 56 int count = 0; 57 58 /* 59 * Note: Once we change the plane hooks to more fine-grained locking we 60 * need to grab the connection_mutex here to be able to make these 61 * checks. 62 */ 63 WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); 64 65 list_for_each_entry(connector, &dev->mode_config.connector_list, head) 66 if (connector->encoder && connector->encoder->crtc == crtc) { 67 if (connector_list != NULL && count < num_connectors) 68 *(connector_list++) = connector; 69 70 count++; 71 } 72 73 return count; 74 } 75 76 /** 77 * drm_primary_helper_update() - Helper for primary plane update 78 * @plane: plane object to update 79 * @crtc: owning CRTC of owning plane 80 * @fb: framebuffer to flip onto plane 81 * @crtc_x: x offset of primary plane on crtc 82 * @crtc_y: y offset of primary plane on crtc 83 * @crtc_w: width of primary plane rectangle on crtc 84 * @crtc_h: height of primary plane rectangle on crtc 85 * @src_x: x offset of @fb for panning 86 * @src_y: y offset of @fb for panning 87 * @src_w: width of source rectangle in @fb 88 * @src_h: height of source rectangle in @fb 89 * 90 * Provides a default plane update handler for primary planes. This is handler 91 * is called in response to a userspace SetPlane operation on the plane with a 92 * non-NULL framebuffer. We call the driver's modeset handler to update the 93 * framebuffer. 94 * 95 * SetPlane() on a primary plane of a disabled CRTC is not supported, and will 96 * return an error. 97 * 98 * Note that we make some assumptions about hardware limitations that may not be 99 * true for all hardware -- 100 * 1) Primary plane cannot be repositioned. 101 * 2) Primary plane cannot be scaled. 102 * 3) Primary plane must cover the entire CRTC. 103 * 4) Subpixel positioning is not supported. 104 * Drivers for hardware that don't have these restrictions can provide their 105 * own implementation rather than using this helper. 106 * 107 * RETURNS: 108 * Zero on success, error code on failure 109 */ 110 int drm_primary_helper_update(struct drm_plane *plane, struct drm_crtc *crtc, 111 struct drm_framebuffer *fb, 112 int crtc_x, int crtc_y, 113 unsigned int crtc_w, unsigned int crtc_h, 114 uint32_t src_x, uint32_t src_y, 115 uint32_t src_w, uint32_t src_h) 116 { 117 struct drm_mode_set set = { 118 .crtc = crtc, 119 .fb = fb, 120 .mode = &crtc->mode, 121 .x = src_x >> 16, 122 .y = src_y >> 16, 123 }; 124 struct drm_rect dest = { 125 .x1 = crtc_x, 126 .y1 = crtc_y, 127 .x2 = crtc_x + crtc_w, 128 .y2 = crtc_y + crtc_h, 129 }; 130 struct drm_rect clip = { 131 .x2 = crtc->mode.hdisplay, 132 .y2 = crtc->mode.vdisplay, 133 }; 134 struct drm_connector **connector_list; 135 int num_connectors, ret; 136 137 if (!crtc->enabled) { 138 DRM_DEBUG_KMS("Cannot update primary plane of a disabled CRTC.\n"); 139 return -EINVAL; 140 } 141 142 /* Disallow subpixel positioning */ 143 if ((src_x | src_y | src_w | src_h) & SUBPIXEL_MASK) { 144 DRM_DEBUG_KMS("Primary plane does not support subpixel positioning\n"); 145 return -EINVAL; 146 } 147 148 /* Primary planes are locked to their owning CRTC */ 149 if (plane->possible_crtcs != drm_crtc_mask(crtc)) { 150 DRM_DEBUG_KMS("Cannot change primary plane CRTC\n"); 151 return -EINVAL; 152 } 153 154 /* Disallow scaling */ 155 src_w >>= 16; 156 src_h >>= 16; 157 if (crtc_w != src_w || crtc_h != src_h) { 158 DRM_DEBUG_KMS("Can't scale primary plane\n"); 159 return -EINVAL; 160 } 161 162 /* Make sure primary plane covers entire CRTC */ 163 drm_rect_intersect(&dest, &clip); 164 if (dest.x1 != 0 || dest.y1 != 0 || 165 dest.x2 != crtc->mode.hdisplay || dest.y2 != crtc->mode.vdisplay) { 166 DRM_DEBUG_KMS("Primary plane must cover entire CRTC\n"); 167 return -EINVAL; 168 } 169 170 /* Framebuffer must be big enough to cover entire plane */ 171 ret = drm_crtc_check_viewport(crtc, crtc_x, crtc_y, &crtc->mode, fb); 172 if (ret) 173 return ret; 174 175 /* Find current connectors for CRTC */ 176 num_connectors = get_connectors_for_crtc(crtc, NULL, 0); 177 BUG_ON(num_connectors == 0); 178 connector_list = kzalloc(num_connectors * sizeof(*connector_list), 179 GFP_KERNEL); 180 if (!connector_list) 181 return -ENOMEM; 182 get_connectors_for_crtc(crtc, connector_list, num_connectors); 183 184 set.connectors = connector_list; 185 set.num_connectors = num_connectors; 186 187 /* 188 * We call set_config() directly here rather than using 189 * drm_mode_set_config_internal. We're reprogramming the same 190 * connectors that were already in use, so we shouldn't need the extra 191 * cross-CRTC fb refcounting to accomodate stealing connectors. 192 * drm_mode_setplane() already handles the basic refcounting for the 193 * framebuffers involved in this operation. 194 */ 195 ret = crtc->funcs->set_config(&set); 196 197 kfree(connector_list); 198 return ret; 199 } 200 EXPORT_SYMBOL(drm_primary_helper_update); 201 202 /** 203 * drm_primary_helper_disable() - Helper for primary plane disable 204 * @plane: plane to disable 205 * 206 * Provides a default plane disable handler for primary planes. This is handler 207 * is called in response to a userspace SetPlane operation on the plane with a 208 * NULL framebuffer parameter. We call the driver's modeset handler with a NULL 209 * framebuffer to disable the CRTC if no other planes are currently enabled. 210 * If other planes are still enabled on the same CRTC, we return -EBUSY. 211 * 212 * Note that some hardware may be able to disable the primary plane without 213 * disabling the whole CRTC. Drivers for such hardware should provide their 214 * own disable handler that disables just the primary plane (and they'll likely 215 * need to provide their own update handler as well to properly re-enable a 216 * disabled primary plane). 217 * 218 * RETURNS: 219 * Zero on success, error code on failure 220 */ 221 int drm_primary_helper_disable(struct drm_plane *plane) 222 { 223 struct drm_plane *p; 224 struct drm_mode_set set = { 225 .crtc = plane->crtc, 226 .fb = NULL, 227 }; 228 229 if (plane->crtc == NULL || plane->fb == NULL) 230 /* Already disabled */ 231 return 0; 232 233 list_for_each_entry(p, &plane->dev->mode_config.plane_list, head) 234 if (p != plane && p->fb) { 235 DRM_DEBUG_KMS("Cannot disable primary plane while other planes are still active on CRTC.\n"); 236 return -EBUSY; 237 } 238 239 /* 240 * N.B. We call set_config() directly here rather than 241 * drm_mode_set_config_internal() since drm_mode_setplane() already 242 * handles the basic refcounting and we don't need the special 243 * cross-CRTC refcounting (no chance of stealing connectors from 244 * other CRTC's with this update). 245 */ 246 return plane->crtc->funcs->set_config(&set); 247 } 248 EXPORT_SYMBOL(drm_primary_helper_disable); 249 250 /** 251 * drm_primary_helper_destroy() - Helper for primary plane destruction 252 * @plane: plane to destroy 253 * 254 * Provides a default plane destroy handler for primary planes. This handler 255 * is called during CRTC destruction. We disable the primary plane, remove 256 * it from the DRM plane list, and deallocate the plane structure. 257 */ 258 void drm_primary_helper_destroy(struct drm_plane *plane) 259 { 260 drm_plane_cleanup(plane); 261 kfree(plane); 262 } 263 EXPORT_SYMBOL(drm_primary_helper_destroy); 264 265 const struct drm_plane_funcs drm_primary_helper_funcs = { 266 .update_plane = drm_primary_helper_update, 267 .disable_plane = drm_primary_helper_disable, 268 .destroy = drm_primary_helper_destroy, 269 }; 270 EXPORT_SYMBOL(drm_primary_helper_funcs); 271 272 /** 273 * drm_primary_helper_create_plane() - Create a generic primary plane 274 * @dev: drm device 275 * @formats: pixel formats supported, or NULL for a default safe list 276 * @num_formats: size of @formats; ignored if @formats is NULL 277 * 278 * Allocates and initializes a primary plane that can be used with the primary 279 * plane helpers. Drivers that wish to use driver-specific plane structures or 280 * provide custom handler functions may perform their own allocation and 281 * initialization rather than calling this function. 282 */ 283 struct drm_plane *drm_primary_helper_create_plane(struct drm_device *dev, 284 const uint32_t *formats, 285 int num_formats) 286 { 287 struct drm_plane *primary; 288 int ret; 289 290 primary = kzalloc(sizeof(*primary), GFP_KERNEL); 291 if (primary == NULL) { 292 DRM_DEBUG_KMS("Failed to allocate primary plane\n"); 293 return NULL; 294 } 295 296 if (formats == NULL) { 297 formats = safe_modeset_formats; 298 num_formats = ARRAY_SIZE(safe_modeset_formats); 299 } 300 301 /* possible_crtc's will be filled in later by crtc_init */ 302 ret = drm_plane_init(dev, primary, 0, &drm_primary_helper_funcs, 303 formats, num_formats, 304 DRM_PLANE_TYPE_PRIMARY); 305 if (ret) { 306 kfree(primary); 307 primary = NULL; 308 } 309 310 return primary; 311 } 312 EXPORT_SYMBOL(drm_primary_helper_create_plane); 313 314 /** 315 * drm_crtc_init - Legacy CRTC initialization function 316 * @dev: DRM device 317 * @crtc: CRTC object to init 318 * @funcs: callbacks for the new CRTC 319 * 320 * Initialize a CRTC object with a default helper-provided primary plane and no 321 * cursor plane. 322 * 323 * Returns: 324 * Zero on success, error code on failure. 325 */ 326 int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, 327 const struct drm_crtc_funcs *funcs) 328 { 329 struct drm_plane *primary; 330 331 primary = drm_primary_helper_create_plane(dev, NULL, 0); 332 return drm_crtc_init_with_planes(dev, crtc, primary, NULL, funcs); 333 } 334 EXPORT_SYMBOL(drm_crtc_init); 335