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_plane_helper.h> 29 #include <drm/drm_rect.h> 30 #include <drm/drm_plane_helper.h> 31 32 #define SUBPIXEL_MASK 0xffff 33 34 /* 35 * This is the minimal list of formats that seem to be safe for modeset use 36 * with all current DRM drivers. Most hardware can actually support more 37 * formats than this and drivers may specify a more accurate list when 38 * creating the primary plane. However drivers that still call 39 * drm_plane_init() will use this minimal format list as the default. 40 */ 41 static const uint32_t safe_modeset_formats[] = { 42 DRM_FORMAT_XRGB8888, 43 DRM_FORMAT_ARGB8888, 44 }; 45 46 /* 47 * Returns the connectors currently associated with a CRTC. This function 48 * should be called twice: once with a NULL connector list to retrieve 49 * the list size, and once with the properly allocated list to be filled in. 50 */ 51 static int get_connectors_for_crtc(struct drm_crtc *crtc, 52 struct drm_connector **connector_list, 53 int num_connectors) 54 { 55 struct drm_device *dev = crtc->dev; 56 struct drm_connector *connector; 57 int count = 0; 58 59 /* 60 * Note: Once we change the plane hooks to more fine-grained locking we 61 * need to grab the connection_mutex here to be able to make these 62 * checks. 63 */ 64 WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); 65 66 list_for_each_entry(connector, &dev->mode_config.connector_list, head) 67 if (connector->encoder && connector->encoder->crtc == crtc) { 68 if (connector_list != NULL && count < num_connectors) 69 *(connector_list++) = connector; 70 71 count++; 72 } 73 74 return count; 75 } 76 77 /** 78 * drm_plane_helper_check_update() - Check plane update for validity 79 * @plane: plane object to update 80 * @crtc: owning CRTC of owning plane 81 * @fb: framebuffer to flip onto plane 82 * @src: source coordinates in 16.16 fixed point 83 * @dest: integer destination coordinates 84 * @clip: integer clipping coordinates 85 * @min_scale: minimum @src:@dest scaling factor in 16.16 fixed point 86 * @max_scale: maximum @src:@dest scaling factor in 16.16 fixed point 87 * @can_position: is it legal to position the plane such that it 88 * doesn't cover the entire crtc? This will generally 89 * only be false for primary planes. 90 * @can_update_disabled: can the plane be updated while the crtc 91 * is disabled? 92 * @visible: output parameter indicating whether plane is still visible after 93 * clipping 94 * 95 * Checks that a desired plane update is valid. Drivers that provide 96 * their own plane handling rather than helper-provided implementations may 97 * still wish to call this function to avoid duplication of error checking 98 * code. 99 * 100 * RETURNS: 101 * Zero if update appears valid, error code on failure 102 */ 103 int drm_plane_helper_check_update(struct drm_plane *plane, 104 struct drm_crtc *crtc, 105 struct drm_framebuffer *fb, 106 struct drm_rect *src, 107 struct drm_rect *dest, 108 const struct drm_rect *clip, 109 int min_scale, 110 int max_scale, 111 bool can_position, 112 bool can_update_disabled, 113 bool *visible) 114 { 115 int hscale, vscale; 116 117 if (!crtc->enabled && !can_update_disabled) { 118 DRM_DEBUG_KMS("Cannot update plane of a disabled CRTC.\n"); 119 return -EINVAL; 120 } 121 122 /* Check scaling */ 123 hscale = drm_rect_calc_hscale(src, dest, min_scale, max_scale); 124 vscale = drm_rect_calc_vscale(src, dest, min_scale, max_scale); 125 if (hscale < 0 || vscale < 0) { 126 DRM_DEBUG_KMS("Invalid scaling of plane\n"); 127 return -ERANGE; 128 } 129 130 *visible = drm_rect_clip_scaled(src, dest, clip, hscale, vscale); 131 if (!*visible) 132 /* 133 * Plane isn't visible; some drivers can handle this 134 * so we just return success here. Drivers that can't 135 * (including those that use the primary plane helper's 136 * update function) will return an error from their 137 * update_plane handler. 138 */ 139 return 0; 140 141 if (!can_position && !drm_rect_equals(dest, clip)) { 142 DRM_DEBUG_KMS("Plane must cover entire CRTC\n"); 143 return -EINVAL; 144 } 145 146 return 0; 147 } 148 EXPORT_SYMBOL(drm_plane_helper_check_update); 149 150 /** 151 * drm_primary_helper_update() - Helper for primary plane update 152 * @plane: plane object to update 153 * @crtc: owning CRTC of owning plane 154 * @fb: framebuffer to flip onto plane 155 * @crtc_x: x offset of primary plane on crtc 156 * @crtc_y: y offset of primary plane on crtc 157 * @crtc_w: width of primary plane rectangle on crtc 158 * @crtc_h: height of primary plane rectangle on crtc 159 * @src_x: x offset of @fb for panning 160 * @src_y: y offset of @fb for panning 161 * @src_w: width of source rectangle in @fb 162 * @src_h: height of source rectangle in @fb 163 * 164 * Provides a default plane update handler for primary planes. This is handler 165 * is called in response to a userspace SetPlane operation on the plane with a 166 * non-NULL framebuffer. We call the driver's modeset handler to update the 167 * framebuffer. 168 * 169 * SetPlane() on a primary plane of a disabled CRTC is not supported, and will 170 * return an error. 171 * 172 * Note that we make some assumptions about hardware limitations that may not be 173 * true for all hardware -- 174 * 1) Primary plane cannot be repositioned. 175 * 2) Primary plane cannot be scaled. 176 * 3) Primary plane must cover the entire CRTC. 177 * 4) Subpixel positioning is not supported. 178 * Drivers for hardware that don't have these restrictions can provide their 179 * own implementation rather than using this helper. 180 * 181 * RETURNS: 182 * Zero on success, error code on failure 183 */ 184 int drm_primary_helper_update(struct drm_plane *plane, struct drm_crtc *crtc, 185 struct drm_framebuffer *fb, 186 int crtc_x, int crtc_y, 187 unsigned int crtc_w, unsigned int crtc_h, 188 uint32_t src_x, uint32_t src_y, 189 uint32_t src_w, uint32_t src_h) 190 { 191 struct drm_mode_set set = { 192 .crtc = crtc, 193 .fb = fb, 194 .mode = &crtc->mode, 195 .x = src_x >> 16, 196 .y = src_y >> 16, 197 }; 198 struct drm_rect src = { 199 .x1 = src_x, 200 .y1 = src_y, 201 .x2 = src_x + src_w, 202 .y2 = src_y + src_h, 203 }; 204 struct drm_rect dest = { 205 .x1 = crtc_x, 206 .y1 = crtc_y, 207 .x2 = crtc_x + crtc_w, 208 .y2 = crtc_y + crtc_h, 209 }; 210 const struct drm_rect clip = { 211 .x2 = crtc->mode.hdisplay, 212 .y2 = crtc->mode.vdisplay, 213 }; 214 struct drm_connector **connector_list; 215 int num_connectors, ret; 216 bool visible; 217 218 ret = drm_plane_helper_check_update(plane, crtc, fb, 219 &src, &dest, &clip, 220 DRM_PLANE_HELPER_NO_SCALING, 221 DRM_PLANE_HELPER_NO_SCALING, 222 false, false, &visible); 223 if (ret) 224 return ret; 225 226 if (!visible) 227 /* 228 * Primary plane isn't visible. Note that unless a driver 229 * provides their own disable function, this will just 230 * wind up returning -EINVAL to userspace. 231 */ 232 return plane->funcs->disable_plane(plane); 233 234 /* Find current connectors for CRTC */ 235 num_connectors = get_connectors_for_crtc(crtc, NULL, 0); 236 BUG_ON(num_connectors == 0); 237 connector_list = kzalloc(num_connectors * sizeof(*connector_list), 238 GFP_KERNEL); 239 if (!connector_list) 240 return -ENOMEM; 241 get_connectors_for_crtc(crtc, connector_list, num_connectors); 242 243 set.connectors = connector_list; 244 set.num_connectors = num_connectors; 245 246 /* 247 * We call set_config() directly here rather than using 248 * drm_mode_set_config_internal. We're reprogramming the same 249 * connectors that were already in use, so we shouldn't need the extra 250 * cross-CRTC fb refcounting to accomodate stealing connectors. 251 * drm_mode_setplane() already handles the basic refcounting for the 252 * framebuffers involved in this operation. 253 */ 254 ret = crtc->funcs->set_config(&set); 255 256 kfree(connector_list); 257 return ret; 258 } 259 EXPORT_SYMBOL(drm_primary_helper_update); 260 261 /** 262 * drm_primary_helper_disable() - Helper for primary plane disable 263 * @plane: plane to disable 264 * 265 * Provides a default plane disable handler for primary planes. This is handler 266 * is called in response to a userspace SetPlane operation on the plane with a 267 * NULL framebuffer parameter. It unconditionally fails the disable call with 268 * -EINVAL the only way to disable the primary plane without driver support is 269 * to disable the entier CRTC. Which does not match the plane ->disable hook. 270 * 271 * Note that some hardware may be able to disable the primary plane without 272 * disabling the whole CRTC. Drivers for such hardware should provide their 273 * own disable handler that disables just the primary plane (and they'll likely 274 * need to provide their own update handler as well to properly re-enable a 275 * disabled primary plane). 276 * 277 * RETURNS: 278 * Unconditionally returns -EINVAL. 279 */ 280 int drm_primary_helper_disable(struct drm_plane *plane) 281 { 282 return -EINVAL; 283 } 284 EXPORT_SYMBOL(drm_primary_helper_disable); 285 286 /** 287 * drm_primary_helper_destroy() - Helper for primary plane destruction 288 * @plane: plane to destroy 289 * 290 * Provides a default plane destroy handler for primary planes. This handler 291 * is called during CRTC destruction. We disable the primary plane, remove 292 * it from the DRM plane list, and deallocate the plane structure. 293 */ 294 void drm_primary_helper_destroy(struct drm_plane *plane) 295 { 296 drm_plane_cleanup(plane); 297 kfree(plane); 298 } 299 EXPORT_SYMBOL(drm_primary_helper_destroy); 300 301 const struct drm_plane_funcs drm_primary_helper_funcs = { 302 .update_plane = drm_primary_helper_update, 303 .disable_plane = drm_primary_helper_disable, 304 .destroy = drm_primary_helper_destroy, 305 }; 306 EXPORT_SYMBOL(drm_primary_helper_funcs); 307 308 /** 309 * drm_primary_helper_create_plane() - Create a generic primary plane 310 * @dev: drm device 311 * @formats: pixel formats supported, or NULL for a default safe list 312 * @num_formats: size of @formats; ignored if @formats is NULL 313 * 314 * Allocates and initializes a primary plane that can be used with the primary 315 * plane helpers. Drivers that wish to use driver-specific plane structures or 316 * provide custom handler functions may perform their own allocation and 317 * initialization rather than calling this function. 318 */ 319 struct drm_plane *drm_primary_helper_create_plane(struct drm_device *dev, 320 const uint32_t *formats, 321 int num_formats) 322 { 323 struct drm_plane *primary; 324 int ret; 325 326 primary = kzalloc(sizeof(*primary), GFP_KERNEL); 327 if (primary == NULL) { 328 DRM_DEBUG_KMS("Failed to allocate primary plane\n"); 329 return NULL; 330 } 331 332 if (formats == NULL) { 333 formats = safe_modeset_formats; 334 num_formats = ARRAY_SIZE(safe_modeset_formats); 335 } 336 337 /* possible_crtc's will be filled in later by crtc_init */ 338 ret = drm_universal_plane_init(dev, primary, 0, 339 &drm_primary_helper_funcs, 340 formats, num_formats, 341 DRM_PLANE_TYPE_PRIMARY); 342 if (ret) { 343 kfree(primary); 344 primary = NULL; 345 } 346 347 return primary; 348 } 349 EXPORT_SYMBOL(drm_primary_helper_create_plane); 350 351 /** 352 * drm_crtc_init - Legacy CRTC initialization function 353 * @dev: DRM device 354 * @crtc: CRTC object to init 355 * @funcs: callbacks for the new CRTC 356 * 357 * Initialize a CRTC object with a default helper-provided primary plane and no 358 * cursor plane. 359 * 360 * Returns: 361 * Zero on success, error code on failure. 362 */ 363 int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, 364 const struct drm_crtc_funcs *funcs) 365 { 366 struct drm_plane *primary; 367 368 primary = drm_primary_helper_create_plane(dev, NULL, 0); 369 return drm_crtc_init_with_planes(dev, crtc, primary, NULL, funcs); 370 } 371 EXPORT_SYMBOL(drm_crtc_init); 372