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_plane_helper_check_update() - Check plane update for validity 78 * @plane: plane object to update 79 * @crtc: owning CRTC of owning plane 80 * @fb: framebuffer to flip onto plane 81 * @src: source coordinates in 16.16 fixed point 82 * @dest: integer destination coordinates 83 * @clip: integer clipping coordinates 84 * @min_scale: minimum @src:@dest scaling factor in 16.16 fixed point 85 * @max_scale: maximum @src:@dest scaling factor in 16.16 fixed point 86 * @can_position: is it legal to position the plane such that it 87 * doesn't cover the entire crtc? This will generally 88 * only be false for primary planes. 89 * @can_update_disabled: can the plane be updated while the crtc 90 * is disabled? 91 * @visible: output parameter indicating whether plane is still visible after 92 * clipping 93 * 94 * Checks that a desired plane update is valid. Drivers that provide 95 * their own plane handling rather than helper-provided implementations may 96 * still wish to call this function to avoid duplication of error checking 97 * code. 98 * 99 * RETURNS: 100 * Zero if update appears valid, error code on failure 101 */ 102 int drm_plane_helper_check_update(struct drm_plane *plane, 103 struct drm_crtc *crtc, 104 struct drm_framebuffer *fb, 105 struct drm_rect *src, 106 struct drm_rect *dest, 107 const struct drm_rect *clip, 108 int min_scale, 109 int max_scale, 110 bool can_position, 111 bool can_update_disabled, 112 bool *visible) 113 { 114 int hscale, vscale; 115 116 if (!crtc->enabled && !can_update_disabled) { 117 DRM_DEBUG_KMS("Cannot update plane of a disabled CRTC.\n"); 118 return -EINVAL; 119 } 120 121 /* Check scaling */ 122 hscale = drm_rect_calc_hscale(src, dest, min_scale, max_scale); 123 vscale = drm_rect_calc_vscale(src, dest, min_scale, max_scale); 124 if (hscale < 0 || vscale < 0) { 125 DRM_DEBUG_KMS("Invalid scaling of plane\n"); 126 return -ERANGE; 127 } 128 129 *visible = drm_rect_clip_scaled(src, dest, clip, hscale, vscale); 130 if (!*visible) 131 /* 132 * Plane isn't visible; some drivers can handle this 133 * so we just return success here. Drivers that can't 134 * (including those that use the primary plane helper's 135 * update function) will return an error from their 136 * update_plane handler. 137 */ 138 return 0; 139 140 if (!can_position && !drm_rect_equals(dest, clip)) { 141 DRM_DEBUG_KMS("Plane must cover entire CRTC\n"); 142 return -EINVAL; 143 } 144 145 return 0; 146 } 147 EXPORT_SYMBOL(drm_plane_helper_check_update); 148 149 /** 150 * drm_primary_helper_update() - Helper for primary plane update 151 * @plane: plane object to update 152 * @crtc: owning CRTC of owning plane 153 * @fb: framebuffer to flip onto plane 154 * @crtc_x: x offset of primary plane on crtc 155 * @crtc_y: y offset of primary plane on crtc 156 * @crtc_w: width of primary plane rectangle on crtc 157 * @crtc_h: height of primary plane rectangle on crtc 158 * @src_x: x offset of @fb for panning 159 * @src_y: y offset of @fb for panning 160 * @src_w: width of source rectangle in @fb 161 * @src_h: height of source rectangle in @fb 162 * 163 * Provides a default plane update handler for primary planes. This is handler 164 * is called in response to a userspace SetPlane operation on the plane with a 165 * non-NULL framebuffer. We call the driver's modeset handler to update the 166 * framebuffer. 167 * 168 * SetPlane() on a primary plane of a disabled CRTC is not supported, and will 169 * return an error. 170 * 171 * Note that we make some assumptions about hardware limitations that may not be 172 * true for all hardware -- 173 * 1) Primary plane cannot be repositioned. 174 * 2) Primary plane cannot be scaled. 175 * 3) Primary plane must cover the entire CRTC. 176 * 4) Subpixel positioning is not supported. 177 * Drivers for hardware that don't have these restrictions can provide their 178 * own implementation rather than using this helper. 179 * 180 * RETURNS: 181 * Zero on success, error code on failure 182 */ 183 int drm_primary_helper_update(struct drm_plane *plane, struct drm_crtc *crtc, 184 struct drm_framebuffer *fb, 185 int crtc_x, int crtc_y, 186 unsigned int crtc_w, unsigned int crtc_h, 187 uint32_t src_x, uint32_t src_y, 188 uint32_t src_w, uint32_t src_h) 189 { 190 struct drm_mode_set set = { 191 .crtc = crtc, 192 .fb = fb, 193 .mode = &crtc->mode, 194 .x = src_x >> 16, 195 .y = src_y >> 16, 196 }; 197 struct drm_rect dest = { 198 .x1 = crtc_x, 199 .y1 = crtc_y, 200 .x2 = crtc_x + crtc_w, 201 .y2 = crtc_y + crtc_h, 202 }; 203 struct drm_rect clip = { 204 .x2 = crtc->mode.hdisplay, 205 .y2 = crtc->mode.vdisplay, 206 }; 207 struct drm_connector **connector_list; 208 int num_connectors, ret; 209 210 if (!crtc->enabled) { 211 DRM_DEBUG_KMS("Cannot update primary plane of a disabled CRTC.\n"); 212 return -EINVAL; 213 } 214 215 /* Disallow subpixel positioning */ 216 if ((src_x | src_y | src_w | src_h) & SUBPIXEL_MASK) { 217 DRM_DEBUG_KMS("Primary plane does not support subpixel positioning\n"); 218 return -EINVAL; 219 } 220 221 /* Primary planes are locked to their owning CRTC */ 222 if (plane->possible_crtcs != drm_crtc_mask(crtc)) { 223 DRM_DEBUG_KMS("Cannot change primary plane CRTC\n"); 224 return -EINVAL; 225 } 226 227 /* Disallow scaling */ 228 src_w >>= 16; 229 src_h >>= 16; 230 if (crtc_w != src_w || crtc_h != src_h) { 231 DRM_DEBUG_KMS("Can't scale primary plane\n"); 232 return -EINVAL; 233 } 234 235 /* Make sure primary plane covers entire CRTC */ 236 drm_rect_intersect(&dest, &clip); 237 if (dest.x1 != 0 || dest.y1 != 0 || 238 dest.x2 != crtc->mode.hdisplay || dest.y2 != crtc->mode.vdisplay) { 239 DRM_DEBUG_KMS("Primary plane must cover entire CRTC\n"); 240 return -EINVAL; 241 } 242 243 /* Framebuffer must be big enough to cover entire plane */ 244 ret = drm_crtc_check_viewport(crtc, crtc_x, crtc_y, &crtc->mode, fb); 245 if (ret) 246 return ret; 247 248 /* Find current connectors for CRTC */ 249 num_connectors = get_connectors_for_crtc(crtc, NULL, 0); 250 BUG_ON(num_connectors == 0); 251 connector_list = kzalloc(num_connectors * sizeof(*connector_list), 252 GFP_KERNEL); 253 if (!connector_list) 254 return -ENOMEM; 255 get_connectors_for_crtc(crtc, connector_list, num_connectors); 256 257 set.connectors = connector_list; 258 set.num_connectors = num_connectors; 259 260 /* 261 * We call set_config() directly here rather than using 262 * drm_mode_set_config_internal. We're reprogramming the same 263 * connectors that were already in use, so we shouldn't need the extra 264 * cross-CRTC fb refcounting to accomodate stealing connectors. 265 * drm_mode_setplane() already handles the basic refcounting for the 266 * framebuffers involved in this operation. 267 */ 268 ret = crtc->funcs->set_config(&set); 269 270 kfree(connector_list); 271 return ret; 272 } 273 EXPORT_SYMBOL(drm_primary_helper_update); 274 275 /** 276 * drm_primary_helper_disable() - Helper for primary plane disable 277 * @plane: plane to disable 278 * 279 * Provides a default plane disable handler for primary planes. This is handler 280 * is called in response to a userspace SetPlane operation on the plane with a 281 * NULL framebuffer parameter. We call the driver's modeset handler with a NULL 282 * framebuffer to disable the CRTC if no other planes are currently enabled. 283 * If other planes are still enabled on the same CRTC, we return -EBUSY. 284 * 285 * Note that some hardware may be able to disable the primary plane without 286 * disabling the whole CRTC. Drivers for such hardware should provide their 287 * own disable handler that disables just the primary plane (and they'll likely 288 * need to provide their own update handler as well to properly re-enable a 289 * disabled primary plane). 290 * 291 * RETURNS: 292 * Zero on success, error code on failure 293 */ 294 int drm_primary_helper_disable(struct drm_plane *plane) 295 { 296 struct drm_plane *p; 297 struct drm_mode_set set = { 298 .crtc = plane->crtc, 299 .fb = NULL, 300 }; 301 302 if (plane->crtc == NULL || plane->fb == NULL) 303 /* Already disabled */ 304 return 0; 305 306 list_for_each_entry(p, &plane->dev->mode_config.plane_list, head) 307 if (p != plane && p->fb) { 308 DRM_DEBUG_KMS("Cannot disable primary plane while other planes are still active on CRTC.\n"); 309 return -EBUSY; 310 } 311 312 /* 313 * N.B. We call set_config() directly here rather than 314 * drm_mode_set_config_internal() since drm_mode_setplane() already 315 * handles the basic refcounting and we don't need the special 316 * cross-CRTC refcounting (no chance of stealing connectors from 317 * other CRTC's with this update). 318 */ 319 return plane->crtc->funcs->set_config(&set); 320 } 321 EXPORT_SYMBOL(drm_primary_helper_disable); 322 323 /** 324 * drm_primary_helper_destroy() - Helper for primary plane destruction 325 * @plane: plane to destroy 326 * 327 * Provides a default plane destroy handler for primary planes. This handler 328 * is called during CRTC destruction. We disable the primary plane, remove 329 * it from the DRM plane list, and deallocate the plane structure. 330 */ 331 void drm_primary_helper_destroy(struct drm_plane *plane) 332 { 333 drm_plane_cleanup(plane); 334 kfree(plane); 335 } 336 EXPORT_SYMBOL(drm_primary_helper_destroy); 337 338 const struct drm_plane_funcs drm_primary_helper_funcs = { 339 .update_plane = drm_primary_helper_update, 340 .disable_plane = drm_primary_helper_disable, 341 .destroy = drm_primary_helper_destroy, 342 }; 343 EXPORT_SYMBOL(drm_primary_helper_funcs); 344 345 /** 346 * drm_primary_helper_create_plane() - Create a generic primary plane 347 * @dev: drm device 348 * @formats: pixel formats supported, or NULL for a default safe list 349 * @num_formats: size of @formats; ignored if @formats is NULL 350 * 351 * Allocates and initializes a primary plane that can be used with the primary 352 * plane helpers. Drivers that wish to use driver-specific plane structures or 353 * provide custom handler functions may perform their own allocation and 354 * initialization rather than calling this function. 355 */ 356 struct drm_plane *drm_primary_helper_create_plane(struct drm_device *dev, 357 const uint32_t *formats, 358 int num_formats) 359 { 360 struct drm_plane *primary; 361 int ret; 362 363 primary = kzalloc(sizeof(*primary), GFP_KERNEL); 364 if (primary == NULL) { 365 DRM_DEBUG_KMS("Failed to allocate primary plane\n"); 366 return NULL; 367 } 368 369 if (formats == NULL) { 370 formats = safe_modeset_formats; 371 num_formats = ARRAY_SIZE(safe_modeset_formats); 372 } 373 374 /* possible_crtc's will be filled in later by crtc_init */ 375 ret = drm_universal_plane_init(dev, primary, 0, 376 &drm_primary_helper_funcs, 377 formats, num_formats, 378 DRM_PLANE_TYPE_PRIMARY); 379 if (ret) { 380 kfree(primary); 381 primary = NULL; 382 } 383 384 return primary; 385 } 386 EXPORT_SYMBOL(drm_primary_helper_create_plane); 387 388 /** 389 * drm_crtc_init - Legacy CRTC initialization function 390 * @dev: DRM device 391 * @crtc: CRTC object to init 392 * @funcs: callbacks for the new CRTC 393 * 394 * Initialize a CRTC object with a default helper-provided primary plane and no 395 * cursor plane. 396 * 397 * Returns: 398 * Zero on success, error code on failure. 399 */ 400 int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, 401 const struct drm_crtc_funcs *funcs) 402 { 403 struct drm_plane *primary; 404 405 primary = drm_primary_helper_create_plane(dev, NULL, 0); 406 return drm_crtc_init_with_planes(dev, crtc, primary, NULL, funcs); 407 } 408 EXPORT_SYMBOL(drm_crtc_init); 409