diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_fbdev.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_fbdev.c | 79 |
1 files changed, 33 insertions, 46 deletions
diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index 0c4cde6b2e6f..b8af35187d22 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -189,7 +189,7 @@ static int intelfb_create(struct drm_fb_helper *helper, " releasing it\n", intel_fb->base.width, intel_fb->base.height, sizes->fb_width, sizes->fb_height); - drm_framebuffer_unreference(&intel_fb->base); + drm_framebuffer_put(&intel_fb->base); intel_fb = ifbdev->fb = NULL; } if (!intel_fb || WARN_ON(!intel_fb->obj)) { @@ -206,6 +206,7 @@ static int intelfb_create(struct drm_fb_helper *helper, } mutex_lock(&dev->struct_mutex); + intel_runtime_pm_get(dev_priv); /* Pin the GGTT vma for our access via info->screen_base. * This also validates that any existing fb inherited from the @@ -232,7 +233,6 @@ static int intelfb_create(struct drm_fb_helper *helper, strcpy(info->fix.id, "inteldrmfb"); - info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT; info->fbops = &intelfb_ops; /* setup aperture base/size for vesafb takeover */ @@ -270,6 +270,7 @@ static int intelfb_create(struct drm_fb_helper *helper, fb->width, fb->height, i915_ggtt_offset(vma)); ifbdev->vma = vma; + intel_runtime_pm_put(dev_priv); mutex_unlock(&dev->struct_mutex); vga_switcheroo_client_fb_set(pdev, info); return 0; @@ -277,31 +278,11 @@ static int intelfb_create(struct drm_fb_helper *helper, out_unpin: intel_unpin_fb_vma(vma); out_unlock: + intel_runtime_pm_put(dev_priv); mutex_unlock(&dev->struct_mutex); return ret; } -/** Sets the color ramps on behalf of RandR */ -static void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, - u16 blue, int regno) -{ - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - - intel_crtc->lut_r[regno] = red >> 8; - intel_crtc->lut_g[regno] = green >> 8; - intel_crtc->lut_b[regno] = blue >> 8; -} - -static void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, - u16 *blue, int regno) -{ - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - - *red = intel_crtc->lut_r[regno] << 8; - *green = intel_crtc->lut_g[regno] << 8; - *blue = intel_crtc->lut_b[regno] << 8; -} - static struct drm_fb_helper_crtc * intel_fb_helper_crtc(struct drm_fb_helper *fb_helper, struct drm_crtc *crtc) { @@ -352,14 +333,20 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper, unsigned int count = min(fb_helper->connector_count, BITS_PER_LONG); int i, j; bool *save_enabled; - bool fallback = true; + bool fallback = true, ret = true; int num_connectors_enabled = 0; int num_connectors_detected = 0; + struct drm_modeset_acquire_ctx ctx; save_enabled = kcalloc(count, sizeof(bool), GFP_KERNEL); if (!save_enabled) return false; + drm_modeset_acquire_init(&ctx, 0); + + while (drm_modeset_lock_all_ctx(fb_helper->dev, &ctx) != 0) + drm_modeset_backoff(&ctx); + memcpy(save_enabled, enabled, count); mask = GENMASK(count - 1, 0); conn_configured = 0; @@ -370,7 +357,6 @@ retry: struct drm_connector *connector; struct drm_encoder *encoder; struct drm_fb_helper_crtc *new_crtc; - struct intel_crtc *intel_crtc; fb_conn = fb_helper->connector_info[i]; connector = fb_conn->connector; @@ -412,13 +398,6 @@ retry: num_connectors_enabled++; - intel_crtc = to_intel_crtc(connector->state->crtc); - for (j = 0; j < 256; j++) { - intel_crtc->lut_r[j] = j; - intel_crtc->lut_g[j] = j; - intel_crtc->lut_b[j] = j; - } - new_crtc = intel_fb_helper_crtc(fb_helper, connector->state->crtc); @@ -509,18 +488,18 @@ retry: bail: DRM_DEBUG_KMS("Not using firmware configuration\n"); memcpy(enabled, save_enabled, count); - kfree(save_enabled); - return false; + ret = false; } + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); + kfree(save_enabled); - return true; + return ret; } static const struct drm_fb_helper_funcs intel_fb_helper_funcs = { .initial_config = intel_fb_initial_config, - .gamma_set = intel_crtc_fb_gamma_set, - .gamma_get = intel_crtc_fb_gamma_get, .fb_probe = intelfb_create, }; @@ -531,8 +510,6 @@ static void intel_fbdev_destroy(struct intel_fbdev *ifbdev) * trying to rectify all the possible error paths leading here. */ - drm_fb_helper_unregister_fbi(&ifbdev->helper); - drm_fb_helper_fini(&ifbdev->helper); if (ifbdev->vma) { @@ -650,7 +627,7 @@ static bool intel_fbdev_init_bios(struct drm_device *dev, ifbdev->preferred_bpp = fb->base.format->cpp[0] * 8; ifbdev->fb = fb; - drm_framebuffer_reference(&ifbdev->fb->base); + drm_framebuffer_get(&ifbdev->fb->base); /* Final pass to check if any active pipes don't have fbs */ for_each_crtc(dev, crtc) { @@ -720,8 +697,10 @@ static void intel_fbdev_initial_config(void *data, async_cookie_t cookie) /* Due to peculiar init order wrt to hpd handling this is separate. */ if (drm_fb_helper_initial_config(&ifbdev->helper, - ifbdev->preferred_bpp)) - intel_fbdev_fini(ifbdev->helper.dev); + ifbdev->preferred_bpp)) { + intel_fbdev_unregister(to_i915(ifbdev->helper.dev)); + intel_fbdev_fini(to_i915(ifbdev->helper.dev)); + } } void intel_fbdev_initial_config_async(struct drm_device *dev) @@ -744,9 +723,8 @@ static void intel_fbdev_sync(struct intel_fbdev *ifbdev) ifbdev->cookie = 0; } -void intel_fbdev_fini(struct drm_device *dev) +void intel_fbdev_unregister(struct drm_i915_private *dev_priv) { - struct drm_i915_private *dev_priv = to_i915(dev); struct intel_fbdev *ifbdev = dev_priv->fbdev; if (!ifbdev) @@ -756,8 +734,17 @@ void intel_fbdev_fini(struct drm_device *dev) if (!current_is_async()) intel_fbdev_sync(ifbdev); + drm_fb_helper_unregister_fbi(&ifbdev->helper); +} + +void intel_fbdev_fini(struct drm_i915_private *dev_priv) +{ + struct intel_fbdev *ifbdev = fetch_and_zero(&dev_priv->fbdev); + + if (!ifbdev) + return; + intel_fbdev_destroy(ifbdev); - dev_priv->fbdev = NULL; } void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous) @@ -813,7 +800,7 @@ void intel_fbdev_output_poll_changed(struct drm_device *dev) { struct intel_fbdev *ifbdev = to_i915(dev)->fbdev; - if (ifbdev && ifbdev->vma) + if (ifbdev) drm_fb_helper_hotplug_event(&ifbdev->helper); } |