static int set_property_legacy(struct drm_mode_object *obj, struct drm_property *prop, uint64_t prop_value) { struct drm_device *dev = prop->dev; struct drm_mode_object *ref; int ret = -EINVAL; if (!drm_property_change_valid_get(prop, prop_value, &ref)) return -EINVAL; drm_modeset_lock_all(dev); switch (obj->type) { case DRM_MODE_OBJECT_CONNECTOR: ret = drm_mode_connector_set_obj_prop(obj, prop, prop_value); break; case DRM_MODE_OBJECT_CRTC: ret = drm_mode_crtc_set_obj_prop(obj, prop, prop_value); break; case DRM_MODE_OBJECT_PLANE: ret = drm_mode_plane_set_obj_prop(obj_to_plane(obj), prop, prop_value); break; } drm_property_change_valid_put(prop, ref); drm_modeset_unlock_all(dev); return ret; }
/** * drm_mode_obj_get_properties_ioctl - get the current value of a object's property * @dev: DRM device * @data: ioctl data * @file_priv: DRM file info * * This function retrieves the current value for an object's property. Compared * to the connector specific ioctl this one is extended to also work on crtc and * plane objects. * * Called by the user via ioctl. * * Returns: * Zero on success, negative errno on failure. */ int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_mode_obj_get_properties *arg = data; struct drm_mode_object *obj; int ret = 0; if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EINVAL; drm_modeset_lock_all(dev); obj = drm_mode_object_find(dev, file_priv, arg->obj_id, arg->obj_type); if (!obj) { ret = -ENOENT; goto out; } if (!obj->properties) { ret = -EINVAL; goto out_unref; } ret = drm_mode_object_get_properties(obj, file_priv->atomic, (uint32_t __user *)(unsigned long)(arg->props_ptr), (uint64_t __user *)(unsigned long)(arg->prop_values_ptr), &arg->count_props); out_unref: drm_mode_object_put(obj); out: drm_modeset_unlock_all(dev); return ret; }
int intel_sprite_set_colorkey(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_intel_sprite_colorkey *set = data; struct drm_mode_object *obj; struct drm_plane *plane; struct intel_plane *intel_plane; int ret = 0; if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -ENODEV; /* Make sure we don't try to enable both src & dest simultaneously */ if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) return -EINVAL; drm_modeset_lock_all(dev); obj = drm_mode_object_find(dev, set->plane_id, DRM_MODE_OBJECT_PLANE); if (!obj) { ret = -EINVAL; goto out_unlock; } plane = obj_to_plane(obj); intel_plane = to_intel_plane(plane); ret = intel_plane->update_colorkey(plane, set); out_unlock: drm_modeset_unlock_all(dev); return ret; }
void radeondrm_doswitch(void *v) { struct rasops_info *ri = v; struct radeon_device *rdev = ri->ri_hw; struct radeon_crtc *radeon_crtc; int i, crtc; rasops_show_screen(ri, rdev->switchcookie, 0, NULL, NULL); for (crtc = 0; crtc < rdev->num_crtc; crtc++) { for (i = 0; i < 256; i++) { radeon_crtc = rdev->mode_info.crtcs[crtc]; radeon_crtc->lut_r[i] = rasops_cmap[3 * i] << 2; radeon_crtc->lut_g[i] = rasops_cmap[(3 * i) + 1] << 2; radeon_crtc->lut_b[i] = rasops_cmap[(3 * i) + 2] << 2; } } #ifdef __sparc64__ fbwscons_setcolormap(&rdev->sf, radeondrm_setcolor); #endif drm_modeset_lock_all(rdev->ddev); drm_fb_helper_restore_fbdev_mode((void *)rdev->mode_info.rfbdev); drm_modeset_unlock_all(rdev->ddev); if (rdev->switchcb) (rdev->switchcb)(rdev->switchcbarg, 0, 0); }
int intel_sprite_get_colorkey(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_intel_sprite_colorkey *get = data; struct drm_mode_object *obj; struct drm_plane *plane; struct intel_plane *intel_plane; int ret = 0; if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -ENODEV; drm_modeset_lock_all(dev); obj = drm_mode_object_find(dev, get->plane_id, DRM_MODE_OBJECT_PLANE); if (!obj) { ret = -EINVAL; goto out_unlock; } plane = obj_to_plane(obj); intel_plane = to_intel_plane(plane); intel_plane->get_colorkey(plane, get); out_unlock: drm_modeset_unlock_all(dev); return ret; }
static int drmfb_genfb_ioctl(void *v, void *vs, unsigned long cmd, void *data, int flag, struct lwp *l) { struct genfb_softc *const genfb = v; struct drmfb_softc *const sc = container_of(genfb, struct drmfb_softc, sc_genfb); int error; if (sc->sc_da.da_params->dp_ioctl) { error = (*sc->sc_da.da_params->dp_ioctl)(sc, cmd, data, flag, l); if (error != EPASSTHROUGH) return error; } switch (cmd) { /* * Screen blanking ioctls. Not to be confused with backlight * (can be disabled while stuff is still drawn on the screen), * brightness, or contrast (which we don't support). Backlight * and brightness are done through WSDISPLAYIO_{GET,SET}PARAM. * This toggles between DPMS ON and DPMS OFF; backlight toggles * between DPMS ON and DPMS SUSPEND. */ case WSDISPLAYIO_GVIDEO: { int *onp = (int *)data; /* XXX Can't really determine a single answer here. */ *onp = 1; return 0; } case WSDISPLAYIO_SVIDEO: { const int on = *(const int *)data; const int dpms_mode = on? DRM_MODE_DPMS_ON : DRM_MODE_DPMS_OFF; struct drm_fb_helper *const fb_helper = sc->sc_da.da_fb_helper; struct drm_device *const dev = fb_helper->dev; unsigned i; drm_modeset_lock_all(dev); for (i = 0; i < fb_helper->connector_count; i++) { struct drm_connector *const connector = fb_helper->connector_info[i]->connector; (*connector->funcs->dpms)(connector, dpms_mode); drm_object_property_set_value(&connector->base, dev->mode_config.dpms_property, dpms_mode); } drm_modeset_unlock_all(dev); return 0; } default: return EPASSTHROUGH; } }
static void intel_dp_register_mst_connector(struct drm_connector *connector) { struct intel_connector *intel_connector = to_intel_connector(connector); struct drm_device *dev = connector->dev; drm_modeset_lock_all(dev); intel_connector_add_to_fbdev(intel_connector); drm_modeset_unlock_all(dev); drm_connector_register(&intel_connector->base); }
static void intel_suspend_encoders(struct drm_i915_private *dev_priv) { struct drm_device *dev = dev_priv->dev; struct intel_encoder *encoder; drm_modeset_lock_all(dev); for_each_intel_encoder(dev, encoder) if (encoder->suspend) encoder->suspend(encoder); drm_modeset_unlock_all(dev); }
static int shmob_drm_pm_resume(struct device *dev) { struct shmob_drm_device *sdev = dev_get_drvdata(dev); drm_modeset_lock_all(sdev->ddev); shmob_drm_crtc_resume(&sdev->crtc); drm_modeset_unlock_all(sdev->ddev); drm_kms_helper_poll_enable(sdev->ddev); return 0; }
static int omap_drm_resume(struct device *dev) { struct drm_device *drm_dev = dev_get_drvdata(dev); drm_modeset_lock_all(drm_dev); omap_drm_resume_all_displays(); drm_modeset_unlock_all(drm_dev); drm_kms_helper_poll_enable(drm_dev); return omap_gem_resume(drm_dev); }
static int omap_drm_suspend(struct device *dev) { struct drm_device *drm_dev = dev_get_drvdata(dev); drm_kms_helper_poll_disable(drm_dev); drm_modeset_lock_all(drm_dev); omap_drm_suspend_all_displays(); drm_modeset_unlock_all(drm_dev); return 0; }
static int i9xx_pipe_crc_auto_source(struct drm_i915_private *dev_priv, enum pipe pipe, enum intel_pipe_crc_source *source) { struct drm_device *dev = &dev_priv->drm; struct intel_encoder *encoder; struct intel_crtc *crtc; struct intel_digital_port *dig_port; int ret = 0; *source = INTEL_PIPE_CRC_SOURCE_PIPE; drm_modeset_lock_all(dev); for_each_intel_encoder(dev, encoder) { if (!encoder->base.crtc) continue; crtc = to_intel_crtc(encoder->base.crtc); if (crtc->pipe != pipe) continue; switch (encoder->type) { case INTEL_OUTPUT_TVOUT: *source = INTEL_PIPE_CRC_SOURCE_TV; break; case INTEL_OUTPUT_DP: case INTEL_OUTPUT_EDP: dig_port = enc_to_dig_port(&encoder->base); switch (dig_port->port) { case PORT_B: *source = INTEL_PIPE_CRC_SOURCE_DP_B; break; case PORT_C: *source = INTEL_PIPE_CRC_SOURCE_DP_C; break; case PORT_D: *source = INTEL_PIPE_CRC_SOURCE_DP_D; break; default: WARN(1, "nonexisting DP port %c\n", port_name(dig_port->port)); break; } break; default: break; } } drm_modeset_unlock_all(dev); return ret; }
static int qxl_framebuffer_surface_dirty(struct drm_framebuffer *fb, struct drm_file *file_priv, unsigned flags, unsigned color, struct drm_clip_rect *clips, unsigned num_clips) { /* TODO: vmwgfx where this was cribbed from had locking. Why? */ struct qxl_framebuffer *qxl_fb = to_qxl_framebuffer(fb); struct qxl_device *qdev = qxl_fb->base.dev->dev_private; struct drm_clip_rect norect; struct qxl_bo *qobj; int inc = 1; drm_modeset_lock_all(fb->dev); qobj = gem_to_qxl_bo(qxl_fb->obj); /* if we aren't primary surface ignore this */ if (!qobj->is_primary) { drm_modeset_unlock_all(fb->dev); return 0; } if (!num_clips) { num_clips = 1; clips = &norect; norect.x1 = norect.y1 = 0; norect.x2 = fb->width; norect.y2 = fb->height; } else if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY) { num_clips /= 2; inc = 2; /* skip source rects */ } qxl_draw_dirty_fb(qdev, qxl_fb, qobj, flags, color, clips, num_clips, inc); drm_modeset_unlock_all(fb->dev); return 0; }
int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_mode_obj_set_property *arg = data; struct drm_mode_object *arg_obj; struct drm_property *property; int ret = -EINVAL; struct drm_mode_object *ref; if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EINVAL; drm_modeset_lock_all(dev); arg_obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type); if (!arg_obj) { ret = -ENOENT; goto out; } if (!arg_obj->properties) goto out_unref; property = drm_mode_obj_find_prop_id(arg_obj, arg->prop_id); if (!property) goto out_unref; if (!drm_property_change_valid_get(property, arg->value, &ref)) goto out_unref; switch (arg_obj->type) { case DRM_MODE_OBJECT_CONNECTOR: ret = drm_mode_connector_set_obj_prop(arg_obj, property, arg->value); break; case DRM_MODE_OBJECT_CRTC: ret = drm_mode_crtc_set_obj_prop(arg_obj, property, arg->value); break; case DRM_MODE_OBJECT_PLANE: ret = drm_mode_plane_set_obj_prop(obj_to_plane(arg_obj), property, arg->value); break; } drm_property_change_valid_put(property, ref); out_unref: drm_mode_object_unreference(arg_obj); out: drm_modeset_unlock_all(dev); return ret; }
/** * radeon_driver_firstopen_kms - drm callback for last close * * @dev: drm dev pointer * * Switch vga switcheroo state after last close (all asics). */ void radeon_driver_lastclose_kms(struct drm_device *dev) { struct radeon_device *rdev = dev->dev_private; #ifdef __sparc64__ fbwscons_setcolormap(&rdev->sf, radeondrm_setcolor); #endif drm_modeset_lock_all(dev); drm_fb_helper_restore_fbdev_mode((void *)rdev->mode_info.rfbdev); drm_modeset_unlock_all(dev); #ifdef notyet vga_switcheroo_process_delayed_switch(); #endif }
static int evdi_user_framebuffer_dirty(struct drm_framebuffer *fb, __always_unused struct drm_file *file, __always_unused unsigned int flags, __always_unused unsigned int color, struct drm_clip_rect *clips, unsigned int num_clips) { struct evdi_framebuffer *ufb = to_evdi_fb(fb); struct drm_device *dev = ufb->base.dev; struct evdi_device *evdi = dev->dev_private; int i; int ret = 0; EVDI_CHECKPT(); drm_modeset_lock_all(fb->dev); if (!ufb->active) goto unlock; if (ufb->obj->base.import_attach) { ret = dma_buf_begin_cpu_access( ufb->obj->base.import_attach->dmabuf, #if KERNEL_VERSION(4, 6, 0) > LINUX_VERSION_CODE 0, ufb->obj->base.size, #endif DMA_FROM_DEVICE); if (ret) goto unlock; } for (i = 0; i < num_clips; i++) { ret = evdi_handle_damage(ufb, clips[i].x1, clips[i].y1, clips[i].x2 - clips[i].x1, clips[i].y2 - clips[i].y1); if (ret) goto unlock; } if (ufb->obj->base.import_attach) dma_buf_end_cpu_access(ufb->obj->base.import_attach->dmabuf, #if KERNEL_VERSION(4, 6, 0) > LINUX_VERSION_CODE 0, ufb->obj->base.size, #endif DMA_FROM_DEVICE); atomic_add(1, &evdi->frame_count); unlock: drm_modeset_unlock_all(fb->dev); return ret; }
static int atmel_hlcdc_dc_drm_resume(struct device *dev) { struct drm_device *drm_dev = dev_get_drvdata(dev); struct drm_crtc *crtc; if (pm_runtime_suspended(dev)) return 0; drm_modeset_lock_all(drm_dev); list_for_each_entry(crtc, &drm_dev->mode_config.crtc_list, head) atmel_hlcdc_crtc_resume(crtc); drm_modeset_unlock_all(drm_dev); return 0; }
static int i915_drm_freeze(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_crtc *crtc; intel_runtime_pm_get(dev_priv); /* ignore lid events during suspend */ mutex_lock(&dev_priv->modeset_restore_lock); dev_priv->modeset_restore = MODESET_SUSPENDED; mutex_unlock(&dev_priv->modeset_restore_lock); /* We do a lot of poking in a lot of registers, make sure they work * properly. */ intel_display_set_init_power(dev_priv, true); drm_kms_helper_poll_disable(dev); pci_save_state(dev->pdev); /* If KMS is active, we do the leavevt stuff here */ if (drm_core_check_feature(dev, DRIVER_MODESET)) { int error; error = i915_gem_suspend(dev); if (error) { dev_err(&dev->pdev->dev, "GEM idle failed, resume might fail\n"); return error; } intel_disable_gt_powersave(dev); /* * Disable CRTCs directly since we want to preserve sw state * for _thaw. */ drm_modeset_lock_all(dev); for_each_crtc(dev, crtc) { dev_priv->display.crtc_disable(crtc); } drm_modeset_unlock_all(dev); intel_dp_mst_suspend(dev); drm_irq_uninstall(dev); intel_modeset_suspend_hw(dev); }
static int ast_drm_thaw(struct drm_device *dev) { int error = 0; ast_post_gpu(dev); drm_mode_config_reset(dev); drm_modeset_lock_all(dev); drm_helper_resume_force_mode(dev); drm_modeset_unlock_all(dev); console_lock(); ast_fbdev_set_suspend(dev, 0); console_unlock(); return error; }
void intel_fbdev_restore_mode(struct drm_device *dev) { int ret; struct drm_i915_private *dev_priv = dev->dev_private; if (INTEL_INFO(dev)->num_pipes == 0) return; drm_modeset_lock_all(dev); ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper); if (ret) DRM_DEBUG("failed to restore crtc mode\n"); drm_modeset_unlock_all(dev); }
/** * drm_crtc_force_disable_all - Forcibly turn off all enabled CRTCs * @dev: DRM device whose CRTCs to turn off * * Drivers may want to call this on unload to ensure that all displays are * unlit and the GPU is in a consistent, low power state. Takes modeset locks. * * Note: This should only be used by non-atomic legacy drivers. For an atomic * version look at drm_atomic_helper_shutdown(). * * Returns: * Zero on success, error code on failure. */ int drm_crtc_force_disable_all(struct drm_device *dev) { struct drm_crtc *crtc; int ret = 0; drm_modeset_lock_all(dev); drm_for_each_crtc(crtc, dev) if (crtc->enabled) { ret = drm_crtc_force_disable(crtc); if (ret) goto out; } out: drm_modeset_unlock_all(dev); return ret; }
static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, struct drm_connector *connector) { struct intel_connector *intel_connector = to_intel_connector(connector); struct drm_device *dev = connector->dev; drm_connector_unregister(connector); /* need to nuke the connector */ drm_modeset_lock_all(dev); intel_connector_remove_from_fbdev(intel_connector); intel_connector->mst_port = NULL; drm_modeset_unlock_all(dev); drm_connector_unreference(&intel_connector->base); DRM_DEBUG_KMS("\n"); }
static int evdi_user_framebuffer_dirty(struct drm_framebuffer *fb, struct drm_file *file, unsigned flags, unsigned color, struct drm_clip_rect *clips, unsigned num_clips) { struct evdi_framebuffer *ufb = to_evdi_fb(fb); struct drm_device *dev = ufb->base.dev; struct evdi_device *evdi = dev->dev_private; int i; int ret = 0; EVDI_CHECKPT(); drm_modeset_lock_all(fb->dev); if (ufb->obj->base.import_attach) { ret = dma_buf_begin_cpu_access(ufb->obj->base.import_attach->dmabuf, 0, ufb->obj->base.size, DMA_FROM_DEVICE); if (ret) { goto unlock; } } for (i = 0; i < num_clips; i++) { ret = evdi_handle_damage(ufb, clips[i].x1, clips[i].y1, clips[i].x2 - clips[i].x1, clips[i].y2 - clips[i].y1); if (ret) { goto unlock; } } if (ufb->obj->base.import_attach) { dma_buf_end_cpu_access(ufb->obj->base.import_attach->dmabuf, 0, ufb->obj->base.size, DMA_FROM_DEVICE); } atomic_add(1, &evdi->frame_count); unlock: drm_modeset_unlock_all(fb->dev); return ret; }
/** * drm_encoder_cleanup - cleans up an initialised encoder * @encoder: encoder to cleanup * * Cleans up the encoder but doesn't free the object. */ void drm_encoder_cleanup(struct drm_encoder *encoder) { struct drm_device *dev = encoder->dev; /* Note that the encoder_list is considered to be static; should we * remove the drm_encoder at runtime we would have to decrement all * the indices on the drm_encoder after us in the encoder_list. */ drm_modeset_lock_all(dev); drm_mode_object_unregister(dev, &encoder->base); kfree(encoder->name); list_del(&encoder->head); dev->mode_config.num_encoder--; drm_modeset_unlock_all(dev); memset(encoder, 0, sizeof(*encoder)); }
static int omap_framebuffer_dirty(struct drm_framebuffer *fb, struct drm_file *file_priv, unsigned flags, unsigned color, struct drm_clip_rect *clips, unsigned num_clips) { int i; drm_modeset_lock_all(fb->dev); for (i = 0; i < num_clips; i++) { omap_framebuffer_flush(fb, clips[i].x1, clips[i].y1, clips[i].x2 - clips[i].x1, clips[i].y2 - clips[i].y1); } drm_modeset_unlock_all(fb->dev); return 0; }
/** * lastclose - clean up after all DRM clients have exited * @dev: DRM device * * Take care of cleaning up after all DRM clients have exited. In the * mode setting case, we want to restore the kernel's initial mode (just * in case the last client left us in a bad state). */ static void dev_lastclose(struct drm_device *dev) { int i; /* we don't support vga-switcheroo.. so just make sure the fbdev * mode is active */ struct omap_drm_private *priv = dev->dev_private; int ret; DBG("lastclose: dev=%p", dev); if (priv->rotation_prop) { /* need to restore default rotation state.. not sure * if there is a cleaner way to restore properties to * default state? Maybe a flag that properties should * automatically be restored to default state on * lastclose? */ for (i = 0; i < priv->num_crtcs; i++) { drm_object_property_set_value(&priv->crtcs[i]->base, priv->rotation_prop, 0); } for (i = 0; i < priv->num_planes; i++) { drm_object_property_set_value(&priv->planes[i]->base, priv->rotation_prop, 0); } } if (priv->fbdev) { drm_modeset_lock_all(dev); ret = drm_fb_helper_restore_fbdev_mode(priv->fbdev); drm_modeset_unlock_all(dev); if (ret) DBG("failed to restore crtc mode"); /* * Flush crtcs to finish any pending work. * This makes sure the fbdev mode has been restored. */ for (i = 0; i < priv->num_crtcs; i++) omap_crtc_flush(priv->crtcs[i]); } }
/** * drm_encoder_init - Init a preallocated encoder * @dev: drm device * @encoder: the encoder to init * @funcs: callbacks for this encoder * @encoder_type: user visible type of the encoder * @name: printf style format string for the encoder name, or NULL for default name * * Initialises a preallocated encoder. Encoder should be subclassed as part of * driver encoder objects. At driver unload time drm_encoder_cleanup() should be * called from the driver's destroy hook in &drm_encoder_funcs. * * Returns: * Zero on success, error code on failure. */ int drm_encoder_init(struct drm_device *dev, struct drm_encoder *encoder, const struct drm_encoder_funcs *funcs, int encoder_type, const char *name, ...) { int ret; drm_modeset_lock_all(dev); ret = drm_mode_object_get(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER); if (ret) goto out_unlock; encoder->dev = dev; encoder->encoder_type = encoder_type; encoder->funcs = funcs; if (name) { va_list ap; va_start(ap, name); encoder->name = kvasprintf(GFP_KERNEL, name, ap); va_end(ap); } else { encoder->name = kasprintf(GFP_KERNEL, "%s-%d", drm_encoder_enum_list[encoder_type].name, encoder->base.id); } if (!encoder->name) { ret = -ENOMEM; goto out_put; } list_add_tail(&encoder->head, &dev->mode_config.encoder_list); encoder->index = dev->mode_config.num_encoder++; out_put: if (ret) drm_mode_object_unregister(dev, &encoder->base); out_unlock: drm_modeset_unlock_all(dev); return ret; }
static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb, struct drm_file *file, unsigned flags, unsigned color, struct drm_clip_rect *clips, unsigned num_clips) { struct udl_framebuffer *ufb = to_udl_fb(fb); int i; int ret = 0; drm_modeset_lock_all(fb->dev); if (!ufb->active_16) goto unlock; if (ufb->obj->base.import_attach) { ret = dma_buf_begin_cpu_access(ufb->obj->base.import_attach->dmabuf, DMA_FROM_DEVICE); if (ret) goto unlock; } for (i = 0; i < num_clips; i++) { ret = udl_handle_damage(ufb, clips[i].x1, clips[i].y1, clips[i].x2 - clips[i].x1, clips[i].y2 - clips[i].y1); if (ret) break; } if (ufb->obj->base.import_attach) { ret = dma_buf_end_cpu_access(ufb->obj->base.import_attach->dmabuf, DMA_FROM_DEVICE); } unlock: drm_modeset_unlock_all(fb->dev); return ret; }
static void hsw_trans_edp_pipe_A_crc_wa(struct drm_i915_private *dev_priv, bool enable) { struct drm_device *dev = &dev_priv->drm; struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, PIPE_A); struct intel_crtc_state *pipe_config; struct drm_atomic_state *state; int ret = 0; drm_modeset_lock_all(dev); state = drm_atomic_state_alloc(dev); if (!state) { ret = -ENOMEM; goto unlock; } state->acquire_ctx = drm_modeset_legacy_acquire_ctx(&crtc->base); pipe_config = intel_atomic_get_crtc_state(state, crtc); if (IS_ERR(pipe_config)) { ret = PTR_ERR(pipe_config); goto put_state; } pipe_config->pch_pfit.force_thru = enable; if (pipe_config->cpu_transcoder == TRANSCODER_EDP && pipe_config->pch_pfit.enabled != enable) pipe_config->base.connectors_changed = true; ret = drm_atomic_commit(state); put_state: drm_atomic_state_put(state); unlock: WARN(ret, "Toggling workaround to %i returns %i\n", enable, ret); drm_modeset_unlock_all(dev); }
int vmw_present_readback_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct vmw_private *dev_priv = vmw_priv(dev); struct drm_vmw_present_readback_arg *arg = (struct drm_vmw_present_readback_arg *)data; struct drm_vmw_fence_rep __user *user_fence_rep = (struct drm_vmw_fence_rep __user *) (unsigned long)arg->fence_rep; struct vmw_master *vmaster = vmw_master(file_priv->master); struct drm_vmw_rect __user *clips_ptr; struct drm_vmw_rect *clips = NULL; struct drm_framebuffer *fb; struct vmw_framebuffer *vfb; uint32_t num_clips; int ret; num_clips = arg->num_clips; clips_ptr = (struct drm_vmw_rect *)(unsigned long)arg->clips_ptr; if (unlikely(num_clips == 0)) return 0; if (clips_ptr == NULL) { DRM_ERROR("Argument clips_ptr must be specified.\n"); ret = -EINVAL; goto out_clips; } clips = kcalloc(num_clips, sizeof(*clips), GFP_KERNEL); if (clips == NULL) { DRM_ERROR("Failed to allocate clip rect list.\n"); ret = -ENOMEM; goto out_clips; } ret = copy_from_user(clips, clips_ptr, num_clips * sizeof(*clips)); if (ret) { DRM_ERROR("Failed to copy clip rects from userspace.\n"); ret = -EFAULT; goto out_no_copy; } drm_modeset_lock_all(dev); fb = drm_framebuffer_lookup(dev, arg->fb_id); if (!fb) { DRM_ERROR("Invalid framebuffer id.\n"); ret = -ENOENT; goto out_no_fb; } vfb = vmw_framebuffer_to_vfb(fb); if (!vfb->dmabuf) { DRM_ERROR("Framebuffer not dmabuf backed.\n"); ret = -EINVAL; goto out_no_ttm_lock; } ret = ttm_read_lock(&vmaster->lock, true); if (unlikely(ret != 0)) goto out_no_ttm_lock; ret = vmw_kms_readback(dev_priv, file_priv, vfb, user_fence_rep, clips, num_clips); ttm_read_unlock(&vmaster->lock); out_no_ttm_lock: drm_framebuffer_unreference(fb); out_no_fb: drm_modeset_unlock_all(dev); out_no_copy: kfree(clips); out_clips: return ret; }