162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * vivid-osd.c - osd support for testing overlays. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/module.h> 962306a36Sopenharmony_ci#include <linux/errno.h> 1062306a36Sopenharmony_ci#include <linux/kernel.h> 1162306a36Sopenharmony_ci#include <linux/init.h> 1262306a36Sopenharmony_ci#include <linux/sched.h> 1362306a36Sopenharmony_ci#include <linux/slab.h> 1462306a36Sopenharmony_ci#include <linux/font.h> 1562306a36Sopenharmony_ci#include <linux/mutex.h> 1662306a36Sopenharmony_ci#include <linux/videodev2.h> 1762306a36Sopenharmony_ci#include <linux/kthread.h> 1862306a36Sopenharmony_ci#include <linux/freezer.h> 1962306a36Sopenharmony_ci#include <linux/fb.h> 2062306a36Sopenharmony_ci#include <media/videobuf2-vmalloc.h> 2162306a36Sopenharmony_ci#include <media/v4l2-device.h> 2262306a36Sopenharmony_ci#include <media/v4l2-ioctl.h> 2362306a36Sopenharmony_ci#include <media/v4l2-ctrls.h> 2462306a36Sopenharmony_ci#include <media/v4l2-fh.h> 2562306a36Sopenharmony_ci#include <media/v4l2-event.h> 2662306a36Sopenharmony_ci#include <media/v4l2-common.h> 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci#include "vivid-core.h" 2962306a36Sopenharmony_ci#include "vivid-osd.h" 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci#define MAX_OSD_WIDTH 720 3262306a36Sopenharmony_ci#define MAX_OSD_HEIGHT 576 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci/* 3562306a36Sopenharmony_ci * Order: white, yellow, cyan, green, magenta, red, blue, black, 3662306a36Sopenharmony_ci * and same again with the alpha bit set (if any) 3762306a36Sopenharmony_ci */ 3862306a36Sopenharmony_cistatic const u16 rgb555[16] = { 3962306a36Sopenharmony_ci 0x7fff, 0x7fe0, 0x03ff, 0x03e0, 0x7c1f, 0x7c00, 0x001f, 0x0000, 4062306a36Sopenharmony_ci 0xffff, 0xffe0, 0x83ff, 0x83e0, 0xfc1f, 0xfc00, 0x801f, 0x8000 4162306a36Sopenharmony_ci}; 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_cistatic const u16 rgb565[16] = { 4462306a36Sopenharmony_ci 0xffff, 0xffe0, 0x07ff, 0x07e0, 0xf81f, 0xf800, 0x001f, 0x0000, 4562306a36Sopenharmony_ci 0xffff, 0xffe0, 0x07ff, 0x07e0, 0xf81f, 0xf800, 0x001f, 0x0000 4662306a36Sopenharmony_ci}; 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_civoid vivid_clear_fb(struct vivid_dev *dev) 4962306a36Sopenharmony_ci{ 5062306a36Sopenharmony_ci void *p = dev->video_vbase; 5162306a36Sopenharmony_ci const u16 *rgb = rgb555; 5262306a36Sopenharmony_ci unsigned x, y; 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci if (dev->fb_defined.green.length == 6) 5562306a36Sopenharmony_ci rgb = rgb565; 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci for (y = 0; y < dev->display_height; y++) { 5862306a36Sopenharmony_ci u16 *d = p; 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci for (x = 0; x < dev->display_width; x++) 6162306a36Sopenharmony_ci d[x] = rgb[(y / 16 + x / 16) % 16]; 6262306a36Sopenharmony_ci p += dev->display_byte_stride; 6362306a36Sopenharmony_ci } 6462306a36Sopenharmony_ci} 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci/* --------------------------------------------------------------------- */ 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_cistatic int vivid_fb_ioctl(struct fb_info *info, unsigned cmd, unsigned long arg) 6962306a36Sopenharmony_ci{ 7062306a36Sopenharmony_ci struct vivid_dev *dev = (struct vivid_dev *)info->par; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci switch (cmd) { 7362306a36Sopenharmony_ci case FBIOGET_VBLANK: { 7462306a36Sopenharmony_ci struct fb_vblank vblank; 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci memset(&vblank, 0, sizeof(vblank)); 7762306a36Sopenharmony_ci vblank.flags = FB_VBLANK_HAVE_COUNT | FB_VBLANK_HAVE_VCOUNT | 7862306a36Sopenharmony_ci FB_VBLANK_HAVE_VSYNC; 7962306a36Sopenharmony_ci vblank.count = 0; 8062306a36Sopenharmony_ci vblank.vcount = 0; 8162306a36Sopenharmony_ci vblank.hcount = 0; 8262306a36Sopenharmony_ci if (copy_to_user((void __user *)arg, &vblank, sizeof(vblank))) 8362306a36Sopenharmony_ci return -EFAULT; 8462306a36Sopenharmony_ci return 0; 8562306a36Sopenharmony_ci } 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci default: 8862306a36Sopenharmony_ci dprintk(dev, 1, "Unknown ioctl %08x\n", cmd); 8962306a36Sopenharmony_ci return -EINVAL; 9062306a36Sopenharmony_ci } 9162306a36Sopenharmony_ci return 0; 9262306a36Sopenharmony_ci} 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci/* Framebuffer device handling */ 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_cistatic int vivid_fb_set_var(struct vivid_dev *dev, struct fb_var_screeninfo *var) 9762306a36Sopenharmony_ci{ 9862306a36Sopenharmony_ci dprintk(dev, 1, "vivid_fb_set_var\n"); 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci if (var->bits_per_pixel != 16) { 10162306a36Sopenharmony_ci dprintk(dev, 1, "vivid_fb_set_var - Invalid bpp\n"); 10262306a36Sopenharmony_ci return -EINVAL; 10362306a36Sopenharmony_ci } 10462306a36Sopenharmony_ci dev->display_byte_stride = var->xres * dev->bytes_per_pixel; 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci return 0; 10762306a36Sopenharmony_ci} 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_cistatic int vivid_fb_get_fix(struct vivid_dev *dev, struct fb_fix_screeninfo *fix) 11062306a36Sopenharmony_ci{ 11162306a36Sopenharmony_ci dprintk(dev, 1, "vivid_fb_get_fix\n"); 11262306a36Sopenharmony_ci memset(fix, 0, sizeof(struct fb_fix_screeninfo)); 11362306a36Sopenharmony_ci strscpy(fix->id, "vioverlay fb", sizeof(fix->id)); 11462306a36Sopenharmony_ci fix->smem_start = dev->video_pbase; 11562306a36Sopenharmony_ci fix->smem_len = dev->video_buffer_size; 11662306a36Sopenharmony_ci fix->type = FB_TYPE_PACKED_PIXELS; 11762306a36Sopenharmony_ci fix->visual = FB_VISUAL_TRUECOLOR; 11862306a36Sopenharmony_ci fix->xpanstep = 1; 11962306a36Sopenharmony_ci fix->ypanstep = 1; 12062306a36Sopenharmony_ci fix->ywrapstep = 0; 12162306a36Sopenharmony_ci fix->line_length = dev->display_byte_stride; 12262306a36Sopenharmony_ci fix->accel = FB_ACCEL_NONE; 12362306a36Sopenharmony_ci return 0; 12462306a36Sopenharmony_ci} 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci/* Check the requested display mode, returning -EINVAL if we can't 12762306a36Sopenharmony_ci handle it. */ 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_cistatic int _vivid_fb_check_var(struct fb_var_screeninfo *var, struct vivid_dev *dev) 13062306a36Sopenharmony_ci{ 13162306a36Sopenharmony_ci dprintk(dev, 1, "vivid_fb_check_var\n"); 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci var->bits_per_pixel = 16; 13462306a36Sopenharmony_ci if (var->green.length == 5) { 13562306a36Sopenharmony_ci var->red.offset = 10; 13662306a36Sopenharmony_ci var->red.length = 5; 13762306a36Sopenharmony_ci var->green.offset = 5; 13862306a36Sopenharmony_ci var->green.length = 5; 13962306a36Sopenharmony_ci var->blue.offset = 0; 14062306a36Sopenharmony_ci var->blue.length = 5; 14162306a36Sopenharmony_ci var->transp.offset = 15; 14262306a36Sopenharmony_ci var->transp.length = 1; 14362306a36Sopenharmony_ci } else { 14462306a36Sopenharmony_ci var->red.offset = 11; 14562306a36Sopenharmony_ci var->red.length = 5; 14662306a36Sopenharmony_ci var->green.offset = 5; 14762306a36Sopenharmony_ci var->green.length = 6; 14862306a36Sopenharmony_ci var->blue.offset = 0; 14962306a36Sopenharmony_ci var->blue.length = 5; 15062306a36Sopenharmony_ci var->transp.offset = 0; 15162306a36Sopenharmony_ci var->transp.length = 0; 15262306a36Sopenharmony_ci } 15362306a36Sopenharmony_ci var->xoffset = var->yoffset = 0; 15462306a36Sopenharmony_ci var->left_margin = var->upper_margin = 0; 15562306a36Sopenharmony_ci var->nonstd = 0; 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci var->vmode &= ~FB_VMODE_MASK; 15862306a36Sopenharmony_ci var->vmode |= FB_VMODE_NONINTERLACED; 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci /* Dummy values */ 16162306a36Sopenharmony_ci var->hsync_len = 24; 16262306a36Sopenharmony_ci var->vsync_len = 2; 16362306a36Sopenharmony_ci var->pixclock = 84316; 16462306a36Sopenharmony_ci var->right_margin = 776; 16562306a36Sopenharmony_ci var->lower_margin = 591; 16662306a36Sopenharmony_ci return 0; 16762306a36Sopenharmony_ci} 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_cistatic int vivid_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 17062306a36Sopenharmony_ci{ 17162306a36Sopenharmony_ci struct vivid_dev *dev = (struct vivid_dev *) info->par; 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci dprintk(dev, 1, "vivid_fb_check_var\n"); 17462306a36Sopenharmony_ci return _vivid_fb_check_var(var, dev); 17562306a36Sopenharmony_ci} 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_cistatic int vivid_fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) 17862306a36Sopenharmony_ci{ 17962306a36Sopenharmony_ci return 0; 18062306a36Sopenharmony_ci} 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_cistatic int vivid_fb_set_par(struct fb_info *info) 18362306a36Sopenharmony_ci{ 18462306a36Sopenharmony_ci int rc = 0; 18562306a36Sopenharmony_ci struct vivid_dev *dev = (struct vivid_dev *) info->par; 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci dprintk(dev, 1, "vivid_fb_set_par\n"); 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci rc = vivid_fb_set_var(dev, &info->var); 19062306a36Sopenharmony_ci vivid_fb_get_fix(dev, &info->fix); 19162306a36Sopenharmony_ci return rc; 19262306a36Sopenharmony_ci} 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_cistatic int vivid_fb_setcolreg(unsigned regno, unsigned red, unsigned green, 19562306a36Sopenharmony_ci unsigned blue, unsigned transp, 19662306a36Sopenharmony_ci struct fb_info *info) 19762306a36Sopenharmony_ci{ 19862306a36Sopenharmony_ci u32 color, *palette; 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci if (regno >= info->cmap.len) 20162306a36Sopenharmony_ci return -EINVAL; 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci color = ((transp & 0xFF00) << 16) | ((red & 0xFF00) << 8) | 20462306a36Sopenharmony_ci (green & 0xFF00) | ((blue & 0xFF00) >> 8); 20562306a36Sopenharmony_ci if (regno >= 16) 20662306a36Sopenharmony_ci return -EINVAL; 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci palette = info->pseudo_palette; 20962306a36Sopenharmony_ci if (info->var.bits_per_pixel == 16) { 21062306a36Sopenharmony_ci switch (info->var.green.length) { 21162306a36Sopenharmony_ci case 6: 21262306a36Sopenharmony_ci color = (red & 0xf800) | 21362306a36Sopenharmony_ci ((green & 0xfc00) >> 5) | 21462306a36Sopenharmony_ci ((blue & 0xf800) >> 11); 21562306a36Sopenharmony_ci break; 21662306a36Sopenharmony_ci case 5: 21762306a36Sopenharmony_ci color = ((red & 0xf800) >> 1) | 21862306a36Sopenharmony_ci ((green & 0xf800) >> 6) | 21962306a36Sopenharmony_ci ((blue & 0xf800) >> 11) | 22062306a36Sopenharmony_ci (transp ? 0x8000 : 0); 22162306a36Sopenharmony_ci break; 22262306a36Sopenharmony_ci } 22362306a36Sopenharmony_ci } 22462306a36Sopenharmony_ci palette[regno] = color; 22562306a36Sopenharmony_ci return 0; 22662306a36Sopenharmony_ci} 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ci/* We don't really support blanking. All this does is enable or 22962306a36Sopenharmony_ci disable the OSD. */ 23062306a36Sopenharmony_cistatic int vivid_fb_blank(int blank_mode, struct fb_info *info) 23162306a36Sopenharmony_ci{ 23262306a36Sopenharmony_ci struct vivid_dev *dev = (struct vivid_dev *)info->par; 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci dprintk(dev, 1, "Set blanking mode : %d\n", blank_mode); 23562306a36Sopenharmony_ci switch (blank_mode) { 23662306a36Sopenharmony_ci case FB_BLANK_UNBLANK: 23762306a36Sopenharmony_ci break; 23862306a36Sopenharmony_ci case FB_BLANK_NORMAL: 23962306a36Sopenharmony_ci case FB_BLANK_HSYNC_SUSPEND: 24062306a36Sopenharmony_ci case FB_BLANK_VSYNC_SUSPEND: 24162306a36Sopenharmony_ci case FB_BLANK_POWERDOWN: 24262306a36Sopenharmony_ci break; 24362306a36Sopenharmony_ci } 24462306a36Sopenharmony_ci return 0; 24562306a36Sopenharmony_ci} 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_cistatic const struct fb_ops vivid_fb_ops = { 24862306a36Sopenharmony_ci .owner = THIS_MODULE, 24962306a36Sopenharmony_ci FB_DEFAULT_IOMEM_OPS, 25062306a36Sopenharmony_ci .fb_check_var = vivid_fb_check_var, 25162306a36Sopenharmony_ci .fb_set_par = vivid_fb_set_par, 25262306a36Sopenharmony_ci .fb_setcolreg = vivid_fb_setcolreg, 25362306a36Sopenharmony_ci .fb_cursor = NULL, 25462306a36Sopenharmony_ci .fb_ioctl = vivid_fb_ioctl, 25562306a36Sopenharmony_ci .fb_pan_display = vivid_fb_pan_display, 25662306a36Sopenharmony_ci .fb_blank = vivid_fb_blank, 25762306a36Sopenharmony_ci}; 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ci/* Initialization */ 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ci/* Setup our initial video mode */ 26362306a36Sopenharmony_cistatic int vivid_fb_init_vidmode(struct vivid_dev *dev) 26462306a36Sopenharmony_ci{ 26562306a36Sopenharmony_ci struct v4l2_rect start_window; 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci /* Color mode */ 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci dev->bits_per_pixel = 16; 27062306a36Sopenharmony_ci dev->bytes_per_pixel = dev->bits_per_pixel / 8; 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci start_window.width = MAX_OSD_WIDTH; 27362306a36Sopenharmony_ci start_window.left = 0; 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_ci dev->display_byte_stride = start_window.width * dev->bytes_per_pixel; 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci /* Vertical size & position */ 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci start_window.height = MAX_OSD_HEIGHT; 28062306a36Sopenharmony_ci start_window.top = 0; 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ci dev->display_width = start_window.width; 28362306a36Sopenharmony_ci dev->display_height = start_window.height; 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci /* Generate a valid fb_var_screeninfo */ 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci dev->fb_defined.xres = dev->display_width; 28862306a36Sopenharmony_ci dev->fb_defined.yres = dev->display_height; 28962306a36Sopenharmony_ci dev->fb_defined.xres_virtual = dev->display_width; 29062306a36Sopenharmony_ci dev->fb_defined.yres_virtual = dev->display_height; 29162306a36Sopenharmony_ci dev->fb_defined.bits_per_pixel = dev->bits_per_pixel; 29262306a36Sopenharmony_ci dev->fb_defined.vmode = FB_VMODE_NONINTERLACED; 29362306a36Sopenharmony_ci dev->fb_defined.left_margin = start_window.left + 1; 29462306a36Sopenharmony_ci dev->fb_defined.upper_margin = start_window.top + 1; 29562306a36Sopenharmony_ci dev->fb_defined.accel_flags = FB_ACCEL_NONE; 29662306a36Sopenharmony_ci dev->fb_defined.nonstd = 0; 29762306a36Sopenharmony_ci /* set default to 1:5:5:5 */ 29862306a36Sopenharmony_ci dev->fb_defined.green.length = 5; 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ci /* We've filled in the most data, let the usual mode check 30162306a36Sopenharmony_ci routine fill in the rest. */ 30262306a36Sopenharmony_ci _vivid_fb_check_var(&dev->fb_defined, dev); 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ci /* Generate valid fb_fix_screeninfo */ 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_ci vivid_fb_get_fix(dev, &dev->fb_fix); 30762306a36Sopenharmony_ci 30862306a36Sopenharmony_ci /* Generate valid fb_info */ 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_ci dev->fb_info.node = -1; 31162306a36Sopenharmony_ci dev->fb_info.par = dev; 31262306a36Sopenharmony_ci dev->fb_info.var = dev->fb_defined; 31362306a36Sopenharmony_ci dev->fb_info.fix = dev->fb_fix; 31462306a36Sopenharmony_ci dev->fb_info.screen_base = (u8 __iomem *)dev->video_vbase; 31562306a36Sopenharmony_ci dev->fb_info.fbops = &vivid_fb_ops; 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci /* Supply some monitor specs. Bogus values will do for now */ 31862306a36Sopenharmony_ci dev->fb_info.monspecs.hfmin = 8000; 31962306a36Sopenharmony_ci dev->fb_info.monspecs.hfmax = 70000; 32062306a36Sopenharmony_ci dev->fb_info.monspecs.vfmin = 10; 32162306a36Sopenharmony_ci dev->fb_info.monspecs.vfmax = 100; 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_ci /* Allocate color map */ 32462306a36Sopenharmony_ci if (fb_alloc_cmap(&dev->fb_info.cmap, 256, 1)) { 32562306a36Sopenharmony_ci pr_err("abort, unable to alloc cmap\n"); 32662306a36Sopenharmony_ci return -ENOMEM; 32762306a36Sopenharmony_ci } 32862306a36Sopenharmony_ci 32962306a36Sopenharmony_ci /* Allocate the pseudo palette */ 33062306a36Sopenharmony_ci dev->fb_info.pseudo_palette = kmalloc_array(16, sizeof(u32), GFP_KERNEL); 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_ci return dev->fb_info.pseudo_palette ? 0 : -ENOMEM; 33362306a36Sopenharmony_ci} 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci/* Release any memory we've grabbed */ 33662306a36Sopenharmony_civoid vivid_fb_release_buffers(struct vivid_dev *dev) 33762306a36Sopenharmony_ci{ 33862306a36Sopenharmony_ci if (dev->video_vbase == NULL) 33962306a36Sopenharmony_ci return; 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_ci /* Release cmap */ 34262306a36Sopenharmony_ci if (dev->fb_info.cmap.len) 34362306a36Sopenharmony_ci fb_dealloc_cmap(&dev->fb_info.cmap); 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_ci /* Release pseudo palette */ 34662306a36Sopenharmony_ci kfree(dev->fb_info.pseudo_palette); 34762306a36Sopenharmony_ci kfree(dev->video_vbase); 34862306a36Sopenharmony_ci} 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_ci/* Initialize the specified card */ 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_ciint vivid_fb_init(struct vivid_dev *dev) 35362306a36Sopenharmony_ci{ 35462306a36Sopenharmony_ci int ret; 35562306a36Sopenharmony_ci 35662306a36Sopenharmony_ci dev->video_buffer_size = MAX_OSD_HEIGHT * MAX_OSD_WIDTH * 2; 35762306a36Sopenharmony_ci dev->video_vbase = kzalloc(dev->video_buffer_size, GFP_KERNEL); 35862306a36Sopenharmony_ci if (dev->video_vbase == NULL) 35962306a36Sopenharmony_ci return -ENOMEM; 36062306a36Sopenharmony_ci dev->video_pbase = virt_to_phys(dev->video_vbase); 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci pr_info("Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n", 36362306a36Sopenharmony_ci dev->video_pbase, dev->video_vbase, 36462306a36Sopenharmony_ci dev->video_buffer_size / 1024); 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci /* Set the startup video mode information */ 36762306a36Sopenharmony_ci ret = vivid_fb_init_vidmode(dev); 36862306a36Sopenharmony_ci if (ret) { 36962306a36Sopenharmony_ci vivid_fb_release_buffers(dev); 37062306a36Sopenharmony_ci return ret; 37162306a36Sopenharmony_ci } 37262306a36Sopenharmony_ci 37362306a36Sopenharmony_ci vivid_clear_fb(dev); 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_ci /* Register the framebuffer */ 37662306a36Sopenharmony_ci if (register_framebuffer(&dev->fb_info) < 0) { 37762306a36Sopenharmony_ci vivid_fb_release_buffers(dev); 37862306a36Sopenharmony_ci return -EINVAL; 37962306a36Sopenharmony_ci } 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_ci /* Set the card to the requested mode */ 38262306a36Sopenharmony_ci vivid_fb_set_par(&dev->fb_info); 38362306a36Sopenharmony_ci return 0; 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_ci} 386