diff options
Diffstat (limited to 'drivers/gpu/drm')
56 files changed, 786 insertions, 333 deletions
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 5e792b0a5f75..9d25dbbe6771 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -13,7 +13,8 @@ drm-y := drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \ drm_crtc.o drm_modes.o drm_edid.o \ drm_info.o drm_debugfs.o drm_encoder_slave.o \ drm_trace_points.o drm_global.o drm_prime.o \ - drm_rect.o drm_vma_manager.o drm_flip_work.o + drm_rect.o drm_vma_manager.o drm_flip_work.o \ + drm_plane_helper.o drm-$(CONFIG_COMPAT) += drm_ioc32.o drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c index d8e398275ca8..5831e4109e75 100644 --- a/drivers/gpu/drm/armada/armada_crtc.c +++ b/drivers/gpu/drm/armada/armada_crtc.c @@ -478,11 +478,12 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc, unsigned i; bool interlaced; - drm_framebuffer_reference(crtc->fb); + drm_framebuffer_reference(crtc->primary->fb); interlaced = !!(adj->flags & DRM_MODE_FLAG_INTERLACE); - i = armada_drm_crtc_calc_fb(dcrtc->crtc.fb, x, y, regs, interlaced); + i = armada_drm_crtc_calc_fb(dcrtc->crtc.primary->fb, + x, y, regs, interlaced); rm = adj->crtc_hsync_start - adj->crtc_hdisplay; lm = adj->crtc_htotal - adj->crtc_hsync_end; @@ -567,10 +568,10 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc, } val = CFG_GRA_ENA | CFG_GRA_HSMOOTH; - val |= CFG_GRA_FMT(drm_fb_to_armada_fb(dcrtc->crtc.fb)->fmt); - val |= CFG_GRA_MOD(drm_fb_to_armada_fb(dcrtc->crtc.fb)->mod); + val |= CFG_GRA_FMT(drm_fb_to_armada_fb(dcrtc->crtc.primary->fb)->fmt); + val |= CFG_GRA_MOD(drm_fb_to_armada_fb(dcrtc->crtc.primary->fb)->mod); - if (drm_fb_to_armada_fb(dcrtc->crtc.fb)->fmt > CFG_420) + if (drm_fb_to_armada_fb(dcrtc->crtc.primary->fb)->fmt > CFG_420) val |= CFG_PALETTE_ENA; if (interlaced) @@ -608,7 +609,7 @@ static int armada_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, struct armada_regs regs[4]; unsigned i; - i = armada_drm_crtc_calc_fb(crtc->fb, crtc->x, crtc->y, regs, + i = armada_drm_crtc_calc_fb(crtc->primary->fb, crtc->x, crtc->y, regs, dcrtc->interlaced); armada_reg_queue_end(regs, i); @@ -616,7 +617,7 @@ static int armada_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, wait_event(dcrtc->frame_wait, !dcrtc->frame_work); /* Take a reference to the new fb as we're using it */ - drm_framebuffer_reference(crtc->fb); + drm_framebuffer_reference(crtc->primary->fb); /* Update the base in the CRTC */ armada_drm_crtc_update_regs(dcrtc, regs); @@ -637,7 +638,7 @@ static void armada_drm_crtc_disable(struct drm_crtc *crtc) struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); armada_drm_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); - armada_drm_crtc_finish_fb(dcrtc, crtc->fb, true); + armada_drm_crtc_finish_fb(dcrtc, crtc->primary->fb, true); /* Power down most RAMs and FIFOs */ writel_relaxed(CFG_PDWN256x32 | CFG_PDWN256x24 | CFG_PDWN256x8 | @@ -904,7 +905,7 @@ static int armada_drm_crtc_page_flip(struct drm_crtc *crtc, int ret; /* We don't support changing the pixel format */ - if (fb->pixel_format != crtc->fb->pixel_format) + if (fb->pixel_format != crtc->primary->fb->pixel_format) return -EINVAL; work = kmalloc(sizeof(*work), GFP_KERNEL); @@ -912,7 +913,7 @@ static int armada_drm_crtc_page_flip(struct drm_crtc *crtc, return -ENOMEM; work->event = event; - work->old_fb = dcrtc->crtc.fb; + work->old_fb = dcrtc->crtc.primary->fb; i = armada_drm_crtc_calc_fb(fb, crtc->x, crtc->y, work->regs, dcrtc->interlaced); @@ -941,7 +942,7 @@ static int armada_drm_crtc_page_flip(struct drm_crtc *crtc, * will _not_ drop that reference on successful return from this * function. Simply mark this new framebuffer as the current one. */ - dcrtc->crtc.fb = fb; + dcrtc->crtc.primary->fb = fb; /* * Finally, if the display is blanked, we won't receive an diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index cca063b11083..a4afdc8bb578 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -81,7 +81,7 @@ static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mo u32 refresh_rate_index = 0, mode_id, color_index, refresh_rate; u32 hborder, vborder; - switch (crtc->fb->bits_per_pixel) { + switch (crtc->primary->fb->bits_per_pixel) { case 8: vbios_mode->std_table = &vbios_stdtable[VGAModeIndex]; color_index = VGAModeIndex - 1; @@ -176,7 +176,7 @@ static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mo ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8e, mode_id & 0xff); ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x92, crtc->fb->bits_per_pixel); + ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x92, crtc->primary->fb->bits_per_pixel); ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x93, adjusted_mode->clock / 1000); ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x94, adjusted_mode->crtc_hdisplay); ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x95, adjusted_mode->crtc_hdisplay >> 8); @@ -340,7 +340,7 @@ static void ast_set_offset_reg(struct drm_crtc *crtc) u16 offset; - offset = crtc->fb->pitches[0] >> 3; + offset = crtc->primary->fb->pitches[0] >> 3; ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x13, (offset & 0xff)); ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xb0, (offset >> 8) & 0x3f); } @@ -365,7 +365,7 @@ static void ast_set_ext_reg(struct drm_crtc *crtc, struct drm_display_mode *mode struct ast_private *ast = crtc->dev->dev_private; u8 jregA0 = 0, jregA3 = 0, jregA8 = 0; - switch (crtc->fb->bits_per_pixel) { + switch (crtc->primary->fb->bits_per_pixel) { case 8: jregA0 = 0x70; jregA3 = 0x01; @@ -418,7 +418,7 @@ static void ast_set_sync_reg(struct drm_device *dev, struct drm_display_mode *mo static bool ast_set_dac_reg(struct drm_crtc *crtc, struct drm_display_mode *mode, struct ast_vbios_mode_info *vbios_mode) { - switch (crtc->fb->bits_per_pixel) { + switch (crtc->primary->fb->bits_per_pixel) { case 8: break; default: @@ -490,7 +490,7 @@ static int ast_crtc_do_set_base(struct drm_crtc *crtc, ast_bo_unreserve(bo); } - ast_fb = to_ast_framebuffer(crtc->fb); + ast_fb = to_ast_framebuffer(crtc->primary->fb); obj = ast_fb->obj; bo = gem_to_ast_bo(obj); diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c index 62ec7d4b3816..dcf2e55f4ae9 100644 --- a/drivers/gpu/drm/bochs/bochs_kms.c +++ b/drivers/gpu/drm/bochs/bochs_kms.c @@ -62,10 +62,10 @@ static int bochs_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, } } - if (WARN_ON(crtc->fb == NULL)) + if (WARN_ON(crtc->primary->fb == NULL)) return -EINVAL; - bochs_fb = to_bochs_framebuffer(crtc->fb); + bochs_fb = to_bochs_framebuffer(crtc->primary->fb); bo = gem_to_bochs_bo(bochs_fb->obj); ret = ttm_bo_reserve(&bo->bo, true, false, false, 0); if (ret) diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c index 530f78f84dee..2d64aea83df2 100644 --- a/drivers/gpu/drm/cirrus/cirrus_mode.c +++ b/drivers/gpu/drm/cirrus/cirrus_mode.c @@ -149,7 +149,7 @@ static int cirrus_crtc_do_set_base(struct drm_crtc *crtc, cirrus_bo_unreserve(bo); } - cirrus_fb = to_cirrus_framebuffer(crtc->fb); + cirrus_fb = to_cirrus_framebuffer(crtc->primary->fb); obj = cirrus_fb->obj; bo = gem_to_cirrus_bo(obj); @@ -268,7 +268,7 @@ static int cirrus_crtc_mode_set(struct drm_crtc *crtc, sr07 = RREG8(SEQ_DATA); sr07 &= 0xe0; hdr = 0; - switch (crtc->fb->bits_per_pixel) { + switch (crtc->primary->fb->bits_per_pixel) { case 8: sr07 |= 0x11; break; @@ -291,13 +291,13 @@ static int cirrus_crtc_mode_set(struct drm_crtc *crtc, WREG_SEQ(0x7, sr07); /* Program the pitch */ - tmp = crtc->fb->pitches[0] / 8; + tmp = crtc->primary->fb->pitches[0] / 8; WREG_CRT(VGA_CRTC_OFFSET, tmp); /* Enable extended blanking and pitch bits, and enable full memory */ tmp = 0x22; - tmp |= (crtc->fb->pitches[0] >> 7) & 0x10; - tmp |= (crtc->fb->pitches[0] >> 6) & 0x40; + tmp |= (crtc->primary->fb->pitches[0] >> 7) & 0x10; + tmp |= (crtc->primary->fb->pitches[0] >> 6) & 0x40; WREG_CRT(0x1b, tmp); /* Enable high-colour modes */ diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 960ca987c20f..d8b7099abece 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -121,6 +121,13 @@ static const struct drm_prop_enum_list drm_dpms_enum_list[] = DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list) +static const struct drm_prop_enum_list drm_plane_type_enum_list[] = +{ + { DRM_PLANE_TYPE_OVERLAY, "Overlay" }, + { DRM_PLANE_TYPE_PRIMARY, "Primary" }, + { DRM_PLANE_TYPE_CURSOR, "Cursor" }, +}; + /* * Optional properties */ @@ -662,7 +669,7 @@ void drm_framebuffer_remove(struct drm_framebuffer *fb) drm_modeset_lock_all(dev); /* remove from any CRTC */ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - if (crtc->fb == fb) { + if (crtc->primary->fb == fb) { /* should turn off the crtc */ memset(&set, 0, sizeof(struct drm_mode_set)); set.crtc = crtc; @@ -685,9 +692,12 @@ void drm_framebuffer_remove(struct drm_framebuffer *fb) EXPORT_SYMBOL(drm_framebuffer_remove); /** - * drm_crtc_init - Initialise a new CRTC object + * drm_crtc_init_with_planes - Initialise a new CRTC object with + * specified primary and cursor planes. * @dev: DRM device * @crtc: CRTC object to init + * @primary: Primary plane for CRTC + * @cursor: Cursor plane for CRTC * @funcs: callbacks for the new CRTC * * Inits a new object created as base part of a driver crtc object. @@ -695,8 +705,10 @@ EXPORT_SYMBOL(drm_framebuffer_remove); * Returns: * Zero on success, error code on failure. */ -int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, - const struct drm_crtc_funcs *funcs) +int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc, + struct drm_plane *primary, + void *cursor, + const struct drm_crtc_funcs *funcs) { int ret; @@ -717,12 +729,16 @@ int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, list_add_tail(&crtc->head, &dev->mode_config.crtc_list); dev->mode_config.num_crtc++; + crtc->primary = primary; + if (primary) + primary->possible_crtcs = 1 << drm_crtc_index(crtc); + out: drm_modeset_unlock_all(dev); return ret; } -EXPORT_SYMBOL(drm_crtc_init); +EXPORT_SYMBOL(drm_crtc_init_with_planes); /** * drm_crtc_cleanup - Clean up the core crtc usage @@ -1000,26 +1016,25 @@ void drm_encoder_cleanup(struct drm_encoder *encoder) EXPORT_SYMBOL(drm_encoder_cleanup); /** - * drm_plane_init - Initialise a new plane object + * drm_universal_plane_init - Initialize a new universal plane object * @dev: DRM device * @plane: plane object to init * @possible_crtcs: bitmask of possible CRTCs * @funcs: callbacks for the new plane * @formats: array of supported formats (%DRM_FORMAT_*) * @format_count: number of elements in @formats - * @priv: plane is private (hidden from userspace)? + * @type: type of plane (overlay, primary, cursor) * - * Inits a preallocate plane object created as base part of a driver plane - * object. + * Initializes a plane object of type @type. * * Returns: * Zero on success, error code on failure. */ -int drm_plane_init(struct drm_device *dev, struct drm_plane *plane, - unsigned long possible_crtcs, - const struct drm_plane_funcs *funcs, - const uint32_t *formats, uint32_t format_count, - bool priv) +int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, + unsigned long possible_crtcs, + const struct drm_plane_funcs *funcs, + const uint32_t *formats, uint32_t format_count, + enum drm_plane_type type) { int ret; @@ -1044,23 +1059,53 @@ int drm_plane_init(struct drm_device *dev, struct drm_plane *plane, memcpy(plane->format_types, formats, format_count * sizeof(uint32_t)); plane->format_count = format_count; plane->possible_crtcs = possible_crtcs; + plane->type = type; - /* private planes are not exposed to userspace, but depending on - * display hardware, might be convenient to allow sharing programming - * for the scanout engine with the crtc implementation. - */ - if (!priv) { - list_add_tail(&plane->head, &dev->mode_config.plane_list); - dev->mode_config.num_plane++; - } else { - INIT_LIST_HEAD(&plane->head); - } + list_add_tail(&plane->head, &dev->mode_config.plane_list); + dev->mode_config.num_total_plane++; + if (plane->type == DRM_PLANE_TYPE_OVERLAY) + dev->mode_config.num_overlay_plane++; + + drm_object_attach_property(&plane->base, + dev->mode_config.plane_type_property, + plane->type); out: drm_modeset_unlock_all(dev); return ret; } +EXPORT_SYMBOL(drm_universal_plane_init); + +/** + * drm_plane_init - Initialize a legacy plane + * @dev: DRM device + * @plane: plane object to init + * @possible_crtcs: bitmask of possible CRTCs + * @funcs: callbacks for the new plane + * @formats: array of supported formats (%DRM_FORMAT_*) + * @format_count: number of elements in @formats + * @is_primary: plane type (primary vs overlay) + * + * Legacy API to initialize a DRM plane. + * + * New drivers should call drm_universal_plane_init() instead. + * + * Returns: + * Zero on success, error code on failure. + */ +int drm_plane_init(struct drm_device *dev, struct drm_plane *plane, + unsigned long possible_crtcs, + const struct drm_plane_funcs *funcs, + const uint32_t *formats, uint32_t format_count, + bool is_primary) +{ + enum drm_plane_type type; + + type = is_primary ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY; + return drm_universal_plane_init(dev, plane, possible_crtcs, funcs, + formats, format_count, type); +} EXPORT_SYMBOL(drm_plane_init); /** @@ -1078,11 +1123,13 @@ void drm_plane_cleanup(struct drm_plane *plane) drm_modeset_lock_all(dev); kfree(plane->format_types); drm_mode_object_put(dev, &plane->base); - /* if not added to a list, it must be a private plane */ - if (!list_empty(&plane->head)) { - list_del(&plane->head); - dev->mode_config.num_plane--; - } + + BUG_ON(list_empty(&plane->head)); + + list_del(&plane->head); + dev->mode_config.num_total_plane--; + if (plane->type == DRM_PLANE_TYPE_OVERLAY) + dev->mode_config.num_overlay_plane--; drm_modeset_unlock_all(dev); } EXPORT_SYMBOL(drm_plane_cleanup); @@ -1134,6 +1181,21 @@ static int drm_mode_create_standard_connector_properties(struct drm_device *dev) return 0; } +static int drm_mode_create_standard_plane_properties(struct drm_device *dev) +{ + struct drm_property *type; + + /* + * Standard properties (apply to all planes) + */ + type = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE, + "type", drm_plane_type_enum_list, + ARRAY_SIZE(drm_plane_type_enum_list)); + dev->mode_config.plane_type_property = type; + + return 0; +} + /** * drm_mode_create_dvi_i_properties - create DVI-I specific connector properties * @dev: DRM device @@ -1652,8 +1714,8 @@ int drm_mode_getcrtc(struct drm_device *dev, crtc_resp->x = crtc->x; crtc_resp->y = crtc->y; crtc_resp->gamma_size = crtc->gamma_size; - if (crtc->fb) - crtc_resp->fb_id = crtc->fb->base.id; + if (crtc->primary->fb) + crtc_resp->fb_id = crtc->primary->fb->base.id; else crtc_resp->fb_id = 0; @@ -1897,6 +1959,7 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data, struct drm_plane *plane; uint32_t __user *plane_ptr; int copied = 0, ret = 0; + unsigned num_planes; if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EINVAL; @@ -1904,15 +1967,28 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data, drm_modeset_lock_all(dev); config = &dev->mode_config; + if (file_priv->universal_planes) + num_planes = config->num_total_plane; + else + num_planes = config->num_overlay_plane; + /* * This ioctl is called twice, once to determine how much space is * needed, and the 2nd time to fill it. */ - if (config->num_plane && - (plane_resp->count_planes >= config->num_plane)) { + if (num_planes && + (plane_resp->count_planes >= num_planes)) { plane_ptr = (uint32_t __user *)(unsigned long)plane_resp->plane_id_ptr; list_for_each_entry(plane, &config->plane_list, head) { + /* + * Unless userspace set the 'universal planes' + * capability bit, only advertise overlays. + */ + if (plane->type != DRM_PLANE_TYPE_OVERLAY && + !file_priv->universal_planes) + continue; + if (put_user(plane->base.id, plane_ptr + copied)) { ret = -EFAULT; goto out; @@ -1920,7 +1996,7 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data, copied++; } } - plane_resp->count_planes = config->num_plane; + plane_resp->count_planes = num_planes; out: drm_modeset_unlock_all(dev); @@ -2156,19 +2232,21 @@ int drm_mode_set_config_internal(struct drm_mode_set *set) * crtcs. Atomic modeset will have saner semantics ... */ list_for_each_entry(tmp, &crtc->dev->mode_config.crtc_list, head) - tmp->old_fb = tmp->fb; + tmp->old_fb = tmp->primary->fb; fb = set->fb; ret = crtc->funcs->set_config(set); if (ret == 0) { + crtc->primary->crtc = crtc; + /* crtc->fb must be updated by ->set_config, enforces this. */ - WARN_ON(fb != crtc->fb); + WARN_ON(fb != crtc->primary->fb); } list_for_each_entry(tmp, &crtc->dev->mode_config.crtc_list, head) { - if (tmp->fb) - drm_framebuffer_reference(tmp->fb); + if (tmp->primary->fb) + drm_framebuffer_reference(tmp->primary->fb); if (tmp->old_fb) drm_framebuffer_unreference(tmp->old_fb); } @@ -2177,14 +2255,19 @@ int drm_mode_set_config_internal(struct drm_mode_set *set) } EXPORT_SYMBOL(drm_mode_set_config_internal); -/* - * Checks that the framebuffer is big enough for the CRTC viewport - * (x, y, hdisplay, vdisplay) +/** + * drm_crtc_check_viewport - Checks that a framebuffer is big enough for the + * CRTC viewport + * @crtc: CRTC that framebuffer will be displayed on + * @x: x panning + * @y: y panning + * @mode: mode that framebuffer will be displayed under + * @fb: framebuffer to check size of */ -static int drm_crtc_check_viewport(const struct drm_crtc *crtc, - int x, int y, - const struct drm_display_mode *mode, - const struct drm_framebuffer *fb) +int drm_crtc_check_viewport(const struct drm_crtc *crtc, + int x, int y, + const struct drm_display_mode *mode, + const struct drm_framebuffer *fb) { int hdisplay, vdisplay; @@ -2215,6 +2298,7 @@ static int drm_crtc_check_viewport(const struct drm_crtc *crtc, return 0; } +EXPORT_SYMBOL(drm_crtc_check_viewport); /** * drm_mode_setcrtc - set CRTC configuration @@ -2266,12 +2350,12 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, /* If we have a mode we need a framebuffer. */ /* If we pass -1, set the mode with the currently bound fb */ if (crtc_req->fb_id == -1) { - if (!crtc->fb) { + if (!crtc->primary->fb) { DRM_DEBUG_KMS("CRTC doesn't have current FB\n"); ret = -EINVAL; goto out; } - fb = crtc->fb; + fb = crtc->primary->fb; /* Make refcounting symmetric with the lookup path. */ drm_framebuffer_reference(fb); } else { @@ -4065,7 +4149,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, crtc = obj_to_crtc(obj); mutex_lock(&crtc->mutex); - if (crtc->fb == NULL) { + if (crtc->primary->fb == NULL) { /* The framebuffer is currently unbound, presumably * due to a hotplug event, that userspace has not * yet discovered. @@ -4087,7 +4171,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, if (ret) goto out; - if (crtc->fb->pixel_format != fb->pixel_format) { + if (crtc->primary->fb->pixel_format != fb->pixel_format) { DRM_DEBUG_KMS("Page flip is not allowed to change frame buffer format.\n"); ret = -EINVAL; goto out; @@ -4120,7 +4204,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, (void (*) (struct drm_pending_event *)) kfree; } - old_fb = crtc->fb; + old_fb = crtc->primary->fb; ret = crtc->funcs->page_flip(crtc, fb, e, page_flip->flags); if (ret) { if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) { @@ -4138,7 +4222,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, * Failing to do so will screw with the reference counting * on framebuffers. */ - WARN_ON(crtc->fb != fb); + WARN_ON(crtc->primary->fb != fb); /* Unref only the old framebuffer. */ fb = NULL; } @@ -4527,6 +4611,7 @@ void drm_mode_config_init(struct drm_device *dev) drm_modeset_lock_all(dev); drm_mode_create_standard_connector_properties(dev); + drm_mode_create_standard_plane_properties(dev); drm_modeset_unlock_all(dev); /* Just to be sure */ @@ -4534,6 +4619,8 @@ void drm_mode_config_init(struct drm_device *dev) dev->mode_config.num_connector = 0; dev->mode_config.num_crtc = 0; dev->mode_config.num_encoder = 0; + dev->mode_config.num_overlay_plane = 0; + dev->mode_config.num_total_plane = 0; } EXPORT_SYMBOL(drm_mode_config_init); diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 003924025aa7..1fbe8427c70e 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -307,7 +307,7 @@ static void __drm_helper_disable_unused_functions(struct drm_device *dev) (*crtc_funcs->disable)(crtc); else (*crtc_funcs->dpms)(crtc, DRM_MODE_DPMS_OFF); - crtc->fb = NULL; + crtc->primary->fb = NULL; } } } @@ -651,19 +651,19 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) save_set.mode = &set->crtc->mode; save_set.x = set->crtc->x; save_set.y = set->crtc->y; - save_set.fb = set->crtc->fb; + save_set.fb = set->crtc->primary->fb; /* We should be able to check here if the fb has the same properties * and then just flip_or_move it */ - if (set->crtc->fb != set->fb) { + if (set->crtc->primary->fb != set->fb) { /* If we have no fb then treat it as a full mode set */ - if (set->crtc->fb == NULL) { + if (set->crtc->primary->fb == NULL) { DRM_DEBUG_KMS("crtc has no fb, full mode set\n"); mode_changed = true; } else if (set->fb == NULL) { mode_changed = true; } else if (set->fb->pixel_format != - set->crtc->fb->pixel_format) { + set->crtc->primary->fb->pixel_format) { mode_changed = true; } else fb_changed = true; @@ -765,13 +765,13 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) DRM_DEBUG_KMS("attempting to set mode from" " userspace\n"); drm_mode_debug_printmodeline(set->mode); - set->crtc->fb = set->fb; + set->crtc->primary->fb = set->fb; if (!drm_crtc_helper_set_mode(set->crtc, set->mode, set->x, set->y, save_set.fb)) { DRM_ERROR("failed to set mode on [CRTC:%d]\n", set->crtc->base.id); - set->crtc->fb = save_set.fb; + set->crtc->primary->fb = save_set.fb; ret = -EINVAL; goto fail; } @@ -786,13 +786,13 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) } else if (fb_changed) { set->crtc->x = set->x; set->crtc->y = set->y; - set->crtc->fb = set->fb; + set->crtc->primary->fb = set->fb; ret = crtc_funcs->mode_set_base(set->crtc, set->x, set->y, save_set.fb); if (ret != 0) { set->crtc->x = save_set.x; set->crtc->y = save_set.y; - set->crtc->fb = save_set.fb; + set->crtc->primary->fb = save_set.fb; goto fail; } } @@ -989,7 +989,7 @@ void drm_helper_resume_force_mode(struct drm_device *dev) continue; ret = drm_crtc_helper_set_mode(crtc, &crtc->mode, - crtc->x, crtc->y, crtc->fb); + crtc->x, crtc->y, crtc->primary->fb); /* Restoring the old config should never fail! */ if (ret == false) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 16f271e21b9c..9795c0636da2 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -232,7 +232,7 @@ static struct drm_framebuffer *drm_mode_config_fb(struct drm_crtc *crtc) list_for_each_entry(c, &dev->mode_config.crtc_list, head) { if (crtc->base.id == c->base.id) - return c->fb; + return c->primary->fb; } return NULL; @@ -291,7 +291,8 @@ bool drm_fb_helper_restore_fbdev_mode(struct drm_fb_helper *fb_helper) drm_warn_on_modeset_not_all_locked(dev); list_for_each_entry(plane, &dev->mode_config.plane_list, head) - drm_plane_force_disable(plane); + if (plane->type != DRM_PLANE_TYPE_PRIMARY) + drm_plane_force_disable(plane); for (i = 0; i < fb_helper->crtc_count; i++) { struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set; @@ -365,9 +366,9 @@ static bool drm_fb_helper_is_bound(struct drm_fb_helper *fb_helper) return false; list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - if (crtc->fb) + if (crtc->primary->fb) crtcs_bound++; - if (crtc->fb == fb_helper->fb) + if (crtc->primary->fb == fb_helper->fb) bound++; } diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index f4dc9b7a3831..93a42040bedb 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -328,6 +328,13 @@ drm_setclientcap(struct drm_device *dev, void *data, struct drm_file *file_priv) return -EINVAL; file_priv->stereo_allowed = req->value; break; + case DRM_CLIENT_CAP_UNIVERSAL_PLANES: + if (!drm_universal_planes) + return -EINVAL; + if (req->value > 1) + return -EINVAL; + file_priv->universal_planes = req->value; + break; default: return -EINVAL; } diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c new file mode 100644 index 000000000000..e768d35ff22e --- /dev/null +++ b/drivers/gpu/drm/drm_plane_helper.c @@ -0,0 +1,333 @@ +/* + * Copyright (C) 2014 Intel Corporation + * + * DRM universal plane helper functions + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include <linux/list.h> +#include <drm/drmP.h> +#include <drm/drm_rect.h> + +#define SUBPIXEL_MASK 0xffff + +/* + * This is the minimal list of formats that seem to be safe for modeset use + * with all current DRM drivers. Most hardware can actually support more + * formats than this and drivers may specify a more accurate list when + * creating the primary plane. However drivers that still call + * drm_plane_init() will use this minimal format list as the default. + */ +const static uint32_t safe_modeset_formats[] = { + DRM_FORMAT_XRGB8888, + DRM_FORMAT_ARGB8888, +}; + +/* + * Returns the connectors currently associated with a CRTC. This function + * should be called twice: once with a NULL connector list to retrieve + * the list size, and once with the properly allocated list to be filled in. + */ +static int get_connectors_for_crtc(struct drm_crtc *crtc, + struct drm_connector **connector_list, + int num_connectors) +{ + struct drm_device *dev = crtc->dev; + struct drm_connector *connector; + int count = 0; + + list_for_each_entry(connector, &dev->mode_config.connector_list, head) + if (connector->encoder && connector->encoder->crtc == crtc) { + if (connector_list != NULL && count < num_connectors) + *(connector_list++) = connector; + + count++; + } + + return count; +} + +/** + * drm_primary_helper_update() - Helper for primary plane update + * @plane: plane object to update + * @crtc: owning CRTC of owning plane + * @fb: framebuffer to flip onto plane + * @crtc_x: x offset of primary plane on crtc + * @crtc_y: y offset of primary plane on crtc + * @crtc_w: width of primary plane rectangle on crtc + * @crtc_h: height of primary plane rectangle on crtc + * @src_x: x offset of @fb for panning + * @src_y: y offset of @fb for panning + * @src_w: width of source rectangle in @fb + * @src_h: height of source rectangle in @fb + * + * Provides a default plane update handler for primary planes. This is handler + * is called in response to a userspace SetPlane operation on the plane with a + * non-NULL framebuffer. We call the driver's modeset handler to update the + * framebuffer. + * + * SetPlane() on a primary plane of a disabled CRTC is not supported, and will + * return an error. + * + * Note that we make some assumptions about hardware limitations that may not be + * true for all hardware -- + * 1) Primary plane cannot be repositioned. + * 2) Primary plane cannot be scaled. + * 3) Primary plane must cover the entire CRTC. + * 4) Subpixel positioning is not supported. + * Drivers for hardware that don't have these restrictions can provide their + * own implementation rather than using this helper. + * + * RETURNS: + * Zero on success, error code on failure + */ +int drm_primary_helper_update(struct drm_plane *plane, struct drm_crtc *crtc, + struct drm_framebuffer *fb, + int crtc_x, int crtc_y, + unsigned int crtc_w, unsigned int crtc_h, + uint32_t src_x, uint32_t src_y, + uint32_t src_w, uint32_t src_h) +{ + struct drm_mode_set set = { + .crtc = crtc, + .fb = fb, + .mode = &crtc->mode, + .x = src_x >> 16, + .y = src_y >> 16, + }; + struct drm_rect dest = { + .x1 = crtc_x, + .y1 = crtc_y, + .x2 = crtc_x + crtc_w, + .y2 = crtc_y + crtc_h, + }; + struct drm_rect clip = { + .x2 = crtc->mode.hdisplay, + .y2 = crtc->mode.vdisplay, + }; + struct drm_connector **connector_list; + struct drm_framebuffer *tmpfb; + int num_connectors, ret; + + if (!crtc->enabled) { + DRM_DEBUG_KMS("Cannot update primary plane of a disabled CRTC.\n"); + return -EINVAL; + } + + /* Disallow subpixel positioning */ + if ((src_x | src_y | src_w | src_h) & SUBPIXEL_MASK) { + DRM_DEBUG_KMS("Primary plane does not support subpixel positioning\n"); + return -EINVAL; + } + + /* Primary planes are locked to their owning CRTC */ + if (plane->possible_crtcs != drm_crtc_mask(crtc)) { + DRM_DEBUG_KMS("Cannot change primary plane CRTC\n"); + return -EINVAL; + } + + /* Disallow scaling */ + if (crtc_w != src_w || crtc_h != src_h) { + DRM_DEBUG_KMS("Can't scale primary plane\n"); + return -EINVAL; + } + + /* Make sure primary plane covers entire CRTC */ + drm_rect_intersect(&dest, &clip); + if (dest.x1 != 0 || dest.y1 != 0 || + dest.x2 != crtc->mode.hdisplay || dest.y2 != crtc->mode.vdisplay) { + DRM_DEBUG_KMS("Primary plane must cover entire CRTC\n"); + return -EINVAL; + } + + /* Framebuffer must be big enough to cover entire plane */ + ret = drm_crtc_check_viewport(crtc, crtc_x, crtc_y, &crtc->mode, fb); + if (ret) + return ret; + + /* Find current connectors for CRTC */ + num_connectors = get_connectors_for_crtc(crtc, NULL, 0); + BUG_ON(num_connectors == 0); + connector_list = kzalloc(num_connectors * sizeof(*connector_list), + GFP_KERNEL); + if (!connector_list) + return -ENOMEM; + get_connectors_for_crtc(crtc, connector_list, num_connectors); + + set.connectors = connector_list; + set.num_connectors = num_connectors; + + /* + * set_config() adjusts crtc->primary->fb; however the DRM setplane + * code that called us expects to handle the framebuffer update and + * reference counting; save and restore the current fb before + * calling it. + * + * N.B., we call set_config() directly here rather than using + * drm_mode_set_config_internal. We're reprogramming the same + * connectors that were already in use, so we shouldn't need the extra + * cross-CRTC fb refcounting to accomodate stealing connectors. + * drm_mode_setplane() already handles the basic refcounting for the + * framebuffers involved in this operation. + */ + tmpfb = plane->fb; + ret = crtc->funcs->set_config(&set); + plane->fb = tmpfb; + + kfree(connector_list); + return ret; +} +EXPORT_SYMBOL(drm_primary_helper_update); + +/** + * drm_primary_helper_disable() - Helper for primary plane disable + * @plane: plane to disable + * + * Provides a default plane disable handler for primary planes. This is handler + * is called in response to a userspace SetPlane operation on the plane with a + * NULL framebuffer parameter. We call the driver's modeset handler with a NULL + * framebuffer to disable the CRTC if no other planes are currently enabled. + * If other planes are still enabled on the same CRTC, we return -EBUSY. + * + * Note that some hardware may be able to disable the primary plane without + * disabling the whole CRTC. Drivers for such hardware should provide their + * own disable handler that disables just the primary plane (and they'll likely + * need to provide their own update handler as well to properly re-enable a + * disabled primary plane). + * + * RETURNS: + * Zero on success, error code on failure + */ +int drm_primary_helper_disable(struct drm_plane *plane) +{ + struct drm_plane *p; + struct drm_mode_set set = { + .crtc = plane->crtc, + .fb = NULL, + }; + + if (plane->crtc == NULL || plane->fb == NULL) + /* Already disabled */ + return 0; + + list_for_each_entry(p, &plane->dev->mode_config.plane_list, head) + if (p != plane && p->fb) { + DRM_DEBUG_KMS("Cannot disable primary plane while other planes are still active on CRTC.\n"); + return -EBUSY; + } + + /* + * N.B. We call set_config() directly here rather than + * drm_mode_set_config_internal() since drm_mode_setplane() already + * handles the basic refcounting and we don't need the special + * cross-CRTC refcounting (no chance of stealing connectors from + * other CRTC's with this update). + */ + return plane->crtc->funcs->set_config(&set); +} +EXPORT_SYMBOL(drm_primary_helper_disable); + +/** + * drm_primary_helper_destroy() - Helper for primary plane destruction + * @plane: plane to destroy + * + * Provides a default plane destroy handler for primary planes. This handler + * is called during CRTC destruction. We disable the primary plane, remove + * it from the DRM plane list, and deallocate the plane structure. + */ +void drm_primary_helper_destroy(struct drm_plane *plane) +{ + plane->funcs->disable_plane(plane); + drm_plane_cleanup(plane); + kfree(plane); +} +EXPORT_SYMBOL(drm_primary_helper_destroy); + +const struct drm_plane_funcs drm_primary_helper_funcs = { + .update_plane = drm_primary_helper_update, + .disable_plane = drm_primary_helper_disable, + .destroy = drm_primary_helper_destroy, +}; +EXPORT_SYMBOL(drm_primary_helper_funcs); + +/** + * drm_primary_helper_create_plane() - Create a generic primary plane + * @dev: drm device + * @formats: pixel formats supported, or NULL for a default safe list + * @num_formats: size of @formats; ignored if @formats is NULL + * + * Allocates and initializes a primary plane that can be used with the primary + * plane helpers. Drivers that wish to use driver-specific plane structures or + * provide custom handler functions may perform their own allocation and + * initialization rather than calling this function. + */ +struct drm_plane *drm_primary_helper_create_plane(struct drm_device *dev, + const uint32_t *formats, + int num_formats) +{ + struct drm_plane *primary; + int ret; + + primary = kzalloc(sizeof(*primary), GFP_KERNEL); + if (primary == NULL) { + DRM_DEBUG_KMS("Failed to allocate primary plane\n"); + return NULL; + } + + if (formats == NULL) { + formats = safe_modeset_formats; + num_formats = ARRAY_SIZE(safe_modeset_formats); + } + + /* possible_crtc's will be filled in later by crtc_init */ + ret = drm_plane_init(dev, primary, 0, &drm_primary_helper_funcs, + formats, num_formats, + DRM_PLANE_TYPE_PRIMARY); + if (ret) { + kfree(primary); + primary = NULL; + } + + return primary; +} +EXPORT_SYMBOL(drm_primary_helper_create_plane); + +/** + * drm_crtc_init - Legacy CRTC initialization function + * @dev: DRM device + * @crtc: CRTC object to init + * @funcs: callbacks for the new CRTC + * + * Initialize a CRTC object with a default helper-provided primary plane and no + * cursor plane. + * + * Returns: + * Zero on success, error code on failure. + */ +int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, + const struct drm_crtc_funcs *funcs) +{ + struct drm_plane *primary; + + primary = drm_primary_helper_create_plane(dev, NULL, 0); + return drm_crtc_init_with_planes(dev, crtc, primary, NULL, funcs); +} +EXPORT_SYMBOL(drm_crtc_init); diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index fac6f9834257..4c24c3ac1efa 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c @@ -45,6 +45,10 @@ EXPORT_SYMBOL(drm_debug); unsigned int drm_rnodes = 0; /* 1 to enable experimental render nodes API */ EXPORT_SYMBOL(drm_rnodes); +/* 1 to allow user space to request universal planes (experimental) */ +unsigned int drm_universal_planes = 0; +EXPORT_SYMBOL(drm_universal_planes); + unsigned int drm_vblank_offdelay = 5000; /* Default to 5000 msecs. */ EXPORT_SYMBOL(drm_vblank_offdelay); @@ -68,6 +72,7 @@ MODULE_PARM_DESC(timestamp_monotonic, "Use monotonic timestamps"); module_param_named(debug, drm_debug, int, 0600); module_param_named(rnodes, drm_rnodes, int, 0600); +module_param_named(universal_planes, drm_universal_planes, int, 0600); module_param_named(vblankoffdelay, drm_vblank_offdelay, int, 0600); module_param_named(timestamp_precision_usec, drm_timestamp_precision, int, 0600); module_param_named(timestamp_monotonic, drm_timestamp_monotonic, int, 0600); diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index 9cc92ae6b710..e930d4fe29c7 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -132,19 +132,19 @@ exynos_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, */ memcpy(&crtc->mode, adjusted_mode, sizeof(*adjusted_mode)); - crtc_w = crtc->fb->width - x; - crtc_h = crtc->fb->height - y; + crtc_w = crtc->primary->fb->width - x; + crtc_h = crtc->primary->fb->height - y; if (manager->ops->mode_set) manager->ops->mode_set(manager, &crtc->mode); - ret = exynos_plane_mode_set(plane, crtc, crtc->fb, 0, 0, crtc_w, crtc_h, + ret = exynos_plane_mode_set(plane, crtc, crtc->primary->fb, 0, 0, crtc_w, crtc_h, x, y, crtc_w, crtc_h); if (ret) return ret; plane->crtc = crtc; - plane->fb = crtc->fb; + plane->fb = crtc->primary->fb; return 0; } @@ -164,10 +164,10 @@ static int exynos_drm_crtc_mode_set_commit(struct drm_crtc *crtc, int x, int y, return -EPERM; } - crtc_w = crtc->fb->width - x; - crtc_h = crtc->fb->height - y; + crtc_w = crtc->primary->fb->width - x; + crtc_h = crtc->primary->fb->height - y; - ret = exynos_plane_mode_set(plane, crtc, crtc->fb, 0, 0, crtc_w, crtc_h, + ret = exynos_plane_mode_set(plane, crtc, crtc->primary->fb, 0, 0, crtc_w, crtc_h, x, y, crtc_w, crtc_h); if (ret) return ret; @@ -190,7 +190,7 @@ static void exynos_drm_crtc_disable(struct drm_crtc *crtc) exynos_drm_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); - list_for_each_entry(plane, &crtc->dev->mode_config.plane_list, head) { + drm_for_each_legacy_plane(plane, &crtc->dev->mode_config.plane_list) { if (plane->crtc != crtc) continue; @@ -218,7 +218,7 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc, struct drm_device *dev = crtc->dev; struct exynos_drm_private *dev_priv = dev->dev_private; struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); - struct drm_framebuffer *old_fb = crtc->fb; + struct drm_framebuffer *old_fb = crtc->primary->fb; int ret = -EINVAL; /* when the page flip is requested, crtc's dpms should be on */ @@ -249,11 +249,11 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc, atomic_set(&exynos_crtc->pending_flip, 1); spin_unlock_irq(&dev->event_lock); - crtc->fb = fb; + crtc->primary->fb = fb; ret = exynos_drm_crtc_mode_set_commit(crtc, crtc->x, crtc->y, NULL); if (ret) { - crtc->fb = old_fb; + crtc->primary->fb = old_fb; spin_lock_irq(&dev->event_lock); drm_vblank_put(dev, exynos_crtc->pipe); diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c index 835c0f1e88a7..7e282e3d6038 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c +++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c @@ -101,7 +101,7 @@ static void exynos_drm_encoder_disable(struct drm_encoder *encoder) exynos_drm_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); /* all planes connected to this encoder should be also disabled. */ - list_for_each_entry(plane, &dev->mode_config.plane_list, head) { + drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) { if (plane->crtc == encoder->crtc) plane->funcs->disable_plane(plane); } diff --git a/drivers/gpu/drm/gma500/cdv_intel_display.c b/drivers/gpu/drm/gma500/cdv_intel_display.c index 7ff91ce3b12a..66727328832d 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_display.c +++ b/drivers/gpu/drm/gma500/cdv_intel_display.c @@ -469,7 +469,7 @@ static bool cdv_intel_pipe_enabled(struct drm_device *dev, int pipe) crtc = dev_priv->pipe_to_crtc_mapping[pipe]; gma_crtc = to_gma_crtc(crtc); - if (crtc->fb == NULL || !gma_crtc->active) + if (crtc->primary->fb == NULL || !gma_crtc->active) return false; return true; } diff --git a/drivers/gpu/drm/gma500/cdv_intel_dp.c b/drivers/gpu/drm/gma500/cdv_intel_dp.c index 0490ce36b53f..9ff30c2efadb 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_dp.c +++ b/drivers/gpu/drm/gma500/cdv_intel_dp.c @@ -1693,7 +1693,7 @@ done: struct drm_crtc *crtc = encoder->base.crtc; drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, - crtc->fb); + crtc->primary->fb); } return 0; diff --git a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c index 968b42a5a32b..b99084b3f706 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c +++ b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c @@ -192,7 +192,7 @@ static int cdv_hdmi_set_property(struct drm_connector *connector, crtc->saved_mode.vdisplay != 0) { if (centre) { if (!drm_crtc_helper_set_mode(encoder->crtc, &crtc->saved_mode, - encoder->crtc->x, encoder->crtc->y, encoder->crtc->fb)) + encoder->crtc->x, encoder->crtc->y, encoder->crtc->primary->fb)) return -1; } else { struct drm_encoder_helper_funcs *helpers diff --git a/drivers/gpu/drm/gma500/cdv_intel_lvds.c b/drivers/gpu/drm/gma500/cdv_intel_lvds.c index 66a41c026834..8ecc920fc26d 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_lvds.c +++ b/drivers/gpu/drm/gma500/cdv_intel_lvds.c @@ -494,7 +494,7 @@ static int cdv_intel_lvds_set_property(struct drm_connector *connector, &crtc->saved_mode, encoder->crtc->x, encoder->crtc->y, - encoder->crtc->fb)) + encoder->crtc->primary->fb)) return -1; } } else if (!strcmp(property->name, "backlight") && encoder) { diff --git a/drivers/gpu/drm/gma500/gma_display.c b/drivers/gpu/drm/gma500/gma_display.c index d45476b72aad..9bb9bddd881a 100644 --- a/drivers/gpu/drm/gma500/gma_display.c +++ b/drivers/gpu/drm/gma500/gma_display.c @@ -59,7 +59,7 @@ int gma_pipe_set_base(struct drm_crtc *crtc, int x, int y, struct drm_device *dev = crtc->dev; struct drm_psb_private *dev_priv = dev->dev_private; struct gma_crtc *gma_crtc = to_gma_crtc(crtc); - struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb); + struct psb_framebuffer *psbfb = to_psb_fb(crtc->primary->fb); int pipe = gma_crtc->pipe; const struct psb_offset *map = &dev_priv->regmap[pipe]; unsigned long start, offset; @@ -70,7 +70,7 @@ int gma_pipe_set_base(struct drm_crtc *crtc, int x, int y, return 0; /* no fb bound */ - if (!crtc->fb) { + if (!crtc->primary->fb) { dev_err(dev->dev, "No FB bound\n"); goto gma_pipe_cleaner; } @@ -81,19 +81,19 @@ int gma_pipe_set_base(struct drm_crtc *crtc, int x, int y, if (ret < 0) goto gma_pipe_set_base_exit; start = psbfb->gtt->offset; - offset = y * crtc->fb->pitches[0] + x * (crtc->fb->bits_per_pixel / 8); + offset = y * crtc->primary->fb->pitches[0] + x * (crtc->primary->fb->bits_per_pixel / 8); - REG_WRITE(map->stride, crtc->fb->pitches[0]); + REG_WRITE(map->stride, crtc->primary->fb->pitches[0]); dspcntr = REG_READ(map->cntr); dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; - switch (crtc->fb->bits_per_pixel) { + switch (crtc->primary->fb->bits_per_pixel) { case 8: dspcntr |= DISPPLANE_8BPP; break; case 16: - if (crtc->fb->depth == 15) + if (crtc->primary->fb->depth == 15) dspcntr |= DISPPLANE_15_16BPP; else dspcntr |= DISPPLANE_16BPP; @@ -518,8 +518,8 @@ void gma_crtc_disable(struct drm_crtc *crtc) crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); - if (crtc->fb) { - gt = to_psb_fb(crtc->fb)->gtt; + if (crtc->primary->fb) { + gt = to_psb_fb(crtc->primary->fb)->gtt; psb_gtt_unpin(gt); } } diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_output.c b/drivers/gpu/drm/gma500/mdfld_dsi_output.c index 860a4ee9baaf..6e91b20ce2e5 100644 --- a/drivers/gpu/drm/gma500/mdfld_dsi_output.c +++ b/drivers/gpu/drm/gma500/mdfld_dsi_output.c @@ -287,7 +287,7 @@ static int mdfld_dsi_connector_set_property(struct drm_connector *connector, &gma_crtc->saved_mode, encoder->crtc->x, encoder->crtc->y, - encoder->crtc->fb)) + encoder->crtc->primary->fb)) goto set_prop_error; } else { struct drm_encoder_helper_funcs *funcs = diff --git a/drivers/gpu/drm/gma500/mdfld_intel_display.c b/drivers/gpu/drm/gma500/mdfld_intel_display.c index 321c00a944e9..8cc8a5abbc7b 100644 --- a/drivers/gpu/drm/gma500/mdfld_intel_display.c +++ b/drivers/gpu/drm/gma500/mdfld_intel_display.c @@ -166,7 +166,7 @@ static int mdfld__intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, struct drm_device *dev = crtc->dev; struct drm_psb_private *dev_priv = dev->dev_private; struct gma_crtc *gma_crtc = to_gma_crtc(crtc); - struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb); + struct psb_framebuffer *psbfb = to_psb_fb(crtc->primary->fb); int pipe = gma_crtc->pipe; const struct psb_offset *map = &dev_priv->regmap[pipe]; unsigned long start, offset; @@ -178,12 +178,12 @@ static int mdfld__intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, dev_dbg(dev->dev, "pipe = 0x%x.\n", pipe); /* no fb bound */ - if (!crtc->fb) { + if (!crtc->primary->fb) { dev_dbg(dev->dev, "No FB bound\n"); return 0; } - ret = check_fb(crtc->fb); + ret = check_fb(crtc->primary->fb); if (ret) return ret; @@ -196,18 +196,18 @@ static int mdfld__intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, return 0; start = psbfb->gtt->offset; - offset = y * crtc->fb->pitches[0] + x * (crtc->fb->bits_per_pixel / 8); + offset = y * crtc->primary->fb->pitches[0] + x * (crtc->primary->fb->bits_per_pixel / 8); - REG_WRITE(map->stride, crtc->fb->pitches[0]); + REG_WRITE(map->stride, crtc->primary->fb->pitches[0]); dspcntr = REG_READ(map->cntr); dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; - switch (crtc->fb->bits_per_pixel) { + switch (crtc->primary->fb->bits_per_pixel) { case 8: dspcntr |= DISPPLANE_8BPP; break; case 16: - if (crtc->fb->depth == 15) + if (crtc->primary->fb->depth == 15) dspcntr |= DISPPLANE_15_16BPP; else dspcntr |= DISPPLANE_16BPP; @@ -700,7 +700,7 @@ static int mdfld_crtc_mode_set(struct drm_crtc *crtc, } #endif - ret = check_fb(crtc->fb); + ret = check_fb(crtc->primary->fb); if (ret) return ret; diff --git a/drivers/gpu/drm/gma500/oaktrail_crtc.c b/drivers/gpu/drm/gma500/oaktrail_crtc.c index 8195e8592107..2de216c2374f 100644 --- a/drivers/gpu/drm/gma500/oaktrail_crtc.c +++ b/drivers/gpu/drm/gma500/oaktrail_crtc.c @@ -599,7 +599,7 @@ static int oaktrail_pipe_set_base(struct drm_crtc *crtc, struct drm_device *dev = crtc->dev; struct drm_psb_private *dev_priv = dev->dev_private; struct gma_crtc *gma_crtc = to_gma_crtc(crtc); - struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb); + struct psb_framebuffer *psbfb = to_psb_fb(crtc->primary->fb); int pipe = gma_crtc->pipe; const struct psb_offset *map = &dev_priv->regmap[pipe]; unsigned long start, offset; @@ -608,7 +608,7 @@ static int oaktrail_pipe_set_base(struct drm_crtc *crtc, int ret = 0; /* no fb bound */ - if (!crtc->fb) { + if (!crtc->primary->fb) { dev_dbg(dev->dev, "No FB bound\n"); return 0; } @@ -617,19 +617,19 @@ static int oaktrail_pipe_set_base(struct drm_crtc *crtc, return 0; start = psbfb->gtt->offset; - offset = y * crtc->fb->pitches[0] + x * (crtc->fb->bits_per_pixel / 8); + offset = y * crtc->primary->fb->pitches[0] + x * (crtc->primary->fb->bits_per_pixel / 8); - REG_WRITE(map->stride, crtc->fb->pitches[0]); + REG_WRITE(map->stride, crtc->primary->fb->pitches[0]); dspcntr = REG_READ(map->cntr); dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; - switch (crtc->fb->bits_per_pixel) { + switch (crtc->primary->fb->bits_per_pixel) { case 8: dspcntr |= DISPPLANE_8BPP; break; case 16: - if (crtc->fb->depth == 15) + if (crtc->primary->fb->depth == 15) dspcntr |= DISPPLANE_15_16BPP; else dspcntr |= DISPPLANE_16BPP; diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c index 21aed85eb96e..87b50ba64ed4 100644 --- a/drivers/gpu/drm/gma500/psb_intel_display.c +++ b/drivers/gpu/drm/gma500/psb_intel_display.c @@ -120,7 +120,7 @@ static int psb_intel_crtc_mode_set(struct drm_crtc *crtc, const struct gma_limit_t *limit; /* No scan out no play */ - if (crtc->fb == NULL) { + if (crtc->primary->fb == NULL) { crtc_funcs->mode_set_base(crtc, x, y, old_fb); return 0; } diff --git a/drivers/gpu/drm/gma500/psb_intel_lvds.c b/drivers/gpu/drm/gma500/psb_intel_lvds.c index 891a028a0826..d7778d0472c1 100644 --- a/drivers/gpu/drm/gma500/psb_intel_lvds.c +++ b/drivers/gpu/drm/gma500/psb_intel_lvds.c @@ -614,7 +614,7 @@ int psb_intel_lvds_set_property(struct drm_connector *connector, &crtc->saved_mode, encoder->crtc->x, encoder->crtc->y, - encoder->crtc->fb)) + encoder->crtc->primary->fb)) goto set_prop_error; } } else if (!strcmp(property->name, "backlight")) { diff --git a/drivers/gpu/drm/gma500/psb_intel_sdvo.c b/drivers/gpu/drm/gma500/psb_intel_sdvo.c index 681efecb718b..deeb0829b129 100644 --- a/drivers/gpu/drm/gma500/psb_intel_sdvo.c +++ b/drivers/gpu/drm/gma500/psb_intel_sdvo.c @@ -1844,7 +1844,7 @@ done: if (psb_intel_sdvo->base.base.crtc) { struct drm_crtc *crtc = psb_intel_sdvo->base.base.crtc; drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, - crtc->y, crtc->fb); + crtc->y, crtc->primary->fb); } return 0; diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index a90d31c78643..cacd4974cf23 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2172,8 +2172,8 @@ static void intel_crtc_info(struct seq_file *m, struct intel_crtc *intel_crtc) struct intel_encoder *intel_encoder; seq_printf(m, "\tfb: %d, pos: %dx%d, size: %dx%d\n", - crtc->fb->base.id, crtc->x, crtc->y, - crtc->fb->width, crtc->fb->height); + crtc->primary->fb->base.id, crtc->x, crtc->y, + crtc->primary->fb->width, crtc->primary->fb->height); for_each_encoder_on_crtc(dev, crtc, intel_encoder) intel_encoder_info(m, intel_crtc, intel_encoder); } diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index be2713f12e08..15d5e61eb415 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2367,8 +2367,8 @@ static void __always_unused i915_pageflip_stall_check(struct drm_device *dev, in } else { int dspaddr = DSPADDR(intel_crtc->plane); stall_detected = I915_READ(dspaddr) == (i915_gem_obj_ggtt_offset(obj) + - crtc->y * crtc->fb->pitches[0] + - crtc->x * crtc->fb->bits_per_pixel/8); + crtc->y * crtc->primary->fb->pitches[0] + + crtc->x * crtc->primary->fb->bits_per_pixel/8); } spin_unlock_irqrestore(&dev->event_lock, flags); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0868afbb19d2..3ffe5a6124f1 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -744,7 +744,7 @@ bool intel_crtc_active(struct drm_crtc *crtc) * We can ditch the crtc->fb check as soon as we can * properly reconstruct framebuffers. */ - return intel_crtc->active && crtc->fb && + return intel_crtc->active && crtc->primary->fb && intel_crtc->config.adjusted_mode.crtc_clock; } @@ -2291,8 +2291,8 @@ void intel_display_handle_reset(struct drm_device *dev) * disabling them without disabling the entire crtc) allow again * a NULL crtc->fb. */ - if (intel_crtc->active && crtc->fb) - dev_priv->display.update_plane(crtc, crtc->fb, + if (intel_crtc->active && crtc->primary->fb) + dev_priv->display.update_plane(crtc, crtc->primary->fb, crtc->x, crtc->y); mutex_unlock(&crtc->mutex); } @@ -2417,8 +2417,8 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, return ret; } - old_fb = crtc->fb; - crtc->fb = fb; + old_fb = crtc->primary->fb; + crtc->primary->fb = fb; crtc->x = x; crtc->y = y; @@ -3009,7 +3009,7 @@ static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc) struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; - if (crtc->fb == NULL) + if (crtc->primary->fb == NULL) return; WARN_ON(waitqueue_active(&dev_priv->pending_flip_queue)); @@ -3018,7 +3018,7 @@ static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc) !intel_crtc_has_pending_flip(crtc)); mutex_lock(&dev->struct_mutex); - intel_finish_fb(crtc->fb); + intel_finish_fb(crtc->primary->fb); mutex_unlock(&dev->struct_mutex); } @@ -3423,22 +3423,28 @@ static void intel_enable_planes(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; enum pipe pipe = to_intel_crtc(crtc)->pipe; + struct drm_plane *plane; struct intel_plane *intel_plane; - list_for_each_entry(intel_plane, &dev->mode_config.plane_list, base.head) + drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) { + intel_plane = to_intel_plane(plane); if (intel_plane->pipe == pipe) intel_plane_restore(&intel_plane->base); + } } static void intel_disable_planes(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; enum pipe pipe = to_intel_crtc(crtc)->pipe; + struct drm_plane *plane; struct intel_plane *intel_plane; - list_for_each_entry(intel_plane, &dev->mode_config.plane_list, base.head) + drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) { + intel_plane = to_intel_plane(plane); if (intel_plane->pipe == pipe) intel_plane_disable(&intel_plane->base); + } } void hsw_enable_ips(struct intel_crtc *crtc) @@ -4460,11 +4466,11 @@ static void intel_crtc_disable(struct drm_crtc *crtc) assert_cursor_disabled(dev_priv, to_intel_crtc(crtc)->pipe); assert_pipe_disabled(dev->dev_private, to_intel_crtc(crtc)->pipe); - if (crtc->fb) { + if (crtc->primary->fb) { mutex_lock(&dev->struct_mutex); - intel_unpin_fb_obj(to_intel_framebuffer(crtc->fb)->obj); + intel_unpin_fb_obj(to_intel_framebuffer(crtc->primary->fb)->obj); mutex_unlock(&dev->struct_mutex); - crtc->fb = NULL; + crtc->primary->fb = NULL; } /* Update computed state. */ @@ -8243,7 +8249,7 @@ void intel_mark_idle(struct drm_device *dev) goto out; list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - if (!crtc->fb) + if (!crtc->primary->fb) continue; intel_decrease_pllclock(crtc); @@ -8266,10 +8272,10 @@ void intel_mark_fb_busy(struct drm_i915_gem_object *obj, return; list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - if (!crtc->fb) + if (!crtc->primary->fb) continue; - if (to_intel_framebuffer(crtc->fb)->obj != obj) + if (to_intel_framebuffer(crtc->primary->fb)->obj != obj) continue; intel_increase_pllclock(crtc); @@ -8697,7 +8703,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, { struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_framebuffer *old_fb = crtc->fb; + struct drm_framebuffer *old_fb = crtc->primary->fb; struct drm_i915_gem_object *obj = to_intel_framebuffer(fb)->obj; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_unpin_work *work; @@ -8705,7 +8711,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, int ret; /* Can't change pixel format via MI display flips. */ - if (fb->pixel_format != crtc->fb->pixel_format) + if (fb->pixel_format != crtc->primary->fb->pixel_format) return -EINVAL; /* @@ -8713,8 +8719,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, * Note that pitch changes could also affect these register. */ if (INTEL_INFO(dev)->gen > 3 && - (fb->offsets[0] != crtc->fb->offsets[0] || - fb->pitches[0] != crtc->fb->pitches[0])) + (fb->offsets[0] != crtc->primary->fb->offsets[0] || + fb->pitches[0] != crtc->primary->fb->pitches[0])) return -EINVAL; if (i915_terminally_wedged(&dev_priv->gpu_error)) @@ -8757,7 +8763,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, drm_gem_object_reference(&work->old_fb_obj->base); drm_gem_object_reference(&obj->base); - crtc->fb = fb; + crtc->primary->fb = fb; work->pending_flip_obj = obj; @@ -8780,7 +8786,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, cleanup_pending: atomic_dec(&intel_crtc->unpin_work_count); - crtc->fb = old_fb; + crtc->primary->fb = old_fb; drm_gem_object_unreference(&work->old_fb_obj->base); drm_gem_object_unreference(&obj->base); mutex_unlock(&dev->struct_mutex); @@ -9797,7 +9803,7 @@ static int intel_set_mode(struct drm_crtc *crtc, void intel_crtc_restore_mode(struct drm_crtc *crtc) { - intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, crtc->fb); + intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, crtc->primary->fb); } #undef for_each_intel_crtc_masked @@ -9921,9 +9927,9 @@ intel_set_config_compute_mode_changes(struct drm_mode_set *set, * and then just flip_or_move it */ if (is_crtc_connector_off(set)) { config->mode_changed = true; - } else if (set->crtc->fb != set->fb) { + } else if (set->crtc->primary->fb != set->fb) { /* If we have no fb then treat it as a full mode set */ - if (set->crtc->fb == NULL) { + if (set->crtc->primary->fb == NULL) { struct intel_crtc *intel_crtc = to_intel_crtc(set->crtc); @@ -9937,7 +9943,7 @@ intel_set_config_compute_mode_changes(struct drm_mode_set *set, } else if (set->fb == NULL) { config->mode_changed = true; } else if (set->fb->pixel_format != - set->crtc->fb->pixel_format) { + set->crtc->primary->fb->pixel_format) { config->mode_changed = true; } else { config->fb_changed = true; @@ -10150,7 +10156,7 @@ static int intel_crtc_set_config(struct drm_mode_set *set) save_set.mode = &set->crtc->mode; save_set.x = set->crtc->x; save_set.y = set->crtc->y; - save_set.fb = set->crtc->fb; + save_set.fb = set->crtc->primary->fb; /* Compute whether we need a full modeset, only an fb base update or no * change at all. In the future we might also check whether only the @@ -11467,7 +11473,7 @@ void intel_modeset_setup_hw_state(struct drm_device *dev, dev_priv->pipe_to_crtc_mapping[pipe]; __intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, - crtc->fb); + crtc->primary->fb); } } else { intel_modeset_update_staged_output_state(dev); @@ -11516,7 +11522,7 @@ void intel_modeset_cleanup(struct drm_device *dev) list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { /* Skip inactive CRTCs */ - if (!crtc->fb) + if (!crtc->primary->fb) continue; intel_increase_pllclock(crtc); diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index f2833de3f7a9..f2fedc06976b 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1744,7 +1744,7 @@ static bool intel_edp_psr_match_conditions(struct intel_dp *intel_dp) struct drm_i915_private *dev_priv = dev->dev_private; struct drm_crtc *crtc = dig_port->base.base.crtc; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct drm_i915_gem_object *obj = to_intel_framebuffer(crtc->fb)->obj; + struct drm_i915_gem_object *obj = to_intel_framebuffer(crtc->primary->fb)->obj; struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base; dev_priv->psr.source_ok = false; @@ -1777,7 +1777,7 @@ static bool intel_edp_psr_match_conditions(struct intel_dp *intel_dp) return false; } - obj = to_intel_framebuffer(crtc->fb)->obj; + obj = to_intel_framebuffer(crtc->primary->fb)->obj; if (obj->tiling_mode != I915_TILING_X || obj->fence_reg == I915_FENCE_REG_NONE) { DRM_DEBUG_KMS("PSR condition failed: fb not tiled or fenced\n"); diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 312961a8472e..623cd328b196 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -606,14 +606,14 @@ static void update_colorkey(struct intel_overlay *overlay, { u32 key = overlay->color_key; - switch (overlay->crtc->base.fb->bits_per_pixel) { + switch (overlay->crtc->base.primary->fb->bits_per_pixel) { case 8: iowrite32(0, ®s->DCLRKV); iowrite32(CLK_RGB8I_MASK | DST_KEY_ENABLE, ®s->DCLRKM); break; case 16: - if (overlay->crtc->base.fb->depth == 15) { + if (overlay->crtc->base.primary->fb->depth == 15) { iowrite32(RGB15_TO_COLORKEY(key), ®s->DCLRKV); iowrite32(CLK_RGB15_MASK | DST_KEY_ENABLE, ®s->DCLRKM); diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index ad58ce3b7675..f070d5d769ce 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -92,7 +92,7 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_framebuffer *fb = crtc->fb; + struct drm_framebuffer *fb = crtc->primary->fb; struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); struct drm_i915_gem_object *obj = intel_fb->obj; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); @@ -149,7 +149,7 @@ static void g4x_enable_fbc(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_framebuffer *fb = crtc->fb; + struct drm_framebuffer *fb = crtc->primary->fb; struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); struct drm_i915_gem_object *obj = intel_fb->obj; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); @@ -221,7 +221,7 @@ static void ironlake_enable_fbc(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_framebuffer *fb = crtc->fb; + struct drm_framebuffer *fb = crtc->primary->fb; struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); struct drm_i915_gem_object *obj = intel_fb->obj; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); @@ -277,7 +277,7 @@ static void gen7_enable_fbc(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_framebuffer *fb = crtc->fb; + struct drm_framebuffer *fb = crtc->primary->fb; struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); struct drm_i915_gem_object *obj = intel_fb->obj; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); @@ -336,11 +336,11 @@ static void intel_fbc_work_fn(struct work_struct *__work) /* Double check that we haven't switched fb without cancelling * the prior work. */ - if (work->crtc->fb == work->fb) { + if (work->crtc->primary->fb == work->fb) { dev_priv->display.enable_fbc(work->crtc); dev_priv->fbc.plane = to_intel_crtc(work->crtc)->plane; - dev_priv->fbc.fb_id = work->crtc->fb->base.id; + dev_priv->fbc.fb_id = work->crtc->primary->fb->base.id; dev_priv->fbc.y = work->crtc->y; } @@ -393,7 +393,7 @@ static void intel_enable_fbc(struct drm_crtc *crtc) } work->crtc = crtc; - work->fb = crtc->fb; + work->fb = crtc->primary->fb; INIT_DELAYED_WORK(&work->work, intel_fbc_work_fn); dev_priv->fbc.fbc_work = work; @@ -499,14 +499,14 @@ void intel_update_fbc(struct drm_device *dev) } } - if (!crtc || crtc->fb == NULL) { + if (!crtc || crtc->primary->fb == NULL) { if (set_no_fbc_reason(dev_priv, FBC_NO_OUTPUT)) DRM_DEBUG_KMS("no output, disabling\n"); goto out_disable; } intel_crtc = to_intel_crtc(crtc); - fb = crtc->fb; + fb = crtc->primary->fb; intel_fb = to_intel_framebuffer(fb); obj = intel_fb->obj; adjusted_mode = &intel_crtc->config.adjusted_mode; @@ -1041,7 +1041,7 @@ static void pineview_update_wm(struct drm_crtc *unused_crtc) crtc = single_enabled_crtc(dev); if (crtc) { const struct drm_display_mode *adjusted_mode; - int pixel_size = crtc->fb->bits_per_pixel / 8; + int pixel_size = crtc->primary->fb->bits_per_pixel / 8; int clock; adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode; @@ -1121,7 +1121,7 @@ static bool g4x_compute_wm0(struct drm_device *dev, clock = adjusted_mode->crtc_clock; htotal = adjusted_mode->crtc_htotal; hdisplay = to_intel_crtc(crtc)->config.pipe_src_w; - pixel_size = crtc->fb->bits_per_pixel / 8; + pixel_size = crtc->primary->fb->bits_per_pixel / 8; /* Use the small buffer method to calculate plane watermark */ entries = ((clock * pixel_size / 1000) * display_latency_ns) / 1000; @@ -1208,7 +1208,7 @@ static bool g4x_compute_srwm(struct drm_device *dev, clock = adjusted_mode->crtc_clock; htotal = adjusted_mode->crtc_htotal; hdisplay = to_intel_crtc(crtc)->config.pipe_src_w; - pixel_size = crtc->fb->bits_per_pixel / 8; + pixel_size = crtc->primary->fb->bits_per_pixel / 8; line_time_us = max(htotal * 1000 / clock, 1); line_count = (latency_ns / line_time_us + 1000) / 1000; @@ -1247,7 +1247,7 @@ static bool vlv_compute_drain_latency(struct drm_device *dev, return false; clock = to_intel_crtc(crtc)->config.adjusted_mode.crtc_clock; - pixel_size = crtc->fb->bits_per_pixel / 8; /* BPP */ + pixel_size = crtc->primary->fb->bits_per_pixel / 8; /* BPP */ entries = (clock / 1000) * pixel_size; *plane_prec_mult = (entries > 256) ? @@ -1439,7 +1439,7 @@ static void i965_update_wm(struct drm_crtc *unused_crtc) int clock = adjusted_mode->crtc_clock; int htotal = adjusted_mode->crtc_htotal; int hdisplay = to_intel_crtc(crtc)->config.pipe_src_w; - int pixel_size = crtc->fb->bits_per_pixel / 8; + int pixel_size = crtc->primary->fb->bits_per_pixel / 8; unsigned long line_time_us; int entries; @@ -1512,7 +1512,7 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc) crtc = intel_get_crtc_for_plane(dev, 0); if (intel_crtc_active(crtc)) { const struct drm_display_mode *adjusted_mode; - int cpp = crtc->fb->bits_per_pixel / 8; + int cpp = crtc->primary->fb->bits_per_pixel / 8; if (IS_GEN2(dev)) cpp = 4; @@ -1528,7 +1528,7 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc) crtc = intel_get_crtc_for_plane(dev, 1); if (intel_crtc_active(crtc)) { const struct drm_display_mode *adjusted_mode; - int cpp = crtc->fb->bits_per_pixel / 8; + int cpp = crtc->primary->fb->bits_per_pixel / 8; if (IS_GEN2(dev)) cpp = 4; @@ -1565,7 +1565,7 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc) int clock = adjusted_mode->crtc_clock; int htotal = adjusted_mode->crtc_htotal; int hdisplay = to_intel_crtc(enabled)->config.pipe_src_w; - int pixel_size = enabled->fb->bits_per_pixel / 8; + int pixel_size = enabled->primary->fb->bits_per_pixel / 8; unsigned long line_time_us; int entries; @@ -2117,7 +2117,7 @@ static void ilk_compute_wm_parameters(struct drm_crtc *crtc, if (p->active) { p->pipe_htotal = intel_crtc->config.adjusted_mode.crtc_htotal; p->pixel_rate = ilk_pipe_pixel_rate(dev, crtc); - p->pri.bytes_per_pixel = crtc->fb->bits_per_pixel / 8; + p->pri.bytes_per_pixel = crtc->primary->fb->bits_per_pixel / 8; p->cur.bytes_per_pixel = 4; p->pri.horiz_pixels = intel_crtc->config.pipe_src_w; p->cur.horiz_pixels = 64; @@ -2129,7 +2129,7 @@ static void ilk_compute_wm_parameters(struct drm_crtc *crtc, list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) config->num_pipes_active += intel_crtc_active(crtc); - list_for_each_entry(plane, &dev->mode_config.plane_list, head) { + drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) { struct intel_plane *intel_plane = to_intel_plane(plane); if (intel_plane->pipe == pipe) diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index 968374776db9..a034ed408252 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -29,7 +29,7 @@ static void mga_crtc_load_lut(struct drm_crtc *crtc) struct mga_crtc *mga_crtc = to_mga_crtc(crtc); struct drm_device *dev = crtc->dev; struct mga_device *mdev = dev->dev_private; - struct drm_framebuffer *fb = crtc->fb; + struct drm_framebuffer *fb = crtc->primary->fb; int i; if (!crtc->enabled) @@ -742,7 +742,7 @@ static int mga_crtc_do_set_base(struct drm_crtc *crtc, mgag200_bo_unreserve(bo); } - mga_fb = to_mga_framebuffer(crtc->fb); + mga_fb = to_mga_framebuffer(crtc->primary->fb); obj = mga_fb->obj; bo = gem_to_mga_bo(obj); @@ -805,7 +805,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, /* 0x48: */ 0, 0, 0, 0, 0, 0, 0, 0 }; - bppshift = mdev->bpp_shifts[(crtc->fb->bits_per_pixel >> 3) - 1]; + bppshift = mdev->bpp_shifts[(crtc->primary->fb->bits_per_pixel >> 3) - 1]; switch (mdev->type) { case G200_SE_A: @@ -843,12 +843,12 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, break; } - switch (crtc->fb->bits_per_pixel) { + switch (crtc->primary->fb->bits_per_pixel) { case 8: dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_8bits; break; case 16: - if (crtc->fb->depth == 15) + if (crtc->primary->fb->depth == 15) dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_15bits; else dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_16bits; @@ -896,8 +896,8 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, WREG_SEQ(3, 0); WREG_SEQ(4, 0xe); - pitch = crtc->fb->pitches[0] / (crtc->fb->bits_per_pixel / 8); - if (crtc->fb->bits_per_pixel == 24) + pitch = crtc->primary->fb->pitches[0] / (crtc->primary->fb->bits_per_pixel / 8); + if (crtc->primary->fb->bits_per_pixel == 24) pitch = (pitch * 3) >> (4 - bppshift); else pitch = pitch >> (4 - bppshift); @@ -974,7 +974,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, ((vdisplay & 0xc00) >> 7) | ((vsyncstart & 0xc00) >> 5) | ((vdisplay & 0x400) >> 3); - if (crtc->fb->bits_per_pixel == 24) + if (crtc->primary->fb->bits_per_pixel == 24) ext_vga[3] = (((1 << bppshift) * 3) - 1) | 0x80; else ext_vga[3] = ((1 << bppshift) - 1) | 0x80; @@ -1034,9 +1034,9 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, u32 bpp; u32 mb; - if (crtc->fb->bits_per_pixel > 16) + if (crtc->primary->fb->bits_per_pixel > 16) bpp = 32; - else if (crtc->fb->bits_per_pixel > 8) + else if (crtc->primary->fb->bits_per_pixel > 8) bpp = 16; else bpp = 8; @@ -1277,8 +1277,8 @@ static void mga_crtc_disable(struct drm_crtc *crtc) int ret; DRM_DEBUG_KMS("\n"); mga_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); - if (crtc->fb) { - struct mga_framebuffer *mga_fb = to_mga_framebuffer(crtc->fb); + if (crtc->primary->fb) { + struct mga_framebuffer *mga_fb = to_mga_framebuffer(crtc->primary->fb); struct drm_gem_object *obj = mga_fb->obj; struct mgag200_bo *bo = gem_to_mga_bo(obj); ret = mgag200_bo_reserve(bo, false); @@ -1287,7 +1287,7 @@ static void mga_crtc_disable(struct drm_crtc *crtc) mgag200_bo_push_sysram(bo); mgag200_bo_unreserve(bo); } - crtc->fb = NULL; + crtc->primary->fb = NULL; } /* These provide the minimum set of functions required to handle a CRTC */ diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c index 84c5b13b33c9..3e6c0f3ed592 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c @@ -120,7 +120,7 @@ static void update_fb(struct drm_crtc *crtc, struct drm_framebuffer *new_fb) /* grab reference to incoming scanout fb: */ drm_framebuffer_reference(new_fb); - mdp4_crtc->base.fb = new_fb; + mdp4_crtc->base.primary->fb = new_fb; mdp4_crtc->fb = new_fb; if (old_fb) @@ -182,7 +182,7 @@ static void pageflip_cb(struct msm_fence_cb *cb) struct mdp4_crtc *mdp4_crtc = container_of(cb, struct mdp4_crtc, pageflip_cb); struct drm_crtc *crtc = &mdp4_crtc->base; - struct drm_framebuffer *fb = crtc->fb; + struct drm_framebuffer *fb = crtc->primary->fb; if (!fb) return; @@ -348,14 +348,14 @@ static int mdp4_crtc_mode_set(struct drm_crtc *crtc, mode->type, mode->flags); /* grab extra ref for update_scanout() */ - drm_framebuffer_reference(crtc->fb); + drm_framebuffer_reference(crtc->primary->fb); - ret = mdp4_plane_mode_set(mdp4_crtc->plane, crtc, crtc->fb, + ret = mdp4_plane_mode_set(mdp4_crtc->plane, crtc, crtc->primary->fb, 0, 0, mode->hdisplay, mode->vdisplay, x << 16, y << 16, mode->hdisplay << 16, mode->vdisplay << 16); if (ret) { - drm_framebuffer_unreference(crtc->fb); + drm_framebuffer_unreference(crtc->primary->fb); dev_err(crtc->dev->dev, "%s: failed to set mode on plane: %d\n", mdp4_crtc->name, ret); return ret; @@ -368,7 +368,7 @@ static int mdp4_crtc_mode_set(struct drm_crtc *crtc, /* take data from pipe: */ mdp4_write(mdp4_kms, REG_MDP4_DMA_SRC_BASE(dma), 0); mdp4_write(mdp4_kms, REG_MDP4_DMA_SRC_STRIDE(dma), - crtc->fb->pitches[0]); + crtc->primary->fb->pitches[0]); mdp4_write(mdp4_kms, REG_MDP4_DMA_DST_SIZE(dma), MDP4_DMA_DST_SIZE_WIDTH(0) | MDP4_DMA_DST_SIZE_HEIGHT(0)); @@ -378,7 +378,7 @@ static int mdp4_crtc_mode_set(struct drm_crtc *crtc, MDP4_OVLP_SIZE_WIDTH(mode->hdisplay) | MDP4_OVLP_SIZE_HEIGHT(mode->vdisplay)); mdp4_write(mdp4_kms, REG_MDP4_OVLP_STRIDE(ovlp), - crtc->fb->pitches[0]); + crtc->primary->fb->pitches[0]); mdp4_write(mdp4_kms, REG_MDP4_OVLP_CFG(ovlp), 1); @@ -388,8 +388,8 @@ static int mdp4_crtc_mode_set(struct drm_crtc *crtc, mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(2), 0x00ff0000); } - update_fb(crtc, crtc->fb); - update_scanout(crtc, crtc->fb); + update_fb(crtc, crtc->primary->fb); + update_scanout(crtc, crtc->primary->fb); return 0; } @@ -420,19 +420,19 @@ static int mdp4_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, int ret; /* grab extra ref for update_scanout() */ - drm_framebuffer_reference(crtc->fb); + drm_framebuffer_reference(crtc->primary->fb); - ret = mdp4_plane_mode_set(plane, crtc, crtc->fb, + ret = mdp4_plane_mode_set(plane, crtc, crtc->primary->fb, 0, 0, mode->hdisplay, mode->vdisplay, x << 16, y << 16, mode->hdisplay << 16, mode->vdisplay << 16); if (ret) { - drm_framebuffer_unreference(crtc->fb); + drm_framebuffer_unreference(crtc->primary->fb); return ret; } - update_fb(crtc, crtc->fb); - update_scanout(crtc, crtc->fb); + update_fb(crtc, crtc->primary->fb); + update_scanout(crtc, crtc->primary->fb); return 0; } @@ -740,6 +740,9 @@ void mdp4_crtc_attach(struct drm_crtc *crtc, struct drm_plane *plane) void mdp4_crtc_detach(struct drm_crtc *crtc, struct drm_plane *plane) { + /* don't actually detatch our primary plane: */ + if (to_mdp4_crtc(crtc)->plane == plane) + return; set_attach(crtc, mdp4_plane_pipe(plane), NULL); } @@ -791,7 +794,7 @@ struct drm_crtc *mdp4_crtc_init(struct drm_device *dev, INIT_FENCE_CB(&mdp4_crtc->pageflip_cb, pageflip_cb); - drm_crtc_init(dev, crtc, &mdp4_crtc_funcs); + drm_crtc_init_with_planes(dev, crtc, plane, NULL, &mdp4_crtc_funcs); drm_crtc_helper_add(crtc, &mdp4_crtc_helper_funcs); mdp4_plane_install_properties(mdp4_crtc->plane, &crtc->base); diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c index 1e893dd13859..66f33dba1ebb 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c @@ -222,6 +222,7 @@ struct drm_plane *mdp4_plane_init(struct drm_device *dev, struct drm_plane *plane = NULL; struct mdp4_plane *mdp4_plane; int ret; + enum drm_plane_type type; mdp4_plane = kzalloc(sizeof(*mdp4_plane), GFP_KERNEL); if (!mdp4_plane) { @@ -237,9 +238,10 @@ struct drm_plane *mdp4_plane_init(struct drm_device *dev, mdp4_plane->nformats = mdp4_get_formats(pipe_id, mdp4_plane->formats, ARRAY_SIZE(mdp4_plane->formats)); - drm_plane_init(dev, plane, 0xff, &mdp4_plane_funcs, - mdp4_plane->formats, mdp4_plane->nformats, - private_plane); + type = private_plane ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY; + drm_universal_plane_init(dev, plane, 0xff, &mdp4_plane_funcs, + mdp4_plane->formats, mdp4_plane->nformats, + type); mdp4_plane_install_properties(plane, &plane->base); diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c index f2794021f086..6ea10bdb6e8f 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c @@ -102,7 +102,7 @@ static void update_fb(struct drm_crtc *crtc, struct drm_framebuffer *new_fb) /* grab reference to incoming scanout fb: */ drm_framebuffer_reference(new_fb); - mdp5_crtc->base.fb = new_fb; + mdp5_crtc->base.primary->fb = new_fb; mdp5_crtc->fb = new_fb; if (old_fb) @@ -289,14 +289,14 @@ static int mdp5_crtc_mode_set(struct drm_crtc *crtc, mode->type, mode->flags); /* grab extra ref for update_scanout() */ - drm_framebuffer_reference(crtc->fb); + drm_framebuffer_reference(crtc->primary->fb); - ret = mdp5_plane_mode_set(mdp5_crtc->plane, crtc, crtc->fb, + ret = mdp5_plane_mode_set(mdp5_crtc->plane, crtc, crtc->primary->fb, 0, 0, mode->hdisplay, mode->vdisplay, x << 16, y << 16, mode->hdisplay << 16, mode->vdisplay << 16); if (ret) { - drm_framebuffer_unreference(crtc->fb); + drm_framebuffer_unreference(crtc->primary->fb); dev_err(crtc->dev->dev, "%s: failed to set mode on plane: %d\n", mdp5_crtc->name, ret); return ret; @@ -306,8 +306,8 @@ static int mdp5_crtc_mode_set(struct drm_crtc *crtc, MDP5_LM_OUT_SIZE_WIDTH(mode->hdisplay) | MDP5_LM_OUT_SIZE_HEIGHT(mode->vdisplay)); - update_fb(crtc, crtc->fb); - update_scanout(crtc, crtc->fb); + update_fb(crtc, crtc->primary->fb); + update_scanout(crtc, crtc->primary->fb); return 0; } @@ -338,19 +338,19 @@ static int mdp5_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, int ret; /* grab extra ref for update_scanout() */ - drm_framebuffer_reference(crtc->fb); + drm_framebuffer_reference(crtc->primary->fb); - ret = mdp5_plane_mode_set(plane, crtc, crtc->fb, + ret = mdp5_plane_mode_set(plane, crtc, crtc->primary->fb, 0, 0, mode->hdisplay, mode->vdisplay, x << 16, y << 16, mode->hdisplay << 16, mode->vdisplay << 16); if (ret) { - drm_framebuffer_unreference(crtc->fb); + drm_framebuffer_unreference(crtc->primary->fb); return ret; } - update_fb(crtc, crtc->fb); - update_scanout(crtc, crtc->fb); + update_fb(crtc, crtc->primary->fb); + update_scanout(crtc, crtc->primary->fb); return 0; } @@ -524,6 +524,9 @@ void mdp5_crtc_attach(struct drm_crtc *crtc, struct drm_plane *plane) void mdp5_crtc_detach(struct drm_crtc *crtc, struct drm_plane *plane) { + /* don't actually detatch our primary plane: */ + if (to_mdp5_crtc(crtc)->plane == plane) + return; set_attach(crtc, mdp5_plane_pipe(plane), NULL); } @@ -559,7 +562,7 @@ struct drm_crtc *mdp5_crtc_init(struct drm_device *dev, INIT_FENCE_CB(&mdp5_crtc->pageflip_cb, pageflip_cb); - drm_crtc_init(dev, crtc, &mdp5_crtc_funcs); + drm_crtc_init_with_planes(dev, crtc, plane, NULL, &mdp5_crtc_funcs); drm_crtc_helper_add(crtc, &mdp5_crtc_helper_funcs); mdp5_plane_install_properties(mdp5_crtc->plane, &crtc->base); diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c index 0ac8bb5e7e85..47f7bbb9c15a 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c @@ -358,6 +358,7 @@ struct drm_plane *mdp5_plane_init(struct drm_device *dev, struct drm_plane *plane = NULL; struct mdp5_plane *mdp5_plane; int ret; + enum drm_plane_type type; mdp5_plane = kzalloc(sizeof(*mdp5_plane), GFP_KERNEL); if (!mdp5_plane) { @@ -373,9 +374,10 @@ struct drm_plane *mdp5_plane_init(struct drm_device *dev, mdp5_plane->nformats = mdp5_get_formats(pipe, mdp5_plane->formats, ARRAY_SIZE(mdp5_plane->formats)); - drm_plane_init(dev, plane, 0xff, &mdp5_plane_funcs, - mdp5_plane->formats, mdp5_plane->nformats, - private_plane); + type = private_plane ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY; + drm_universal_plane_init(dev, plane, 0xff, &mdp5_plane_funcs, + mdp5_plane->formats, mdp5_plane->nformats, + type); mdp5_plane_install_properties(plane, &plane->base); diff --git a/drivers/gpu/drm/nouveau/dispnv04/crtc.c b/drivers/gpu/drm/nouveau/dispnv04/crtc.c index 1caef1fd139e..41be3424c906 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/crtc.c +++ b/drivers/gpu/drm/nouveau/dispnv04/crtc.c @@ -239,7 +239,7 @@ nv_crtc_mode_set_vga(struct drm_crtc *crtc, struct drm_display_mode *mode) struct drm_device *dev = crtc->dev; struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); struct nv04_crtc_reg *regp = &nv04_display(dev)->mode_reg.crtc_reg[nv_crtc->index]; - struct drm_framebuffer *fb = crtc->fb; + struct drm_framebuffer *fb = crtc->primary->fb; /* Calculate our timings */ int horizDisplay = (mode->crtc_hdisplay >> 3) - 1; @@ -574,7 +574,7 @@ nv_crtc_mode_set_regs(struct drm_crtc *crtc, struct drm_display_mode * mode) regp->CRTC[NV_CIO_CRE_86] = 0x1; } - regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] = (crtc->fb->depth + 1) / 8; + regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] = (crtc->primary->fb->depth + 1) / 8; /* Enable slaved mode (called MODE_TV in nv4ref.h) */ if (lvds_output || tmds_output || tv_output) regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] |= (1 << 7); @@ -588,7 +588,7 @@ nv_crtc_mode_set_regs(struct drm_crtc *crtc, struct drm_display_mode * mode) regp->ramdac_gen_ctrl = NV_PRAMDAC_GENERAL_CONTROL_BPC_8BITS | NV_PRAMDAC_GENERAL_CONTROL_VGA_STATE_SEL | NV_PRAMDAC_GENERAL_CONTROL_PIXMIX_ON; - if (crtc->fb->depth == 16) + if (crtc->primary->fb->depth == 16) regp->ramdac_gen_ctrl |= NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL; if (nv_device(drm->device)->chipset >= 0x11) regp->ramdac_gen_ctrl |= NV_PRAMDAC_GENERAL_CONTROL_PIPE_LONG; @@ -609,7 +609,7 @@ static int nv_crtc_swap_fbs(struct drm_crtc *crtc, struct drm_framebuffer *old_fb) { struct nv04_display *disp = nv04_display(crtc->dev); - struct nouveau_framebuffer *nvfb = nouveau_framebuffer(crtc->fb); + struct nouveau_framebuffer *nvfb = nouveau_framebuffer(crtc->primary->fb); struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); int ret; @@ -808,7 +808,7 @@ nv_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, uint32_t start, * mark the lut values as dirty by setting depth==0, and it'll be * uploaded on the first mode_set_base() */ - if (!nv_crtc->base.fb) { + if (!nv_crtc->base.primary->fb) { nv_crtc->lut.depth = 0; return; } @@ -832,7 +832,7 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc, NV_DEBUG(drm, "index %d\n", nv_crtc->index); /* no fb bound */ - if (!atomic && !crtc->fb) { + if (!atomic && !crtc->primary->fb) { NV_DEBUG(drm, "No FB bound\n"); return 0; } @@ -844,8 +844,8 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc, drm_fb = passed_fb; fb = nouveau_framebuffer(passed_fb); } else { - drm_fb = crtc->fb; - fb = nouveau_framebuffer(crtc->fb); + drm_fb = crtc->primary->fb; + fb = nouveau_framebuffer(crtc->primary->fb); } nv_crtc->fb.offset = fb->nvbo->bo.offset; @@ -857,9 +857,9 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc, /* Update the framebuffer format. */ regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] &= ~3; - regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] |= (crtc->fb->depth + 1) / 8; + regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] |= (crtc->primary->fb->depth + 1) / 8; regp->ramdac_gen_ctrl &= ~NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL; - if (crtc->fb->depth == 16) + if (crtc->primary->fb->depth == 16) regp->ramdac_gen_ctrl |= NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL; crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_PIXEL_INDEX); NVWriteRAMDAC(dev, nv_crtc->index, NV_PRAMDAC_GENERAL_CONTROL, diff --git a/drivers/gpu/drm/nouveau/dispnv04/dfp.c b/drivers/gpu/drm/nouveau/dispnv04/dfp.c index 7fdc51e2a571..a2d669b4acf2 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/dfp.c +++ b/drivers/gpu/drm/nouveau/dispnv04/dfp.c @@ -415,7 +415,7 @@ static void nv04_dfp_mode_set(struct drm_encoder *encoder, /* Output property. */ if ((nv_connector->dithering_mode == DITHERING_MODE_ON) || (nv_connector->dithering_mode == DITHERING_MODE_AUTO && - encoder->crtc->fb->depth > connector->display_info.bpc * 3)) { + encoder->crtc->primary->fb->depth > connector->display_info.bpc * 3)) { if (nv_device(drm->device)->chipset == 0x11) regp->dither = savep->dither | 0x00010000; else { diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index b1547b032150..3ff030dc1ee3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -571,7 +571,7 @@ nouveau_display_suspend(struct drm_device *dev) list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { struct nouveau_framebuffer *nouveau_fb; - nouveau_fb = nouveau_framebuffer(crtc->fb); + nouveau_fb = nouveau_framebuffer(crtc->primary->fb); if (!nouveau_fb || !nouveau_fb->nvbo) continue; @@ -598,7 +598,7 @@ nouveau_display_repin(struct drm_device *dev) list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { struct nouveau_framebuffer *nouveau_fb; - nouveau_fb = nouveau_framebuffer(crtc->fb); + nouveau_fb = nouveau_framebuffer(crtc->primary->fb); if (!nouveau_fb || !nouveau_fb->nvbo) continue; @@ -695,7 +695,7 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, const int swap_interval = (flags & DRM_MODE_PAGE_FLIP_ASYNC) ? 0 : 1; struct drm_device *dev = crtc->dev; struct nouveau_drm *drm = nouveau_drm(dev); - struct nouveau_bo *old_bo = nouveau_framebuffer(crtc->fb)->nvbo; + struct nouveau_bo *old_bo = nouveau_framebuffer(crtc->primary->fb)->nvbo; struct nouveau_bo *new_bo = nouveau_framebuffer(fb)->nvbo; struct nouveau_page_flip_state *s; struct nouveau_channel *chan = drm->channel; @@ -769,7 +769,7 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, goto fail_unreserve; /* Update the crtc struct and cleanup */ - crtc->fb = fb; + crtc->primary->fb = fb; nouveau_bo_fence(old_bo, fence); ttm_bo_unreserve(&old_bo->bo); diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 2dccafc6e9db..58af547b0b93 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -651,7 +651,7 @@ nv50_crtc_set_dither(struct nouveau_crtc *nv_crtc, bool update) nv_connector = nouveau_crtc_connector_get(nv_crtc); connector = &nv_connector->base; if (nv_connector->dithering_mode == DITHERING_MODE_AUTO) { - if (nv_crtc->base.fb->depth > connector->display_info.bpc * 3) + if (nv_crtc->base.primary->fb->depth > connector->display_info.bpc * 3) mode = DITHERING_MODE_DYNAMIC2X2; } else { mode = nv_connector->dithering_mode; @@ -785,7 +785,8 @@ nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, bool update) if (update) { nv50_display_flip_stop(crtc); - nv50_display_flip_next(crtc, crtc->fb, NULL, 1); + nv50_display_flip_next(crtc, crtc->primary->fb, + NULL, 1); } } @@ -1028,7 +1029,7 @@ nv50_crtc_commit(struct drm_crtc *crtc) } nv50_crtc_cursor_show_hide(nv_crtc, nv_crtc->cursor.visible, true); - nv50_display_flip_next(crtc, crtc->fb, NULL, 1); + nv50_display_flip_next(crtc, crtc->primary->fb, NULL, 1); } static bool @@ -1042,7 +1043,7 @@ nv50_crtc_mode_fixup(struct drm_crtc *crtc, const struct drm_display_mode *mode, static int nv50_crtc_swap_fbs(struct drm_crtc *crtc, struct drm_framebuffer *old_fb) { - struct nouveau_framebuffer *nvfb = nouveau_framebuffer(crtc->fb); + struct nouveau_framebuffer *nvfb = nouveau_framebuffer(crtc->primary->fb); struct nv50_head *head = nv50_head(crtc); int ret; @@ -1139,7 +1140,7 @@ nv50_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *umode, nv50_crtc_set_dither(nv_crtc, false); nv50_crtc_set_scale(nv_crtc, false); nv50_crtc_set_color_vibrance(nv_crtc, false); - nv50_crtc_set_image(nv_crtc, crtc->fb, x, y, false); + nv50_crtc_set_image(nv_crtc, crtc->primary->fb, x, y, false); return 0; } @@ -1151,7 +1152,7 @@ nv50_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); int ret; - if (!crtc->fb) { + if (!crtc->primary->fb) { NV_DEBUG(drm, "No FB bound\n"); return 0; } @@ -1161,8 +1162,8 @@ nv50_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, return ret; nv50_display_flip_stop(crtc); - nv50_crtc_set_image(nv_crtc, crtc->fb, x, y, true); - nv50_display_flip_next(crtc, crtc->fb, NULL, 1); + nv50_crtc_set_image(nv_crtc, crtc->primary->fb, x, y, true); + nv50_display_flip_next(crtc, crtc->primary->fb, NULL, 1); return 0; } diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 4313bb0a49a6..355157e4f78d 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -245,7 +245,7 @@ static int omap_crtc_mode_set(struct drm_crtc *crtc, copy_timings_drm_to_omap(&omap_crtc->timings, mode); omap_crtc->full_update = true; - return omap_plane_mode_set(omap_crtc->plane, crtc, crtc->fb, + return omap_plane_mode_set(omap_crtc->plane, crtc, crtc->primary->fb, 0, 0, mode->hdisplay, mode->vdisplay, x << 16, y << 16, mode->hdisplay << 16, mode->vdisplay << 16, @@ -273,7 +273,7 @@ static int omap_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, struct drm_plane *plane = omap_crtc->plane; struct drm_display_mode *mode = &crtc->mode; - return omap_plane_mode_set(plane, crtc, crtc->fb, + return omap_plane_mode_set(plane, crtc, crtc->primary->fb, 0, 0, mode->hdisplay, mode->vdisplay, x << 16, y << 16, mode->hdisplay << 16, mode->vdisplay << 16, @@ -308,14 +308,14 @@ static void page_flip_worker(struct work_struct *work) struct drm_gem_object *bo; mutex_lock(&crtc->mutex); - omap_plane_mode_set(omap_crtc->plane, crtc, crtc->fb, + omap_plane_mode_set(omap_crtc->plane, crtc, crtc->primary->fb, 0, 0, mode->hdisplay, mode->vdisplay, crtc->x << 16, crtc->y << 16, mode->hdisplay << 16, mode->vdisplay << 16, vblank_cb, crtc); mutex_unlock(&crtc->mutex); - bo = omap_framebuffer_bo(crtc->fb, 0); + bo = omap_framebuffer_bo(crtc->primary->fb, 0); drm_gem_object_unreference_unlocked(bo); } @@ -336,9 +336,10 @@ static int omap_crtc_page_flip_locked(struct drm_crtc *crtc, { struct drm_device *dev = crtc->dev; struct omap_crtc *omap_crtc = to_omap_crtc(crtc); + struct drm_plane *primary = crtc->primary; struct drm_gem_object *bo; - DBG("%d -> %d (event=%p)", crtc->fb ? crtc->fb->base.id : -1, + DBG("%d -> %d (event=%p)", primary->fb ? primary->fb->base.id : -1, fb->base.id, event); if (omap_crtc->old_fb) { @@ -347,7 +348,7 @@ static int omap_crtc_page_flip_locked(struct drm_crtc *crtc, } omap_crtc->event = event; - crtc->fb = fb; + primary->fb = fb; /* * Hold a reference temporarily until the crtc is updated diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c index f466c4aaee94..0d5e9b7e8bbf 100644 --- a/drivers/gpu/drm/omapdrm/omap_fb.c +++ b/drivers/gpu/drm/omapdrm/omap_fb.c @@ -312,7 +312,7 @@ struct drm_connector *omap_framebuffer_get_next_connector( if (connector != from) { struct drm_encoder *encoder = connector->encoder; struct drm_crtc *crtc = encoder ? encoder->crtc : NULL; - if (crtc && crtc->fb == fb) + if (crtc && crtc->primary->fb == fb) return connector; } diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index 798bde2e5881..41bdd174657e 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -527,7 +527,7 @@ static int qxl_crtc_mode_set(struct drm_crtc *crtc, bool recreate_primary = false; int ret; int surf_id; - if (!crtc->fb) { + if (!crtc->primary->fb) { DRM_DEBUG_KMS("No FB bound\n"); return 0; } @@ -536,7 +536,7 @@ static int qxl_crtc_mode_set(struct drm_crtc *crtc, qfb = to_qxl_framebuffer(old_fb); old_bo = gem_to_qxl_bo(qfb->obj); } - qfb = to_qxl_framebuffer(crtc->fb); + qfb = to_qxl_framebuffer(crtc->primary->fb); bo = gem_to_qxl_bo(qfb->obj); if (!m) /* and do we care? */ @@ -609,14 +609,14 @@ static void qxl_crtc_disable(struct drm_crtc *crtc) struct qxl_crtc *qcrtc = to_qxl_crtc(crtc); struct drm_device *dev = crtc->dev; struct qxl_device *qdev = dev->dev_private; - if (crtc->fb) { - struct qxl_framebuffer *qfb = to_qxl_framebuffer(crtc->fb); + if (crtc->primary->fb) { + struct qxl_framebuffer *qfb = to_qxl_framebuffer(crtc->primary->fb); struct qxl_bo *bo = gem_to_qxl_bo(qfb->obj); int ret; ret = qxl_bo_reserve(bo, false); qxl_bo_unpin(bo); qxl_bo_unreserve(bo); - crtc->fb = NULL; + crtc->primary->fb = NULL; } qxl_monitors_config_set(qdev, qcrtc->index, 0, 0, 0, 0, 0); diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index daa4dd375ab1..fb187c78978f 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -1106,7 +1106,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, int r; /* no fb bound */ - if (!atomic && !crtc->fb) { + if (!atomic && !crtc->primary->fb) { DRM_DEBUG_KMS("No FB bound\n"); return 0; } @@ -1116,8 +1116,8 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, target_fb = fb; } else { - radeon_fb = to_radeon_framebuffer(crtc->fb); - target_fb = crtc->fb; + radeon_fb = to_radeon_framebuffer(crtc->primary->fb); + target_fb = crtc->primary->fb; } /* If atomic, assume fb object is pinned & idle & fenced and @@ -1316,7 +1316,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, /* set pageflip to happen anywhere in vblank interval */ WREG32(EVERGREEN_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0); - if (!atomic && fb && fb != crtc->fb) { + if (!atomic && fb && fb != crtc->primary->fb) { radeon_fb = to_radeon_framebuffer(fb); rbo = gem_to_radeon_bo(radeon_fb->obj); r = radeon_bo_reserve(rbo, false); @@ -1350,7 +1350,7 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, int r; /* no fb bound */ - if (!atomic && !crtc->fb) { + if (!atomic && !crtc->primary->fb) { DRM_DEBUG_KMS("No FB bound\n"); return 0; } @@ -1360,8 +1360,8 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, target_fb = fb; } else { - radeon_fb = to_radeon_framebuffer(crtc->fb); - target_fb = crtc->fb; + radeon_fb = to_radeon_framebuffer(crtc->primary->fb); + target_fb = crtc->primary->fb; } obj = radeon_fb->obj; @@ -1485,7 +1485,7 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, /* set pageflip to happen anywhere in vblank interval */ WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0); - if (!atomic && fb && fb != crtc->fb) { + if (!atomic && fb && fb != crtc->primary->fb) { radeon_fb = to_radeon_framebuffer(fb); rbo = gem_to_radeon_bo(radeon_fb->obj); r = radeon_bo_reserve(rbo, false); @@ -1972,12 +1972,12 @@ static void atombios_crtc_disable(struct drm_crtc *crtc) int i; atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); - if (crtc->fb) { + if (crtc->primary->fb) { int r; struct radeon_framebuffer *radeon_fb; struct radeon_bo *rbo; - radeon_fb = to_radeon_framebuffer(crtc->fb); + radeon_fb = to_radeon_framebuffer(crtc->primary->fb); rbo = gem_to_radeon_bo(radeon_fb->obj); r = radeon_bo_reserve(rbo, false); if (unlikely(r)) diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 030f8e49c5ee..b6c32640df20 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -3220,12 +3220,12 @@ void r100_bandwidth_update(struct radeon_device *rdev) if (rdev->mode_info.crtcs[0]->base.enabled) { mode1 = &rdev->mode_info.crtcs[0]->base.mode; - pixel_bytes1 = rdev->mode_info.crtcs[0]->base.fb->bits_per_pixel / 8; + pixel_bytes1 = rdev->mode_info.crtcs[0]->base.primary->fb->bits_per_pixel / 8; } if (!(rdev->flags & RADEON_SINGLE_CRTC)) { if (rdev->mode_info.crtcs[1]->base.enabled) { mode2 = &rdev->mode_info.crtcs[1]->base.mode; - pixel_bytes2 = rdev->mode_info.crtcs[1]->base.fb->bits_per_pixel / 8; + pixel_bytes2 = rdev->mode_info.crtcs[1]->base.primary->fb->bits_per_pixel / 8; } } diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index ec958e86fd8b..c566b486ca08 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -89,7 +89,7 @@ static void radeon_property_change_mode(struct drm_encoder *encoder) if (crtc && crtc->enabled) { drm_crtc_helper_set_mode(crtc, &crtc->mode, - crtc->x, crtc->y, crtc->fb); + crtc->x, crtc->y, crtc->primary->fb); } } diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 2e72dcd94b13..15f954cd81cb 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -1424,7 +1424,7 @@ int radeon_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon) /* unpin the front buffers */ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - struct radeon_framebuffer *rfb = to_radeon_framebuffer(crtc->fb); + struct radeon_framebuffer *rfb = to_radeon_framebuffer(crtc->primary->fb); struct radeon_bo *robj; if (rfb == NULL || rfb->obj == NULL) { diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index fbd8b930f2be..5701fbb36b3c 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -369,7 +369,7 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc, work->event = event; work->rdev = rdev; work->crtc_id = radeon_crtc->crtc_id; - old_radeon_fb = to_radeon_framebuffer(crtc->fb); + old_radeon_fb = to_radeon_framebuffer(crtc->primary->fb); new_radeon_fb = to_radeon_framebuffer(fb); /* schedule unpin of the old buffer */ obj = old_radeon_fb->obj; @@ -460,7 +460,7 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc, spin_unlock_irqrestore(&dev->event_lock, flags); /* update crtc fb */ - crtc->fb = fb; + crtc->primary->fb = fb; r = drm_vblank_get(dev, radeon_crtc->crtc_id); if (r) { diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 0b158f98d287..cafb1ccf2ec3 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c @@ -385,7 +385,7 @@ int radeon_crtc_do_set_base(struct drm_crtc *crtc, DRM_DEBUG_KMS("\n"); /* no fb bound */ - if (!atomic && !crtc->fb) { + if (!atomic && !crtc->primary->fb) { DRM_DEBUG_KMS("No FB bound\n"); return 0; } @@ -395,8 +395,8 @@ int radeon_crtc_do_set_base(struct drm_crtc *crtc, target_fb = fb; } else { - radeon_fb = to_radeon_framebuffer(crtc->fb); - target_fb = crtc->fb; + radeon_fb = to_radeon_framebuffer(crtc->primary->fb); + target_fb = crtc->primary->fb; } switch (target_fb->bits_per_pixel) { @@ -444,7 +444,7 @@ retry: * We don't shutdown the display controller because new buffer * will end up in same spot. */ - if (!atomic && fb && fb != crtc->fb) { + if (!atomic && fb && fb != crtc->primary->fb) { struct radeon_bo *old_rbo; unsigned long nsize, osize; @@ -555,7 +555,7 @@ retry: WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, crtc_offset); WREG32(RADEON_CRTC_PITCH + radeon_crtc->crtc_offset, crtc_pitch); - if (!atomic && fb && fb != crtc->fb) { + if (!atomic && fb && fb != crtc->primary->fb) { radeon_fb = to_radeon_framebuffer(fb); rbo = gem_to_radeon_bo(radeon_fb->obj); r = radeon_bo_reserve(rbo, false); @@ -599,7 +599,7 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod } } - switch (crtc->fb->bits_per_pixel) { + switch (crtc->primary->fb->bits_per_pixel) { case 8: format = 2; break; @@ -1087,12 +1087,12 @@ static void radeon_crtc_commit(struct drm_crtc *crtc) static void radeon_crtc_disable(struct drm_crtc *crtc) { radeon_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); - if (crtc->fb) { + if (crtc->primary->fb) { int r; struct radeon_framebuffer *radeon_fb; struct radeon_bo *rbo; - radeon_fb = to_radeon_framebuffer(crtc->fb); + radeon_fb = to_radeon_framebuffer(crtc->primary->fb); rbo = gem_to_radeon_bo(radeon_fb->obj); r = radeon_bo_reserve(rbo, false); if (unlikely(r)) diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index fbf4be316d0b..299267db2898 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c @@ -299,7 +299,7 @@ static void rcar_du_crtc_update_base(struct rcar_du_crtc *rcrtc) { struct drm_crtc *crtc = &rcrtc->crtc; - rcar_du_plane_compute_base(rcrtc->plane, crtc->fb); + rcar_du_plane_compute_base(rcrtc->plane, crtc->primary->fb); rcar_du_plane_update_base(rcrtc->plane); } @@ -358,10 +358,10 @@ static int rcar_du_crtc_mode_set(struct drm_crtc *crtc, const struct rcar_du_format_info *format; int ret; - format = rcar_du_format_info(crtc->fb->pixel_format); + format = rcar_du_format_info(crtc->primary->fb->pixel_format); if (format == NULL) { dev_dbg(rcdu->dev, "mode_set: unsupported format %08x\n", - crtc->fb->pixel_format); + crtc->primary->fb->pixel_format); ret = -EINVAL; goto error; } @@ -377,7 +377,7 @@ static int rcar_du_crtc_mode_set(struct drm_crtc *crtc, rcrtc->plane->width = mode->hdisplay; rcrtc->plane->height = mode->vdisplay; - rcar_du_plane_compute_base(rcrtc->plane, crtc->fb); + rcar_du_plane_compute_base(rcrtc->plane, crtc->primary->fb); rcrtc->outputs = 0; @@ -510,7 +510,7 @@ static int rcar_du_crtc_page_flip(struct drm_crtc *crtc, } spin_unlock_irqrestore(&dev->event_lock, flags); - crtc->fb = fb; + crtc->primary->fb = fb; rcar_du_crtc_update_base(rcrtc); if (event) { diff --git a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c index 0428076f1ce8..e9e5e6d368cc 100644 --- a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c +++ b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c @@ -173,7 +173,7 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc) if (scrtc->started) return; - format = shmob_drm_format_info(crtc->fb->pixel_format); + format = shmob_drm_format_info(crtc->primary->fb->pixel_format); if (WARN_ON(format == NULL)) return; @@ -247,7 +247,7 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc) lcdc_write(sdev, LDDDSR, value); /* Setup planes. */ - list_for_each_entry(plane, &dev->mode_config.plane_list, head) { + drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) { if (plane->crtc == crtc) shmob_drm_plane_setup(plane); } @@ -303,7 +303,7 @@ static void shmob_drm_crtc_compute_base(struct shmob_drm_crtc *scrtc, int x, int y) { struct drm_crtc *crtc = &scrtc->crtc; - struct drm_framebuffer *fb = crtc->fb; + struct drm_framebuffer *fb = crtc->primary->fb; struct shmob_drm_device *sdev = crtc->dev->dev_private; struct drm_gem_cma_object *gem; unsigned int bpp; @@ -382,15 +382,15 @@ static int shmob_drm_crtc_mode_set(struct drm_crtc *crtc, const struct shmob_drm_format_info *format; void *cache; - format = shmob_drm_format_info(crtc->fb->pixel_format); + format = shmob_drm_format_info(crtc->primary->fb->pixel_format); if (format == NULL) { dev_dbg(sdev->dev, "mode_set: unsupported format %08x\n", - crtc->fb->pixel_format); + crtc->primary->fb->pixel_format); return -EINVAL; } scrtc->format = format; - scrtc->line_size = crtc->fb->pitches[0]; + scrtc->line_size = crtc->primary->fb->pitches[0]; if (sdev->meram) { /* Enable MERAM cache if configured. We need to de-init @@ -402,7 +402,7 @@ static int shmob_drm_crtc_mode_set(struct drm_crtc *crtc, } cache = sh_mobile_meram_cache_alloc(sdev->meram, mdata, - crtc->fb->pitches[0], + crtc->primary->fb->pitches[0], adjusted_mode->vdisplay, format->meram, &scrtc->line_size); @@ -489,7 +489,7 @@ static int shmob_drm_crtc_page_flip(struct drm_crtc *crtc, } spin_unlock_irqrestore(&dev->event_lock, flags); - crtc->fb = fb; + crtc->primary->fb = fb; shmob_drm_crtc_update_base(scrtc); if (event) { diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 9336006b475d..36c717af6cf9 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -235,14 +235,14 @@ static void tegra_dc_finish_page_flip(struct tegra_dc *dc) if (!dc->event) return; - bo = tegra_fb_get_plane(crtc->fb, 0); + bo = tegra_fb_get_plane(crtc->primary->fb, 0); /* check if new start address has been latched */ tegra_dc_writel(dc, READ_MUX, DC_CMD_STATE_ACCESS); base = tegra_dc_readl(dc, DC_WINBUF_START_ADDR); tegra_dc_writel(dc, 0, DC_CMD_STATE_ACCESS); - if (base == bo->paddr + crtc->fb->offsets[0]) { + if (base == bo->paddr + crtc->primary->fb->offsets[0]) { spin_lock_irqsave(&drm->event_lock, flags); drm_send_vblank_event(drm, dc->pipe, dc->event); drm_vblank_put(drm, dc->pipe); @@ -284,7 +284,7 @@ static int tegra_dc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, } tegra_dc_set_base(dc, 0, 0, fb); - crtc->fb = fb; + crtc->primary->fb = fb; return 0; } @@ -645,7 +645,7 @@ static int tegra_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *adjusted, int x, int y, struct drm_framebuffer *old_fb) { - struct tegra_bo *bo = tegra_fb_get_plane(crtc->fb, 0); + struct tegra_bo *bo = tegra_fb_get_plane(crtc->primary->fb, 0); struct tegra_dc *dc = to_tegra_dc(crtc); struct tegra_dc_window window; unsigned long div, value; @@ -682,9 +682,9 @@ static int tegra_crtc_mode_set(struct drm_crtc *crtc, window.dst.y = 0; window.dst.w = mode->hdisplay; window.dst.h = mode->vdisplay; - window.format = tegra_dc_format(crtc->fb->pixel_format); - window.bits_per_pixel = crtc->fb->bits_per_pixel; - window.stride[0] = crtc->fb->pitches[0]; + window.format = tegra_dc_format(crtc->primary->fb->pixel_format); + window.bits_per_pixel = crtc->primary->fb->bits_per_pixel; + window.stride[0] = crtc->primary->fb->pitches[0]; window.base[0] = bo->paddr; err = tegra_dc_setup_window(dc, 0, &window); @@ -699,7 +699,7 @@ static int tegra_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, { struct tegra_dc *dc = to_tegra_dc(crtc); - return tegra_dc_set_base(dc, x, y, crtc->fb); + return tegra_dc_set_base(dc, x, y, crtc->primary->fb); } static void tegra_crtc_prepare(struct drm_crtc *crtc) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index d36efc13b16f..d642d4a02134 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -74,7 +74,7 @@ static void set_scanout(struct drm_crtc *crtc, int n) drm_flip_work_queue(&tilcdc_crtc->unref_work, tilcdc_crtc->scanout[n]); drm_flip_work_commit(&tilcdc_crtc->unref_work, priv->wq); } - tilcdc_crtc->scanout[n] = crtc->fb; + tilcdc_crtc->scanout[n] = crtc->primary->fb; drm_framebuffer_reference(tilcdc_crtc->scanout[n]); tilcdc_crtc->dirty &= ~stat[n]; pm_runtime_put_sync(dev->dev); @@ -84,7 +84,7 @@ static void update_scanout(struct drm_crtc *crtc) { struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); struct drm_device *dev = crtc->dev; - struct drm_framebuffer *fb = crtc->fb; + struct drm_framebuffer *fb = crtc->primary->fb; struct drm_gem_cma_object *gem; unsigned int depth, bpp; @@ -159,7 +159,7 @@ static int tilcdc_crtc_page_flip(struct drm_crtc *crtc, return -EBUSY; } - crtc->fb = fb; + crtc->primary->fb = fb; tilcdc_crtc->event = event; update_scanout(crtc); @@ -339,7 +339,7 @@ static int tilcdc_crtc_mode_set(struct drm_crtc *crtc, if (priv->rev == 2) { unsigned int depth, bpp; - drm_fb_get_bpp_depth(crtc->fb->pixel_format, &depth, &bpp); + drm_fb_get_bpp_depth(crtc->primary->fb->pixel_format, &depth, &bpp); switch (bpp) { case 16: break; diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c index 2ae1eb7d1635..cddc4fcf35cf 100644 --- a/drivers/gpu/drm/udl/udl_modeset.c +++ b/drivers/gpu/drm/udl/udl_modeset.c @@ -310,7 +310,7 @@ static int udl_crtc_mode_set(struct drm_crtc *crtc, { struct drm_device *dev = crtc->dev; - struct udl_framebuffer *ufb = to_udl_fb(crtc->fb); + struct udl_framebuffer *ufb = to_udl_fb(crtc->primary->fb); struct udl_device *udl = dev->dev_private; char *buf; char *wrptr; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 159af7ee111f..a2dde5ad8138 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -468,7 +468,7 @@ static int do_surface_dirty_sou(struct vmw_private *dev_priv, num_units = 0; list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list, head) { - if (crtc->fb != &framebuffer->base) + if (crtc->primary->fb != &framebuffer->base) continue; units[num_units++] = vmw_crtc_to_du(crtc); } @@ -882,7 +882,7 @@ static int do_dmabuf_dirty_sou(struct drm_file *file_priv, num_units = 0; list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list, head) { - if (crtc->fb != &framebuffer->base) + if (crtc->primary->fb != &framebuffer->base) continue; units[num_units++] = vmw_crtc_to_du(crtc); } @@ -1243,7 +1243,7 @@ int vmw_kms_present(struct vmw_private *dev_priv, num_units = 0; list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list, head) { - if (crtc->fb != &vfb->base) + if (crtc->primary->fb != &vfb->base) continue; units[num_units++] = vmw_crtc_to_du(crtc); } @@ -1380,7 +1380,7 @@ int vmw_kms_readback(struct vmw_private *dev_priv, num_units = 0; list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list, head) { - if (crtc->fb != &vfb->base) + if (crtc->primary->fb != &vfb->base) continue; units[num_units++] = vmw_crtc_to_du(crtc); } @@ -1723,7 +1723,7 @@ int vmw_du_page_flip(struct drm_crtc *crtc, uint32_t page_flip_flags) { struct vmw_private *dev_priv = vmw_priv(crtc->dev); - struct drm_framebuffer *old_fb = crtc->fb; + struct drm_framebuffer *old_fb = crtc->primary->fb; struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(fb); struct drm_file *file_priv ; struct vmw_fence_obj *fence = NULL; @@ -1741,7 +1741,7 @@ int vmw_du_page_flip(struct drm_crtc *crtc, if (!vmw_kms_screen_object_flippable(dev_priv, crtc)) return -EINVAL; - crtc->fb = fb; + crtc->primary->fb = fb; /* do a full screen dirty update */ clips.x1 = clips.y1 = 0; @@ -1781,7 +1781,7 @@ int vmw_du_page_flip(struct drm_crtc *crtc, return ret; out_no_fence: - crtc->fb = old_fb; + crtc->primary->fb = old_fb; return ret; } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index a055a26819c2..b2b9bd23aeee 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c @@ -93,7 +93,7 @@ static int vmw_ldu_commit_list(struct vmw_private *dev_priv) if (crtc == NULL) return 0; - fb = entry->base.crtc.fb; + fb = entry->base.crtc.primary->fb; return vmw_kms_write_svga(dev_priv, w, h, fb->pitches[0], fb->bits_per_pixel, fb->depth); @@ -101,7 +101,7 @@ static int vmw_ldu_commit_list(struct vmw_private *dev_priv) if (!list_empty(&lds->active)) { entry = list_entry(lds->active.next, typeof(*entry), active); - fb = entry->base.crtc.fb; + fb = entry->base.crtc.primary->fb; vmw_kms_write_svga(dev_priv, fb->width, fb->height, fb->pitches[0], fb->bits_per_pixel, fb->depth); @@ -259,7 +259,7 @@ static int vmw_ldu_crtc_set_config(struct drm_mode_set *set) connector->encoder = NULL; encoder->crtc = NULL; - crtc->fb = NULL; + crtc->primary->fb = NULL; crtc->enabled = false; vmw_ldu_del_active(dev_priv, ldu); @@ -280,7 +280,7 @@ static int vmw_ldu_crtc_set_config(struct drm_mode_set *set) vmw_fb_off(dev_priv); - crtc->fb = fb; + crtc->primary->fb = fb; encoder->crtc = crtc; connector->encoder = encoder; crtc->x = set->x; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c index 22406c8651ea..a95d3a0cabe4 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c @@ -307,7 +307,7 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set) connector->encoder = NULL; encoder->crtc = NULL; - crtc->fb = NULL; + crtc->primary->fb = NULL; crtc->x = 0; crtc->y = 0; crtc->enabled = false; @@ -368,7 +368,7 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set) connector->encoder = NULL; encoder->crtc = NULL; - crtc->fb = NULL; + crtc->primary->fb = NULL; crtc->x = 0; crtc->y = 0; crtc->enabled = false; @@ -381,7 +381,7 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set) connector->encoder = encoder; encoder->crtc = crtc; crtc->mode = *mode; - crtc->fb = fb; + crtc->primary->fb = fb; crtc->x = set->x; crtc->y = set->y; crtc->enabled = true; @@ -572,5 +572,5 @@ void vmw_kms_screen_object_update_implicit_fb(struct vmw_private *dev_priv, BUG_ON(!sou->base.is_implicit); dev_priv->sou_priv->implicit_fb = - vmw_framebuffer_to_vfb(sou->base.crtc.fb); + vmw_framebuffer_to_vfb(sou->base.crtc.primary->fb); } |