|
@@ -212,6 +212,58 @@ static struct fb_ops nouveau_fbcon_sw_ops = {
|
|
|
.fb_debug_leave = drm_fb_helper_debug_leave,
|
|
|
};
|
|
|
|
|
|
+void
|
|
|
+nouveau_fbcon_accel_save_disable(struct drm_device *dev)
|
|
|
+{
|
|
|
+ struct nouveau_drm *drm = nouveau_drm(dev);
|
|
|
+ if (drm->fbcon) {
|
|
|
+ drm->fbcon->saved_flags = drm->fbcon->helper.fbdev->flags;
|
|
|
+ drm->fbcon->helper.fbdev->flags |= FBINFO_HWACCEL_DISABLED;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void
|
|
|
+nouveau_fbcon_accel_restore(struct drm_device *dev)
|
|
|
+{
|
|
|
+ struct nouveau_drm *drm = nouveau_drm(dev);
|
|
|
+ if (drm->fbcon) {
|
|
|
+ drm->fbcon->helper.fbdev->flags = drm->fbcon->saved_flags;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void
|
|
|
+nouveau_fbcon_accel_fini(struct drm_device *dev)
|
|
|
+{
|
|
|
+ struct nouveau_drm *drm = nouveau_drm(dev);
|
|
|
+ struct nouveau_fbdev *fbcon = drm->fbcon;
|
|
|
+ if (fbcon && drm->channel) {
|
|
|
+ console_lock();
|
|
|
+ fbcon->helper.fbdev->flags |= FBINFO_HWACCEL_DISABLED;
|
|
|
+ console_unlock();
|
|
|
+ nouveau_channel_idle(drm->channel);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void
|
|
|
+nouveau_fbcon_accel_init(struct drm_device *dev)
|
|
|
+{
|
|
|
+ struct nouveau_drm *drm = nouveau_drm(dev);
|
|
|
+ struct nouveau_fbdev *fbcon = drm->fbcon;
|
|
|
+ struct fb_info *info = fbcon->helper.fbdev;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ if (nv_device(drm->device)->card_type < NV_50)
|
|
|
+ ret = nv04_fbcon_accel_init(info);
|
|
|
+ else
|
|
|
+ if (nv_device(drm->device)->card_type < NV_C0)
|
|
|
+ ret = nv50_fbcon_accel_init(info);
|
|
|
+ else
|
|
|
+ ret = nvc0_fbcon_accel_init(info);
|
|
|
+
|
|
|
+ if (ret == 0)
|
|
|
+ info->fbops = &nouveau_fbcon_ops;
|
|
|
+}
|
|
|
+
|
|
|
static void nouveau_fbcon_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
|
|
|
u16 blue, int regno)
|
|
|
{
|
|
@@ -357,20 +409,8 @@ nouveau_fbcon_create(struct drm_fb_helper *helper,
|
|
|
|
|
|
mutex_unlock(&dev->struct_mutex);
|
|
|
|
|
|
- if (chan) {
|
|
|
- ret = -ENODEV;
|
|
|
- if (device->card_type < NV_50)
|
|
|
- ret = nv04_fbcon_accel_init(info);
|
|
|
- else
|
|
|
- if (device->card_type < NV_C0)
|
|
|
- ret = nv50_fbcon_accel_init(info);
|
|
|
- else
|
|
|
- ret = nvc0_fbcon_accel_init(info);
|
|
|
-
|
|
|
- if (ret == 0)
|
|
|
- info->fbops = &nouveau_fbcon_ops;
|
|
|
- }
|
|
|
-
|
|
|
+ if (chan)
|
|
|
+ nouveau_fbcon_accel_init(dev);
|
|
|
nouveau_fbcon_zfill(dev, fbcon);
|
|
|
|
|
|
/* To allow resizeing without swapping buffers */
|
|
@@ -499,30 +539,12 @@ nouveau_fbcon_fini(struct drm_device *dev)
|
|
|
if (!drm->fbcon)
|
|
|
return;
|
|
|
|
|
|
+ nouveau_fbcon_accel_fini(dev);
|
|
|
nouveau_fbcon_destroy(dev, drm->fbcon);
|
|
|
kfree(drm->fbcon);
|
|
|
drm->fbcon = NULL;
|
|
|
}
|
|
|
|
|
|
-void
|
|
|
-nouveau_fbcon_save_disable_accel(struct drm_device *dev)
|
|
|
-{
|
|
|
- struct nouveau_drm *drm = nouveau_drm(dev);
|
|
|
- if (drm->fbcon) {
|
|
|
- drm->fbcon->saved_flags = drm->fbcon->helper.fbdev->flags;
|
|
|
- drm->fbcon->helper.fbdev->flags |= FBINFO_HWACCEL_DISABLED;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-void
|
|
|
-nouveau_fbcon_restore_accel(struct drm_device *dev)
|
|
|
-{
|
|
|
- struct nouveau_drm *drm = nouveau_drm(dev);
|
|
|
- if (drm->fbcon) {
|
|
|
- drm->fbcon->helper.fbdev->flags = drm->fbcon->saved_flags;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
void
|
|
|
nouveau_fbcon_set_suspend(struct drm_device *dev, int state)
|
|
|
{
|
|
@@ -530,10 +552,10 @@ nouveau_fbcon_set_suspend(struct drm_device *dev, int state)
|
|
|
if (drm->fbcon) {
|
|
|
console_lock();
|
|
|
if (state == 1)
|
|
|
- nouveau_fbcon_save_disable_accel(dev);
|
|
|
+ nouveau_fbcon_accel_save_disable(dev);
|
|
|
fb_set_suspend(drm->fbcon->helper.fbdev, state);
|
|
|
if (state == 0) {
|
|
|
- nouveau_fbcon_restore_accel(dev);
|
|
|
+ nouveau_fbcon_accel_restore(dev);
|
|
|
nouveau_fbcon_zfill(dev, drm->fbcon);
|
|
|
}
|
|
|
console_unlock();
|