drm/tegra: Make legacy fbdev support optional
authorThierry Reding <treding@nvidia.com>
Thu, 31 Oct 2013 12:28:50 +0000 (13:28 +0100)
committerThierry Reding <treding@nvidia.com>
Fri, 20 Dec 2013 14:56:05 +0000 (15:56 +0100)
A lot of the modern userspace is capable of working without the legacy
fbdev support. kmscon can be used as a replacement for the framebuffer
console, and KMS X drivers create their own framebuffers.

Most people don't have a system where all of this works yet, though, so
leave support enabled by default.

Signed-off-by: Thierry Reding <treding@nvidia.com>
drivers/gpu/drm/tegra/Kconfig
drivers/gpu/drm/tegra/drm.c
drivers/gpu/drm/tegra/drm.h
drivers/gpu/drm/tegra/fb.c

index ce214c3..354ddb2 100644 (file)
@@ -3,13 +3,9 @@ config DRM_TEGRA
        depends on ARCH_TEGRA || (ARM && COMPILE_TEST)
        depends on DRM
        depends on RESET_CONTROLLER
-       select DRM_KMS_FB_HELPER
        select DRM_KMS_HELPER
        select DRM_MIPI_DSI
        select DRM_PANEL
-       select FB_SYS_FILLRECT
-       select FB_SYS_COPYAREA
-       select FB_SYS_IMAGEBLIT
        select TEGRA_HOST1X
        help
          Choose this option if you have an NVIDIA Tegra SoC.
@@ -19,6 +15,18 @@ config DRM_TEGRA
 
 if DRM_TEGRA
 
+config DRM_TEGRA_FBDEV
+       bool "Enable legacy fbdev support"
+       select DRM_KMS_FB_HELPER
+       select FB_SYS_FILLRECT
+       select FB_SYS_COPYAREA
+       select FB_SYS_IMAGEBLIT
+       default y
+       help
+         Choose this option if you have a need for the legacy fbdev support.
+         Note that this support also provides the Linux console on top of
+         the Tegra modesetting driver.
+
 config DRM_TEGRA_DEBUG
        bool "NVIDIA Tegra DRM debug support"
        help
index 08e9e37..a0b3481 100644 (file)
@@ -104,9 +104,11 @@ static void tegra_drm_context_free(struct tegra_drm_context *context)
 
 static void tegra_drm_lastclose(struct drm_device *drm)
 {
+#ifdef CONFIG_TEGRA_DRM_FBDEV
        struct tegra_drm *tegra = drm->dev_private;
 
        tegra_fbdev_restore_mode(tegra->fbdev);
+#endif
 }
 
 static struct host1x_bo *
index ddaa937..6b293c8 100644 (file)
@@ -27,10 +27,12 @@ struct tegra_fb {
        unsigned int num_planes;
 };
 
+#ifdef CONFIG_DRM_TEGRA_FBDEV
 struct tegra_fbdev {
        struct drm_fb_helper base;
        struct tegra_fb *fb;
 };
+#endif
 
 struct tegra_drm {
        struct drm_device *drm;
@@ -38,7 +40,9 @@ struct tegra_drm {
        struct mutex clients_lock;
        struct list_head clients;
 
+#ifdef CONFIG_DRM_TEGRA_FBDEV
        struct tegra_fbdev *fbdev;
+#endif
 };
 
 struct tegra_drm_client;
@@ -265,7 +269,9 @@ bool tegra_fb_is_bottom_up(struct drm_framebuffer *framebuffer);
 bool tegra_fb_is_tiled(struct drm_framebuffer *framebuffer);
 extern int tegra_drm_fb_init(struct drm_device *drm);
 extern void tegra_drm_fb_exit(struct drm_device *drm);
+#ifdef CONFIG_DRM_TEGRA_FBDEV
 extern void tegra_fbdev_restore_mode(struct tegra_fbdev *fbdev);
+#endif
 
 extern struct platform_driver tegra_dc_driver;
 extern struct platform_driver tegra_dsi_driver;
index a3835e7..bd4bf21 100644 (file)
@@ -18,10 +18,12 @@ static inline struct tegra_fb *to_tegra_fb(struct drm_framebuffer *fb)
        return container_of(fb, struct tegra_fb, base);
 }
 
+#ifdef CONFIG_DRM_TEGRA_FBDEV
 static inline struct tegra_fbdev *to_tegra_fbdev(struct drm_fb_helper *helper)
 {
        return container_of(helper, struct tegra_fbdev, base);
 }
+#endif
 
 struct tegra_bo *tegra_fb_get_plane(struct drm_framebuffer *framebuffer,
                                    unsigned int index)
@@ -172,6 +174,7 @@ unreference:
        return ERR_PTR(err);
 }
 
+#ifdef CONFIG_DRM_TEGRA_FBDEV
 static struct fb_ops tegra_fb_ops = {
        .owner = THIS_MODULE,
        .fb_fillrect = sys_fillrect,
@@ -339,6 +342,15 @@ static void tegra_fbdev_free(struct tegra_fbdev *fbdev)
        kfree(fbdev);
 }
 
+void tegra_fbdev_restore_mode(struct tegra_fbdev *fbdev)
+{
+       if (fbdev) {
+               drm_modeset_lock_all(fbdev->base.dev);
+               drm_fb_helper_restore_fbdev_mode(&fbdev->base);
+               drm_modeset_unlock_all(fbdev->base.dev);
+       }
+}
+
 static void tegra_fb_output_poll_changed(struct drm_device *drm)
 {
        struct tegra_drm *tegra = drm->dev_private;
@@ -346,16 +358,20 @@ static void tegra_fb_output_poll_changed(struct drm_device *drm)
        if (tegra->fbdev)
                drm_fb_helper_hotplug_event(&tegra->fbdev->base);
 }
+#endif
 
 static const struct drm_mode_config_funcs tegra_drm_mode_funcs = {
        .fb_create = tegra_fb_create,
+#ifdef CONFIG_DRM_TEGRA_FBDEV
        .output_poll_changed = tegra_fb_output_poll_changed,
+#endif
 };
 
 int tegra_drm_fb_init(struct drm_device *drm)
 {
+#ifdef CONFIG_DRM_TEGRA_FBDEV
        struct tegra_drm *tegra = drm->dev_private;
-       struct tegra_fbdev *fbdev;
+#endif
 
        drm->mode_config.min_width = 0;
        drm->mode_config.min_height = 0;
@@ -365,28 +381,21 @@ int tegra_drm_fb_init(struct drm_device *drm)
 
        drm->mode_config.funcs = &tegra_drm_mode_funcs;
 
-       fbdev = tegra_fbdev_create(drm, 32, drm->mode_config.num_crtc,
-                                  drm->mode_config.num_connector);
-       if (IS_ERR(fbdev))
-               return PTR_ERR(fbdev);
-
-       tegra->fbdev = fbdev;
+#ifdef CONFIG_DRM_TEGRA_FBDEV
+       tegra->fbdev = tegra_fbdev_create(drm, 32, drm->mode_config.num_crtc,
+                                         drm->mode_config.num_connector);
+       if (IS_ERR(tegra->fbdev))
+               return PTR_ERR(tegra->fbdev);
+#endif
 
        return 0;
 }
 
 void tegra_drm_fb_exit(struct drm_device *drm)
 {
+#ifdef CONFIG_DRM_TEGRA_FBDEV
        struct tegra_drm *tegra = drm->dev_private;
 
        tegra_fbdev_free(tegra->fbdev);
-}
-
-void tegra_fbdev_restore_mode(struct tegra_fbdev *fbdev)
-{
-       if (fbdev) {
-               drm_modeset_lock_all(fbdev->base.dev);
-               drm_fb_helper_restore_fbdev_mode(&fbdev->base);
-               drm_modeset_unlock_all(fbdev->base.dev);
-       }
+#endif
 }