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

Merge branch 'primary-plane' of git://people.freedesktop.org/~robclark/linux into drm-next

Here's the latest iteration of the universal planes work, which I believe is
finally ready for merging. Aside from the minor driver patches to use the
new drm_for_each_legacy_plane() macro for plane loops, these should all have
an r-b from Rob Clark now.

Actual userspace-visibility is currently hidden behind a
drm.universal_planes module parameter so that we can do some experimental
testing of this before flipping it on universally.

* 'primary-plane' of git://people.freedesktop.org/~robclark/linux:
drm/doc: Update plane documentation and add plane helper library
drm: Allow userspace to ask for universal plane list (v2)
drm: Remove unused drm_crtc->fb
drm: Replace crtc fb with primary plane fb (v3)
drm/msm: Switch to universal plane API's
drm: Add drm_crtc_init_with_planes() (v2)
drm: Add plane type property (v2)
drm: Add drm_universal_plane_init()
drm: Add primary plane helpers (v3)
drm: Make drm_crtc_check_viewport non-static
drm/shmobile: Restrict plane loops to only operate on legacy planes
drm/i915: Restrict plane loops to only operate on overlay planes (v2)
drm/exynos: Restrict plane loops to only operate on overlay planes (v2)
drm: Add support for multiple plane types (v2)

+941 -347
+43 -7
Documentation/DocBook/drm.tmpl
··· 1194 1194 pointer to CRTC functions. 1195 1195 </para> 1196 1196 </sect3> 1197 - <sect3> 1197 + <sect3 id="drm-kms-crtcops"> 1198 1198 <title>CRTC Operations</title> 1199 1199 <sect4> 1200 1200 <title>Set Configuration</title> ··· 1335 1335 optionally scale it to a destination size. The result is then blended 1336 1336 with or overlayed on top of a CRTC. 1337 1337 </para> 1338 + <para> 1339 + The DRM core recognizes three types of planes: 1340 + <itemizedlist> 1341 + <listitem> 1342 + DRM_PLANE_TYPE_PRIMARY represents a "main" plane for a CRTC. Primary 1343 + planes are the planes operated upon by by CRTC modesetting and flipping 1344 + operations described in <xref linkend="drm-kms-crtcops"/>. 1345 + </listitem> 1346 + <listitem> 1347 + DRM_PLANE_TYPE_CURSOR represents a "cursor" plane for a CRTC. Cursor 1348 + planes are the planes operated upon by the DRM_IOCTL_MODE_CURSOR and 1349 + DRM_IOCTL_MODE_CURSOR2 ioctls. 1350 + </listitem> 1351 + <listitem> 1352 + DRM_PLANE_TYPE_OVERLAY represents all non-primary, non-cursor planes. 1353 + Some drivers refer to these types of planes as "sprites" internally. 1354 + </listitem> 1355 + </itemizedlist> 1356 + For compatibility with legacy userspace, only overlay planes are made 1357 + available to userspace by default. Userspace clients may set the 1358 + DRM_CLIENT_CAP_UNIVERSAL_PLANES client capability bit to indicate that 1359 + they wish to receive a universal plane list containing all plane types. 1360 + </para> 1338 1361 <sect3> 1339 1362 <title>Plane Initialization</title> 1340 1363 <para> 1341 - Planes are optional. To create a plane, a KMS drivers allocates and 1364 + To create a plane, a KMS drivers allocates and 1342 1365 zeroes an instances of struct <structname>drm_plane</structname> 1343 1366 (possibly as part of a larger structure) and registers it with a call 1344 - to <function>drm_plane_init</function>. The function takes a bitmask 1367 + to <function>drm_universal_plane_init</function>. The function takes a bitmask 1345 1368 of the CRTCs that can be associated with the plane, a pointer to the 1346 - plane functions and a list of format supported formats. 1369 + plane functions, a list of format supported formats, and the type of 1370 + plane (primary, cursor, or overlay) being initialized. 1371 + </para> 1372 + <para> 1373 + Cursor and overlay planes are optional. All drivers should provide 1374 + one primary plane per CRTC (although this requirement may change in 1375 + the future); drivers that do not wish to provide special handling for 1376 + primary planes may make use of the helper functions described in 1377 + <xref linkend="drm-kms-planehelpers"/> to create and register a 1378 + primary plane with standard capabilities. 1347 1379 </para> 1348 1380 </sect3> 1349 1381 <sect3> ··· 1806 1774 <sect1> 1807 1775 <title>Mode Setting Helper Functions</title> 1808 1776 <para> 1809 - The CRTC, encoder and connector functions provided by the drivers 1777 + The plane, CRTC, encoder and connector functions provided by the drivers 1810 1778 implement the DRM API. They're called by the DRM core and ioctl handlers 1811 1779 to handle device state changes and configuration request. As implementing 1812 1780 those functions often requires logic not specific to drivers, mid-layer ··· 1814 1782 </para> 1815 1783 <para> 1816 1784 The DRM core contains one mid-layer implementation. The mid-layer provides 1817 - implementations of several CRTC, encoder and connector functions (called 1818 - from the top of the mid-layer) that pre-process requests and call 1785 + implementations of several plane, CRTC, encoder and connector functions 1786 + (called from the top of the mid-layer) that pre-process requests and call 1819 1787 lower-level functions provided by the driver (at the bottom of the 1820 1788 mid-layer). For instance, the 1821 1789 <function>drm_crtc_helper_set_config</function> function can be used to ··· 2324 2292 </para> 2325 2293 !Iinclude/linux/hdmi.h 2326 2294 !Edrivers/video/hdmi.c 2295 + </sect2> 2296 + <sect2> 2297 + <title id="drm-kms-planehelpers">Plane Helper Reference</title> 2298 + !Edrivers/gpu/drm/drm_plane_helper.c Plane Helpers 2327 2299 </sect2> 2328 2300 </sect1> 2329 2301
+2 -1
drivers/gpu/drm/Makefile
··· 13 13 drm_crtc.o drm_modes.o drm_edid.o \ 14 14 drm_info.o drm_debugfs.o drm_encoder_slave.o \ 15 15 drm_trace_points.o drm_global.o drm_prime.o \ 16 - drm_rect.o drm_vma_manager.o drm_flip_work.o 16 + drm_rect.o drm_vma_manager.o drm_flip_work.o \ 17 + drm_plane_helper.o 17 18 18 19 drm-$(CONFIG_COMPAT) += drm_ioc32.o 19 20 drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o
+12 -11
drivers/gpu/drm/armada/armada_crtc.c
··· 478 478 unsigned i; 479 479 bool interlaced; 480 480 481 - drm_framebuffer_reference(crtc->fb); 481 + drm_framebuffer_reference(crtc->primary->fb); 482 482 483 483 interlaced = !!(adj->flags & DRM_MODE_FLAG_INTERLACE); 484 484 485 - i = armada_drm_crtc_calc_fb(dcrtc->crtc.fb, x, y, regs, interlaced); 485 + i = armada_drm_crtc_calc_fb(dcrtc->crtc.primary->fb, 486 + x, y, regs, interlaced); 486 487 487 488 rm = adj->crtc_hsync_start - adj->crtc_hdisplay; 488 489 lm = adj->crtc_htotal - adj->crtc_hsync_end; ··· 568 567 } 569 568 570 569 val = CFG_GRA_ENA | CFG_GRA_HSMOOTH; 571 - val |= CFG_GRA_FMT(drm_fb_to_armada_fb(dcrtc->crtc.fb)->fmt); 572 - val |= CFG_GRA_MOD(drm_fb_to_armada_fb(dcrtc->crtc.fb)->mod); 570 + val |= CFG_GRA_FMT(drm_fb_to_armada_fb(dcrtc->crtc.primary->fb)->fmt); 571 + val |= CFG_GRA_MOD(drm_fb_to_armada_fb(dcrtc->crtc.primary->fb)->mod); 573 572 574 - if (drm_fb_to_armada_fb(dcrtc->crtc.fb)->fmt > CFG_420) 573 + if (drm_fb_to_armada_fb(dcrtc->crtc.primary->fb)->fmt > CFG_420) 575 574 val |= CFG_PALETTE_ENA; 576 575 577 576 if (interlaced) ··· 609 608 struct armada_regs regs[4]; 610 609 unsigned i; 611 610 612 - i = armada_drm_crtc_calc_fb(crtc->fb, crtc->x, crtc->y, regs, 611 + i = armada_drm_crtc_calc_fb(crtc->primary->fb, crtc->x, crtc->y, regs, 613 612 dcrtc->interlaced); 614 613 armada_reg_queue_end(regs, i); 615 614 ··· 617 616 wait_event(dcrtc->frame_wait, !dcrtc->frame_work); 618 617 619 618 /* Take a reference to the new fb as we're using it */ 620 - drm_framebuffer_reference(crtc->fb); 619 + drm_framebuffer_reference(crtc->primary->fb); 621 620 622 621 /* Update the base in the CRTC */ 623 622 armada_drm_crtc_update_regs(dcrtc, regs); ··· 638 637 struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); 639 638 640 639 armada_drm_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); 641 - armada_drm_crtc_finish_fb(dcrtc, crtc->fb, true); 640 + armada_drm_crtc_finish_fb(dcrtc, crtc->primary->fb, true); 642 641 643 642 /* Power down most RAMs and FIFOs */ 644 643 writel_relaxed(CFG_PDWN256x32 | CFG_PDWN256x24 | CFG_PDWN256x8 | ··· 905 904 int ret; 906 905 907 906 /* We don't support changing the pixel format */ 908 - if (fb->pixel_format != crtc->fb->pixel_format) 907 + if (fb->pixel_format != crtc->primary->fb->pixel_format) 909 908 return -EINVAL; 910 909 911 910 work = kmalloc(sizeof(*work), GFP_KERNEL); ··· 913 912 return -ENOMEM; 914 913 915 914 work->event = event; 916 - work->old_fb = dcrtc->crtc.fb; 915 + work->old_fb = dcrtc->crtc.primary->fb; 917 916 918 917 i = armada_drm_crtc_calc_fb(fb, crtc->x, crtc->y, work->regs, 919 918 dcrtc->interlaced); ··· 942 941 * will _not_ drop that reference on successful return from this 943 942 * function. Simply mark this new framebuffer as the current one. 944 943 */ 945 - dcrtc->crtc.fb = fb; 944 + dcrtc->crtc.primary->fb = fb; 946 945 947 946 /* 948 947 * Finally, if the display is blanked, we won't receive an
+6 -6
drivers/gpu/drm/ast/ast_mode.c
··· 81 81 u32 refresh_rate_index = 0, mode_id, color_index, refresh_rate; 82 82 u32 hborder, vborder; 83 83 84 - switch (crtc->fb->bits_per_pixel) { 84 + switch (crtc->primary->fb->bits_per_pixel) { 85 85 case 8: 86 86 vbios_mode->std_table = &vbios_stdtable[VGAModeIndex]; 87 87 color_index = VGAModeIndex - 1; ··· 176 176 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8e, mode_id & 0xff); 177 177 178 178 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8); 179 - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x92, crtc->fb->bits_per_pixel); 179 + ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x92, crtc->primary->fb->bits_per_pixel); 180 180 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x93, adjusted_mode->clock / 1000); 181 181 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x94, adjusted_mode->crtc_hdisplay); 182 182 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x95, adjusted_mode->crtc_hdisplay >> 8); ··· 340 340 341 341 u16 offset; 342 342 343 - offset = crtc->fb->pitches[0] >> 3; 343 + offset = crtc->primary->fb->pitches[0] >> 3; 344 344 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x13, (offset & 0xff)); 345 345 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xb0, (offset >> 8) & 0x3f); 346 346 } ··· 365 365 struct ast_private *ast = crtc->dev->dev_private; 366 366 u8 jregA0 = 0, jregA3 = 0, jregA8 = 0; 367 367 368 - switch (crtc->fb->bits_per_pixel) { 368 + switch (crtc->primary->fb->bits_per_pixel) { 369 369 case 8: 370 370 jregA0 = 0x70; 371 371 jregA3 = 0x01; ··· 418 418 static bool ast_set_dac_reg(struct drm_crtc *crtc, struct drm_display_mode *mode, 419 419 struct ast_vbios_mode_info *vbios_mode) 420 420 { 421 - switch (crtc->fb->bits_per_pixel) { 421 + switch (crtc->primary->fb->bits_per_pixel) { 422 422 case 8: 423 423 break; 424 424 default: ··· 490 490 ast_bo_unreserve(bo); 491 491 } 492 492 493 - ast_fb = to_ast_framebuffer(crtc->fb); 493 + ast_fb = to_ast_framebuffer(crtc->primary->fb); 494 494 obj = ast_fb->obj; 495 495 bo = gem_to_ast_bo(obj); 496 496
+2 -2
drivers/gpu/drm/bochs/bochs_kms.c
··· 62 62 } 63 63 } 64 64 65 - if (WARN_ON(crtc->fb == NULL)) 65 + if (WARN_ON(crtc->primary->fb == NULL)) 66 66 return -EINVAL; 67 67 68 - bochs_fb = to_bochs_framebuffer(crtc->fb); 68 + bochs_fb = to_bochs_framebuffer(crtc->primary->fb); 69 69 bo = gem_to_bochs_bo(bochs_fb->obj); 70 70 ret = ttm_bo_reserve(&bo->bo, true, false, false, 0); 71 71 if (ret)
+5 -5
drivers/gpu/drm/cirrus/cirrus_mode.c
··· 149 149 cirrus_bo_unreserve(bo); 150 150 } 151 151 152 - cirrus_fb = to_cirrus_framebuffer(crtc->fb); 152 + cirrus_fb = to_cirrus_framebuffer(crtc->primary->fb); 153 153 obj = cirrus_fb->obj; 154 154 bo = gem_to_cirrus_bo(obj); 155 155 ··· 268 268 sr07 = RREG8(SEQ_DATA); 269 269 sr07 &= 0xe0; 270 270 hdr = 0; 271 - switch (crtc->fb->bits_per_pixel) { 271 + switch (crtc->primary->fb->bits_per_pixel) { 272 272 case 8: 273 273 sr07 |= 0x11; 274 274 break; ··· 291 291 WREG_SEQ(0x7, sr07); 292 292 293 293 /* Program the pitch */ 294 - tmp = crtc->fb->pitches[0] / 8; 294 + tmp = crtc->primary->fb->pitches[0] / 8; 295 295 WREG_CRT(VGA_CRTC_OFFSET, tmp); 296 296 297 297 /* Enable extended blanking and pitch bits, and enable full memory */ 298 298 tmp = 0x22; 299 - tmp |= (crtc->fb->pitches[0] >> 7) & 0x10; 300 - tmp |= (crtc->fb->pitches[0] >> 6) & 0x40; 299 + tmp |= (crtc->primary->fb->pitches[0] >> 7) & 0x10; 300 + tmp |= (crtc->primary->fb->pitches[0] >> 6) & 0x40; 301 301 WREG_CRT(0x1b, tmp); 302 302 303 303 /* Enable high-colour modes */
+138 -51
drivers/gpu/drm/drm_crtc.c
··· 121 121 122 122 DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list) 123 123 124 + static const struct drm_prop_enum_list drm_plane_type_enum_list[] = 125 + { 126 + { DRM_PLANE_TYPE_OVERLAY, "Overlay" }, 127 + { DRM_PLANE_TYPE_PRIMARY, "Primary" }, 128 + { DRM_PLANE_TYPE_CURSOR, "Cursor" }, 129 + }; 130 + 124 131 /* 125 132 * Optional properties 126 133 */ ··· 669 662 drm_modeset_lock_all(dev); 670 663 /* remove from any CRTC */ 671 664 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 672 - if (crtc->fb == fb) { 665 + if (crtc->primary->fb == fb) { 673 666 /* should turn off the crtc */ 674 667 memset(&set, 0, sizeof(struct drm_mode_set)); 675 668 set.crtc = crtc; ··· 692 685 EXPORT_SYMBOL(drm_framebuffer_remove); 693 686 694 687 /** 695 - * drm_crtc_init - Initialise a new CRTC object 688 + * drm_crtc_init_with_planes - Initialise a new CRTC object with 689 + * specified primary and cursor planes. 696 690 * @dev: DRM device 697 691 * @crtc: CRTC object to init 692 + * @primary: Primary plane for CRTC 693 + * @cursor: Cursor plane for CRTC 698 694 * @funcs: callbacks for the new CRTC 699 695 * 700 696 * Inits a new object created as base part of a driver crtc object. ··· 705 695 * Returns: 706 696 * Zero on success, error code on failure. 707 697 */ 708 - int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, 709 - const struct drm_crtc_funcs *funcs) 698 + int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc, 699 + struct drm_plane *primary, 700 + void *cursor, 701 + const struct drm_crtc_funcs *funcs) 710 702 { 711 703 int ret; 712 704 ··· 729 717 list_add_tail(&crtc->head, &dev->mode_config.crtc_list); 730 718 dev->mode_config.num_crtc++; 731 719 720 + crtc->primary = primary; 721 + if (primary) 722 + primary->possible_crtcs = 1 << drm_crtc_index(crtc); 723 + 732 724 out: 733 725 drm_modeset_unlock_all(dev); 734 726 735 727 return ret; 736 728 } 737 - EXPORT_SYMBOL(drm_crtc_init); 729 + EXPORT_SYMBOL(drm_crtc_init_with_planes); 738 730 739 731 /** 740 732 * drm_crtc_cleanup - Clean up the core crtc usage ··· 1016 1000 EXPORT_SYMBOL(drm_encoder_cleanup); 1017 1001 1018 1002 /** 1019 - * drm_plane_init - Initialise a new plane object 1003 + * drm_universal_plane_init - Initialize a new universal plane object 1020 1004 * @dev: DRM device 1021 1005 * @plane: plane object to init 1022 1006 * @possible_crtcs: bitmask of possible CRTCs 1023 1007 * @funcs: callbacks for the new plane 1024 1008 * @formats: array of supported formats (%DRM_FORMAT_*) 1025 1009 * @format_count: number of elements in @formats 1026 - * @priv: plane is private (hidden from userspace)? 1010 + * @type: type of plane (overlay, primary, cursor) 1027 1011 * 1028 - * Inits a preallocate plane object created as base part of a driver plane 1029 - * object. 1012 + * Initializes a plane object of type @type. 1030 1013 * 1031 1014 * Returns: 1032 1015 * Zero on success, error code on failure. 1033 1016 */ 1034 - int drm_plane_init(struct drm_device *dev, struct drm_plane *plane, 1035 - unsigned long possible_crtcs, 1036 - const struct drm_plane_funcs *funcs, 1037 - const uint32_t *formats, uint32_t format_count, 1038 - bool priv) 1017 + int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, 1018 + unsigned long possible_crtcs, 1019 + const struct drm_plane_funcs *funcs, 1020 + const uint32_t *formats, uint32_t format_count, 1021 + enum drm_plane_type type) 1039 1022 { 1040 1023 int ret; 1041 1024 ··· 1059 1044 memcpy(plane->format_types, formats, format_count * sizeof(uint32_t)); 1060 1045 plane->format_count = format_count; 1061 1046 plane->possible_crtcs = possible_crtcs; 1047 + plane->type = type; 1062 1048 1063 - /* private planes are not exposed to userspace, but depending on 1064 - * display hardware, might be convenient to allow sharing programming 1065 - * for the scanout engine with the crtc implementation. 1066 - */ 1067 - if (!priv) { 1068 - list_add_tail(&plane->head, &dev->mode_config.plane_list); 1069 - dev->mode_config.num_plane++; 1070 - } else { 1071 - INIT_LIST_HEAD(&plane->head); 1072 - } 1049 + list_add_tail(&plane->head, &dev->mode_config.plane_list); 1050 + dev->mode_config.num_total_plane++; 1051 + if (plane->type == DRM_PLANE_TYPE_OVERLAY) 1052 + dev->mode_config.num_overlay_plane++; 1053 + 1054 + drm_object_attach_property(&plane->base, 1055 + dev->mode_config.plane_type_property, 1056 + plane->type); 1073 1057 1074 1058 out: 1075 1059 drm_modeset_unlock_all(dev); 1076 1060 1077 1061 return ret; 1062 + } 1063 + EXPORT_SYMBOL(drm_universal_plane_init); 1064 + 1065 + /** 1066 + * drm_plane_init - Initialize a legacy plane 1067 + * @dev: DRM device 1068 + * @plane: plane object to init 1069 + * @possible_crtcs: bitmask of possible CRTCs 1070 + * @funcs: callbacks for the new plane 1071 + * @formats: array of supported formats (%DRM_FORMAT_*) 1072 + * @format_count: number of elements in @formats 1073 + * @is_primary: plane type (primary vs overlay) 1074 + * 1075 + * Legacy API to initialize a DRM plane. 1076 + * 1077 + * New drivers should call drm_universal_plane_init() instead. 1078 + * 1079 + * Returns: 1080 + * Zero on success, error code on failure. 1081 + */ 1082 + int drm_plane_init(struct drm_device *dev, struct drm_plane *plane, 1083 + unsigned long possible_crtcs, 1084 + const struct drm_plane_funcs *funcs, 1085 + const uint32_t *formats, uint32_t format_count, 1086 + bool is_primary) 1087 + { 1088 + enum drm_plane_type type; 1089 + 1090 + type = is_primary ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY; 1091 + return drm_universal_plane_init(dev, plane, possible_crtcs, funcs, 1092 + formats, format_count, type); 1078 1093 } 1079 1094 EXPORT_SYMBOL(drm_plane_init); 1080 1095 ··· 1123 1078 drm_modeset_lock_all(dev); 1124 1079 kfree(plane->format_types); 1125 1080 drm_mode_object_put(dev, &plane->base); 1126 - /* if not added to a list, it must be a private plane */ 1127 - if (!list_empty(&plane->head)) { 1128 - list_del(&plane->head); 1129 - dev->mode_config.num_plane--; 1130 - } 1081 + 1082 + BUG_ON(list_empty(&plane->head)); 1083 + 1084 + list_del(&plane->head); 1085 + dev->mode_config.num_total_plane--; 1086 + if (plane->type == DRM_PLANE_TYPE_OVERLAY) 1087 + dev->mode_config.num_overlay_plane--; 1131 1088 drm_modeset_unlock_all(dev); 1132 1089 } 1133 1090 EXPORT_SYMBOL(drm_plane_cleanup); ··· 1177 1130 "DPMS", drm_dpms_enum_list, 1178 1131 ARRAY_SIZE(drm_dpms_enum_list)); 1179 1132 dev->mode_config.dpms_property = dpms; 1133 + 1134 + return 0; 1135 + } 1136 + 1137 + static int drm_mode_create_standard_plane_properties(struct drm_device *dev) 1138 + { 1139 + struct drm_property *type; 1140 + 1141 + /* 1142 + * Standard properties (apply to all planes) 1143 + */ 1144 + type = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE, 1145 + "type", drm_plane_type_enum_list, 1146 + ARRAY_SIZE(drm_plane_type_enum_list)); 1147 + dev->mode_config.plane_type_property = type; 1180 1148 1181 1149 return 0; 1182 1150 } ··· 1714 1652 crtc_resp->x = crtc->x; 1715 1653 crtc_resp->y = crtc->y; 1716 1654 crtc_resp->gamma_size = crtc->gamma_size; 1717 - if (crtc->fb) 1718 - crtc_resp->fb_id = crtc->fb->base.id; 1655 + if (crtc->primary->fb) 1656 + crtc_resp->fb_id = crtc->primary->fb->base.id; 1719 1657 else 1720 1658 crtc_resp->fb_id = 0; 1721 1659 ··· 1959 1897 struct drm_plane *plane; 1960 1898 uint32_t __user *plane_ptr; 1961 1899 int copied = 0, ret = 0; 1900 + unsigned num_planes; 1962 1901 1963 1902 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 1964 1903 return -EINVAL; ··· 1967 1904 drm_modeset_lock_all(dev); 1968 1905 config = &dev->mode_config; 1969 1906 1907 + if (file_priv->universal_planes) 1908 + num_planes = config->num_total_plane; 1909 + else 1910 + num_planes = config->num_overlay_plane; 1911 + 1970 1912 /* 1971 1913 * This ioctl is called twice, once to determine how much space is 1972 1914 * needed, and the 2nd time to fill it. 1973 1915 */ 1974 - if (config->num_plane && 1975 - (plane_resp->count_planes >= config->num_plane)) { 1916 + if (num_planes && 1917 + (plane_resp->count_planes >= num_planes)) { 1976 1918 plane_ptr = (uint32_t __user *)(unsigned long)plane_resp->plane_id_ptr; 1977 1919 1978 1920 list_for_each_entry(plane, &config->plane_list, head) { 1921 + /* 1922 + * Unless userspace set the 'universal planes' 1923 + * capability bit, only advertise overlays. 1924 + */ 1925 + if (plane->type != DRM_PLANE_TYPE_OVERLAY && 1926 + !file_priv->universal_planes) 1927 + continue; 1928 + 1979 1929 if (put_user(plane->base.id, plane_ptr + copied)) { 1980 1930 ret = -EFAULT; 1981 1931 goto out; ··· 1996 1920 copied++; 1997 1921 } 1998 1922 } 1999 - plane_resp->count_planes = config->num_plane; 1923 + plane_resp->count_planes = num_planes; 2000 1924 2001 1925 out: 2002 1926 drm_modeset_unlock_all(dev); ··· 2232 2156 * crtcs. Atomic modeset will have saner semantics ... 2233 2157 */ 2234 2158 list_for_each_entry(tmp, &crtc->dev->mode_config.crtc_list, head) 2235 - tmp->old_fb = tmp->fb; 2159 + tmp->old_fb = tmp->primary->fb; 2236 2160 2237 2161 fb = set->fb; 2238 2162 2239 2163 ret = crtc->funcs->set_config(set); 2240 2164 if (ret == 0) { 2165 + crtc->primary->crtc = crtc; 2166 + 2241 2167 /* crtc->fb must be updated by ->set_config, enforces this. */ 2242 - WARN_ON(fb != crtc->fb); 2168 + WARN_ON(fb != crtc->primary->fb); 2243 2169 } 2244 2170 2245 2171 list_for_each_entry(tmp, &crtc->dev->mode_config.crtc_list, head) { 2246 - if (tmp->fb) 2247 - drm_framebuffer_reference(tmp->fb); 2172 + if (tmp->primary->fb) 2173 + drm_framebuffer_reference(tmp->primary->fb); 2248 2174 if (tmp->old_fb) 2249 2175 drm_framebuffer_unreference(tmp->old_fb); 2250 2176 } ··· 2255 2177 } 2256 2178 EXPORT_SYMBOL(drm_mode_set_config_internal); 2257 2179 2258 - /* 2259 - * Checks that the framebuffer is big enough for the CRTC viewport 2260 - * (x, y, hdisplay, vdisplay) 2180 + /** 2181 + * drm_crtc_check_viewport - Checks that a framebuffer is big enough for the 2182 + * CRTC viewport 2183 + * @crtc: CRTC that framebuffer will be displayed on 2184 + * @x: x panning 2185 + * @y: y panning 2186 + * @mode: mode that framebuffer will be displayed under 2187 + * @fb: framebuffer to check size of 2261 2188 */ 2262 - static int drm_crtc_check_viewport(const struct drm_crtc *crtc, 2263 - int x, int y, 2264 - const struct drm_display_mode *mode, 2265 - const struct drm_framebuffer *fb) 2189 + int drm_crtc_check_viewport(const struct drm_crtc *crtc, 2190 + int x, int y, 2191 + const struct drm_display_mode *mode, 2192 + const struct drm_framebuffer *fb) 2266 2193 2267 2194 { 2268 2195 int hdisplay, vdisplay; ··· 2298 2215 2299 2216 return 0; 2300 2217 } 2218 + EXPORT_SYMBOL(drm_crtc_check_viewport); 2301 2219 2302 2220 /** 2303 2221 * drm_mode_setcrtc - set CRTC configuration ··· 2350 2266 /* If we have a mode we need a framebuffer. */ 2351 2267 /* If we pass -1, set the mode with the currently bound fb */ 2352 2268 if (crtc_req->fb_id == -1) { 2353 - if (!crtc->fb) { 2269 + if (!crtc->primary->fb) { 2354 2270 DRM_DEBUG_KMS("CRTC doesn't have current FB\n"); 2355 2271 ret = -EINVAL; 2356 2272 goto out; 2357 2273 } 2358 - fb = crtc->fb; 2274 + fb = crtc->primary->fb; 2359 2275 /* Make refcounting symmetric with the lookup path. */ 2360 2276 drm_framebuffer_reference(fb); 2361 2277 } else { ··· 4149 4065 crtc = obj_to_crtc(obj); 4150 4066 4151 4067 mutex_lock(&crtc->mutex); 4152 - if (crtc->fb == NULL) { 4068 + if (crtc->primary->fb == NULL) { 4153 4069 /* The framebuffer is currently unbound, presumably 4154 4070 * due to a hotplug event, that userspace has not 4155 4071 * yet discovered. ··· 4171 4087 if (ret) 4172 4088 goto out; 4173 4089 4174 - if (crtc->fb->pixel_format != fb->pixel_format) { 4090 + if (crtc->primary->fb->pixel_format != fb->pixel_format) { 4175 4091 DRM_DEBUG_KMS("Page flip is not allowed to change frame buffer format.\n"); 4176 4092 ret = -EINVAL; 4177 4093 goto out; ··· 4204 4120 (void (*) (struct drm_pending_event *)) kfree; 4205 4121 } 4206 4122 4207 - old_fb = crtc->fb; 4123 + old_fb = crtc->primary->fb; 4208 4124 ret = crtc->funcs->page_flip(crtc, fb, e, page_flip->flags); 4209 4125 if (ret) { 4210 4126 if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) { ··· 4222 4138 * Failing to do so will screw with the reference counting 4223 4139 * on framebuffers. 4224 4140 */ 4225 - WARN_ON(crtc->fb != fb); 4141 + WARN_ON(crtc->primary->fb != fb); 4226 4142 /* Unref only the old framebuffer. */ 4227 4143 fb = NULL; 4228 4144 } ··· 4611 4527 4612 4528 drm_modeset_lock_all(dev); 4613 4529 drm_mode_create_standard_connector_properties(dev); 4530 + drm_mode_create_standard_plane_properties(dev); 4614 4531 drm_modeset_unlock_all(dev); 4615 4532 4616 4533 /* Just to be sure */ ··· 4619 4534 dev->mode_config.num_connector = 0; 4620 4535 dev->mode_config.num_crtc = 0; 4621 4536 dev->mode_config.num_encoder = 0; 4537 + dev->mode_config.num_overlay_plane = 0; 4538 + dev->mode_config.num_total_plane = 0; 4622 4539 } 4623 4540 EXPORT_SYMBOL(drm_mode_config_init); 4624 4541
+10 -10
drivers/gpu/drm/drm_crtc_helper.c
··· 307 307 (*crtc_funcs->disable)(crtc); 308 308 else 309 309 (*crtc_funcs->dpms)(crtc, DRM_MODE_DPMS_OFF); 310 - crtc->fb = NULL; 310 + crtc->primary->fb = NULL; 311 311 } 312 312 } 313 313 } ··· 651 651 save_set.mode = &set->crtc->mode; 652 652 save_set.x = set->crtc->x; 653 653 save_set.y = set->crtc->y; 654 - save_set.fb = set->crtc->fb; 654 + save_set.fb = set->crtc->primary->fb; 655 655 656 656 /* We should be able to check here if the fb has the same properties 657 657 * and then just flip_or_move it */ 658 - if (set->crtc->fb != set->fb) { 658 + if (set->crtc->primary->fb != set->fb) { 659 659 /* If we have no fb then treat it as a full mode set */ 660 - if (set->crtc->fb == NULL) { 660 + if (set->crtc->primary->fb == NULL) { 661 661 DRM_DEBUG_KMS("crtc has no fb, full mode set\n"); 662 662 mode_changed = true; 663 663 } else if (set->fb == NULL) { 664 664 mode_changed = true; 665 665 } else if (set->fb->pixel_format != 666 - set->crtc->fb->pixel_format) { 666 + set->crtc->primary->fb->pixel_format) { 667 667 mode_changed = true; 668 668 } else 669 669 fb_changed = true; ··· 765 765 DRM_DEBUG_KMS("attempting to set mode from" 766 766 " userspace\n"); 767 767 drm_mode_debug_printmodeline(set->mode); 768 - set->crtc->fb = set->fb; 768 + set->crtc->primary->fb = set->fb; 769 769 if (!drm_crtc_helper_set_mode(set->crtc, set->mode, 770 770 set->x, set->y, 771 771 save_set.fb)) { 772 772 DRM_ERROR("failed to set mode on [CRTC:%d]\n", 773 773 set->crtc->base.id); 774 - set->crtc->fb = save_set.fb; 774 + set->crtc->primary->fb = save_set.fb; 775 775 ret = -EINVAL; 776 776 goto fail; 777 777 } ··· 786 786 } else if (fb_changed) { 787 787 set->crtc->x = set->x; 788 788 set->crtc->y = set->y; 789 - set->crtc->fb = set->fb; 789 + set->crtc->primary->fb = set->fb; 790 790 ret = crtc_funcs->mode_set_base(set->crtc, 791 791 set->x, set->y, save_set.fb); 792 792 if (ret != 0) { 793 793 set->crtc->x = save_set.x; 794 794 set->crtc->y = save_set.y; 795 - set->crtc->fb = save_set.fb; 795 + set->crtc->primary->fb = save_set.fb; 796 796 goto fail; 797 797 } 798 798 } ··· 989 989 continue; 990 990 991 991 ret = drm_crtc_helper_set_mode(crtc, &crtc->mode, 992 - crtc->x, crtc->y, crtc->fb); 992 + crtc->x, crtc->y, crtc->primary->fb); 993 993 994 994 /* Restoring the old config should never fail! */ 995 995 if (ret == false)
+5 -4
drivers/gpu/drm/drm_fb_helper.c
··· 232 232 233 233 list_for_each_entry(c, &dev->mode_config.crtc_list, head) { 234 234 if (crtc->base.id == c->base.id) 235 - return c->fb; 235 + return c->primary->fb; 236 236 } 237 237 238 238 return NULL; ··· 291 291 drm_warn_on_modeset_not_all_locked(dev); 292 292 293 293 list_for_each_entry(plane, &dev->mode_config.plane_list, head) 294 - drm_plane_force_disable(plane); 294 + if (plane->type != DRM_PLANE_TYPE_PRIMARY) 295 + drm_plane_force_disable(plane); 295 296 296 297 for (i = 0; i < fb_helper->crtc_count; i++) { 297 298 struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set; ··· 366 365 return false; 367 366 368 367 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 369 - if (crtc->fb) 368 + if (crtc->primary->fb) 370 369 crtcs_bound++; 371 - if (crtc->fb == fb_helper->fb) 370 + if (crtc->primary->fb == fb_helper->fb) 372 371 bound++; 373 372 } 374 373
+7
drivers/gpu/drm/drm_ioctl.c
··· 328 328 return -EINVAL; 329 329 file_priv->stereo_allowed = req->value; 330 330 break; 331 + case DRM_CLIENT_CAP_UNIVERSAL_PLANES: 332 + if (!drm_universal_planes) 333 + return -EINVAL; 334 + if (req->value > 1) 335 + return -EINVAL; 336 + file_priv->universal_planes = req->value; 337 + break; 331 338 default: 332 339 return -EINVAL; 333 340 }
+333
drivers/gpu/drm/drm_plane_helper.c
··· 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 + 30 + #define SUBPIXEL_MASK 0xffff 31 + 32 + /* 33 + * This is the minimal list of formats that seem to be safe for modeset use 34 + * with all current DRM drivers. Most hardware can actually support more 35 + * formats than this and drivers may specify a more accurate list when 36 + * creating the primary plane. However drivers that still call 37 + * drm_plane_init() will use this minimal format list as the default. 38 + */ 39 + const static uint32_t safe_modeset_formats[] = { 40 + DRM_FORMAT_XRGB8888, 41 + DRM_FORMAT_ARGB8888, 42 + }; 43 + 44 + /* 45 + * Returns the connectors currently associated with a CRTC. This function 46 + * should be called twice: once with a NULL connector list to retrieve 47 + * the list size, and once with the properly allocated list to be filled in. 48 + */ 49 + static int get_connectors_for_crtc(struct drm_crtc *crtc, 50 + struct drm_connector **connector_list, 51 + int num_connectors) 52 + { 53 + struct drm_device *dev = crtc->dev; 54 + struct drm_connector *connector; 55 + int count = 0; 56 + 57 + list_for_each_entry(connector, &dev->mode_config.connector_list, head) 58 + if (connector->encoder && connector->encoder->crtc == crtc) { 59 + if (connector_list != NULL && count < num_connectors) 60 + *(connector_list++) = connector; 61 + 62 + count++; 63 + } 64 + 65 + return count; 66 + } 67 + 68 + /** 69 + * drm_primary_helper_update() - Helper for primary plane update 70 + * @plane: plane object to update 71 + * @crtc: owning CRTC of owning plane 72 + * @fb: framebuffer to flip onto plane 73 + * @crtc_x: x offset of primary plane on crtc 74 + * @crtc_y: y offset of primary plane on crtc 75 + * @crtc_w: width of primary plane rectangle on crtc 76 + * @crtc_h: height of primary plane rectangle on crtc 77 + * @src_x: x offset of @fb for panning 78 + * @src_y: y offset of @fb for panning 79 + * @src_w: width of source rectangle in @fb 80 + * @src_h: height of source rectangle in @fb 81 + * 82 + * Provides a default plane update handler for primary planes. This is handler 83 + * is called in response to a userspace SetPlane operation on the plane with a 84 + * non-NULL framebuffer. We call the driver's modeset handler to update the 85 + * framebuffer. 86 + * 87 + * SetPlane() on a primary plane of a disabled CRTC is not supported, and will 88 + * return an error. 89 + * 90 + * Note that we make some assumptions about hardware limitations that may not be 91 + * true for all hardware -- 92 + * 1) Primary plane cannot be repositioned. 93 + * 2) Primary plane cannot be scaled. 94 + * 3) Primary plane must cover the entire CRTC. 95 + * 4) Subpixel positioning is not supported. 96 + * Drivers for hardware that don't have these restrictions can provide their 97 + * own implementation rather than using this helper. 98 + * 99 + * RETURNS: 100 + * Zero on success, error code on failure 101 + */ 102 + int drm_primary_helper_update(struct drm_plane *plane, struct drm_crtc *crtc, 103 + struct drm_framebuffer *fb, 104 + int crtc_x, int crtc_y, 105 + unsigned int crtc_w, unsigned int crtc_h, 106 + uint32_t src_x, uint32_t src_y, 107 + uint32_t src_w, uint32_t src_h) 108 + { 109 + struct drm_mode_set set = { 110 + .crtc = crtc, 111 + .fb = fb, 112 + .mode = &crtc->mode, 113 + .x = src_x >> 16, 114 + .y = src_y >> 16, 115 + }; 116 + struct drm_rect dest = { 117 + .x1 = crtc_x, 118 + .y1 = crtc_y, 119 + .x2 = crtc_x + crtc_w, 120 + .y2 = crtc_y + crtc_h, 121 + }; 122 + struct drm_rect clip = { 123 + .x2 = crtc->mode.hdisplay, 124 + .y2 = crtc->mode.vdisplay, 125 + }; 126 + struct drm_connector **connector_list; 127 + struct drm_framebuffer *tmpfb; 128 + int num_connectors, ret; 129 + 130 + if (!crtc->enabled) { 131 + DRM_DEBUG_KMS("Cannot update primary plane of a disabled CRTC.\n"); 132 + return -EINVAL; 133 + } 134 + 135 + /* Disallow subpixel positioning */ 136 + if ((src_x | src_y | src_w | src_h) & SUBPIXEL_MASK) { 137 + DRM_DEBUG_KMS("Primary plane does not support subpixel positioning\n"); 138 + return -EINVAL; 139 + } 140 + 141 + /* Primary planes are locked to their owning CRTC */ 142 + if (plane->possible_crtcs != drm_crtc_mask(crtc)) { 143 + DRM_DEBUG_KMS("Cannot change primary plane CRTC\n"); 144 + return -EINVAL; 145 + } 146 + 147 + /* Disallow scaling */ 148 + if (crtc_w != src_w || crtc_h != src_h) { 149 + DRM_DEBUG_KMS("Can't scale primary plane\n"); 150 + return -EINVAL; 151 + } 152 + 153 + /* Make sure primary plane covers entire CRTC */ 154 + drm_rect_intersect(&dest, &clip); 155 + if (dest.x1 != 0 || dest.y1 != 0 || 156 + dest.x2 != crtc->mode.hdisplay || dest.y2 != crtc->mode.vdisplay) { 157 + DRM_DEBUG_KMS("Primary plane must cover entire CRTC\n"); 158 + return -EINVAL; 159 + } 160 + 161 + /* Framebuffer must be big enough to cover entire plane */ 162 + ret = drm_crtc_check_viewport(crtc, crtc_x, crtc_y, &crtc->mode, fb); 163 + if (ret) 164 + return ret; 165 + 166 + /* Find current connectors for CRTC */ 167 + num_connectors = get_connectors_for_crtc(crtc, NULL, 0); 168 + BUG_ON(num_connectors == 0); 169 + connector_list = kzalloc(num_connectors * sizeof(*connector_list), 170 + GFP_KERNEL); 171 + if (!connector_list) 172 + return -ENOMEM; 173 + get_connectors_for_crtc(crtc, connector_list, num_connectors); 174 + 175 + set.connectors = connector_list; 176 + set.num_connectors = num_connectors; 177 + 178 + /* 179 + * set_config() adjusts crtc->primary->fb; however the DRM setplane 180 + * code that called us expects to handle the framebuffer update and 181 + * reference counting; save and restore the current fb before 182 + * calling it. 183 + * 184 + * N.B., we call set_config() directly here rather than using 185 + * drm_mode_set_config_internal. We're reprogramming the same 186 + * connectors that were already in use, so we shouldn't need the extra 187 + * cross-CRTC fb refcounting to accomodate stealing connectors. 188 + * drm_mode_setplane() already handles the basic refcounting for the 189 + * framebuffers involved in this operation. 190 + */ 191 + tmpfb = plane->fb; 192 + ret = crtc->funcs->set_config(&set); 193 + plane->fb = tmpfb; 194 + 195 + kfree(connector_list); 196 + return ret; 197 + } 198 + EXPORT_SYMBOL(drm_primary_helper_update); 199 + 200 + /** 201 + * drm_primary_helper_disable() - Helper for primary plane disable 202 + * @plane: plane to disable 203 + * 204 + * Provides a default plane disable handler for primary planes. This is handler 205 + * is called in response to a userspace SetPlane operation on the plane with a 206 + * NULL framebuffer parameter. We call the driver's modeset handler with a NULL 207 + * framebuffer to disable the CRTC if no other planes are currently enabled. 208 + * If other planes are still enabled on the same CRTC, we return -EBUSY. 209 + * 210 + * Note that some hardware may be able to disable the primary plane without 211 + * disabling the whole CRTC. Drivers for such hardware should provide their 212 + * own disable handler that disables just the primary plane (and they'll likely 213 + * need to provide their own update handler as well to properly re-enable a 214 + * disabled primary plane). 215 + * 216 + * RETURNS: 217 + * Zero on success, error code on failure 218 + */ 219 + int drm_primary_helper_disable(struct drm_plane *plane) 220 + { 221 + struct drm_plane *p; 222 + struct drm_mode_set set = { 223 + .crtc = plane->crtc, 224 + .fb = NULL, 225 + }; 226 + 227 + if (plane->crtc == NULL || plane->fb == NULL) 228 + /* Already disabled */ 229 + return 0; 230 + 231 + list_for_each_entry(p, &plane->dev->mode_config.plane_list, head) 232 + if (p != plane && p->fb) { 233 + DRM_DEBUG_KMS("Cannot disable primary plane while other planes are still active on CRTC.\n"); 234 + return -EBUSY; 235 + } 236 + 237 + /* 238 + * N.B. We call set_config() directly here rather than 239 + * drm_mode_set_config_internal() since drm_mode_setplane() already 240 + * handles the basic refcounting and we don't need the special 241 + * cross-CRTC refcounting (no chance of stealing connectors from 242 + * other CRTC's with this update). 243 + */ 244 + return plane->crtc->funcs->set_config(&set); 245 + } 246 + EXPORT_SYMBOL(drm_primary_helper_disable); 247 + 248 + /** 249 + * drm_primary_helper_destroy() - Helper for primary plane destruction 250 + * @plane: plane to destroy 251 + * 252 + * Provides a default plane destroy handler for primary planes. This handler 253 + * is called during CRTC destruction. We disable the primary plane, remove 254 + * it from the DRM plane list, and deallocate the plane structure. 255 + */ 256 + void drm_primary_helper_destroy(struct drm_plane *plane) 257 + { 258 + plane->funcs->disable_plane(plane); 259 + drm_plane_cleanup(plane); 260 + kfree(plane); 261 + } 262 + EXPORT_SYMBOL(drm_primary_helper_destroy); 263 + 264 + const struct drm_plane_funcs drm_primary_helper_funcs = { 265 + .update_plane = drm_primary_helper_update, 266 + .disable_plane = drm_primary_helper_disable, 267 + .destroy = drm_primary_helper_destroy, 268 + }; 269 + EXPORT_SYMBOL(drm_primary_helper_funcs); 270 + 271 + /** 272 + * drm_primary_helper_create_plane() - Create a generic primary plane 273 + * @dev: drm device 274 + * @formats: pixel formats supported, or NULL for a default safe list 275 + * @num_formats: size of @formats; ignored if @formats is NULL 276 + * 277 + * Allocates and initializes a primary plane that can be used with the primary 278 + * plane helpers. Drivers that wish to use driver-specific plane structures or 279 + * provide custom handler functions may perform their own allocation and 280 + * initialization rather than calling this function. 281 + */ 282 + struct drm_plane *drm_primary_helper_create_plane(struct drm_device *dev, 283 + const uint32_t *formats, 284 + int num_formats) 285 + { 286 + struct drm_plane *primary; 287 + int ret; 288 + 289 + primary = kzalloc(sizeof(*primary), GFP_KERNEL); 290 + if (primary == NULL) { 291 + DRM_DEBUG_KMS("Failed to allocate primary plane\n"); 292 + return NULL; 293 + } 294 + 295 + if (formats == NULL) { 296 + formats = safe_modeset_formats; 297 + num_formats = ARRAY_SIZE(safe_modeset_formats); 298 + } 299 + 300 + /* possible_crtc's will be filled in later by crtc_init */ 301 + ret = drm_plane_init(dev, primary, 0, &drm_primary_helper_funcs, 302 + formats, num_formats, 303 + DRM_PLANE_TYPE_PRIMARY); 304 + if (ret) { 305 + kfree(primary); 306 + primary = NULL; 307 + } 308 + 309 + return primary; 310 + } 311 + EXPORT_SYMBOL(drm_primary_helper_create_plane); 312 + 313 + /** 314 + * drm_crtc_init - Legacy CRTC initialization function 315 + * @dev: DRM device 316 + * @crtc: CRTC object to init 317 + * @funcs: callbacks for the new CRTC 318 + * 319 + * Initialize a CRTC object with a default helper-provided primary plane and no 320 + * cursor plane. 321 + * 322 + * Returns: 323 + * Zero on success, error code on failure. 324 + */ 325 + int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, 326 + const struct drm_crtc_funcs *funcs) 327 + { 328 + struct drm_plane *primary; 329 + 330 + primary = drm_primary_helper_create_plane(dev, NULL, 0); 331 + return drm_crtc_init_with_planes(dev, crtc, primary, NULL, funcs); 332 + } 333 + EXPORT_SYMBOL(drm_crtc_init);
+5
drivers/gpu/drm/drm_stub.c
··· 45 45 unsigned int drm_rnodes = 0; /* 1 to enable experimental render nodes API */ 46 46 EXPORT_SYMBOL(drm_rnodes); 47 47 48 + /* 1 to allow user space to request universal planes (experimental) */ 49 + unsigned int drm_universal_planes = 0; 50 + EXPORT_SYMBOL(drm_universal_planes); 51 + 48 52 unsigned int drm_vblank_offdelay = 5000; /* Default to 5000 msecs. */ 49 53 EXPORT_SYMBOL(drm_vblank_offdelay); 50 54 ··· 72 68 73 69 module_param_named(debug, drm_debug, int, 0600); 74 70 module_param_named(rnodes, drm_rnodes, int, 0600); 71 + module_param_named(universal_planes, drm_universal_planes, int, 0600); 75 72 module_param_named(vblankoffdelay, drm_vblank_offdelay, int, 0600); 76 73 module_param_named(timestamp_precision_usec, drm_timestamp_precision, int, 0600); 77 74 module_param_named(timestamp_monotonic, drm_timestamp_monotonic, int, 0600);
+11 -11
drivers/gpu/drm/exynos/exynos_drm_crtc.c
··· 132 132 */ 133 133 memcpy(&crtc->mode, adjusted_mode, sizeof(*adjusted_mode)); 134 134 135 - crtc_w = crtc->fb->width - x; 136 - crtc_h = crtc->fb->height - y; 135 + crtc_w = crtc->primary->fb->width - x; 136 + crtc_h = crtc->primary->fb->height - y; 137 137 138 138 if (manager->ops->mode_set) 139 139 manager->ops->mode_set(manager, &crtc->mode); 140 140 141 - ret = exynos_plane_mode_set(plane, crtc, crtc->fb, 0, 0, crtc_w, crtc_h, 141 + ret = exynos_plane_mode_set(plane, crtc, crtc->primary->fb, 0, 0, crtc_w, crtc_h, 142 142 x, y, crtc_w, crtc_h); 143 143 if (ret) 144 144 return ret; 145 145 146 146 plane->crtc = crtc; 147 - plane->fb = crtc->fb; 147 + plane->fb = crtc->primary->fb; 148 148 149 149 return 0; 150 150 } ··· 164 164 return -EPERM; 165 165 } 166 166 167 - crtc_w = crtc->fb->width - x; 168 - crtc_h = crtc->fb->height - y; 167 + crtc_w = crtc->primary->fb->width - x; 168 + crtc_h = crtc->primary->fb->height - y; 169 169 170 - ret = exynos_plane_mode_set(plane, crtc, crtc->fb, 0, 0, crtc_w, crtc_h, 170 + ret = exynos_plane_mode_set(plane, crtc, crtc->primary->fb, 0, 0, crtc_w, crtc_h, 171 171 x, y, crtc_w, crtc_h); 172 172 if (ret) 173 173 return ret; ··· 190 190 191 191 exynos_drm_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); 192 192 193 - list_for_each_entry(plane, &crtc->dev->mode_config.plane_list, head) { 193 + drm_for_each_legacy_plane(plane, &crtc->dev->mode_config.plane_list) { 194 194 if (plane->crtc != crtc) 195 195 continue; 196 196 ··· 218 218 struct drm_device *dev = crtc->dev; 219 219 struct exynos_drm_private *dev_priv = dev->dev_private; 220 220 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); 221 - struct drm_framebuffer *old_fb = crtc->fb; 221 + struct drm_framebuffer *old_fb = crtc->primary->fb; 222 222 int ret = -EINVAL; 223 223 224 224 /* when the page flip is requested, crtc's dpms should be on */ ··· 249 249 atomic_set(&exynos_crtc->pending_flip, 1); 250 250 spin_unlock_irq(&dev->event_lock); 251 251 252 - crtc->fb = fb; 252 + crtc->primary->fb = fb; 253 253 ret = exynos_drm_crtc_mode_set_commit(crtc, crtc->x, crtc->y, 254 254 NULL); 255 255 if (ret) { 256 - crtc->fb = old_fb; 256 + crtc->primary->fb = old_fb; 257 257 258 258 spin_lock_irq(&dev->event_lock); 259 259 drm_vblank_put(dev, exynos_crtc->pipe);
+1 -1
drivers/gpu/drm/exynos/exynos_drm_encoder.c
··· 101 101 exynos_drm_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); 102 102 103 103 /* all planes connected to this encoder should be also disabled. */ 104 - list_for_each_entry(plane, &dev->mode_config.plane_list, head) { 104 + drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) { 105 105 if (plane->crtc == encoder->crtc) 106 106 plane->funcs->disable_plane(plane); 107 107 }
+1 -1
drivers/gpu/drm/gma500/cdv_intel_display.c
··· 469 469 crtc = dev_priv->pipe_to_crtc_mapping[pipe]; 470 470 gma_crtc = to_gma_crtc(crtc); 471 471 472 - if (crtc->fb == NULL || !gma_crtc->active) 472 + if (crtc->primary->fb == NULL || !gma_crtc->active) 473 473 return false; 474 474 return true; 475 475 }
+1 -1
drivers/gpu/drm/gma500/cdv_intel_dp.c
··· 1693 1693 struct drm_crtc *crtc = encoder->base.crtc; 1694 1694 drm_crtc_helper_set_mode(crtc, &crtc->mode, 1695 1695 crtc->x, crtc->y, 1696 - crtc->fb); 1696 + crtc->primary->fb); 1697 1697 } 1698 1698 1699 1699 return 0;
+1 -1
drivers/gpu/drm/gma500/cdv_intel_hdmi.c
··· 192 192 crtc->saved_mode.vdisplay != 0) { 193 193 if (centre) { 194 194 if (!drm_crtc_helper_set_mode(encoder->crtc, &crtc->saved_mode, 195 - encoder->crtc->x, encoder->crtc->y, encoder->crtc->fb)) 195 + encoder->crtc->x, encoder->crtc->y, encoder->crtc->primary->fb)) 196 196 return -1; 197 197 } else { 198 198 struct drm_encoder_helper_funcs *helpers
+1 -1
drivers/gpu/drm/gma500/cdv_intel_lvds.c
··· 494 494 &crtc->saved_mode, 495 495 encoder->crtc->x, 496 496 encoder->crtc->y, 497 - encoder->crtc->fb)) 497 + encoder->crtc->primary->fb)) 498 498 return -1; 499 499 } 500 500 } else if (!strcmp(property->name, "backlight") && encoder) {
+8 -8
drivers/gpu/drm/gma500/gma_display.c
··· 59 59 struct drm_device *dev = crtc->dev; 60 60 struct drm_psb_private *dev_priv = dev->dev_private; 61 61 struct gma_crtc *gma_crtc = to_gma_crtc(crtc); 62 - struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb); 62 + struct psb_framebuffer *psbfb = to_psb_fb(crtc->primary->fb); 63 63 int pipe = gma_crtc->pipe; 64 64 const struct psb_offset *map = &dev_priv->regmap[pipe]; 65 65 unsigned long start, offset; ··· 70 70 return 0; 71 71 72 72 /* no fb bound */ 73 - if (!crtc->fb) { 73 + if (!crtc->primary->fb) { 74 74 dev_err(dev->dev, "No FB bound\n"); 75 75 goto gma_pipe_cleaner; 76 76 } ··· 81 81 if (ret < 0) 82 82 goto gma_pipe_set_base_exit; 83 83 start = psbfb->gtt->offset; 84 - offset = y * crtc->fb->pitches[0] + x * (crtc->fb->bits_per_pixel / 8); 84 + offset = y * crtc->primary->fb->pitches[0] + x * (crtc->primary->fb->bits_per_pixel / 8); 85 85 86 - REG_WRITE(map->stride, crtc->fb->pitches[0]); 86 + REG_WRITE(map->stride, crtc->primary->fb->pitches[0]); 87 87 88 88 dspcntr = REG_READ(map->cntr); 89 89 dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; 90 90 91 - switch (crtc->fb->bits_per_pixel) { 91 + switch (crtc->primary->fb->bits_per_pixel) { 92 92 case 8: 93 93 dspcntr |= DISPPLANE_8BPP; 94 94 break; 95 95 case 16: 96 - if (crtc->fb->depth == 15) 96 + if (crtc->primary->fb->depth == 15) 97 97 dspcntr |= DISPPLANE_15_16BPP; 98 98 else 99 99 dspcntr |= DISPPLANE_16BPP; ··· 518 518 519 519 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); 520 520 521 - if (crtc->fb) { 522 - gt = to_psb_fb(crtc->fb)->gtt; 521 + if (crtc->primary->fb) { 522 + gt = to_psb_fb(crtc->primary->fb)->gtt; 523 523 psb_gtt_unpin(gt); 524 524 } 525 525 }
+1 -1
drivers/gpu/drm/gma500/mdfld_dsi_output.c
··· 287 287 &gma_crtc->saved_mode, 288 288 encoder->crtc->x, 289 289 encoder->crtc->y, 290 - encoder->crtc->fb)) 290 + encoder->crtc->primary->fb)) 291 291 goto set_prop_error; 292 292 } else { 293 293 struct drm_encoder_helper_funcs *funcs =
+8 -8
drivers/gpu/drm/gma500/mdfld_intel_display.c
··· 166 166 struct drm_device *dev = crtc->dev; 167 167 struct drm_psb_private *dev_priv = dev->dev_private; 168 168 struct gma_crtc *gma_crtc = to_gma_crtc(crtc); 169 - struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb); 169 + struct psb_framebuffer *psbfb = to_psb_fb(crtc->primary->fb); 170 170 int pipe = gma_crtc->pipe; 171 171 const struct psb_offset *map = &dev_priv->regmap[pipe]; 172 172 unsigned long start, offset; ··· 178 178 dev_dbg(dev->dev, "pipe = 0x%x.\n", pipe); 179 179 180 180 /* no fb bound */ 181 - if (!crtc->fb) { 181 + if (!crtc->primary->fb) { 182 182 dev_dbg(dev->dev, "No FB bound\n"); 183 183 return 0; 184 184 } 185 185 186 - ret = check_fb(crtc->fb); 186 + ret = check_fb(crtc->primary->fb); 187 187 if (ret) 188 188 return ret; 189 189 ··· 196 196 return 0; 197 197 198 198 start = psbfb->gtt->offset; 199 - offset = y * crtc->fb->pitches[0] + x * (crtc->fb->bits_per_pixel / 8); 199 + offset = y * crtc->primary->fb->pitches[0] + x * (crtc->primary->fb->bits_per_pixel / 8); 200 200 201 - REG_WRITE(map->stride, crtc->fb->pitches[0]); 201 + REG_WRITE(map->stride, crtc->primary->fb->pitches[0]); 202 202 dspcntr = REG_READ(map->cntr); 203 203 dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; 204 204 205 - switch (crtc->fb->bits_per_pixel) { 205 + switch (crtc->primary->fb->bits_per_pixel) { 206 206 case 8: 207 207 dspcntr |= DISPPLANE_8BPP; 208 208 break; 209 209 case 16: 210 - if (crtc->fb->depth == 15) 210 + if (crtc->primary->fb->depth == 15) 211 211 dspcntr |= DISPPLANE_15_16BPP; 212 212 else 213 213 dspcntr |= DISPPLANE_16BPP; ··· 700 700 } 701 701 #endif 702 702 703 - ret = check_fb(crtc->fb); 703 + ret = check_fb(crtc->primary->fb); 704 704 if (ret) 705 705 return ret; 706 706
+6 -6
drivers/gpu/drm/gma500/oaktrail_crtc.c
··· 599 599 struct drm_device *dev = crtc->dev; 600 600 struct drm_psb_private *dev_priv = dev->dev_private; 601 601 struct gma_crtc *gma_crtc = to_gma_crtc(crtc); 602 - struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb); 602 + struct psb_framebuffer *psbfb = to_psb_fb(crtc->primary->fb); 603 603 int pipe = gma_crtc->pipe; 604 604 const struct psb_offset *map = &dev_priv->regmap[pipe]; 605 605 unsigned long start, offset; ··· 608 608 int ret = 0; 609 609 610 610 /* no fb bound */ 611 - if (!crtc->fb) { 611 + if (!crtc->primary->fb) { 612 612 dev_dbg(dev->dev, "No FB bound\n"); 613 613 return 0; 614 614 } ··· 617 617 return 0; 618 618 619 619 start = psbfb->gtt->offset; 620 - offset = y * crtc->fb->pitches[0] + x * (crtc->fb->bits_per_pixel / 8); 620 + offset = y * crtc->primary->fb->pitches[0] + x * (crtc->primary->fb->bits_per_pixel / 8); 621 621 622 - REG_WRITE(map->stride, crtc->fb->pitches[0]); 622 + REG_WRITE(map->stride, crtc->primary->fb->pitches[0]); 623 623 624 624 dspcntr = REG_READ(map->cntr); 625 625 dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; 626 626 627 - switch (crtc->fb->bits_per_pixel) { 627 + switch (crtc->primary->fb->bits_per_pixel) { 628 628 case 8: 629 629 dspcntr |= DISPPLANE_8BPP; 630 630 break; 631 631 case 16: 632 - if (crtc->fb->depth == 15) 632 + if (crtc->primary->fb->depth == 15) 633 633 dspcntr |= DISPPLANE_15_16BPP; 634 634 else 635 635 dspcntr |= DISPPLANE_16BPP;
+1 -1
drivers/gpu/drm/gma500/psb_intel_display.c
··· 120 120 const struct gma_limit_t *limit; 121 121 122 122 /* No scan out no play */ 123 - if (crtc->fb == NULL) { 123 + if (crtc->primary->fb == NULL) { 124 124 crtc_funcs->mode_set_base(crtc, x, y, old_fb); 125 125 return 0; 126 126 }
+1 -1
drivers/gpu/drm/gma500/psb_intel_lvds.c
··· 614 614 &crtc->saved_mode, 615 615 encoder->crtc->x, 616 616 encoder->crtc->y, 617 - encoder->crtc->fb)) 617 + encoder->crtc->primary->fb)) 618 618 goto set_prop_error; 619 619 } 620 620 } else if (!strcmp(property->name, "backlight")) {
+1 -1
drivers/gpu/drm/gma500/psb_intel_sdvo.c
··· 1844 1844 if (psb_intel_sdvo->base.base.crtc) { 1845 1845 struct drm_crtc *crtc = psb_intel_sdvo->base.base.crtc; 1846 1846 drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, 1847 - crtc->y, crtc->fb); 1847 + crtc->y, crtc->primary->fb); 1848 1848 } 1849 1849 1850 1850 return 0;
+2 -2
drivers/gpu/drm/i915/i915_debugfs.c
··· 2172 2172 struct intel_encoder *intel_encoder; 2173 2173 2174 2174 seq_printf(m, "\tfb: %d, pos: %dx%d, size: %dx%d\n", 2175 - crtc->fb->base.id, crtc->x, crtc->y, 2176 - crtc->fb->width, crtc->fb->height); 2175 + crtc->primary->fb->base.id, crtc->x, crtc->y, 2176 + crtc->primary->fb->width, crtc->primary->fb->height); 2177 2177 for_each_encoder_on_crtc(dev, crtc, intel_encoder) 2178 2178 intel_encoder_info(m, intel_crtc, intel_encoder); 2179 2179 }
+2 -2
drivers/gpu/drm/i915/i915_irq.c
··· 2367 2367 } else { 2368 2368 int dspaddr = DSPADDR(intel_crtc->plane); 2369 2369 stall_detected = I915_READ(dspaddr) == (i915_gem_obj_ggtt_offset(obj) + 2370 - crtc->y * crtc->fb->pitches[0] + 2371 - crtc->x * crtc->fb->bits_per_pixel/8); 2370 + crtc->y * crtc->primary->fb->pitches[0] + 2371 + crtc->x * crtc->primary->fb->bits_per_pixel/8); 2372 2372 } 2373 2373 2374 2374 spin_unlock_irqrestore(&dev->event_lock, flags);
+34 -28
drivers/gpu/drm/i915/intel_display.c
··· 744 744 * We can ditch the crtc->fb check as soon as we can 745 745 * properly reconstruct framebuffers. 746 746 */ 747 - return intel_crtc->active && crtc->fb && 747 + return intel_crtc->active && crtc->primary->fb && 748 748 intel_crtc->config.adjusted_mode.crtc_clock; 749 749 } 750 750 ··· 2291 2291 * disabling them without disabling the entire crtc) allow again 2292 2292 * a NULL crtc->fb. 2293 2293 */ 2294 - if (intel_crtc->active && crtc->fb) 2295 - dev_priv->display.update_plane(crtc, crtc->fb, 2294 + if (intel_crtc->active && crtc->primary->fb) 2295 + dev_priv->display.update_plane(crtc, crtc->primary->fb, 2296 2296 crtc->x, crtc->y); 2297 2297 mutex_unlock(&crtc->mutex); 2298 2298 } ··· 2417 2417 return ret; 2418 2418 } 2419 2419 2420 - old_fb = crtc->fb; 2421 - crtc->fb = fb; 2420 + old_fb = crtc->primary->fb; 2421 + crtc->primary->fb = fb; 2422 2422 crtc->x = x; 2423 2423 crtc->y = y; 2424 2424 ··· 3009 3009 struct drm_device *dev = crtc->dev; 3010 3010 struct drm_i915_private *dev_priv = dev->dev_private; 3011 3011 3012 - if (crtc->fb == NULL) 3012 + if (crtc->primary->fb == NULL) 3013 3013 return; 3014 3014 3015 3015 WARN_ON(waitqueue_active(&dev_priv->pending_flip_queue)); ··· 3018 3018 !intel_crtc_has_pending_flip(crtc)); 3019 3019 3020 3020 mutex_lock(&dev->struct_mutex); 3021 - intel_finish_fb(crtc->fb); 3021 + intel_finish_fb(crtc->primary->fb); 3022 3022 mutex_unlock(&dev->struct_mutex); 3023 3023 } 3024 3024 ··· 3423 3423 { 3424 3424 struct drm_device *dev = crtc->dev; 3425 3425 enum pipe pipe = to_intel_crtc(crtc)->pipe; 3426 + struct drm_plane *plane; 3426 3427 struct intel_plane *intel_plane; 3427 3428 3428 - list_for_each_entry(intel_plane, &dev->mode_config.plane_list, base.head) 3429 + drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) { 3430 + intel_plane = to_intel_plane(plane); 3429 3431 if (intel_plane->pipe == pipe) 3430 3432 intel_plane_restore(&intel_plane->base); 3433 + } 3431 3434 } 3432 3435 3433 3436 static void intel_disable_planes(struct drm_crtc *crtc) 3434 3437 { 3435 3438 struct drm_device *dev = crtc->dev; 3436 3439 enum pipe pipe = to_intel_crtc(crtc)->pipe; 3440 + struct drm_plane *plane; 3437 3441 struct intel_plane *intel_plane; 3438 3442 3439 - list_for_each_entry(intel_plane, &dev->mode_config.plane_list, base.head) 3443 + drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) { 3444 + intel_plane = to_intel_plane(plane); 3440 3445 if (intel_plane->pipe == pipe) 3441 3446 intel_plane_disable(&intel_plane->base); 3447 + } 3442 3448 } 3443 3449 3444 3450 void hsw_enable_ips(struct intel_crtc *crtc) ··· 4466 4460 assert_cursor_disabled(dev_priv, to_intel_crtc(crtc)->pipe); 4467 4461 assert_pipe_disabled(dev->dev_private, to_intel_crtc(crtc)->pipe); 4468 4462 4469 - if (crtc->fb) { 4463 + if (crtc->primary->fb) { 4470 4464 mutex_lock(&dev->struct_mutex); 4471 - intel_unpin_fb_obj(to_intel_framebuffer(crtc->fb)->obj); 4465 + intel_unpin_fb_obj(to_intel_framebuffer(crtc->primary->fb)->obj); 4472 4466 mutex_unlock(&dev->struct_mutex); 4473 - crtc->fb = NULL; 4467 + crtc->primary->fb = NULL; 4474 4468 } 4475 4469 4476 4470 /* Update computed state. */ ··· 8249 8243 goto out; 8250 8244 8251 8245 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 8252 - if (!crtc->fb) 8246 + if (!crtc->primary->fb) 8253 8247 continue; 8254 8248 8255 8249 intel_decrease_pllclock(crtc); ··· 8272 8266 return; 8273 8267 8274 8268 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 8275 - if (!crtc->fb) 8269 + if (!crtc->primary->fb) 8276 8270 continue; 8277 8271 8278 - if (to_intel_framebuffer(crtc->fb)->obj != obj) 8272 + if (to_intel_framebuffer(crtc->primary->fb)->obj != obj) 8279 8273 continue; 8280 8274 8281 8275 intel_increase_pllclock(crtc); ··· 8703 8697 { 8704 8698 struct drm_device *dev = crtc->dev; 8705 8699 struct drm_i915_private *dev_priv = dev->dev_private; 8706 - struct drm_framebuffer *old_fb = crtc->fb; 8700 + struct drm_framebuffer *old_fb = crtc->primary->fb; 8707 8701 struct drm_i915_gem_object *obj = to_intel_framebuffer(fb)->obj; 8708 8702 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 8709 8703 struct intel_unpin_work *work; ··· 8711 8705 int ret; 8712 8706 8713 8707 /* Can't change pixel format via MI display flips. */ 8714 - if (fb->pixel_format != crtc->fb->pixel_format) 8708 + if (fb->pixel_format != crtc->primary->fb->pixel_format) 8715 8709 return -EINVAL; 8716 8710 8717 8711 /* ··· 8719 8713 * Note that pitch changes could also affect these register. 8720 8714 */ 8721 8715 if (INTEL_INFO(dev)->gen > 3 && 8722 - (fb->offsets[0] != crtc->fb->offsets[0] || 8723 - fb->pitches[0] != crtc->fb->pitches[0])) 8716 + (fb->offsets[0] != crtc->primary->fb->offsets[0] || 8717 + fb->pitches[0] != crtc->primary->fb->pitches[0])) 8724 8718 return -EINVAL; 8725 8719 8726 8720 if (i915_terminally_wedged(&dev_priv->gpu_error)) ··· 8763 8757 drm_gem_object_reference(&work->old_fb_obj->base); 8764 8758 drm_gem_object_reference(&obj->base); 8765 8759 8766 - crtc->fb = fb; 8760 + crtc->primary->fb = fb; 8767 8761 8768 8762 work->pending_flip_obj = obj; 8769 8763 ··· 8786 8780 8787 8781 cleanup_pending: 8788 8782 atomic_dec(&intel_crtc->unpin_work_count); 8789 - crtc->fb = old_fb; 8783 + crtc->primary->fb = old_fb; 8790 8784 drm_gem_object_unreference(&work->old_fb_obj->base); 8791 8785 drm_gem_object_unreference(&obj->base); 8792 8786 mutex_unlock(&dev->struct_mutex); ··· 9803 9797 9804 9798 void intel_crtc_restore_mode(struct drm_crtc *crtc) 9805 9799 { 9806 - intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, crtc->fb); 9800 + intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, crtc->primary->fb); 9807 9801 } 9808 9802 9809 9803 #undef for_each_intel_crtc_masked ··· 9927 9921 * and then just flip_or_move it */ 9928 9922 if (is_crtc_connector_off(set)) { 9929 9923 config->mode_changed = true; 9930 - } else if (set->crtc->fb != set->fb) { 9924 + } else if (set->crtc->primary->fb != set->fb) { 9931 9925 /* If we have no fb then treat it as a full mode set */ 9932 - if (set->crtc->fb == NULL) { 9926 + if (set->crtc->primary->fb == NULL) { 9933 9927 struct intel_crtc *intel_crtc = 9934 9928 to_intel_crtc(set->crtc); 9935 9929 ··· 9943 9937 } else if (set->fb == NULL) { 9944 9938 config->mode_changed = true; 9945 9939 } else if (set->fb->pixel_format != 9946 - set->crtc->fb->pixel_format) { 9940 + set->crtc->primary->fb->pixel_format) { 9947 9941 config->mode_changed = true; 9948 9942 } else { 9949 9943 config->fb_changed = true; ··· 10156 10150 save_set.mode = &set->crtc->mode; 10157 10151 save_set.x = set->crtc->x; 10158 10152 save_set.y = set->crtc->y; 10159 - save_set.fb = set->crtc->fb; 10153 + save_set.fb = set->crtc->primary->fb; 10160 10154 10161 10155 /* Compute whether we need a full modeset, only an fb base update or no 10162 10156 * change at all. In the future we might also check whether only the ··· 11473 11467 dev_priv->pipe_to_crtc_mapping[pipe]; 11474 11468 11475 11469 __intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, 11476 - crtc->fb); 11470 + crtc->primary->fb); 11477 11471 } 11478 11472 } else { 11479 11473 intel_modeset_update_staged_output_state(dev); ··· 11522 11516 11523 11517 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 11524 11518 /* Skip inactive CRTCs */ 11525 - if (!crtc->fb) 11519 + if (!crtc->primary->fb) 11526 11520 continue; 11527 11521 11528 11522 intel_increase_pllclock(crtc);
+2 -2
drivers/gpu/drm/i915/intel_dp.c
··· 1744 1744 struct drm_i915_private *dev_priv = dev->dev_private; 1745 1745 struct drm_crtc *crtc = dig_port->base.base.crtc; 1746 1746 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 1747 - struct drm_i915_gem_object *obj = to_intel_framebuffer(crtc->fb)->obj; 1747 + struct drm_i915_gem_object *obj = to_intel_framebuffer(crtc->primary->fb)->obj; 1748 1748 struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base; 1749 1749 1750 1750 dev_priv->psr.source_ok = false; ··· 1777 1777 return false; 1778 1778 } 1779 1779 1780 - obj = to_intel_framebuffer(crtc->fb)->obj; 1780 + obj = to_intel_framebuffer(crtc->primary->fb)->obj; 1781 1781 if (obj->tiling_mode != I915_TILING_X || 1782 1782 obj->fence_reg == I915_FENCE_REG_NONE) { 1783 1783 DRM_DEBUG_KMS("PSR condition failed: fb not tiled or fenced\n");
+2 -2
drivers/gpu/drm/i915/intel_overlay.c
··· 606 606 { 607 607 u32 key = overlay->color_key; 608 608 609 - switch (overlay->crtc->base.fb->bits_per_pixel) { 609 + switch (overlay->crtc->base.primary->fb->bits_per_pixel) { 610 610 case 8: 611 611 iowrite32(0, &regs->DCLRKV); 612 612 iowrite32(CLK_RGB8I_MASK | DST_KEY_ENABLE, &regs->DCLRKM); 613 613 break; 614 614 615 615 case 16: 616 - if (overlay->crtc->base.fb->depth == 15) { 616 + if (overlay->crtc->base.primary->fb->depth == 15) { 617 617 iowrite32(RGB15_TO_COLORKEY(key), &regs->DCLRKV); 618 618 iowrite32(CLK_RGB15_MASK | DST_KEY_ENABLE, 619 619 &regs->DCLRKM);
+19 -19
drivers/gpu/drm/i915/intel_pm.c
··· 92 92 { 93 93 struct drm_device *dev = crtc->dev; 94 94 struct drm_i915_private *dev_priv = dev->dev_private; 95 - struct drm_framebuffer *fb = crtc->fb; 95 + struct drm_framebuffer *fb = crtc->primary->fb; 96 96 struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); 97 97 struct drm_i915_gem_object *obj = intel_fb->obj; 98 98 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); ··· 149 149 { 150 150 struct drm_device *dev = crtc->dev; 151 151 struct drm_i915_private *dev_priv = dev->dev_private; 152 - struct drm_framebuffer *fb = crtc->fb; 152 + struct drm_framebuffer *fb = crtc->primary->fb; 153 153 struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); 154 154 struct drm_i915_gem_object *obj = intel_fb->obj; 155 155 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); ··· 221 221 { 222 222 struct drm_device *dev = crtc->dev; 223 223 struct drm_i915_private *dev_priv = dev->dev_private; 224 - struct drm_framebuffer *fb = crtc->fb; 224 + struct drm_framebuffer *fb = crtc->primary->fb; 225 225 struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); 226 226 struct drm_i915_gem_object *obj = intel_fb->obj; 227 227 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); ··· 277 277 { 278 278 struct drm_device *dev = crtc->dev; 279 279 struct drm_i915_private *dev_priv = dev->dev_private; 280 - struct drm_framebuffer *fb = crtc->fb; 280 + struct drm_framebuffer *fb = crtc->primary->fb; 281 281 struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); 282 282 struct drm_i915_gem_object *obj = intel_fb->obj; 283 283 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); ··· 336 336 /* Double check that we haven't switched fb without cancelling 337 337 * the prior work. 338 338 */ 339 - if (work->crtc->fb == work->fb) { 339 + if (work->crtc->primary->fb == work->fb) { 340 340 dev_priv->display.enable_fbc(work->crtc); 341 341 342 342 dev_priv->fbc.plane = to_intel_crtc(work->crtc)->plane; 343 - dev_priv->fbc.fb_id = work->crtc->fb->base.id; 343 + dev_priv->fbc.fb_id = work->crtc->primary->fb->base.id; 344 344 dev_priv->fbc.y = work->crtc->y; 345 345 } 346 346 ··· 393 393 } 394 394 395 395 work->crtc = crtc; 396 - work->fb = crtc->fb; 396 + work->fb = crtc->primary->fb; 397 397 INIT_DELAYED_WORK(&work->work, intel_fbc_work_fn); 398 398 399 399 dev_priv->fbc.fbc_work = work; ··· 499 499 } 500 500 } 501 501 502 - if (!crtc || crtc->fb == NULL) { 502 + if (!crtc || crtc->primary->fb == NULL) { 503 503 if (set_no_fbc_reason(dev_priv, FBC_NO_OUTPUT)) 504 504 DRM_DEBUG_KMS("no output, disabling\n"); 505 505 goto out_disable; 506 506 } 507 507 508 508 intel_crtc = to_intel_crtc(crtc); 509 - fb = crtc->fb; 509 + fb = crtc->primary->fb; 510 510 intel_fb = to_intel_framebuffer(fb); 511 511 obj = intel_fb->obj; 512 512 adjusted_mode = &intel_crtc->config.adjusted_mode; ··· 1041 1041 crtc = single_enabled_crtc(dev); 1042 1042 if (crtc) { 1043 1043 const struct drm_display_mode *adjusted_mode; 1044 - int pixel_size = crtc->fb->bits_per_pixel / 8; 1044 + int pixel_size = crtc->primary->fb->bits_per_pixel / 8; 1045 1045 int clock; 1046 1046 1047 1047 adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode; ··· 1121 1121 clock = adjusted_mode->crtc_clock; 1122 1122 htotal = adjusted_mode->crtc_htotal; 1123 1123 hdisplay = to_intel_crtc(crtc)->config.pipe_src_w; 1124 - pixel_size = crtc->fb->bits_per_pixel / 8; 1124 + pixel_size = crtc->primary->fb->bits_per_pixel / 8; 1125 1125 1126 1126 /* Use the small buffer method to calculate plane watermark */ 1127 1127 entries = ((clock * pixel_size / 1000) * display_latency_ns) / 1000; ··· 1208 1208 clock = adjusted_mode->crtc_clock; 1209 1209 htotal = adjusted_mode->crtc_htotal; 1210 1210 hdisplay = to_intel_crtc(crtc)->config.pipe_src_w; 1211 - pixel_size = crtc->fb->bits_per_pixel / 8; 1211 + pixel_size = crtc->primary->fb->bits_per_pixel / 8; 1212 1212 1213 1213 line_time_us = max(htotal * 1000 / clock, 1); 1214 1214 line_count = (latency_ns / line_time_us + 1000) / 1000; ··· 1247 1247 return false; 1248 1248 1249 1249 clock = to_intel_crtc(crtc)->config.adjusted_mode.crtc_clock; 1250 - pixel_size = crtc->fb->bits_per_pixel / 8; /* BPP */ 1250 + pixel_size = crtc->primary->fb->bits_per_pixel / 8; /* BPP */ 1251 1251 1252 1252 entries = (clock / 1000) * pixel_size; 1253 1253 *plane_prec_mult = (entries > 256) ? ··· 1439 1439 int clock = adjusted_mode->crtc_clock; 1440 1440 int htotal = adjusted_mode->crtc_htotal; 1441 1441 int hdisplay = to_intel_crtc(crtc)->config.pipe_src_w; 1442 - int pixel_size = crtc->fb->bits_per_pixel / 8; 1442 + int pixel_size = crtc->primary->fb->bits_per_pixel / 8; 1443 1443 unsigned long line_time_us; 1444 1444 int entries; 1445 1445 ··· 1512 1512 crtc = intel_get_crtc_for_plane(dev, 0); 1513 1513 if (intel_crtc_active(crtc)) { 1514 1514 const struct drm_display_mode *adjusted_mode; 1515 - int cpp = crtc->fb->bits_per_pixel / 8; 1515 + int cpp = crtc->primary->fb->bits_per_pixel / 8; 1516 1516 if (IS_GEN2(dev)) 1517 1517 cpp = 4; 1518 1518 ··· 1528 1528 crtc = intel_get_crtc_for_plane(dev, 1); 1529 1529 if (intel_crtc_active(crtc)) { 1530 1530 const struct drm_display_mode *adjusted_mode; 1531 - int cpp = crtc->fb->bits_per_pixel / 8; 1531 + int cpp = crtc->primary->fb->bits_per_pixel / 8; 1532 1532 if (IS_GEN2(dev)) 1533 1533 cpp = 4; 1534 1534 ··· 1565 1565 int clock = adjusted_mode->crtc_clock; 1566 1566 int htotal = adjusted_mode->crtc_htotal; 1567 1567 int hdisplay = to_intel_crtc(enabled)->config.pipe_src_w; 1568 - int pixel_size = enabled->fb->bits_per_pixel / 8; 1568 + int pixel_size = enabled->primary->fb->bits_per_pixel / 8; 1569 1569 unsigned long line_time_us; 1570 1570 int entries; 1571 1571 ··· 2117 2117 if (p->active) { 2118 2118 p->pipe_htotal = intel_crtc->config.adjusted_mode.crtc_htotal; 2119 2119 p->pixel_rate = ilk_pipe_pixel_rate(dev, crtc); 2120 - p->pri.bytes_per_pixel = crtc->fb->bits_per_pixel / 8; 2120 + p->pri.bytes_per_pixel = crtc->primary->fb->bits_per_pixel / 8; 2121 2121 p->cur.bytes_per_pixel = 4; 2122 2122 p->pri.horiz_pixels = intel_crtc->config.pipe_src_w; 2123 2123 p->cur.horiz_pixels = 64; ··· 2129 2129 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) 2130 2130 config->num_pipes_active += intel_crtc_active(crtc); 2131 2131 2132 - list_for_each_entry(plane, &dev->mode_config.plane_list, head) { 2132 + drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) { 2133 2133 struct intel_plane *intel_plane = to_intel_plane(plane); 2134 2134 2135 2135 if (intel_plane->pipe == pipe)
+13 -13
drivers/gpu/drm/mgag200/mgag200_mode.c
··· 29 29 struct mga_crtc *mga_crtc = to_mga_crtc(crtc); 30 30 struct drm_device *dev = crtc->dev; 31 31 struct mga_device *mdev = dev->dev_private; 32 - struct drm_framebuffer *fb = crtc->fb; 32 + struct drm_framebuffer *fb = crtc->primary->fb; 33 33 int i; 34 34 35 35 if (!crtc->enabled) ··· 742 742 mgag200_bo_unreserve(bo); 743 743 } 744 744 745 - mga_fb = to_mga_framebuffer(crtc->fb); 745 + mga_fb = to_mga_framebuffer(crtc->primary->fb); 746 746 obj = mga_fb->obj; 747 747 bo = gem_to_mga_bo(obj); 748 748 ··· 805 805 /* 0x48: */ 0, 0, 0, 0, 0, 0, 0, 0 806 806 }; 807 807 808 - bppshift = mdev->bpp_shifts[(crtc->fb->bits_per_pixel >> 3) - 1]; 808 + bppshift = mdev->bpp_shifts[(crtc->primary->fb->bits_per_pixel >> 3) - 1]; 809 809 810 810 switch (mdev->type) { 811 811 case G200_SE_A: ··· 843 843 break; 844 844 } 845 845 846 - switch (crtc->fb->bits_per_pixel) { 846 + switch (crtc->primary->fb->bits_per_pixel) { 847 847 case 8: 848 848 dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_8bits; 849 849 break; 850 850 case 16: 851 - if (crtc->fb->depth == 15) 851 + if (crtc->primary->fb->depth == 15) 852 852 dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_15bits; 853 853 else 854 854 dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_16bits; ··· 896 896 WREG_SEQ(3, 0); 897 897 WREG_SEQ(4, 0xe); 898 898 899 - pitch = crtc->fb->pitches[0] / (crtc->fb->bits_per_pixel / 8); 900 - if (crtc->fb->bits_per_pixel == 24) 899 + pitch = crtc->primary->fb->pitches[0] / (crtc->primary->fb->bits_per_pixel / 8); 900 + if (crtc->primary->fb->bits_per_pixel == 24) 901 901 pitch = (pitch * 3) >> (4 - bppshift); 902 902 else 903 903 pitch = pitch >> (4 - bppshift); ··· 974 974 ((vdisplay & 0xc00) >> 7) | 975 975 ((vsyncstart & 0xc00) >> 5) | 976 976 ((vdisplay & 0x400) >> 3); 977 - if (crtc->fb->bits_per_pixel == 24) 977 + if (crtc->primary->fb->bits_per_pixel == 24) 978 978 ext_vga[3] = (((1 << bppshift) * 3) - 1) | 0x80; 979 979 else 980 980 ext_vga[3] = ((1 << bppshift) - 1) | 0x80; ··· 1034 1034 u32 bpp; 1035 1035 u32 mb; 1036 1036 1037 - if (crtc->fb->bits_per_pixel > 16) 1037 + if (crtc->primary->fb->bits_per_pixel > 16) 1038 1038 bpp = 32; 1039 - else if (crtc->fb->bits_per_pixel > 8) 1039 + else if (crtc->primary->fb->bits_per_pixel > 8) 1040 1040 bpp = 16; 1041 1041 else 1042 1042 bpp = 8; ··· 1277 1277 int ret; 1278 1278 DRM_DEBUG_KMS("\n"); 1279 1279 mga_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); 1280 - if (crtc->fb) { 1281 - struct mga_framebuffer *mga_fb = to_mga_framebuffer(crtc->fb); 1280 + if (crtc->primary->fb) { 1281 + struct mga_framebuffer *mga_fb = to_mga_framebuffer(crtc->primary->fb); 1282 1282 struct drm_gem_object *obj = mga_fb->obj; 1283 1283 struct mgag200_bo *bo = gem_to_mga_bo(obj); 1284 1284 ret = mgag200_bo_reserve(bo, false); ··· 1287 1287 mgag200_bo_push_sysram(bo); 1288 1288 mgag200_bo_unreserve(bo); 1289 1289 } 1290 - crtc->fb = NULL; 1290 + crtc->primary->fb = NULL; 1291 1291 } 1292 1292 1293 1293 /* These provide the minimum set of functions required to handle a CRTC */
+18 -15
drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c
··· 120 120 121 121 /* grab reference to incoming scanout fb: */ 122 122 drm_framebuffer_reference(new_fb); 123 - mdp4_crtc->base.fb = new_fb; 123 + mdp4_crtc->base.primary->fb = new_fb; 124 124 mdp4_crtc->fb = new_fb; 125 125 126 126 if (old_fb) ··· 182 182 struct mdp4_crtc *mdp4_crtc = 183 183 container_of(cb, struct mdp4_crtc, pageflip_cb); 184 184 struct drm_crtc *crtc = &mdp4_crtc->base; 185 - struct drm_framebuffer *fb = crtc->fb; 185 + struct drm_framebuffer *fb = crtc->primary->fb; 186 186 187 187 if (!fb) 188 188 return; ··· 348 348 mode->type, mode->flags); 349 349 350 350 /* grab extra ref for update_scanout() */ 351 - drm_framebuffer_reference(crtc->fb); 351 + drm_framebuffer_reference(crtc->primary->fb); 352 352 353 - ret = mdp4_plane_mode_set(mdp4_crtc->plane, crtc, crtc->fb, 353 + ret = mdp4_plane_mode_set(mdp4_crtc->plane, crtc, crtc->primary->fb, 354 354 0, 0, mode->hdisplay, mode->vdisplay, 355 355 x << 16, y << 16, 356 356 mode->hdisplay << 16, mode->vdisplay << 16); 357 357 if (ret) { 358 - drm_framebuffer_unreference(crtc->fb); 358 + drm_framebuffer_unreference(crtc->primary->fb); 359 359 dev_err(crtc->dev->dev, "%s: failed to set mode on plane: %d\n", 360 360 mdp4_crtc->name, ret); 361 361 return ret; ··· 368 368 /* take data from pipe: */ 369 369 mdp4_write(mdp4_kms, REG_MDP4_DMA_SRC_BASE(dma), 0); 370 370 mdp4_write(mdp4_kms, REG_MDP4_DMA_SRC_STRIDE(dma), 371 - crtc->fb->pitches[0]); 371 + crtc->primary->fb->pitches[0]); 372 372 mdp4_write(mdp4_kms, REG_MDP4_DMA_DST_SIZE(dma), 373 373 MDP4_DMA_DST_SIZE_WIDTH(0) | 374 374 MDP4_DMA_DST_SIZE_HEIGHT(0)); ··· 378 378 MDP4_OVLP_SIZE_WIDTH(mode->hdisplay) | 379 379 MDP4_OVLP_SIZE_HEIGHT(mode->vdisplay)); 380 380 mdp4_write(mdp4_kms, REG_MDP4_OVLP_STRIDE(ovlp), 381 - crtc->fb->pitches[0]); 381 + crtc->primary->fb->pitches[0]); 382 382 383 383 mdp4_write(mdp4_kms, REG_MDP4_OVLP_CFG(ovlp), 1); 384 384 ··· 388 388 mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(2), 0x00ff0000); 389 389 } 390 390 391 - update_fb(crtc, crtc->fb); 392 - update_scanout(crtc, crtc->fb); 391 + update_fb(crtc, crtc->primary->fb); 392 + update_scanout(crtc, crtc->primary->fb); 393 393 394 394 return 0; 395 395 } ··· 420 420 int ret; 421 421 422 422 /* grab extra ref for update_scanout() */ 423 - drm_framebuffer_reference(crtc->fb); 423 + drm_framebuffer_reference(crtc->primary->fb); 424 424 425 - ret = mdp4_plane_mode_set(plane, crtc, crtc->fb, 425 + ret = mdp4_plane_mode_set(plane, crtc, crtc->primary->fb, 426 426 0, 0, mode->hdisplay, mode->vdisplay, 427 427 x << 16, y << 16, 428 428 mode->hdisplay << 16, mode->vdisplay << 16); 429 429 if (ret) { 430 - drm_framebuffer_unreference(crtc->fb); 430 + drm_framebuffer_unreference(crtc->primary->fb); 431 431 return ret; 432 432 } 433 433 434 - update_fb(crtc, crtc->fb); 435 - update_scanout(crtc, crtc->fb); 434 + update_fb(crtc, crtc->primary->fb); 435 + update_scanout(crtc, crtc->primary->fb); 436 436 437 437 return 0; 438 438 } ··· 740 740 741 741 void mdp4_crtc_detach(struct drm_crtc *crtc, struct drm_plane *plane) 742 742 { 743 + /* don't actually detatch our primary plane: */ 744 + if (to_mdp4_crtc(crtc)->plane == plane) 745 + return; 743 746 set_attach(crtc, mdp4_plane_pipe(plane), NULL); 744 747 } 745 748 ··· 794 791 795 792 INIT_FENCE_CB(&mdp4_crtc->pageflip_cb, pageflip_cb); 796 793 797 - drm_crtc_init(dev, crtc, &mdp4_crtc_funcs); 794 + drm_crtc_init_with_planes(dev, crtc, plane, NULL, &mdp4_crtc_funcs); 798 795 drm_crtc_helper_add(crtc, &mdp4_crtc_helper_funcs); 799 796 800 797 mdp4_plane_install_properties(mdp4_crtc->plane, &crtc->base);
+5 -3
drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c
··· 222 222 struct drm_plane *plane = NULL; 223 223 struct mdp4_plane *mdp4_plane; 224 224 int ret; 225 + enum drm_plane_type type; 225 226 226 227 mdp4_plane = kzalloc(sizeof(*mdp4_plane), GFP_KERNEL); 227 228 if (!mdp4_plane) { ··· 238 237 mdp4_plane->nformats = mdp4_get_formats(pipe_id, mdp4_plane->formats, 239 238 ARRAY_SIZE(mdp4_plane->formats)); 240 239 241 - drm_plane_init(dev, plane, 0xff, &mdp4_plane_funcs, 242 - mdp4_plane->formats, mdp4_plane->nformats, 243 - private_plane); 240 + type = private_plane ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY; 241 + drm_universal_plane_init(dev, plane, 0xff, &mdp4_plane_funcs, 242 + mdp4_plane->formats, mdp4_plane->nformats, 243 + type); 244 244 245 245 mdp4_plane_install_properties(plane, &plane->base); 246 246
+15 -12
drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
··· 102 102 103 103 /* grab reference to incoming scanout fb: */ 104 104 drm_framebuffer_reference(new_fb); 105 - mdp5_crtc->base.fb = new_fb; 105 + mdp5_crtc->base.primary->fb = new_fb; 106 106 mdp5_crtc->fb = new_fb; 107 107 108 108 if (old_fb) ··· 289 289 mode->type, mode->flags); 290 290 291 291 /* grab extra ref for update_scanout() */ 292 - drm_framebuffer_reference(crtc->fb); 292 + drm_framebuffer_reference(crtc->primary->fb); 293 293 294 - ret = mdp5_plane_mode_set(mdp5_crtc->plane, crtc, crtc->fb, 294 + ret = mdp5_plane_mode_set(mdp5_crtc->plane, crtc, crtc->primary->fb, 295 295 0, 0, mode->hdisplay, mode->vdisplay, 296 296 x << 16, y << 16, 297 297 mode->hdisplay << 16, mode->vdisplay << 16); 298 298 if (ret) { 299 - drm_framebuffer_unreference(crtc->fb); 299 + drm_framebuffer_unreference(crtc->primary->fb); 300 300 dev_err(crtc->dev->dev, "%s: failed to set mode on plane: %d\n", 301 301 mdp5_crtc->name, ret); 302 302 return ret; ··· 306 306 MDP5_LM_OUT_SIZE_WIDTH(mode->hdisplay) | 307 307 MDP5_LM_OUT_SIZE_HEIGHT(mode->vdisplay)); 308 308 309 - update_fb(crtc, crtc->fb); 310 - update_scanout(crtc, crtc->fb); 309 + update_fb(crtc, crtc->primary->fb); 310 + update_scanout(crtc, crtc->primary->fb); 311 311 312 312 return 0; 313 313 } ··· 338 338 int ret; 339 339 340 340 /* grab extra ref for update_scanout() */ 341 - drm_framebuffer_reference(crtc->fb); 341 + drm_framebuffer_reference(crtc->primary->fb); 342 342 343 - ret = mdp5_plane_mode_set(plane, crtc, crtc->fb, 343 + ret = mdp5_plane_mode_set(plane, crtc, crtc->primary->fb, 344 344 0, 0, mode->hdisplay, mode->vdisplay, 345 345 x << 16, y << 16, 346 346 mode->hdisplay << 16, mode->vdisplay << 16); 347 347 if (ret) { 348 - drm_framebuffer_unreference(crtc->fb); 348 + drm_framebuffer_unreference(crtc->primary->fb); 349 349 return ret; 350 350 } 351 351 352 - update_fb(crtc, crtc->fb); 353 - update_scanout(crtc, crtc->fb); 352 + update_fb(crtc, crtc->primary->fb); 353 + update_scanout(crtc, crtc->primary->fb); 354 354 355 355 return 0; 356 356 } ··· 524 524 525 525 void mdp5_crtc_detach(struct drm_crtc *crtc, struct drm_plane *plane) 526 526 { 527 + /* don't actually detatch our primary plane: */ 528 + if (to_mdp5_crtc(crtc)->plane == plane) 529 + return; 527 530 set_attach(crtc, mdp5_plane_pipe(plane), NULL); 528 531 } 529 532 ··· 562 559 563 560 INIT_FENCE_CB(&mdp5_crtc->pageflip_cb, pageflip_cb); 564 561 565 - drm_crtc_init(dev, crtc, &mdp5_crtc_funcs); 562 + drm_crtc_init_with_planes(dev, crtc, plane, NULL, &mdp5_crtc_funcs); 566 563 drm_crtc_helper_add(crtc, &mdp5_crtc_helper_funcs); 567 564 568 565 mdp5_plane_install_properties(mdp5_crtc->plane, &crtc->base);
+5 -3
drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
··· 358 358 struct drm_plane *plane = NULL; 359 359 struct mdp5_plane *mdp5_plane; 360 360 int ret; 361 + enum drm_plane_type type; 361 362 362 363 mdp5_plane = kzalloc(sizeof(*mdp5_plane), GFP_KERNEL); 363 364 if (!mdp5_plane) { ··· 374 373 mdp5_plane->nformats = mdp5_get_formats(pipe, mdp5_plane->formats, 375 374 ARRAY_SIZE(mdp5_plane->formats)); 376 375 377 - drm_plane_init(dev, plane, 0xff, &mdp5_plane_funcs, 378 - mdp5_plane->formats, mdp5_plane->nformats, 379 - private_plane); 376 + type = private_plane ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY; 377 + drm_universal_plane_init(dev, plane, 0xff, &mdp5_plane_funcs, 378 + mdp5_plane->formats, mdp5_plane->nformats, 379 + type); 380 380 381 381 mdp5_plane_install_properties(plane, &plane->base); 382 382
+10 -10
drivers/gpu/drm/nouveau/dispnv04/crtc.c
··· 239 239 struct drm_device *dev = crtc->dev; 240 240 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 241 241 struct nv04_crtc_reg *regp = &nv04_display(dev)->mode_reg.crtc_reg[nv_crtc->index]; 242 - struct drm_framebuffer *fb = crtc->fb; 242 + struct drm_framebuffer *fb = crtc->primary->fb; 243 243 244 244 /* Calculate our timings */ 245 245 int horizDisplay = (mode->crtc_hdisplay >> 3) - 1; ··· 574 574 regp->CRTC[NV_CIO_CRE_86] = 0x1; 575 575 } 576 576 577 - regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] = (crtc->fb->depth + 1) / 8; 577 + regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] = (crtc->primary->fb->depth + 1) / 8; 578 578 /* Enable slaved mode (called MODE_TV in nv4ref.h) */ 579 579 if (lvds_output || tmds_output || tv_output) 580 580 regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] |= (1 << 7); ··· 588 588 regp->ramdac_gen_ctrl = NV_PRAMDAC_GENERAL_CONTROL_BPC_8BITS | 589 589 NV_PRAMDAC_GENERAL_CONTROL_VGA_STATE_SEL | 590 590 NV_PRAMDAC_GENERAL_CONTROL_PIXMIX_ON; 591 - if (crtc->fb->depth == 16) 591 + if (crtc->primary->fb->depth == 16) 592 592 regp->ramdac_gen_ctrl |= NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL; 593 593 if (nv_device(drm->device)->chipset >= 0x11) 594 594 regp->ramdac_gen_ctrl |= NV_PRAMDAC_GENERAL_CONTROL_PIPE_LONG; ··· 609 609 nv_crtc_swap_fbs(struct drm_crtc *crtc, struct drm_framebuffer *old_fb) 610 610 { 611 611 struct nv04_display *disp = nv04_display(crtc->dev); 612 - struct nouveau_framebuffer *nvfb = nouveau_framebuffer(crtc->fb); 612 + struct nouveau_framebuffer *nvfb = nouveau_framebuffer(crtc->primary->fb); 613 613 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 614 614 int ret; 615 615 ··· 808 808 * mark the lut values as dirty by setting depth==0, and it'll be 809 809 * uploaded on the first mode_set_base() 810 810 */ 811 - if (!nv_crtc->base.fb) { 811 + if (!nv_crtc->base.primary->fb) { 812 812 nv_crtc->lut.depth = 0; 813 813 return; 814 814 } ··· 832 832 NV_DEBUG(drm, "index %d\n", nv_crtc->index); 833 833 834 834 /* no fb bound */ 835 - if (!atomic && !crtc->fb) { 835 + if (!atomic && !crtc->primary->fb) { 836 836 NV_DEBUG(drm, "No FB bound\n"); 837 837 return 0; 838 838 } ··· 844 844 drm_fb = passed_fb; 845 845 fb = nouveau_framebuffer(passed_fb); 846 846 } else { 847 - drm_fb = crtc->fb; 848 - fb = nouveau_framebuffer(crtc->fb); 847 + drm_fb = crtc->primary->fb; 848 + fb = nouveau_framebuffer(crtc->primary->fb); 849 849 } 850 850 851 851 nv_crtc->fb.offset = fb->nvbo->bo.offset; ··· 857 857 858 858 /* Update the framebuffer format. */ 859 859 regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] &= ~3; 860 - regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] |= (crtc->fb->depth + 1) / 8; 860 + regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] |= (crtc->primary->fb->depth + 1) / 8; 861 861 regp->ramdac_gen_ctrl &= ~NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL; 862 - if (crtc->fb->depth == 16) 862 + if (crtc->primary->fb->depth == 16) 863 863 regp->ramdac_gen_ctrl |= NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL; 864 864 crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_PIXEL_INDEX); 865 865 NVWriteRAMDAC(dev, nv_crtc->index, NV_PRAMDAC_GENERAL_CONTROL,
+1 -1
drivers/gpu/drm/nouveau/dispnv04/dfp.c
··· 415 415 /* Output property. */ 416 416 if ((nv_connector->dithering_mode == DITHERING_MODE_ON) || 417 417 (nv_connector->dithering_mode == DITHERING_MODE_AUTO && 418 - encoder->crtc->fb->depth > connector->display_info.bpc * 3)) { 418 + encoder->crtc->primary->fb->depth > connector->display_info.bpc * 3)) { 419 419 if (nv_device(drm->device)->chipset == 0x11) 420 420 regp->dither = savep->dither | 0x00010000; 421 421 else {
+4 -4
drivers/gpu/drm/nouveau/nouveau_display.c
··· 571 571 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 572 572 struct nouveau_framebuffer *nouveau_fb; 573 573 574 - nouveau_fb = nouveau_framebuffer(crtc->fb); 574 + nouveau_fb = nouveau_framebuffer(crtc->primary->fb); 575 575 if (!nouveau_fb || !nouveau_fb->nvbo) 576 576 continue; 577 577 ··· 598 598 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 599 599 struct nouveau_framebuffer *nouveau_fb; 600 600 601 - nouveau_fb = nouveau_framebuffer(crtc->fb); 601 + nouveau_fb = nouveau_framebuffer(crtc->primary->fb); 602 602 if (!nouveau_fb || !nouveau_fb->nvbo) 603 603 continue; 604 604 ··· 695 695 const int swap_interval = (flags & DRM_MODE_PAGE_FLIP_ASYNC) ? 0 : 1; 696 696 struct drm_device *dev = crtc->dev; 697 697 struct nouveau_drm *drm = nouveau_drm(dev); 698 - struct nouveau_bo *old_bo = nouveau_framebuffer(crtc->fb)->nvbo; 698 + struct nouveau_bo *old_bo = nouveau_framebuffer(crtc->primary->fb)->nvbo; 699 699 struct nouveau_bo *new_bo = nouveau_framebuffer(fb)->nvbo; 700 700 struct nouveau_page_flip_state *s; 701 701 struct nouveau_channel *chan = drm->channel; ··· 769 769 goto fail_unreserve; 770 770 771 771 /* Update the crtc struct and cleanup */ 772 - crtc->fb = fb; 772 + crtc->primary->fb = fb; 773 773 774 774 nouveau_bo_fence(old_bo, fence); 775 775 ttm_bo_unreserve(&old_bo->bo);
+9 -8
drivers/gpu/drm/nouveau/nv50_display.c
··· 651 651 nv_connector = nouveau_crtc_connector_get(nv_crtc); 652 652 connector = &nv_connector->base; 653 653 if (nv_connector->dithering_mode == DITHERING_MODE_AUTO) { 654 - if (nv_crtc->base.fb->depth > connector->display_info.bpc * 3) 654 + if (nv_crtc->base.primary->fb->depth > connector->display_info.bpc * 3) 655 655 mode = DITHERING_MODE_DYNAMIC2X2; 656 656 } else { 657 657 mode = nv_connector->dithering_mode; ··· 785 785 786 786 if (update) { 787 787 nv50_display_flip_stop(crtc); 788 - nv50_display_flip_next(crtc, crtc->fb, NULL, 1); 788 + nv50_display_flip_next(crtc, crtc->primary->fb, 789 + NULL, 1); 789 790 } 790 791 } 791 792 ··· 1029 1028 } 1030 1029 1031 1030 nv50_crtc_cursor_show_hide(nv_crtc, nv_crtc->cursor.visible, true); 1032 - nv50_display_flip_next(crtc, crtc->fb, NULL, 1); 1031 + nv50_display_flip_next(crtc, crtc->primary->fb, NULL, 1); 1033 1032 } 1034 1033 1035 1034 static bool ··· 1043 1042 static int 1044 1043 nv50_crtc_swap_fbs(struct drm_crtc *crtc, struct drm_framebuffer *old_fb) 1045 1044 { 1046 - struct nouveau_framebuffer *nvfb = nouveau_framebuffer(crtc->fb); 1045 + struct nouveau_framebuffer *nvfb = nouveau_framebuffer(crtc->primary->fb); 1047 1046 struct nv50_head *head = nv50_head(crtc); 1048 1047 int ret; 1049 1048 ··· 1140 1139 nv50_crtc_set_dither(nv_crtc, false); 1141 1140 nv50_crtc_set_scale(nv_crtc, false); 1142 1141 nv50_crtc_set_color_vibrance(nv_crtc, false); 1143 - nv50_crtc_set_image(nv_crtc, crtc->fb, x, y, false); 1142 + nv50_crtc_set_image(nv_crtc, crtc->primary->fb, x, y, false); 1144 1143 return 0; 1145 1144 } 1146 1145 ··· 1152 1151 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 1153 1152 int ret; 1154 1153 1155 - if (!crtc->fb) { 1154 + if (!crtc->primary->fb) { 1156 1155 NV_DEBUG(drm, "No FB bound\n"); 1157 1156 return 0; 1158 1157 } ··· 1162 1161 return ret; 1163 1162 1164 1163 nv50_display_flip_stop(crtc); 1165 - nv50_crtc_set_image(nv_crtc, crtc->fb, x, y, true); 1166 - nv50_display_flip_next(crtc, crtc->fb, NULL, 1); 1164 + nv50_crtc_set_image(nv_crtc, crtc->primary->fb, x, y, true); 1165 + nv50_display_flip_next(crtc, crtc->primary->fb, NULL, 1); 1167 1166 return 0; 1168 1167 } 1169 1168
+7 -6
drivers/gpu/drm/omapdrm/omap_crtc.c
··· 245 245 copy_timings_drm_to_omap(&omap_crtc->timings, mode); 246 246 omap_crtc->full_update = true; 247 247 248 - return omap_plane_mode_set(omap_crtc->plane, crtc, crtc->fb, 248 + return omap_plane_mode_set(omap_crtc->plane, crtc, crtc->primary->fb, 249 249 0, 0, mode->hdisplay, mode->vdisplay, 250 250 x << 16, y << 16, 251 251 mode->hdisplay << 16, mode->vdisplay << 16, ··· 273 273 struct drm_plane *plane = omap_crtc->plane; 274 274 struct drm_display_mode *mode = &crtc->mode; 275 275 276 - return omap_plane_mode_set(plane, crtc, crtc->fb, 276 + return omap_plane_mode_set(plane, crtc, crtc->primary->fb, 277 277 0, 0, mode->hdisplay, mode->vdisplay, 278 278 x << 16, y << 16, 279 279 mode->hdisplay << 16, mode->vdisplay << 16, ··· 308 308 struct drm_gem_object *bo; 309 309 310 310 mutex_lock(&crtc->mutex); 311 - omap_plane_mode_set(omap_crtc->plane, crtc, crtc->fb, 311 + omap_plane_mode_set(omap_crtc->plane, crtc, crtc->primary->fb, 312 312 0, 0, mode->hdisplay, mode->vdisplay, 313 313 crtc->x << 16, crtc->y << 16, 314 314 mode->hdisplay << 16, mode->vdisplay << 16, 315 315 vblank_cb, crtc); 316 316 mutex_unlock(&crtc->mutex); 317 317 318 - bo = omap_framebuffer_bo(crtc->fb, 0); 318 + bo = omap_framebuffer_bo(crtc->primary->fb, 0); 319 319 drm_gem_object_unreference_unlocked(bo); 320 320 } 321 321 ··· 336 336 { 337 337 struct drm_device *dev = crtc->dev; 338 338 struct omap_crtc *omap_crtc = to_omap_crtc(crtc); 339 + struct drm_plane *primary = crtc->primary; 339 340 struct drm_gem_object *bo; 340 341 341 - DBG("%d -> %d (event=%p)", crtc->fb ? crtc->fb->base.id : -1, 342 + DBG("%d -> %d (event=%p)", primary->fb ? primary->fb->base.id : -1, 342 343 fb->base.id, event); 343 344 344 345 if (omap_crtc->old_fb) { ··· 348 347 } 349 348 350 349 omap_crtc->event = event; 351 - crtc->fb = fb; 350 + primary->fb = fb; 352 351 353 352 /* 354 353 * Hold a reference temporarily until the crtc is updated
+1 -1
drivers/gpu/drm/omapdrm/omap_fb.c
··· 312 312 if (connector != from) { 313 313 struct drm_encoder *encoder = connector->encoder; 314 314 struct drm_crtc *crtc = encoder ? encoder->crtc : NULL; 315 - if (crtc && crtc->fb == fb) 315 + if (crtc && crtc->primary->fb == fb) 316 316 return connector; 317 317 318 318 }
+5 -5
drivers/gpu/drm/qxl/qxl_display.c
··· 527 527 bool recreate_primary = false; 528 528 int ret; 529 529 int surf_id; 530 - if (!crtc->fb) { 530 + if (!crtc->primary->fb) { 531 531 DRM_DEBUG_KMS("No FB bound\n"); 532 532 return 0; 533 533 } ··· 536 536 qfb = to_qxl_framebuffer(old_fb); 537 537 old_bo = gem_to_qxl_bo(qfb->obj); 538 538 } 539 - qfb = to_qxl_framebuffer(crtc->fb); 539 + qfb = to_qxl_framebuffer(crtc->primary->fb); 540 540 bo = gem_to_qxl_bo(qfb->obj); 541 541 if (!m) 542 542 /* and do we care? */ ··· 609 609 struct qxl_crtc *qcrtc = to_qxl_crtc(crtc); 610 610 struct drm_device *dev = crtc->dev; 611 611 struct qxl_device *qdev = dev->dev_private; 612 - if (crtc->fb) { 613 - struct qxl_framebuffer *qfb = to_qxl_framebuffer(crtc->fb); 612 + if (crtc->primary->fb) { 613 + struct qxl_framebuffer *qfb = to_qxl_framebuffer(crtc->primary->fb); 614 614 struct qxl_bo *bo = gem_to_qxl_bo(qfb->obj); 615 615 int ret; 616 616 ret = qxl_bo_reserve(bo, false); 617 617 qxl_bo_unpin(bo); 618 618 qxl_bo_unreserve(bo); 619 - crtc->fb = NULL; 619 + crtc->primary->fb = NULL; 620 620 } 621 621 622 622 qxl_monitors_config_set(qdev, qcrtc->index, 0, 0, 0, 0, 0);
+10 -10
drivers/gpu/drm/radeon/atombios_crtc.c
··· 1106 1106 int r; 1107 1107 1108 1108 /* no fb bound */ 1109 - if (!atomic && !crtc->fb) { 1109 + if (!atomic && !crtc->primary->fb) { 1110 1110 DRM_DEBUG_KMS("No FB bound\n"); 1111 1111 return 0; 1112 1112 } ··· 1116 1116 target_fb = fb; 1117 1117 } 1118 1118 else { 1119 - radeon_fb = to_radeon_framebuffer(crtc->fb); 1120 - target_fb = crtc->fb; 1119 + radeon_fb = to_radeon_framebuffer(crtc->primary->fb); 1120 + target_fb = crtc->primary->fb; 1121 1121 } 1122 1122 1123 1123 /* If atomic, assume fb object is pinned & idle & fenced and ··· 1316 1316 /* set pageflip to happen anywhere in vblank interval */ 1317 1317 WREG32(EVERGREEN_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0); 1318 1318 1319 - if (!atomic && fb && fb != crtc->fb) { 1319 + if (!atomic && fb && fb != crtc->primary->fb) { 1320 1320 radeon_fb = to_radeon_framebuffer(fb); 1321 1321 rbo = gem_to_radeon_bo(radeon_fb->obj); 1322 1322 r = radeon_bo_reserve(rbo, false); ··· 1350 1350 int r; 1351 1351 1352 1352 /* no fb bound */ 1353 - if (!atomic && !crtc->fb) { 1353 + if (!atomic && !crtc->primary->fb) { 1354 1354 DRM_DEBUG_KMS("No FB bound\n"); 1355 1355 return 0; 1356 1356 } ··· 1360 1360 target_fb = fb; 1361 1361 } 1362 1362 else { 1363 - radeon_fb = to_radeon_framebuffer(crtc->fb); 1364 - target_fb = crtc->fb; 1363 + radeon_fb = to_radeon_framebuffer(crtc->primary->fb); 1364 + target_fb = crtc->primary->fb; 1365 1365 } 1366 1366 1367 1367 obj = radeon_fb->obj; ··· 1485 1485 /* set pageflip to happen anywhere in vblank interval */ 1486 1486 WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0); 1487 1487 1488 - if (!atomic && fb && fb != crtc->fb) { 1488 + if (!atomic && fb && fb != crtc->primary->fb) { 1489 1489 radeon_fb = to_radeon_framebuffer(fb); 1490 1490 rbo = gem_to_radeon_bo(radeon_fb->obj); 1491 1491 r = radeon_bo_reserve(rbo, false); ··· 1972 1972 int i; 1973 1973 1974 1974 atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); 1975 - if (crtc->fb) { 1975 + if (crtc->primary->fb) { 1976 1976 int r; 1977 1977 struct radeon_framebuffer *radeon_fb; 1978 1978 struct radeon_bo *rbo; 1979 1979 1980 - radeon_fb = to_radeon_framebuffer(crtc->fb); 1980 + radeon_fb = to_radeon_framebuffer(crtc->primary->fb); 1981 1981 rbo = gem_to_radeon_bo(radeon_fb->obj); 1982 1982 r = radeon_bo_reserve(rbo, false); 1983 1983 if (unlikely(r))
+2 -2
drivers/gpu/drm/radeon/r100.c
··· 3220 3220 3221 3221 if (rdev->mode_info.crtcs[0]->base.enabled) { 3222 3222 mode1 = &rdev->mode_info.crtcs[0]->base.mode; 3223 - pixel_bytes1 = rdev->mode_info.crtcs[0]->base.fb->bits_per_pixel / 8; 3223 + pixel_bytes1 = rdev->mode_info.crtcs[0]->base.primary->fb->bits_per_pixel / 8; 3224 3224 } 3225 3225 if (!(rdev->flags & RADEON_SINGLE_CRTC)) { 3226 3226 if (rdev->mode_info.crtcs[1]->base.enabled) { 3227 3227 mode2 = &rdev->mode_info.crtcs[1]->base.mode; 3228 - pixel_bytes2 = rdev->mode_info.crtcs[1]->base.fb->bits_per_pixel / 8; 3228 + pixel_bytes2 = rdev->mode_info.crtcs[1]->base.primary->fb->bits_per_pixel / 8; 3229 3229 } 3230 3230 } 3231 3231
+1 -1
drivers/gpu/drm/radeon/radeon_connectors.c
··· 89 89 90 90 if (crtc && crtc->enabled) { 91 91 drm_crtc_helper_set_mode(crtc, &crtc->mode, 92 - crtc->x, crtc->y, crtc->fb); 92 + crtc->x, crtc->y, crtc->primary->fb); 93 93 } 94 94 } 95 95
+1 -1
drivers/gpu/drm/radeon/radeon_device.c
··· 1424 1424 1425 1425 /* unpin the front buffers */ 1426 1426 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 1427 - struct radeon_framebuffer *rfb = to_radeon_framebuffer(crtc->fb); 1427 + struct radeon_framebuffer *rfb = to_radeon_framebuffer(crtc->primary->fb); 1428 1428 struct radeon_bo *robj; 1429 1429 1430 1430 if (rfb == NULL || rfb->obj == NULL) {
+2 -2
drivers/gpu/drm/radeon/radeon_display.c
··· 369 369 work->event = event; 370 370 work->rdev = rdev; 371 371 work->crtc_id = radeon_crtc->crtc_id; 372 - old_radeon_fb = to_radeon_framebuffer(crtc->fb); 372 + old_radeon_fb = to_radeon_framebuffer(crtc->primary->fb); 373 373 new_radeon_fb = to_radeon_framebuffer(fb); 374 374 /* schedule unpin of the old buffer */ 375 375 obj = old_radeon_fb->obj; ··· 460 460 spin_unlock_irqrestore(&dev->event_lock, flags); 461 461 462 462 /* update crtc fb */ 463 - crtc->fb = fb; 463 + crtc->primary->fb = fb; 464 464 465 465 r = drm_vblank_get(dev, radeon_crtc->crtc_id); 466 466 if (r) {
+8 -8
drivers/gpu/drm/radeon/radeon_legacy_crtc.c
··· 385 385 386 386 DRM_DEBUG_KMS("\n"); 387 387 /* no fb bound */ 388 - if (!atomic && !crtc->fb) { 388 + if (!atomic && !crtc->primary->fb) { 389 389 DRM_DEBUG_KMS("No FB bound\n"); 390 390 return 0; 391 391 } ··· 395 395 target_fb = fb; 396 396 } 397 397 else { 398 - radeon_fb = to_radeon_framebuffer(crtc->fb); 399 - target_fb = crtc->fb; 398 + radeon_fb = to_radeon_framebuffer(crtc->primary->fb); 399 + target_fb = crtc->primary->fb; 400 400 } 401 401 402 402 switch (target_fb->bits_per_pixel) { ··· 444 444 * We don't shutdown the display controller because new buffer 445 445 * will end up in same spot. 446 446 */ 447 - if (!atomic && fb && fb != crtc->fb) { 447 + if (!atomic && fb && fb != crtc->primary->fb) { 448 448 struct radeon_bo *old_rbo; 449 449 unsigned long nsize, osize; 450 450 ··· 555 555 WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, crtc_offset); 556 556 WREG32(RADEON_CRTC_PITCH + radeon_crtc->crtc_offset, crtc_pitch); 557 557 558 - if (!atomic && fb && fb != crtc->fb) { 558 + if (!atomic && fb && fb != crtc->primary->fb) { 559 559 radeon_fb = to_radeon_framebuffer(fb); 560 560 rbo = gem_to_radeon_bo(radeon_fb->obj); 561 561 r = radeon_bo_reserve(rbo, false); ··· 599 599 } 600 600 } 601 601 602 - switch (crtc->fb->bits_per_pixel) { 602 + switch (crtc->primary->fb->bits_per_pixel) { 603 603 case 8: 604 604 format = 2; 605 605 break; ··· 1087 1087 static void radeon_crtc_disable(struct drm_crtc *crtc) 1088 1088 { 1089 1089 radeon_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); 1090 - if (crtc->fb) { 1090 + if (crtc->primary->fb) { 1091 1091 int r; 1092 1092 struct radeon_framebuffer *radeon_fb; 1093 1093 struct radeon_bo *rbo; 1094 1094 1095 - radeon_fb = to_radeon_framebuffer(crtc->fb); 1095 + radeon_fb = to_radeon_framebuffer(crtc->primary->fb); 1096 1096 rbo = gem_to_radeon_bo(radeon_fb->obj); 1097 1097 r = radeon_bo_reserve(rbo, false); 1098 1098 if (unlikely(r))
+5 -5
drivers/gpu/drm/rcar-du/rcar_du_crtc.c
··· 299 299 { 300 300 struct drm_crtc *crtc = &rcrtc->crtc; 301 301 302 - rcar_du_plane_compute_base(rcrtc->plane, crtc->fb); 302 + rcar_du_plane_compute_base(rcrtc->plane, crtc->primary->fb); 303 303 rcar_du_plane_update_base(rcrtc->plane); 304 304 } 305 305 ··· 358 358 const struct rcar_du_format_info *format; 359 359 int ret; 360 360 361 - format = rcar_du_format_info(crtc->fb->pixel_format); 361 + format = rcar_du_format_info(crtc->primary->fb->pixel_format); 362 362 if (format == NULL) { 363 363 dev_dbg(rcdu->dev, "mode_set: unsupported format %08x\n", 364 - crtc->fb->pixel_format); 364 + crtc->primary->fb->pixel_format); 365 365 ret = -EINVAL; 366 366 goto error; 367 367 } ··· 377 377 rcrtc->plane->width = mode->hdisplay; 378 378 rcrtc->plane->height = mode->vdisplay; 379 379 380 - rcar_du_plane_compute_base(rcrtc->plane, crtc->fb); 380 + rcar_du_plane_compute_base(rcrtc->plane, crtc->primary->fb); 381 381 382 382 rcrtc->outputs = 0; 383 383 ··· 510 510 } 511 511 spin_unlock_irqrestore(&dev->event_lock, flags); 512 512 513 - crtc->fb = fb; 513 + crtc->primary->fb = fb; 514 514 rcar_du_crtc_update_base(rcrtc); 515 515 516 516 if (event) {
+8 -8
drivers/gpu/drm/shmobile/shmob_drm_crtc.c
··· 173 173 if (scrtc->started) 174 174 return; 175 175 176 - format = shmob_drm_format_info(crtc->fb->pixel_format); 176 + format = shmob_drm_format_info(crtc->primary->fb->pixel_format); 177 177 if (WARN_ON(format == NULL)) 178 178 return; 179 179 ··· 247 247 lcdc_write(sdev, LDDDSR, value); 248 248 249 249 /* Setup planes. */ 250 - list_for_each_entry(plane, &dev->mode_config.plane_list, head) { 250 + drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) { 251 251 if (plane->crtc == crtc) 252 252 shmob_drm_plane_setup(plane); 253 253 } ··· 303 303 int x, int y) 304 304 { 305 305 struct drm_crtc *crtc = &scrtc->crtc; 306 - struct drm_framebuffer *fb = crtc->fb; 306 + struct drm_framebuffer *fb = crtc->primary->fb; 307 307 struct shmob_drm_device *sdev = crtc->dev->dev_private; 308 308 struct drm_gem_cma_object *gem; 309 309 unsigned int bpp; ··· 382 382 const struct shmob_drm_format_info *format; 383 383 void *cache; 384 384 385 - format = shmob_drm_format_info(crtc->fb->pixel_format); 385 + format = shmob_drm_format_info(crtc->primary->fb->pixel_format); 386 386 if (format == NULL) { 387 387 dev_dbg(sdev->dev, "mode_set: unsupported format %08x\n", 388 - crtc->fb->pixel_format); 388 + crtc->primary->fb->pixel_format); 389 389 return -EINVAL; 390 390 } 391 391 392 392 scrtc->format = format; 393 - scrtc->line_size = crtc->fb->pitches[0]; 393 + scrtc->line_size = crtc->primary->fb->pitches[0]; 394 394 395 395 if (sdev->meram) { 396 396 /* Enable MERAM cache if configured. We need to de-init ··· 402 402 } 403 403 404 404 cache = sh_mobile_meram_cache_alloc(sdev->meram, mdata, 405 - crtc->fb->pitches[0], 405 + crtc->primary->fb->pitches[0], 406 406 adjusted_mode->vdisplay, 407 407 format->meram, 408 408 &scrtc->line_size); ··· 489 489 } 490 490 spin_unlock_irqrestore(&dev->event_lock, flags); 491 491 492 - crtc->fb = fb; 492 + crtc->primary->fb = fb; 493 493 shmob_drm_crtc_update_base(scrtc); 494 494 495 495 if (event) {
+8 -8
drivers/gpu/drm/tegra/dc.c
··· 235 235 if (!dc->event) 236 236 return; 237 237 238 - bo = tegra_fb_get_plane(crtc->fb, 0); 238 + bo = tegra_fb_get_plane(crtc->primary->fb, 0); 239 239 240 240 /* check if new start address has been latched */ 241 241 tegra_dc_writel(dc, READ_MUX, DC_CMD_STATE_ACCESS); 242 242 base = tegra_dc_readl(dc, DC_WINBUF_START_ADDR); 243 243 tegra_dc_writel(dc, 0, DC_CMD_STATE_ACCESS); 244 244 245 - if (base == bo->paddr + crtc->fb->offsets[0]) { 245 + if (base == bo->paddr + crtc->primary->fb->offsets[0]) { 246 246 spin_lock_irqsave(&drm->event_lock, flags); 247 247 drm_send_vblank_event(drm, dc->pipe, dc->event); 248 248 drm_vblank_put(drm, dc->pipe); ··· 284 284 } 285 285 286 286 tegra_dc_set_base(dc, 0, 0, fb); 287 - crtc->fb = fb; 287 + crtc->primary->fb = fb; 288 288 289 289 return 0; 290 290 } ··· 645 645 struct drm_display_mode *adjusted, 646 646 int x, int y, struct drm_framebuffer *old_fb) 647 647 { 648 - struct tegra_bo *bo = tegra_fb_get_plane(crtc->fb, 0); 648 + struct tegra_bo *bo = tegra_fb_get_plane(crtc->primary->fb, 0); 649 649 struct tegra_dc *dc = to_tegra_dc(crtc); 650 650 struct tegra_dc_window window; 651 651 unsigned long div, value; ··· 682 682 window.dst.y = 0; 683 683 window.dst.w = mode->hdisplay; 684 684 window.dst.h = mode->vdisplay; 685 - window.format = tegra_dc_format(crtc->fb->pixel_format); 686 - window.bits_per_pixel = crtc->fb->bits_per_pixel; 687 - window.stride[0] = crtc->fb->pitches[0]; 685 + window.format = tegra_dc_format(crtc->primary->fb->pixel_format); 686 + window.bits_per_pixel = crtc->primary->fb->bits_per_pixel; 687 + window.stride[0] = crtc->primary->fb->pitches[0]; 688 688 window.base[0] = bo->paddr; 689 689 690 690 err = tegra_dc_setup_window(dc, 0, &window); ··· 699 699 { 700 700 struct tegra_dc *dc = to_tegra_dc(crtc); 701 701 702 - return tegra_dc_set_base(dc, x, y, crtc->fb); 702 + return tegra_dc_set_base(dc, x, y, crtc->primary->fb); 703 703 } 704 704 705 705 static void tegra_crtc_prepare(struct drm_crtc *crtc)
+4 -4
drivers/gpu/drm/tilcdc/tilcdc_crtc.c
··· 74 74 drm_flip_work_queue(&tilcdc_crtc->unref_work, tilcdc_crtc->scanout[n]); 75 75 drm_flip_work_commit(&tilcdc_crtc->unref_work, priv->wq); 76 76 } 77 - tilcdc_crtc->scanout[n] = crtc->fb; 77 + tilcdc_crtc->scanout[n] = crtc->primary->fb; 78 78 drm_framebuffer_reference(tilcdc_crtc->scanout[n]); 79 79 tilcdc_crtc->dirty &= ~stat[n]; 80 80 pm_runtime_put_sync(dev->dev); ··· 84 84 { 85 85 struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); 86 86 struct drm_device *dev = crtc->dev; 87 - struct drm_framebuffer *fb = crtc->fb; 87 + struct drm_framebuffer *fb = crtc->primary->fb; 88 88 struct drm_gem_cma_object *gem; 89 89 unsigned int depth, bpp; 90 90 ··· 159 159 return -EBUSY; 160 160 } 161 161 162 - crtc->fb = fb; 162 + crtc->primary->fb = fb; 163 163 tilcdc_crtc->event = event; 164 164 update_scanout(crtc); 165 165 ··· 339 339 if (priv->rev == 2) { 340 340 unsigned int depth, bpp; 341 341 342 - drm_fb_get_bpp_depth(crtc->fb->pixel_format, &depth, &bpp); 342 + drm_fb_get_bpp_depth(crtc->primary->fb->pixel_format, &depth, &bpp); 343 343 switch (bpp) { 344 344 case 16: 345 345 break;
+1 -1
drivers/gpu/drm/udl/udl_modeset.c
··· 310 310 311 311 { 312 312 struct drm_device *dev = crtc->dev; 313 - struct udl_framebuffer *ufb = to_udl_fb(crtc->fb); 313 + struct udl_framebuffer *ufb = to_udl_fb(crtc->primary->fb); 314 314 struct udl_device *udl = dev->dev_private; 315 315 char *buf; 316 316 char *wrptr;
+7 -7
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
··· 468 468 num_units = 0; 469 469 list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list, 470 470 head) { 471 - if (crtc->fb != &framebuffer->base) 471 + if (crtc->primary->fb != &framebuffer->base) 472 472 continue; 473 473 units[num_units++] = vmw_crtc_to_du(crtc); 474 474 } ··· 882 882 883 883 num_units = 0; 884 884 list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list, head) { 885 - if (crtc->fb != &framebuffer->base) 885 + if (crtc->primary->fb != &framebuffer->base) 886 886 continue; 887 887 units[num_units++] = vmw_crtc_to_du(crtc); 888 888 } ··· 1243 1243 1244 1244 num_units = 0; 1245 1245 list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list, head) { 1246 - if (crtc->fb != &vfb->base) 1246 + if (crtc->primary->fb != &vfb->base) 1247 1247 continue; 1248 1248 units[num_units++] = vmw_crtc_to_du(crtc); 1249 1249 } ··· 1380 1380 1381 1381 num_units = 0; 1382 1382 list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list, head) { 1383 - if (crtc->fb != &vfb->base) 1383 + if (crtc->primary->fb != &vfb->base) 1384 1384 continue; 1385 1385 units[num_units++] = vmw_crtc_to_du(crtc); 1386 1386 } ··· 1723 1723 uint32_t page_flip_flags) 1724 1724 { 1725 1725 struct vmw_private *dev_priv = vmw_priv(crtc->dev); 1726 - struct drm_framebuffer *old_fb = crtc->fb; 1726 + struct drm_framebuffer *old_fb = crtc->primary->fb; 1727 1727 struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(fb); 1728 1728 struct drm_file *file_priv ; 1729 1729 struct vmw_fence_obj *fence = NULL; ··· 1741 1741 if (!vmw_kms_screen_object_flippable(dev_priv, crtc)) 1742 1742 return -EINVAL; 1743 1743 1744 - crtc->fb = fb; 1744 + crtc->primary->fb = fb; 1745 1745 1746 1746 /* do a full screen dirty update */ 1747 1747 clips.x1 = clips.y1 = 0; ··· 1781 1781 return ret; 1782 1782 1783 1783 out_no_fence: 1784 - crtc->fb = old_fb; 1784 + crtc->primary->fb = old_fb; 1785 1785 return ret; 1786 1786 } 1787 1787
+4 -4
drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
··· 93 93 94 94 if (crtc == NULL) 95 95 return 0; 96 - fb = entry->base.crtc.fb; 96 + fb = entry->base.crtc.primary->fb; 97 97 98 98 return vmw_kms_write_svga(dev_priv, w, h, fb->pitches[0], 99 99 fb->bits_per_pixel, fb->depth); ··· 101 101 102 102 if (!list_empty(&lds->active)) { 103 103 entry = list_entry(lds->active.next, typeof(*entry), active); 104 - fb = entry->base.crtc.fb; 104 + fb = entry->base.crtc.primary->fb; 105 105 106 106 vmw_kms_write_svga(dev_priv, fb->width, fb->height, fb->pitches[0], 107 107 fb->bits_per_pixel, fb->depth); ··· 259 259 260 260 connector->encoder = NULL; 261 261 encoder->crtc = NULL; 262 - crtc->fb = NULL; 262 + crtc->primary->fb = NULL; 263 263 crtc->enabled = false; 264 264 265 265 vmw_ldu_del_active(dev_priv, ldu); ··· 280 280 281 281 vmw_fb_off(dev_priv); 282 282 283 - crtc->fb = fb; 283 + crtc->primary->fb = fb; 284 284 encoder->crtc = crtc; 285 285 connector->encoder = encoder; 286 286 crtc->x = set->x;
+4 -4
drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
··· 307 307 308 308 connector->encoder = NULL; 309 309 encoder->crtc = NULL; 310 - crtc->fb = NULL; 310 + crtc->primary->fb = NULL; 311 311 crtc->x = 0; 312 312 crtc->y = 0; 313 313 crtc->enabled = false; ··· 368 368 369 369 connector->encoder = NULL; 370 370 encoder->crtc = NULL; 371 - crtc->fb = NULL; 371 + crtc->primary->fb = NULL; 372 372 crtc->x = 0; 373 373 crtc->y = 0; 374 374 crtc->enabled = false; ··· 381 381 connector->encoder = encoder; 382 382 encoder->crtc = crtc; 383 383 crtc->mode = *mode; 384 - crtc->fb = fb; 384 + crtc->primary->fb = fb; 385 385 crtc->x = set->x; 386 386 crtc->y = set->y; 387 387 crtc->enabled = true; ··· 572 572 BUG_ON(!sou->base.is_implicit); 573 573 574 574 dev_priv->sou_priv->implicit_fb = 575 - vmw_framebuffer_to_vfb(sou->base.crtc.fb); 575 + vmw_framebuffer_to_vfb(sou->base.crtc.primary->fb); 576 576 }
+3 -3
drivers/staging/imx-drm/ipuv3-crtc.c
··· 120 120 121 121 ipu_crtc->newfb = fb; 122 122 ipu_crtc->page_flip_event = event; 123 - crtc->fb = fb; 123 + crtc->primary->fb = fb; 124 124 125 125 return 0; 126 126 } ··· 192 192 return ret; 193 193 } 194 194 195 - return ipu_plane_mode_set(ipu_crtc->plane[0], crtc, mode, crtc->fb, 195 + return ipu_plane_mode_set(ipu_crtc->plane[0], crtc, mode, crtc->primary->fb, 196 196 0, 0, mode->hdisplay, mode->vdisplay, 197 197 x, y, mode->hdisplay, mode->vdisplay); 198 198 } ··· 218 218 219 219 if (ipu_crtc->newfb) { 220 220 ipu_crtc->newfb = NULL; 221 - ipu_plane_set_base(ipu_crtc->plane[0], ipu_crtc->base.fb, 221 + ipu_plane_set_base(ipu_crtc->plane[0], ipu_crtc->base.primary->fb, 222 222 ipu_crtc->plane[0]->x, ipu_crtc->plane[0]->y); 223 223 ipu_crtc_handle_pageflip(ipu_crtc); 224 224 }
+6
include/drm/drmP.h
··· 409 409 unsigned is_master :1; 410 410 /* true when the client has asked us to expose stereo 3D mode flags */ 411 411 unsigned stereo_allowed :1; 412 + /* 413 + * true if client understands CRTC primary planes and cursor planes 414 + * in the plane list 415 + */ 416 + unsigned universal_planes:1; 412 417 413 418 struct pid *pid; 414 419 kuid_t uid; ··· 1414 1409 extern void drm_unplug_dev(struct drm_device *dev); 1415 1410 extern unsigned int drm_debug; 1416 1411 extern unsigned int drm_rnodes; 1412 + extern unsigned int drm_universal_planes; 1417 1413 1418 1414 extern unsigned int drm_vblank_offdelay; 1419 1415 extern unsigned int drm_timestamp_precision;
+46 -4
include/drm/drm_crtc.h
··· 270 270 * @dev: parent DRM device 271 271 * @head: list management 272 272 * @base: base KMS object for ID tracking etc. 273 + * @primary: primary plane for this CRTC 274 + * @cursor: cursor plane for this CRTC 273 275 * @enabled: is this CRTC enabled? 274 276 * @mode: current mode timings 275 277 * @hwmode: mode timings as programmed to hw regs ··· 307 305 308 306 struct drm_mode_object base; 309 307 310 - /* framebuffer the connector is currently bound to */ 311 - struct drm_framebuffer *fb; 308 + /* primary and cursor planes for CRTC */ 309 + struct drm_plane *primary; 310 + struct drm_plane *cursor; 312 311 313 312 /* Temporary tracking of the old fb while a modeset is ongoing. Used 314 313 * by drm_mode_set_config_internal to implement correct refcounting. */ ··· 544 541 struct drm_property *property, uint64_t val); 545 542 }; 546 543 544 + enum drm_plane_type { 545 + DRM_PLANE_TYPE_OVERLAY, 546 + DRM_PLANE_TYPE_PRIMARY, 547 + DRM_PLANE_TYPE_CURSOR, 548 + }; 549 + 547 550 /** 548 551 * drm_plane - central DRM plane control structure 549 552 * @dev: DRM device this plane belongs to ··· 562 553 * @fb: currently bound fb 563 554 * @funcs: helper functions 564 555 * @properties: property tracking for this plane 556 + * @type: type of plane (overlay, primary, cursor) 565 557 */ 566 558 struct drm_plane { 567 559 struct drm_device *dev; ··· 580 570 const struct drm_plane_funcs *funcs; 581 571 582 572 struct drm_object_properties properties; 573 + 574 + enum drm_plane_type type; 583 575 }; 584 576 585 577 /** ··· 744 732 struct list_head bridge_list; 745 733 int num_encoder; 746 734 struct list_head encoder_list; 747 - int num_plane; 735 + 736 + /* 737 + * Track # of overlay planes separately from # of total planes. By 738 + * default we only advertise overlay planes to userspace; if userspace 739 + * sets the "universal plane" capability bit, we'll go ahead and 740 + * expose all planes. 741 + */ 742 + int num_overlay_plane; 743 + int num_total_plane; 748 744 struct list_head plane_list; 749 745 750 746 int num_crtc; ··· 774 754 struct list_head property_blob_list; 775 755 struct drm_property *edid_property; 776 756 struct drm_property *dpms_property; 757 + struct drm_property *plane_type_property; 777 758 778 759 /* DVI-I properties */ 779 760 struct drm_property *dvi_i_subconnector_property; ··· 827 806 extern void drm_modeset_unlock_all(struct drm_device *dev); 828 807 extern void drm_warn_on_modeset_not_all_locked(struct drm_device *dev); 829 808 809 + extern int drm_crtc_init_with_planes(struct drm_device *dev, 810 + struct drm_crtc *crtc, 811 + struct drm_plane *primary, 812 + void *cursor, 813 + const struct drm_crtc_funcs *funcs); 830 814 extern int drm_crtc_init(struct drm_device *dev, 831 815 struct drm_crtc *crtc, 832 816 const struct drm_crtc_funcs *funcs); ··· 883 857 return !!(encoder->possible_crtcs & drm_crtc_mask(crtc)); 884 858 } 885 859 860 + extern int drm_universal_plane_init(struct drm_device *dev, 861 + struct drm_plane *plane, 862 + unsigned long possible_crtcs, 863 + const struct drm_plane_funcs *funcs, 864 + const uint32_t *formats, 865 + uint32_t format_count, 866 + enum drm_plane_type type); 886 867 extern int drm_plane_init(struct drm_device *dev, 887 868 struct drm_plane *plane, 888 869 unsigned long possible_crtcs, 889 870 const struct drm_plane_funcs *funcs, 890 871 const uint32_t *formats, uint32_t format_count, 891 - bool priv); 872 + bool is_primary); 892 873 extern void drm_plane_cleanup(struct drm_plane *plane); 893 874 extern void drm_plane_force_disable(struct drm_plane *plane); 875 + extern int drm_crtc_check_viewport(const struct drm_crtc *crtc, 876 + int x, int y, 877 + const struct drm_display_mode *mode, 878 + const struct drm_framebuffer *fb); 894 879 895 880 extern void drm_encoder_cleanup(struct drm_encoder *encoder); 896 881 ··· 1072 1035 mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER); 1073 1036 return mo ? obj_to_encoder(mo) : NULL; 1074 1037 } 1038 + 1039 + /* Plane list iterator for legacy (overlay only) planes. */ 1040 + #define drm_for_each_legacy_plane(plane, planelist) \ 1041 + list_for_each_entry(plane, planelist, head) \ 1042 + if (plane->type == DRM_PLANE_TYPE_OVERLAY) 1075 1043 1076 1044 #endif /* __DRM_CRTC_H__ */
+49
include/drm/drm_plane_helper.h
··· 1 + /* 2 + * Copyright (C) 2011-2013 Intel Corporation 3 + * 4 + * Permission is hereby granted, free of charge, to any person obtaining a 5 + * copy of this software and associated documentation files (the "Software"), 6 + * to deal in the Software without restriction, including without limitation 7 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 + * and/or sell copies of the Software, and to permit persons to whom the 9 + * Software is furnished to do so, subject to the following conditions: 10 + * 11 + * The above copyright notice and this permission notice (including the next 12 + * paragraph) shall be included in all copies or substantial portions of the 13 + * Software. 14 + * 15 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 + * SOFTWARE. 22 + */ 23 + 24 + #ifndef DRM_PLANE_HELPER_H 25 + #define DRM_PLANE_HELPER_H 26 + 27 + /** 28 + * DOC: plane helpers 29 + * 30 + * Helper functions to assist with creation and handling of CRTC primary 31 + * planes. 32 + */ 33 + 34 + extern int drm_primary_helper_update(struct drm_plane *plane, 35 + struct drm_crtc *crtc, 36 + struct drm_framebuffer *fb, 37 + int crtc_x, int crtc_y, 38 + unsigned int crtc_w, unsigned int crtc_h, 39 + uint32_t src_x, uint32_t src_y, 40 + uint32_t src_w, uint32_t src_h); 41 + extern int drm_primary_helper_disable(struct drm_plane *plane); 42 + extern void drm_primary_helper_destroy(struct drm_plane *plane); 43 + extern const struct drm_plane_funcs drm_primary_helper_funcs; 44 + extern struct drm_plane *drm_primary_helper_create_plane(struct drm_device *dev, 45 + uint32_t *formats, 46 + int num_formats); 47 + 48 + 49 + #endif
+8
include/uapi/drm/drm.h
··· 646 646 */ 647 647 #define DRM_CLIENT_CAP_STEREO_3D 1 648 648 649 + /** 650 + * DRM_CLIENT_CAP_UNIVERSAL_PLANES 651 + * 652 + * If set to 1, the DRM core will expose all planes (overlay, primary, and 653 + * cursor) to userspace. 654 + */ 655 + #define DRM_CLIENT_CAP_UNIVERSAL_PLANES 2 656 + 649 657 /** DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */ 650 658 struct drm_set_client_cap { 651 659 __u64 capability;