]> rtime.felk.cvut.cz Git - zynq/linux.git/commitdiff
drm: xilinx: fb: Support the virtual resolution
authorHyun Kwon <hyun.kwon@xilinx.com>
Tue, 24 Nov 2015 01:12:48 +0000 (17:12 -0800)
committerMichal Simek <michal.simek@xilinx.com>
Thu, 26 Nov 2015 10:08:00 +0000 (11:08 +0100)
A framebuffer with virtual height can be allocated with this patch.
This would allow fbdev application to use that large framebuffer
as multiple buffers and pan display. The multiplier can be specified
by a module parameter, xilinx_drm.fbdev_vres, and the default value
is '2' to enable double-buffering as default.

Signed-off-by: Hyun Kwon <hyun.kwon@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
drivers/gpu/drm/xilinx/xilinx_drm_drv.c
drivers/gpu/drm/xilinx/xilinx_drm_fb.c
drivers/gpu/drm/xilinx/xilinx_drm_fb.h

index d197aa6aef3a429a6809331966d6476f8d729dd7..4bb7d16ba304a539d9d01ad6112b8eeea52bc60d 100644 (file)
 #define DRIVER_MAJOR   1
 #define DRIVER_MINOR   0
 
+static uint xilinx_drm_fbdev_vres = 2;
+module_param_named(fbdev_vres, xilinx_drm_fbdev_vres, uint, 0444);
+MODULE_PARM_DESC(fbdev_vres,
+                "fbdev virtual resolution multiplier for fb (default: 2)");
+
 /*
  * TODO: The possible pipeline configurations are numerous with Xilinx soft IPs.
  * It's not too bad for now, but the more proper way(Common Display Framework,
@@ -306,7 +311,8 @@ static int xilinx_drm_load(struct drm_device *drm, unsigned long flags)
        /* initialize xilinx framebuffer */
        bpp = xilinx_drm_format_bpp(xilinx_drm_crtc_get_format(private->crtc));
        align = xilinx_drm_crtc_get_align(private->crtc);
-       private->fb = xilinx_drm_fb_init(drm, bpp, 1, 1, align);
+       private->fb = xilinx_drm_fb_init(drm, bpp, 1, 1, align,
+                                        xilinx_drm_fbdev_vres);
        if (IS_ERR(private->fb)) {
                DRM_ERROR("failed to initialize drm cma fb\n");
                ret = PTR_ERR(private->fb);
index 255598b689efd8da4b93679adef49359a75a74fa..04b8987e9039dc97facebf7c3686b65d049f683b 100644 (file)
@@ -37,6 +37,7 @@ struct xilinx_drm_fbdev {
        struct drm_fb_helper    fb_helper;
        struct xilinx_drm_fb    *fb;
        unsigned int align;
+       unsigned int vres_mult;
 };
 
 static inline struct xilinx_drm_fbdev *to_fbdev(struct drm_fb_helper *fb_helper)
@@ -181,6 +182,7 @@ static int xilinx_drm_fbdev_create(struct drm_fb_helper *fb_helper,
                                    fbdev->align);
        mode_cmd.pixel_format = xilinx_drm_get_format(drm);
 
+       mode_cmd.height *= fbdev->vres_mult;
        size = mode_cmd.pitches[0] * mode_cmd.height;
        obj = drm_gem_cma_create(drm, size);
        if (IS_ERR(obj))
@@ -216,6 +218,7 @@ static int xilinx_drm_fbdev_create(struct drm_fb_helper *fb_helper,
 
        drm_fb_helper_fill_fix(fbi, base_fb->pitches[0], base_fb->depth);
        drm_fb_helper_fill_var(fbi, fb_helper, base_fb->width, base_fb->height);
+       fbi->var.yres = base_fb->height / fbdev->vres_mult;
 
        offset = fbi->var.xoffset * bytes_per_pixel;
        offset += fbi->var.yoffset * base_fb->pitches[0];
@@ -249,6 +252,7 @@ static struct drm_fb_helper_funcs xilinx_drm_fb_helper_funcs = {
  * @num_crtc: number of CRTCs
  * @max_conn_count: maximum number of connectors
  * @align: alignment value for pitch
+ * @vres_mult: multiplier for virtual resolution
  *
  * This function is based on drm_fbdev_cma_init().
  *
@@ -257,7 +261,7 @@ static struct drm_fb_helper_funcs xilinx_drm_fb_helper_funcs = {
 struct drm_fb_helper *
 xilinx_drm_fb_init(struct drm_device *drm, unsigned int preferred_bpp,
                   unsigned int num_crtc, unsigned int max_conn_count,
-                  unsigned int align)
+                  unsigned int align, unsigned int vres_mult)
 {
        struct xilinx_drm_fbdev *fbdev;
        struct drm_fb_helper *fb_helper;
@@ -269,6 +273,8 @@ xilinx_drm_fb_init(struct drm_device *drm, unsigned int preferred_bpp,
                return ERR_PTR(-ENOMEM);
        }
 
+       fbdev->vres_mult = vres_mult;
+
        fbdev->align = align;
        fb_helper = &fbdev->fb_helper;
        drm_fb_helper_prepare(drm, fb_helper, &xilinx_drm_fb_helper_funcs);
index af5e381864aa92993a46ab0233e414894028b97d..ae91ace9a4e55e53c0f05418cbe25797e8e11672 100644 (file)
@@ -26,7 +26,7 @@ xilinx_drm_fb_get_gem_obj(struct drm_framebuffer *base_fb, unsigned int plane);
 struct drm_fb_helper *
 xilinx_drm_fb_init(struct drm_device *drm, unsigned int preferred_bpp,
                   unsigned int num_crtc, unsigned int max_conn_count,
-                  unsigned int align);
+                  unsigned int align, unsigned int vres_mult);
 void xilinx_drm_fb_fini(struct drm_fb_helper *fb_helper);
 
 void xilinx_drm_fb_restore_mode(struct drm_fb_helper *fb_helper);