| From fc0913f6a501656257f93a2ac79c01b0ebd2c166 Mon Sep 17 00:00:00 2001 |
| From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> |
| Date: Thu, 14 Mar 2013 22:45:22 +0100 |
| Subject: drm/rcar-du: Add FBDEV emulation support |
| |
| Use the FB CMA helpers to implement FBDEV emulation support. The VGA |
| connector status must be reported as connector_status_connected instead |
| of connector_status_unknown to be usable by the emulation layer. |
| |
| Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> |
| (cherry picked from commit 3864c6f446f3c2ebbeca1d45e28452682706c1aa) |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| --- |
| drivers/gpu/drm/rcar-du/rcar_du_drv.c | 14 +++++++++++++ |
| drivers/gpu/drm/rcar-du/rcar_du_drv.h | 2 ++ |
| drivers/gpu/drm/rcar-du/rcar_du_kms.c | 36 +++++++++++++++++++++++++------- |
| drivers/gpu/drm/rcar-du/rcar_du_vgacon.c | 2 +- |
| 4 files changed, 45 insertions(+), 9 deletions(-) |
| |
| diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c |
| index a4c2007f5bb5..c63914e66089 100644 |
| --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c |
| +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c |
| @@ -21,6 +21,7 @@ |
| |
| #include <drm/drmP.h> |
| #include <drm/drm_crtc_helper.h> |
| +#include <drm/drm_fb_cma_helper.h> |
| #include <drm/drm_gem_cma_helper.h> |
| |
| #include "rcar_du_crtc.h" |
| @@ -34,6 +35,11 @@ |
| |
| static int rcar_du_unload(struct drm_device *dev) |
| { |
| + struct rcar_du_device *rcdu = dev->dev_private; |
| + |
| + if (rcdu->fbdev) |
| + drm_fbdev_cma_fini(rcdu->fbdev); |
| + |
| drm_kms_helper_poll_fini(dev); |
| drm_mode_config_cleanup(dev); |
| drm_vblank_cleanup(dev); |
| @@ -109,6 +115,13 @@ static void rcar_du_preclose(struct drm_device *dev, struct drm_file *file) |
| rcar_du_crtc_cancel_page_flip(&rcdu->crtcs[i], file); |
| } |
| |
| +static void rcar_du_lastclose(struct drm_device *dev) |
| +{ |
| + struct rcar_du_device *rcdu = dev->dev_private; |
| + |
| + drm_fbdev_cma_restore_mode(rcdu->fbdev); |
| +} |
| + |
| static int rcar_du_enable_vblank(struct drm_device *dev, int crtc) |
| { |
| struct rcar_du_device *rcdu = dev->dev_private; |
| @@ -145,6 +158,7 @@ static struct drm_driver rcar_du_driver = { |
| .load = rcar_du_load, |
| .unload = rcar_du_unload, |
| .preclose = rcar_du_preclose, |
| + .lastclose = rcar_du_lastclose, |
| .get_vblank_counter = drm_vblank_count, |
| .enable_vblank = rcar_du_enable_vblank, |
| .disable_vblank = rcar_du_disable_vblank, |
| diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h |
| index 050d71c1f785..65d2d636b002 100644 |
| --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h |
| +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h |
| @@ -23,6 +23,7 @@ |
| struct clk; |
| struct device; |
| struct drm_device; |
| +struct drm_fbdev_cma; |
| struct rcar_du_device; |
| struct rcar_du_lvdsenc; |
| |
| @@ -66,6 +67,7 @@ struct rcar_du_device { |
| void __iomem *mmio; |
| |
| struct drm_device *ddev; |
| + struct drm_fbdev_cma *fbdev; |
| |
| struct rcar_du_crtc crtcs[3]; |
| unsigned int num_crtcs; |
| diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c |
| index cc71b1a0c3ce..b31ac080c4a7 100644 |
| --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c |
| +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c |
| @@ -167,8 +167,16 @@ rcar_du_fb_create(struct drm_device *dev, struct drm_file *file_priv, |
| return drm_fb_cma_create(dev, file_priv, mode_cmd); |
| } |
| |
| +static void rcar_du_output_poll_changed(struct drm_device *dev) |
| +{ |
| + struct rcar_du_device *rcdu = dev->dev_private; |
| + |
| + drm_fbdev_cma_hotplug_event(rcdu->fbdev); |
| +} |
| + |
| static const struct drm_mode_config_funcs rcar_du_mode_config_funcs = { |
| .fb_create = rcar_du_fb_create, |
| + .output_poll_changed = rcar_du_output_poll_changed, |
| }; |
| |
| int rcar_du_modeset_init(struct rcar_du_device *rcdu) |
| @@ -179,17 +187,18 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) |
| |
| struct drm_device *dev = rcdu->ddev; |
| struct drm_encoder *encoder; |
| + struct drm_fbdev_cma *fbdev; |
| unsigned int num_groups; |
| unsigned int i; |
| int ret; |
| |
| - drm_mode_config_init(rcdu->ddev); |
| + drm_mode_config_init(dev); |
| |
| - rcdu->ddev->mode_config.min_width = 0; |
| - rcdu->ddev->mode_config.min_height = 0; |
| - rcdu->ddev->mode_config.max_width = 4095; |
| - rcdu->ddev->mode_config.max_height = 2047; |
| - rcdu->ddev->mode_config.funcs = &rcar_du_mode_config_funcs; |
| + dev->mode_config.min_width = 0; |
| + dev->mode_config.min_height = 0; |
| + dev->mode_config.max_width = 4095; |
| + dev->mode_config.max_height = 2047; |
| + dev->mode_config.funcs = &rcar_du_mode_config_funcs; |
| |
| rcdu->num_crtcs = rcdu->info->num_crtcs; |
| |
| @@ -262,9 +271,20 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) |
| return ret; |
| } |
| |
| - drm_kms_helper_poll_init(rcdu->ddev); |
| + drm_kms_helper_poll_init(dev); |
| + |
| + drm_helper_disable_unused_functions(dev); |
| + |
| + fbdev = drm_fbdev_cma_init(dev, 32, dev->mode_config.num_crtc, |
| + dev->mode_config.num_connector); |
| + if (IS_ERR(fbdev)) |
| + return PTR_ERR(fbdev); |
| + |
| +#ifndef CONFIG_FRAMEBUFFER_CONSOLE |
| + drm_fbdev_cma_restore_mode(fbdev); |
| +#endif |
| |
| - drm_helper_disable_unused_functions(rcdu->ddev); |
| + rcdu->fbdev = fbdev; |
| |
| return 0; |
| } |
| diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vgacon.c b/drivers/gpu/drm/rcar-du/rcar_du_vgacon.c |
| index 36105db9bda1..41d563adfeaa 100644 |
| --- a/drivers/gpu/drm/rcar-du/rcar_du_vgacon.c |
| +++ b/drivers/gpu/drm/rcar-du/rcar_du_vgacon.c |
| @@ -46,7 +46,7 @@ static void rcar_du_vga_connector_destroy(struct drm_connector *connector) |
| static enum drm_connector_status |
| rcar_du_vga_connector_detect(struct drm_connector *connector, bool force) |
| { |
| - return connector_status_unknown; |
| + return connector_status_connected; |
| } |
| |
| static const struct drm_connector_funcs connector_funcs = { |
| -- |
| 1.8.5.rc3 |
| |