Пример #1
0
static int s5ptvfb_alloc_framebuffer(void)
{
	int ret;

	/* alloc for each framebuffer */
	s5ptv_status.fb = framebuffer_alloc(sizeof(struct s5ptvfb_window),
					 s5ptv_status.dev_fb);
	if (!s5ptv_status.fb) {
		dev_err(s5ptv_status.dev_fb, "not enough memory\n");
		ret = -ENOMEM;
		goto err_alloc_fb;
	}

	ret = s5ptvfb_init_fbinfo(5);
	if (ret) {
		dev_err(s5ptv_status.dev_fb,
			"failed to allocate memory for fb for tv\n");
		ret = -ENOMEM;
		goto err_alloc_fb;
	}
#ifndef CONFIG_USER_ALLOC_TVOUT
	if (s5ptvfb_map_video_memory(s5ptv_status.fb)) {
		dev_err(s5ptv_status.dev_fb,
			"failed to map video memory "
			"for default window \n");
		ret = -ENOMEM;
		goto err_alloc_fb;
	}
#endif
	return 0;

err_alloc_fb:
	if (s5ptv_status.fb)
		framebuffer_release(s5ptv_status.fb);

	kfree(s5ptv_status.fb);

	return ret;
}
Пример #2
0
static int q40fb_probe(struct platform_device *dev)
{
	struct fb_info *info;

	if (!MACH_IS_Q40)
		return -ENXIO;

	/* mapped in q40/config.c */
	q40fb_fix.smem_start = Q40_PHYS_SCREEN_ADDR;

	info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);
	if (!info)
		return -ENOMEM;

	info->var = q40fb_var;
	info->fix = q40fb_fix;
	info->fbops = &q40fb_ops;
	info->flags = FBINFO_DEFAULT;  /* not as module for now */
	info->pseudo_palette = info->par;
	info->par = NULL;
	info->screen_base = (char *) q40fb_fix.smem_start;

	if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
		framebuffer_release(info);
		return -ENOMEM;
	}

	master_outb(3, DISPLAY_CONTROL_REG);

	if (register_framebuffer(info) < 0) {
		printk(KERN_ERR "Unable to register Q40 frame buffer\n");
		fb_dealloc_cmap(&info->cmap);
		framebuffer_release(info);
		return -EINVAL;
	}

	fb_info(info, "Q40 frame buffer alive and kicking !\n");
	return 0;
}
int s3cfb_extdsp_alloc_framebuffer(struct s3cfb_extdsp_global *fbdev, int extdsp_id)
{
	int ret = 0;

	fbdev->fb = kmalloc(sizeof(struct fb_info *), GFP_KERNEL);
	if (!fbdev->fb) {
		dev_err(fbdev->dev, "not enough memory\n");
		ret = -ENOMEM;
		goto err_alloc;
	}

	fbdev->fb[0] = framebuffer_alloc(sizeof(struct s3cfb_extdsp_window),
			fbdev->dev);
	if (!fbdev->fb[0]) {
		dev_err(fbdev->dev, "not enough memory\n");
		ret = -ENOMEM;
		goto err_alloc_fb;
	}

	ret = s3cfb_extdsp_init_fbinfo(fbdev, 0);
	if (ret) {
		dev_err(fbdev->dev,
				"failed to allocate memory for fb%d\n", 0);
		ret = -ENOMEM;
		goto err_alloc_fb;
	}

	return 0;

err_alloc_fb:
	if (fbdev->fb[0])
		framebuffer_release(fbdev->fb[0]);
	kfree(fbdev->fb);

err_alloc:
	return ret;
}
Пример #4
0
static int chipsfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent)
{
	struct fb_info *p;
	unsigned long addr, size;
	unsigned short cmd;
	int rc = -ENODEV;

	if (pci_enable_device(dp) < 0) {
		dev_err(&dp->dev, "Cannot enable PCI device\n");
		goto err_out;
	}

	if ((dp->resource[0].flags & IORESOURCE_MEM) == 0)
		goto err_disable;
	addr = pci_resource_start(dp, 0);
	size = pci_resource_len(dp, 0);
	if (addr == 0)
		goto err_disable;

	p = framebuffer_alloc(0, &dp->dev);
	if (p == NULL) {
		dev_err(&dp->dev, "Cannot allocate framebuffer structure\n");
		rc = -ENOMEM;
		goto err_disable;
	}

	if (pci_request_region(dp, 0, "chipsfb") != 0) {
		dev_err(&dp->dev, "Cannot request framebuffer\n");
		rc = -EBUSY;
		goto err_release_fb;
	}

#ifdef __BIG_ENDIAN
	addr += 0x800000;	// Use big-endian aperture
#endif

	/* we should use pci_enable_device here, but,
	   the device doesn't declare its I/O ports in its BARs
	   so pci_enable_device won't turn on I/O responses */
	pci_read_config_word(dp, PCI_COMMAND, &cmd);
	cmd |= 3;	/* enable memory and IO space */
	pci_write_config_word(dp, PCI_COMMAND, cmd);

#ifdef CONFIG_PMAC_BACKLIGHT
	/* turn on the backlight */
	mutex_lock(&pmac_backlight_mutex);
	if (pmac_backlight) {
		pmac_backlight->props.power = FB_BLANK_UNBLANK;
		backlight_update_status(pmac_backlight);
	}
	mutex_unlock(&pmac_backlight_mutex);
#endif /* CONFIG_PMAC_BACKLIGHT */

#ifdef CONFIG_PPC
	p->screen_base = __ioremap(addr, 0x200000, _PAGE_NO_CACHE);
#else
	p->screen_base = ioremap(addr, 0x200000);
#endif
	if (p->screen_base == NULL) {
		dev_err(&dp->dev, "Cannot map framebuffer\n");
		rc = -ENOMEM;
		goto err_release_pci;
	}

	pci_set_drvdata(dp, p);

	init_chips(p, addr);

	if (register_framebuffer(p) < 0) {
		dev_err(&dp->dev,"C&T 65550 framebuffer failed to register\n");
		goto err_unmap;
	}

	dev_info(&dp->dev,"fb%d: Chips 65550 frame buffer"
		 " (%dK RAM detected)\n",
		 p->node, p->fix.smem_len / 1024);

	return 0;

 err_unmap:
	iounmap(p->screen_base);
 err_release_pci:
	pci_release_region(dp, 0);
 err_release_fb:
	framebuffer_release(p);
 err_disable:
 err_out:
	return rc;
}
/**
 * s3c_fb_probe_win() - register an hardware window
 * @sfb: The base resources for the hardware
 * @res: Pointer to where to place the resultant window.
 *
 * Allocate and do the basic initialisation for one of the hardware's graphics
 * windows.
 */
static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no,
				      struct s3c_fb_win **res)
{
	struct fb_var_screeninfo *var;
	struct fb_videomode *initmode;
	struct s3c_fb_pd_win *windata;
	struct s3c_fb_win *win;
	struct fb_info *fbinfo;
	int palette_size;
	int ret;

	dev_dbg(sfb->dev, "probing window %d\n", win_no);

	palette_size = s3c_fb_win_pal_size(win_no);

	fbinfo = framebuffer_alloc(sizeof(struct s3c_fb_win) +
				   palette_size * sizeof(u32), sfb->dev);
	if (!fbinfo) {
		dev_err(sfb->dev, "failed to allocate framebuffer\n");
		return -ENOENT;
	}

	windata = sfb->pdata->win[win_no];
	initmode = &windata->win_mode;

	WARN_ON(windata->max_bpp == 0);
	WARN_ON(windata->win_mode.xres == 0);
	WARN_ON(windata->win_mode.yres == 0);

	win = fbinfo->par;
	var = &fbinfo->var;
	win->fbinfo = fbinfo;
	win->parent = sfb;
	win->windata = windata;
	win->index = win_no;
	win->palette_buffer = (u32 *)(win + 1);

	ret = s3c_fb_alloc_memory(sfb, win);
	if (ret) {
		dev_err(sfb->dev, "failed to allocate display memory\n");
		return ret;
	}

	/* setup the r/b/g positions for the window's palette */
	s3c_fb_init_palette(win_no, &win->palette);

	/* setup the initial video mode from the window */
	fb_videomode_to_var(&fbinfo->var, initmode);

	fbinfo->fix.type	= FB_TYPE_PACKED_PIXELS;
	fbinfo->fix.accel	= FB_ACCEL_NONE;
	fbinfo->var.activate	= FB_ACTIVATE_NOW;
	fbinfo->var.vmode	= FB_VMODE_NONINTERLACED;
	fbinfo->var.bits_per_pixel = windata->default_bpp;
	fbinfo->fbops		= &s3c_fb_ops;
	fbinfo->flags		= FBINFO_FLAG_DEFAULT;
	fbinfo->pseudo_palette  = &win->pseudo_palette;

	/* prepare to actually start the framebuffer */

	ret = s3c_fb_check_var(&fbinfo->var, fbinfo);
	if (ret < 0) {
		dev_err(sfb->dev, "check_var failed on initial video params\n");
		return ret;
	}

	/* create initial colour map */

	ret = fb_alloc_cmap(&fbinfo->cmap, s3c_fb_win_pal_size(win_no), 1);
	if (ret == 0)
		fb_set_cmap(&fbinfo->cmap, fbinfo);
	else
		dev_err(sfb->dev, "failed to allocate fb cmap\n");

	s3c_fb_set_par(fbinfo);

	dev_dbg(sfb->dev, "about to register framebuffer\n");

	/* run the check_var and set_par on our configuration. */

	ret = register_framebuffer(fbinfo);
	if (ret < 0) {
		dev_err(sfb->dev, "failed to register framebuffer\n");
		return ret;
	}

	*res = win;
	dev_info(sfb->dev, "window %d: fb %s\n", win_no, fbinfo->fix.id);

	return 0;
}
Пример #6
0
static int ws_eink_spi_probe(struct spi_device *spi)
{
	struct fb_info *info;
	int retval = 0;
	struct waveshare_eink_platform_data *pdata;
	const struct spi_device_id *spi_id;
	const struct waveshare_eink_device_properties *dev_props;
	struct ws_eink_fb_par *par;
	int vmem_size;

	pdata = spi->dev.platform_data;
	if (!pdata) {
		dev_err(&spi->dev, "Required platform data was not provided");
		return -EINVAL;
	}

	spi_id = spi_get_device_id(spi);
	if (!spi_id) {
		dev_err(&spi->dev, "device id not supported!\n");
		return -EINVAL;
	}

	dev_props = (const struct waveshare_eink_device_properties *)
		spi_id->driver_data;
	if (!dev_props) {
		dev_err(&spi->dev, "device definition lacks driver_data\n");
		return -EINVAL;
	}

	info = framebuffer_alloc(sizeof(struct ws_eink_fb_par), &spi->dev);
	if (!info)
		return -ENOMEM;

	vmem_size = dev_props->width * dev_props->height * dev_props->bpp / 8;
	info->screen_base = vzalloc(vmem_size);
	if (!info->screen_base) {
		retval = -ENOMEM;
		goto screen_base_fail;
	}

	info->fbops = &ws_eink_ops;

	WARN_ON(strlcpy(info->fix.id, "waveshare_eink", sizeof(info->fix.id)) >=
		sizeof(info->fix.id));
	info->fix.type		= FB_TYPE_PACKED_PIXELS;
	info->fix.visual	= FB_VISUAL_PSEUDOCOLOR;
	info->fix.smem_len	= vmem_size;
	info->fix.xpanstep	= 0;
	info->fix.ypanstep	= 0;
	info->fix.ywrapstep	= 0;
	info->fix.line_length	= dev_props->width * dev_props->bpp / 8;

	info->var.xres			= dev_props->width;
	info->var.yres			= dev_props->height;
	info->var.xres_virtual		= dev_props->width;
	info->var.yres_virtual		= dev_props->height;
	info->var.bits_per_pixel	= dev_props->bpp;

	info->flags = FBINFO_FLAG_DEFAULT | FBINFO_VIRTFB;

	info->fbdefio = &ws_eink_defio;
	fb_deferred_io_init(info);

	par		= info->par;
	par->info	= info;
	par->spi	= spi;
	par->props	= dev_props;
	par->rst	= pdata->rst_gpio;
	par->dc		= pdata->dc_gpio;
	par->busy	= pdata->busy_gpio;
	par->ssbuf	= vzalloc(vmem_size);
	if (!par->ssbuf) {
		retval = -ENOMEM;
		goto ssbuf_alloc_fail;
	}

	retval = register_framebuffer(info);
	if (retval < 0) {
		dev_err(&spi->dev, "framebuffer registration failed");
		goto fbreg_fail;
	}

	spi_set_drvdata(spi, info);

	retval = ws_eink_init_display(par);
	if (retval) {
		dev_err(&spi->dev, "display initialization failed");
		goto disp_init_fail;
	}

	dev_dbg(&spi->dev,
		"fb%d: %s frame buffer device,\n\tusing %d KiB of video memory\n",
		info->node, info->fix.id, vmem_size);

	return 0;

disp_init_fail:
	framebuffer_release(info);
fbreg_fail:
	vfree(par->ssbuf);
ssbuf_alloc_fail:
	vfree(info->screen_base);
screen_base_fail:
	vfree(info->screen_base);
	return retval;
}
Пример #7
0
static int32_t __init
gp_fb_init(
	void
)
{
	int32_t ret = 0;
	struct gp_fb_info *info;

#if 0
	/* Init display device */
	if (disp_open(0, 0) < 0)
		return -EIO;

	if (disp_init() < 0)
		return -EIO;
#endif

	fbinfo = framebuffer_alloc(sizeof(struct gp_fb_info), NULL);
	if (!fbinfo)
		return -ENOMEM;

	info = fbinfo->par;
	info->first_open = 0;

	/*Get panel resolution */
	disp_get_panel_res(&info->panelRes);

	/* Color */
	ret = gp_fb_setColorType(fbinfo);
	if (ret < 0) {
		printk("[%s:%d], set color type error\n", __FUNCTION__, __LINE__);
		goto dealloc_fb;
	}

	/* Get buffer width, height, and size */
	gp_fb_getBufInfo(fbinfo);

	/* Get panel rect */
	gp_fb_getPanelRect(fbinfo);

	info->fbmem = disp_allocate_buffer(info->bufinfo);
	if (info->fbmem == NULL) {
		ret = -ENXIO;
		goto dealloc_fb;
	}

	memset(info->fbmem, 0x00, info->bufinfo.size);

	fbinfo->fbops = &gp_fb_ops;
	fbinfo->flags = FBINFO_FLAG_DEFAULT;
	fbinfo->pseudo_palette = NULL;
	fbinfo->screen_base = info->fbmem;
	fbinfo->screen_size = 0;

	/* Resolution */
	fbinfo->var.xres = info->bufinfo.width;
	fbinfo->var.yres = info->bufinfo.height;
	fbinfo->var.xres_virtual = fbinfo->var.xres;
	fbinfo->var.yres_virtual = fbinfo->var.yres * 2;

	/* Timing */
	fbinfo->var.left_margin = 0;
	fbinfo->var.right_margin = 0;
	fbinfo->var.upper_margin = 0;
	fbinfo->var.lower_margin = 0;
	fbinfo->var.hsync_len = 0;
	fbinfo->var.vsync_len = 0;

	fbinfo->var.activate = FB_ACTIVATE_FORCE;
	fbinfo->var.accel_flags = 0;
	fbinfo->var.vmode = FB_VMODE_NONINTERLACED;

	/* fixed info */
	memset(&fbinfo->fix.id, 0, sizeof(fbinfo->fix.id));
	strncpy(fbinfo->fix.id, driver_name, sizeof(driver_name));
	fbinfo->fix.mmio_start  = 0x93000000;
	fbinfo->fix.mmio_len    = 0x1000;
	fbinfo->fix.type        = FB_TYPE_PACKED_PIXELS;
	fbinfo->fix.type_aux	= 0;
	fbinfo->fix.visual      = FB_VISUAL_TRUECOLOR;
	fbinfo->fix.xpanstep	= 0;
	fbinfo->fix.ypanstep	= 1;
	fbinfo->fix.ywrapstep	= 0;
	fbinfo->fix.accel	    = FB_ACCEL_NONE;
	fbinfo->fix.smem_start  = gp_chunk_pa(info->fbmem);
	fbinfo->fix.smem_len    = info->bufinfo.size;
	fbinfo->fix.line_length = (fbinfo->var.xres_virtual * fbinfo->var.bits_per_pixel) / 8;

	gp_fb_activate(fbinfo);

	ret = register_framebuffer(fbinfo);
	if (ret < 0) {
		printk(KERN_ERR "Failed to register framebuffer device: %d\n", ret);
		goto release_fbmem;
	}
	printk(KERN_INFO "fb%d: %s frame buffer device\n",
		fbinfo->node, fbinfo->fix.id);

	return 0;

release_fbmem:
	disp_free_buffer(FB_BUFFER_ID);

dealloc_fb:
	framebuffer_release(fbinfo);

	return ret;
}
Пример #8
0
static int merrifield_fb_probe(struct pci_dev *pdev,
                               const struct pci_device_id *id)
{
    int ret;
    struct fb_info *info = NULL;
    int fb_base = 0;
    int width = H_ACTIVE;
    int height = V_ACTIVE;

    ret = pci_enable_device(pdev);
    if (ret) {
        dev_err(&pdev->dev, "failed to enable device!\n");
        goto failure;
    }

    info = framebuffer_alloc(0, &pdev->dev);
    if (!info) {
        dev_err(&pdev->dev, "framebuffer allocation failure.\n");
        goto failure;
    }

    merrifield_fb_fix.mmio_start = pci_resource_start(pdev, 0);
    merrifield_fb_fix.mmio_len = pci_resource_len(pdev, 0);

    if (!request_mem_region(merrifield_fb_fix.mmio_start,
                            merrifield_fb_fix.mmio_len, DRV_NAME)) {
        dev_err(&pdev->dev, "mmio request_mem_region failure!\n");
        goto failure;
    }

    io_virt = ioremap_nocache(merrifield_fb_fix.mmio_start,
                              merrifield_fb_fix.mmio_len);

    pci_read_config_dword(pdev, 0x5C, &fb_base);

    /* Allocate enough for up 2 x 16-bit frame buffers at
     * our given resolution which is used for double buffering */
    merrifield_fb_fix.smem_start = fb_base;
    merrifield_fb_fix.smem_len = H_ACTIVE * V_ACTIVE * 4;

    info->screen_base = ioremap_nocache(merrifield_fb_fix.smem_start,
                                        merrifield_fb_fix.smem_len);
    info->fix = merrifield_fb_fix;
    info->fbops = &merrifield_fb_ops;
    info->flags =
        FBINFO_DEFAULT | FBINFO_HWACCEL_DISABLED | FBINFO_FLAG_DEFAULT;
    strcat(info->fix.id, DRV_NAME);
    info->var.activate = FB_ACTIVATE_NOW;
    info->device = &pdev->dev;

    ret = fb_alloc_cmap(&info->cmap, 256, 0);
    if (ret < 0) {
        dev_err(&pdev->dev, "cmap allocation failure.\n");
        goto failure;
    }

    /* RGB 5:6:5 */
    info->pseudo_palette = &info->cmap;
    info->cmap.len = 16;
    info->fix.type = FB_TYPE_PACKED_PIXELS;
    info->fix.visual = FB_VISUAL_TRUECOLOR;
    info->fix.line_length = width * 2;
    info->fix.accel = FB_ACCEL_NONE;
    info->fix.ypanstep = 1;
    info->fix.smem_start = merrifield_fb_fix.smem_start;
    info->fix.smem_len = merrifield_fb_fix.smem_len;
    info->var.xres = width;
    info->var.yres = height;
    info->var.xres_virtual = width;
    info->var.yres_virtual = height * 2;
    info->var.bits_per_pixel = 16;
    info->var.height = height;
    info->var.width = width;
    info->var.red.offset = 11;
    info->var.red.length = 5;
    info->var.green.offset = 5;
    info->var.green.length = 6;
    info->var.blue.offset = 0;
    info->var.blue.length = 5;

    ret = fb_set_var(info, &info->var);
    if (ret) {
        dev_err(&pdev->dev, "error setting var info\n");
        goto failure;
    }

    info->pixmap.addr = kmalloc(4096, GFP_KERNEL);
    if (!info->pixmap.addr) {
        dev_err(&pdev->dev, "pixmap allocation failure\n");
        goto failure;
    }

    info->pixmap.size = 4096;
    info->pixmap.buf_align = 4;
    info->pixmap.scan_align = 1;
    info->pixmap.access_align = 32;
    info->pixmap.flags = FB_PIXMAP_SYSTEM;

    pci_set_drvdata(pdev, info);
    if (register_framebuffer(info) < 0) {
        dev_err(&pdev->dev, "could not register framebuffer\n");
        goto failure;
    }

    init_display_controller_registers();

    return 0;

failure:
    merrifield_fb_remove(pdev);

    return ret;
}
Пример #9
0
static int __init vfb_probe(struct platform_device *dev)
{
	struct fb_info *info;
	int retval = -ENOMEM;

	/* Reserve the framebuffer memory */
	if (!request_mem_region(vfb_addr, vfb_size, "STM32F4 Framebuffer")) {
		printk(KERN_ERR "vfb: unable to reserve "
		       "framebuffer at 0x%0x\n", (unsigned int)vfb_addr);
		retval = -EBUSY;
		goto fail_reqmem;
	}

	/* Allocate framebuffer info structure */
	info = framebuffer_alloc(sizeof(struct fb_info), &dev->dev);
	if (!info) {
		printk(KERN_ERR "vfb: unable to reserve framebuffer info\n");
		retval = -ENOMEM;
		goto fail_fballoc;
	}

	/* For real video cards we use ioremap */
	info->screen_base = ioremap(vfb_addr, vfb_size);
	if (!info->screen_base) {
		printk(KERN_ERR "vfb: unable to map framebuffer\n");
		retval = -ENOMEM;
		goto fail_remap;
	}

	/* Assign the frame buffer data */
	info->screen_size = vfb_size;
	info->fbops = &vfb_ops;

	/*
	 * VFB must clear memory to prevent kernel info
	 * leakage into userspace
	 * VGA-based drivers MUST NOT clear memory if
	 * they want to be able to take over vgacon
	 */
	memset(info->screen_base, 0, info->screen_size);

	retval = fb_find_mode(&info->var, info, NULL, NULL, 0, NULL, 8);
	if ((!retval) || (retval == 4))
		memcpy(&(info->var), &vfb_default,
		       sizeof(struct fb_var_screeninfo));

	vfb_fix.smem_start = vfb_addr;
	vfb_fix.smem_len = vfb_size;
	memcpy(&(info->fix), &vfb_fix, sizeof(struct fb_fix_screeninfo));

	/* Allocate pseudo palette data */
	info->pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL);
	if (!info->pseudo_palette) {
		printk(KERN_ERR "vfb: unable to reserve palette memory\n");
		retval = -ENOMEM;
		goto fail_palette;
	}
	//info->pseudo_palette = info->par;
	info->par = NULL;
	info->flags = FBINFO_FLAG_DEFAULT;

	/*
	 * We expect the boot loader to have initialized the chip
	 * with appropriate parameters from which we can determinte
	 * the flavor of lcd panel attached
	 */
	retval = init_vals(info);
	if (retval < 0) {
		printk(KERN_ERR "vfb: unable to reserve cmap memory\n");
		goto fail_cmap;
	}

	/* Regiser the framebuffer */
	retval = register_framebuffer(info);
	if (retval < 0) {
		printk(KERN_ERR "vfb: unable to register framebuffer\n");
		goto fail_register;
	}

	/* Assign the driver data */
	platform_set_drvdata(dev, info);

	/* Everything is OK */
	printk(KERN_INFO
	       "fb%d: Virtual frame buffer device, "
	       "using %ldK of video memory\n",
	       info->node, info->screen_size >> 10);

	return 0;

	/* There is an error! */
fail_register:
	fb_dealloc_cmap(&info->cmap);
fail_cmap:
	kfree(info->pseudo_palette);
fail_palette:
	iounmap(info->screen_base);
fail_remap:
	framebuffer_release(info);
fail_fballoc:
	release_mem_region(vfb_addr, vfb_size);
fail_reqmem:

	return retval;
}
Пример #10
0
Файл: tcx.c Проект: 020gzh/linux
static int tcx_probe(struct platform_device *op)
{
	struct device_node *dp = op->dev.of_node;
	struct fb_info *info;
	struct tcx_par *par;
	int linebytes, i, err;

	info = framebuffer_alloc(sizeof(struct tcx_par), &op->dev);

	err = -ENOMEM;
	if (!info)
		goto out_err;
	par = info->par;

	spin_lock_init(&par->lock);

	par->lowdepth =
		(of_find_property(dp, "tcx-8-bit", NULL) != NULL);

	sbusfb_fill_var(&info->var, dp, 8);
	info->var.red.length = 8;
	info->var.green.length = 8;
	info->var.blue.length = 8;

	linebytes = of_getintprop_default(dp, "linebytes",
					  info->var.xres);
	info->fix.smem_len = PAGE_ALIGN(linebytes * info->var.yres);

	par->tec = of_ioremap(&op->resource[7], 0,
				  sizeof(struct tcx_tec), "tcx tec");
	par->thc = of_ioremap(&op->resource[9], 0,
				  sizeof(struct tcx_thc), "tcx thc");
	par->bt = of_ioremap(&op->resource[8], 0,
				 sizeof(struct bt_regs), "tcx dac");
	info->screen_base = of_ioremap(&op->resource[0], 0,
					   info->fix.smem_len, "tcx ram");
	if (!par->tec || !par->thc ||
	    !par->bt || !info->screen_base)
		goto out_unmap_regs;

	memcpy(&par->mmap_map, &__tcx_mmap_map, sizeof(par->mmap_map));
	if (!par->lowdepth) {
		par->cplane = of_ioremap(&op->resource[4], 0,
					     info->fix.smem_len * sizeof(u32),
					     "tcx cplane");
		if (!par->cplane)
			goto out_unmap_regs;
	} else {
		par->mmap_map[1].size = SBUS_MMAP_EMPTY;
		par->mmap_map[4].size = SBUS_MMAP_EMPTY;
		par->mmap_map[5].size = SBUS_MMAP_EMPTY;
		par->mmap_map[6].size = SBUS_MMAP_EMPTY;
	}

	info->fix.smem_start = op->resource[0].start;
	par->which_io = op->resource[0].flags & IORESOURCE_BITS;

	for (i = 0; i < TCX_MMAP_ENTRIES; i++) {
		int j;

		switch (i) {
		case 10:
			j = 12;
			break;

		case 11: case 12:
			j = i - 1;
			break;

		default:
			j = i;
			break;
		}
		par->mmap_map[i].poff = op->resource[j].start;
	}

	info->flags = FBINFO_DEFAULT;
	info->fbops = &tcx_ops;

	/* Initialize brooktree DAC. */
	sbus_writel(0x04 << 24, &par->bt->addr);         /* color planes */
	sbus_writel(0xff << 24, &par->bt->control);
	sbus_writel(0x05 << 24, &par->bt->addr);
	sbus_writel(0x00 << 24, &par->bt->control);
	sbus_writel(0x06 << 24, &par->bt->addr);         /* overlay plane */
	sbus_writel(0x73 << 24, &par->bt->control);
	sbus_writel(0x07 << 24, &par->bt->addr);
	sbus_writel(0x00 << 24, &par->bt->control);

	tcx_reset(info);

	tcx_blank(FB_BLANK_UNBLANK, info);

	if (fb_alloc_cmap(&info->cmap, 256, 0))
		goto out_unmap_regs;

	fb_set_cmap(&info->cmap, info);
	tcx_init_fix(info, linebytes);

	err = register_framebuffer(info);
	if (err < 0)
		goto out_dealloc_cmap;

	dev_set_drvdata(&op->dev, info);

	printk(KERN_INFO "%s: TCX at %lx:%lx, %s\n",
	       dp->full_name,
	       par->which_io,
	       info->fix.smem_start,
	       par->lowdepth ? "8-bit only" : "24-bit depth");

	return 0;

out_dealloc_cmap:
	fb_dealloc_cmap(&info->cmap);

out_unmap_regs:
	tcx_unmap_regs(op, info, par);
	framebuffer_release(info);

out_err:
	return err;
}
Пример #11
0
static int __devinit leo_probe(struct of_device *op, const struct of_device_id *match)
{
	struct device_node *dp = op->node;
	struct fb_info *info;
	struct leo_par *par;
	int linebytes, err;

	info = framebuffer_alloc(sizeof(struct leo_par), &op->dev);

	err = -ENOMEM;
	if (!info)
		goto out_err;
	par = info->par;

	spin_lock_init(&par->lock);

	par->physbase = op->resource[0].start;
	par->which_io = op->resource[0].flags & IORESOURCE_BITS;

	sbusfb_fill_var(&info->var, dp->node, 32);
	leo_fixup_var_rgb(&info->var);

	linebytes = of_getintprop_default(dp, "linebytes",
					  info->var.xres);
	par->fbsize = PAGE_ALIGN(linebytes * info->var.yres);

	par->lc_ss0_usr =
		of_ioremap(&op->resource[0], LEO_OFF_LC_SS0_USR,
			   0x1000, "leolc ss0usr");
	par->ld_ss0 =
		of_ioremap(&op->resource[0], LEO_OFF_LD_SS0,
			   0x1000, "leold ss0");
	par->ld_ss1 =
		of_ioremap(&op->resource[0], LEO_OFF_LD_SS1,
			   0x1000, "leold ss1");
	par->lx_krn =
		of_ioremap(&op->resource[0], LEO_OFF_LX_KRN,
			   0x1000, "leolx krn");
	par->cursor =
		of_ioremap(&op->resource[0], LEO_OFF_LX_CURSOR,
			   sizeof(struct leo_cursor), "leolx cursor");
	info->screen_base =
		of_ioremap(&op->resource[0], LEO_OFF_SS0,
			   0x800000, "leo ram");
	if (!par->lc_ss0_usr ||
	    !par->ld_ss0 ||
	    !par->ld_ss1 ||
	    !par->lx_krn ||
	    !par->cursor ||
	    !info->screen_base)
		goto out_unmap_regs;

	info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
	info->fbops = &leo_ops;

	leo_init_wids(info);
	leo_init_hw(info);

	leo_blank(0, info);

	if (fb_alloc_cmap(&info->cmap, 256, 0))
		goto out_unmap_regs;

	leo_init_fix(info, dp);

	err = register_framebuffer(info);
	if (err < 0)
		goto out_dealloc_cmap;

	dev_set_drvdata(&op->dev, info);

	printk("%s: leo at %lx:%lx\n",
	       dp->full_name,
	       par->which_io, par->physbase);

	return 0;

out_dealloc_cmap:
	fb_dealloc_cmap(&info->cmap);

out_unmap_regs:
	leo_unmap_regs(op, info, par);
	framebuffer_release(info);

out_err:
	return err;
}
Пример #12
0
static int hvfb_probe(struct hv_device *hdev,
		      const struct hv_vmbus_device_id *dev_id)
{
	struct fb_info *info;
	struct hvfb_par *par;
	int ret;

	info = framebuffer_alloc(sizeof(struct hvfb_par), &hdev->device);
	if (!info) {
		pr_err("No memory for framebuffer info\n");
		return -ENOMEM;
	}

	par = info->par;
	par->info = info;
	par->fb_ready = false;
	init_completion(&par->wait);
	INIT_DELAYED_WORK(&par->dwork, hvfb_update_work);

	/* Connect to VSP */
	hv_set_drvdata(hdev, info);
	ret = synthvid_connect_vsp(hdev);
	if (ret) {
		pr_err("Unable to connect to VSP\n");
		goto error1;
	}

	ret = hvfb_getmem(info);
	if (ret) {
		pr_err("No memory for framebuffer\n");
		goto error2;
	}

	hvfb_get_option(info);
	pr_info("Screen resolution: %dx%d, Color depth: %d\n",
		screen_width, screen_height, screen_depth);


	/* Set up fb_info */
	info->flags = FBINFO_DEFAULT;

	info->var.xres_virtual = info->var.xres = screen_width;
	info->var.yres_virtual = info->var.yres = screen_height;
	info->var.bits_per_pixel = screen_depth;

	if (info->var.bits_per_pixel == 16) {
		info->var.red = (struct fb_bitfield){11, 5, 0};
		info->var.green = (struct fb_bitfield){5, 6, 0};
		info->var.blue = (struct fb_bitfield){0, 5, 0};
		info->var.transp = (struct fb_bitfield){0, 0, 0};
	} else {
		info->var.red = (struct fb_bitfield){16, 8, 0};
		info->var.green = (struct fb_bitfield){8, 8, 0};
		info->var.blue = (struct fb_bitfield){0, 8, 0};
		info->var.transp = (struct fb_bitfield){24, 8, 0};
	}

	info->var.activate = FB_ACTIVATE_NOW;
	info->var.height = -1;
	info->var.width = -1;
	info->var.vmode = FB_VMODE_NONINTERLACED;

	strcpy(info->fix.id, KBUILD_MODNAME);
	info->fix.type = FB_TYPE_PACKED_PIXELS;
	info->fix.visual = FB_VISUAL_TRUECOLOR;
	info->fix.line_length = screen_width * screen_depth / 8;
	info->fix.accel = FB_ACCEL_NONE;

	info->fbops = &hvfb_ops;
	info->pseudo_palette = par->pseudo_palette;

	/* Send config to host */
	ret = synthvid_send_config(hdev);
	if (ret)
		goto error;

	ret = register_framebuffer(info);
	if (ret) {
		pr_err("Unable to register framebuffer\n");
		goto error;
	}

	par->fb_ready = true;

	par->synchronous_fb = false;
	par->hvfb_panic_nb.notifier_call = hvfb_on_panic;
	atomic_notifier_chain_register(&panic_notifier_list,
				       &par->hvfb_panic_nb);

	return 0;

error:
	hvfb_putmem(info);
error2:
	vmbus_close(hdev->channel);
error1:
	cancel_delayed_work_sync(&par->dwork);
	hv_set_drvdata(hdev, NULL);
	framebuffer_release(info);
	return ret;
}


static int hvfb_remove(struct hv_device *hdev)
{
	struct fb_info *info = hv_get_drvdata(hdev);
	struct hvfb_par *par = info->par;

	atomic_notifier_chain_unregister(&panic_notifier_list,
					 &par->hvfb_panic_nb);

	par->update = false;
	par->fb_ready = false;

	unregister_framebuffer(info);
	cancel_delayed_work_sync(&par->dwork);

	vmbus_close(hdev->channel);
	hv_set_drvdata(hdev, NULL);

	hvfb_putmem(info);
	framebuffer_release(info);

	return 0;
}


static const struct pci_device_id pci_stub_id_table[] = {
	{
		.vendor      = PCI_VENDOR_ID_MICROSOFT,
		.device      = PCI_DEVICE_ID_HYPERV_VIDEO,
	},
	{ /* end of list */ }
};

static const struct hv_vmbus_device_id id_table[] = {
	/* Synthetic Video Device GUID */
	{HV_SYNTHVID_GUID},
	{}
};

MODULE_DEVICE_TABLE(pci, pci_stub_id_table);
MODULE_DEVICE_TABLE(vmbus, id_table);

static struct hv_driver hvfb_drv = {
	.name = KBUILD_MODNAME,
	.id_table = id_table,
	.probe = hvfb_probe,
	.remove = hvfb_remove,
};

static int hvfb_pci_stub_probe(struct pci_dev *pdev,
			       const struct pci_device_id *ent)
{
	return 0;
}

static void hvfb_pci_stub_remove(struct pci_dev *pdev)
{
}

static struct pci_driver hvfb_pci_stub_driver = {
	.name =		KBUILD_MODNAME,
	.id_table =	pci_stub_id_table,
	.probe =	hvfb_pci_stub_probe,
	.remove =	hvfb_pci_stub_remove,
};

static int __init hvfb_drv_init(void)
{
	int ret;

	ret = vmbus_driver_register(&hvfb_drv);
	if (ret != 0)
		return ret;

	ret = pci_register_driver(&hvfb_pci_stub_driver);
	if (ret != 0) {
		vmbus_driver_unregister(&hvfb_drv);
		return ret;
	}

	return 0;
}

static void __exit hvfb_drv_exit(void)
{
	pci_unregister_driver(&hvfb_pci_stub_driver);
	vmbus_driver_unregister(&hvfb_drv);
}

module_init(hvfb_drv_init);
module_exit(hvfb_drv_exit);

MODULE_LICENSE("GPL");
MODULE_VERSION(HV_DRV_VERSION);
MODULE_DESCRIPTION("Microsoft Hyper-V Synthetic Video Frame Buffer Driver");
Пример #13
0
static int s5pv210_lcd_init(void)
{
	struct clk		*s5pv210_clk;
	s5pv210_lcd = framebuffer_alloc(0, NULL);
	
	strcpy(s5pv210_lcd->fix.id, "s5pv210_lcd");
	s5pv210_lcd->fix.smem_len = 800*480*4;
	s5pv210_lcd->fix.type = FB_TYPE_PACKED_PIXELS;
	s5pv210_lcd->fix.visual = FB_VISUAL_TRUECOLOR;
	s5pv210_lcd->fix.line_length = 800*4;

	s5pv210_lcd->var.xres             = 800;
	s5pv210_lcd->var.yres             = 480;
	s5pv210_lcd->var.xres_virtual  = 800;
	s5pv210_lcd->var.yres_virtual  = 480;
	s5pv210_lcd->var.bits_per_pixel = 32;
	s5pv210_lcd->var.red.offset          = 16;
	s5pv210_lcd->var.red.length         = 8;
	s5pv210_lcd->var.green.offset       = 8;
	s5pv210_lcd->var.green.length      = 8;
	s5pv210_lcd->var.blue.offset         = 0;
	s5pv210_lcd->var.blue.length        = 8;
	s5pv210_lcd->var.activate             = FB_ACTIVATE_NOW;
	
	s5pv210_lcd->fbops = &s5pv210_lcdfb_ops;
	s5pv210_lcd->screen_size = 800*480*4;

	gpf0con = ioremap(0xE0200120,4);
	gpf1con = ioremap(0xE0200140,4);
	gpf2con = ioremap(0xE0200160,4);
	gpf3con = ioremap(0xE0200180,4);
	//gpd0con = ioremap(0xE02000A0,4);
	//gpd0dat = ioremap(0xE02000A4,4);
	*gpf0con = 0x22222222;		// GPF0[7:0]
	*gpf1con = 0x22222222;		// GPF1[7:0]
	*gpf2con = 0x22222222;		// GPF2[7:0]
	*gpf3con = 0x22222222;		// GPF3[7:0]
	//*gpd0con |= 1<<4;
	//*gpd0dat |= 1<<1;

	s5pv210_clk = clk_get(NULL, "lcd");
	if (!s5pv210_clk || IS_ERR(s5pv210_clk)) {
		printk(KERN_INFO "failed to get lcd clock source\n");
	}
	clk_enable(s5pv210_clk);

	//display_control = ioremap(0xe0107008,4);
	vidcon0 = ioremap(0xF8000000,4);
	vidcon1 = ioremap(0xF8000004,4);
	wincon0 = ioremap(0xF8000020,4);
	vidosd0a = ioremap(0xF8000040,4);
	vidosd0b = ioremap(0xF8000044,4);
	vidosd0c = ioremap(0xF8000048,4);
	vidw00add0b0  = ioremap(0xF80000A0,4);
	vidw00add1b0  = ioremap(0xF80000D0,4);
	vidw00add2  = ioremap(0xF8000100,4);
	vidtcon0  = ioremap(0xF8000010,4);
	vidtcon1  = ioremap(0xF8000014,4);
	vidtcon2  = ioremap(0xF8000018,4);
	wpalcon  = ioremap(0xF80001A0,4);
	shadowcon  = ioremap(0xF8000034,4);
	
	//*display_control = 2<<0;
    //Page 1222
	*vidcon0 &= ~((3<<26) | (1<<18) | (0xff<<6)  | (1<<2));     /* RGB I/F, RGB Parallel format,  */
	*vidcon0 |= ((4<<6) | (1<<4) );      /* Divided by CLKVAL_F,vclk== HCLK / (CLKVAL+1) = 166.75/5 = 33.35MHz */

	//1211
	*vidcon1 &= ~(1<<7);   
	*vidcon1 |= ((1<<6) | (1<<5));  
	
	*vidtcon0 = (VBPD << 16) | (VFPD << 8) | (VSPW << 0);
	*vidtcon1 = (HBPD << 16) | (HFPD << 8) | (HSPW << 0);

	*vidtcon2 = (LINEVAL << 11) | (HOZVAL << 0);

	*wincon0 &= ~(0xf << 2);
	*wincon0 |= (0xB<<2)/*|(1<<15)*/;
	
	*vidosd0a = (LeftTopX<<11) | (LeftTopY << 0);
	*vidosd0b = (RightBotX<<11) | (RightBotY << 0);
	*vidosd0c = (LINEVAL + 1) * (HOZVAL + 1);

	s5pv210_lcd->screen_base = dma_alloc_writecombine(NULL, 
									s5pv210_lcd->fix.smem_len, 
									(dma_addr_t *)&s5pv210_lcd->fix.smem_start, 
									GFP_KERNEL);
	*vidw00add0b0 = s5pv210_lcd->fix.smem_start; 
	*vidw00add1b0 = s5pv210_lcd->fix.smem_start 
						+ s5pv210_lcd->fix.smem_len; 
	*shadowcon = 0x1;

	*vidcon0 |= 0x3; 
	*wincon0 |= 1;   

	register_framebuffer(s5pv210_lcd);
	return 0;
}
Пример #14
0
__s32 Fb_Init(__u32 from)
{
	__s32 i;
	__bool need_open_hdmi = 0;
	__disp_fb_create_para_t fb_para = {
		.primary_screen_id = 0,
	};

	__inf("Fb_Init:%d\n", from);

	if (from == 0) { /* call from lcd driver */
#ifdef CONFIG_FB_SUNXI_RESERVED_MEM
		__inf("fbmem: fb_start=%lu, fb_size=%lu\n", fb_start, fb_size);
		disp_create_heap((unsigned long)(__va(fb_start)), fb_size);
#endif

		for (i = 0; i < SUNXI_MAX_FB; i++) {
			g_fbi.fbinfo[i] = framebuffer_alloc(0, g_fbi.dev);
			g_fbi.fbinfo[i]->fbops = &dispfb_ops;
			g_fbi.fbinfo[i]->flags = 0;
			g_fbi.fbinfo[i]->device = g_fbi.dev;
			g_fbi.fbinfo[i]->par = &g_fbi;
			g_fbi.fbinfo[i]->var.xoffset = 0;
			g_fbi.fbinfo[i]->var.yoffset = 0;
			g_fbi.fbinfo[i]->var.xres = 800;
			g_fbi.fbinfo[i]->var.yres = 480;
			g_fbi.fbinfo[i]->var.xres_virtual = 800;
			g_fbi.fbinfo[i]->var.yres_virtual = 480 * 2;
			g_fbi.fbinfo[i]->var.nonstd = 0;
			g_fbi.fbinfo[i]->var.grayscale = 0;
			g_fbi.fbinfo[i]->var.bits_per_pixel = 32;
			g_fbi.fbinfo[i]->var.transp.length = 8;
			g_fbi.fbinfo[i]->var.red.length = 8;
			g_fbi.fbinfo[i]->var.green.length = 8;
			g_fbi.fbinfo[i]->var.blue.length = 8;
			g_fbi.fbinfo[i]->var.transp.offset = 24;
			g_fbi.fbinfo[i]->var.red.offset = 16;
			g_fbi.fbinfo[i]->var.green.offset = 8;
			g_fbi.fbinfo[i]->var.blue.offset = 0;
			g_fbi.fbinfo[i]->var.activate = FB_ACTIVATE_FORCE;
			g_fbi.fbinfo[i]->fix.type = FB_TYPE_PACKED_PIXELS;
			g_fbi.fbinfo[i]->fix.type_aux = 0;
			g_fbi.fbinfo[i]->fix.visual = FB_VISUAL_TRUECOLOR;
			g_fbi.fbinfo[i]->fix.xpanstep = 1;
			g_fbi.fbinfo[i]->fix.ypanstep = 1;
			g_fbi.fbinfo[i]->fix.ywrapstep = 0;
			g_fbi.fbinfo[i]->fix.accel = FB_ACCEL_NONE;
			g_fbi.fbinfo[i]->fix.line_length =
				g_fbi.fbinfo[i]->var.xres_virtual * 4;
			g_fbi.fbinfo[i]->fix.smem_len =
				g_fbi.fbinfo[i]->fix.line_length *
				g_fbi.fbinfo[i]->var.yres_virtual * 2;
			g_fbi.fbinfo[i]->screen_base = NULL;
			g_fbi.fbinfo[i]->pseudo_palette =
				g_fbi.pseudo_palette[i];
			g_fbi.fbinfo[i]->fix.smem_start = 0x0;
			g_fbi.fbinfo[i]->fix.mmio_start = 0;
			g_fbi.fbinfo[i]->fix.mmio_len = 0;

			if (fb_alloc_cmap(&g_fbi.fbinfo[i]->cmap, 256, 1) < 0)
				return -ENOMEM;
		}
		parser_disp_init_para(&(g_fbi.disp_init));
	}

	if (g_fbi.disp_init.b_init) {
		__u32 sel = 0;

		for (sel = 0; sel < 2; sel++) {
			if (((sel == 0) && (g_fbi.disp_init.disp_mode !=
					    DISP_INIT_MODE_SCREEN1)) ||
			    ((sel == 1) && (g_fbi.disp_init.disp_mode !=
					    DISP_INIT_MODE_SCREEN0))) {
				if (g_fbi.disp_init.output_type[sel] ==
				    DISP_OUTPUT_TYPE_HDMI)
					need_open_hdmi = 1;
			}
		}
	}

	if (need_open_hdmi == 1 && from == 0)
		/* it is called from lcd driver, but hdmi need to be opened */
		return 0;
	else if (need_open_hdmi == 0 && from == 1)
		/* it is called from hdmi driver, but hdmi need not be opened */
		return 0;

	if (g_fbi.disp_init.b_init) {
		__u32 fb_num = 0, sel = 0;

		for (sel = 0; sel < 2; sel++) {
			if (((sel == 0) && (g_fbi.disp_init.disp_mode !=
					    DISP_INIT_MODE_SCREEN1)) ||
			    ((sel == 1) && (g_fbi.disp_init.disp_mode !=
					    DISP_INIT_MODE_SCREEN0))) {
				if (g_fbi.disp_init.output_type[sel] ==
				    DISP_OUTPUT_TYPE_LCD) {
					DRV_lcd_open(sel);
				} else if (g_fbi.disp_init.output_type[sel] ==
					   DISP_OUTPUT_TYPE_TV) {
					BSP_disp_tv_set_mode(sel,
							     g_fbi.disp_init.
							     tv_mode[sel]);
					BSP_disp_tv_open(sel);
				} else if (g_fbi.disp_init.output_type[sel] ==
					   DISP_OUTPUT_TYPE_HDMI) {
					BSP_disp_hdmi_set_mode(sel,
							       g_fbi.disp_init.
							       tv_mode[sel]);
					BSP_disp_hdmi_open(sel);
				} else if (g_fbi.disp_init.output_type[sel] ==
					   DISP_OUTPUT_TYPE_VGA) {
					BSP_disp_vga_set_mode(sel,
							      g_fbi.disp_init.
							      vga_mode[sel]);
					BSP_disp_vga_open(sel);
				}
			}
		}

		fb_num = (g_fbi.disp_init.disp_mode ==
			  DISP_INIT_MODE_TWO_DIFF_SCREEN) ? 2 : 1;
		for (i = 0; i < fb_num; i++) {
			__u32 screen_id = i;

			disp_fb_to_var(g_fbi.disp_init.format[i],
				       g_fbi.disp_init.seq[i],
				       g_fbi.disp_init.br_swap[i],
				       &(g_fbi.fbinfo[i]->var));

			if (g_fbi.disp_init.disp_mode ==
			    DISP_INIT_MODE_SCREEN1)
				screen_id = 1;

			fb_para.buffer_num = g_fbi.disp_init.buffer_num[i];
			fb_para.width = BSP_disp_get_screen_width(screen_id);
			fb_para.height = BSP_disp_get_screen_height(screen_id);
			fb_para.output_width =
				BSP_disp_get_screen_width(screen_id);
			fb_para.output_height =
				BSP_disp_get_screen_height(screen_id);
			fb_para.mode = (g_fbi.disp_init.scaler_mode[i] == 0) ?
				DISP_LAYER_WORK_MODE_NORMAL :
				DISP_LAYER_WORK_MODE_SCALER;
			if (g_fbi.disp_init.disp_mode ==
			    DISP_INIT_MODE_SCREEN0) {
				fb_para.fb_mode = FB_MODE_SCREEN0;
			} else if (g_fbi.disp_init.disp_mode ==
				   DISP_INIT_MODE_SCREEN1) {
				fb_para.fb_mode = FB_MODE_SCREEN1;
			} else if (g_fbi.disp_init.disp_mode ==
				   DISP_INIT_MODE_TWO_DIFF_SCREEN) {
				if (i == 0)
					fb_para.fb_mode = FB_MODE_SCREEN0;
				else
					fb_para.fb_mode = FB_MODE_SCREEN1;
			} else if (g_fbi.disp_init.disp_mode ==
				   DISP_INIT_MODE_TWO_SAME_SCREEN) {
				fb_para.fb_mode = FB_MODE_DUAL_SAME_SCREEN_TB;
				fb_para.height *= 2;
				fb_para.output_height *= 2;
			} else if (g_fbi.disp_init.disp_mode ==
				   DISP_INIT_MODE_TWO_DIFF_SCREEN_SAME_CONTENTS) {
				fb_para.fb_mode =
				    FB_MODE_DUAL_DIFF_SCREEN_SAME_CONTENTS;
				fb_para.output_width =
				    BSP_disp_get_screen_width(fb_para.
							      primary_screen_id);
				fb_para.output_height =
				    BSP_disp_get_screen_height(fb_para.
							       primary_screen_id);
				fb_para.aux_output_width =
				    BSP_disp_get_screen_width(1 -
							      fb_para.
							      primary_screen_id);
				fb_para.aux_output_height =
				    BSP_disp_get_screen_height(1 -
							       fb_para.
							       primary_screen_id);
			}
			Display_Fb_Request(i, &fb_para);

#if 0
			fb_draw_colorbar((__u32)g_fbi.fbinfo[i]->screen_base,
					 fb_para.width, fb_para.height *
					 fb_para.buffer_num,
					 &(g_fbi.fbinfo[i]->var));
#endif
		}

		for (i = 0; i < SUNXI_MAX_FB; i++)
			/* Register framebuffers after they are initialized */
			register_framebuffer(g_fbi.fbinfo[i]);

		if (g_fbi.disp_init.scaler_mode[0])
			BSP_disp_print_reg(0, DISP_REG_SCALER0);

		if (g_fbi.disp_init.scaler_mode[1])
			BSP_disp_print_reg(0, DISP_REG_SCALER1);

		if (g_fbi.disp_init.disp_mode != DISP_INIT_MODE_SCREEN1) {
			BSP_disp_print_reg(0, DISP_REG_IMAGE0);
			BSP_disp_print_reg(0, DISP_REG_LCDC0);
			if ((g_fbi.disp_init.output_type[0] ==
			     DISP_OUTPUT_TYPE_TV) ||
			    (g_fbi.disp_init.output_type[0] ==
			     DISP_OUTPUT_TYPE_VGA))
				BSP_disp_print_reg(0, DISP_REG_TVEC0);
		}
		if (g_fbi.disp_init.disp_mode != DISP_INIT_MODE_SCREEN0) {
			BSP_disp_print_reg(0, DISP_REG_IMAGE1);
			BSP_disp_print_reg(0, DISP_REG_LCDC1);
			if ((g_fbi.disp_init.output_type[1] ==
			     DISP_OUTPUT_TYPE_TV) ||
			    (g_fbi.disp_init.output_type[1] ==
			     DISP_OUTPUT_TYPE_VGA))
				BSP_disp_print_reg(0, DISP_REG_TVEC1);
		}
		BSP_disp_print_reg(0, DISP_REG_CCMU);
		BSP_disp_print_reg(0, DISP_REG_PWM);
		BSP_disp_print_reg(0, DISP_REG_PIOC);
	}

	__inf("Fb_Init: END\n");
	return 0;
}
EXPORT_SYMBOL(Fb_Init);

__s32 Fb_Exit(void)
{
	__u8 fb_id = 0;

	for (fb_id = 0; fb_id < SUNXI_MAX_FB; fb_id++) {
		if (g_fbi.fbinfo[fb_id] == NULL)
			continue;

		Display_Fb_Release(fb_id);

		unregister_framebuffer(g_fbi.fbinfo[fb_id]);
		framebuffer_release(g_fbi.fbinfo[fb_id]);
		g_fbi.fbinfo[fb_id] = NULL;
	}

	return 0;
}
Пример #15
0
static int __devinit nuc900fb_probe(struct platform_device *pdev)
{
	struct nuc900fb_info *fbi;
	struct nuc900fb_display *display;
	struct fb_info	   *fbinfo;
	struct nuc900fb_mach_info *mach_info;
	struct resource *res;
	int ret;
	int irq;
	int i;
	int size;

	dev_dbg(&pdev->dev, "devinit\n");
	mach_info = pdev->dev.platform_data;
	if (mach_info == NULL) {
		dev_err(&pdev->dev,
			"no platform data for lcd, cannot attach\n");
		return -EINVAL;
	}

	if (mach_info->default_display > mach_info->num_displays) {
		dev_err(&pdev->dev,
			"default display No. is %d but only %d displays \n",
			mach_info->default_display, mach_info->num_displays);
		return -EINVAL;
	}


	display = mach_info->displays + mach_info->default_display;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		dev_err(&pdev->dev, "no irq for device\n");
		return -ENOENT;
	}

	fbinfo = framebuffer_alloc(sizeof(struct nuc900fb_info), &pdev->dev);
	if (!fbinfo)
		return -ENOMEM;

	platform_set_drvdata(pdev, fbinfo);

	fbi = fbinfo->par;
	fbi->dev = &pdev->dev;

#ifdef CONFIG_CPU_NUC950
	fbi->drv_type = LCDDRV_NUC950;
#endif

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

	size = (res->end - res->start) + 1;
	fbi->mem = request_mem_region(res->start, size, pdev->name);
	if (fbi->mem == NULL) {
		dev_err(&pdev->dev, "failed to alloc memory region\n");
		ret = -ENOENT;
		goto free_fb;
	}

	fbi->io = ioremap(res->start, size);
	if (fbi->io == NULL) {
		dev_err(&pdev->dev, "ioremap() of lcd registers failed\n");
		ret = -ENXIO;
		goto release_mem_region;
	}

	fbi->irq_base = fbi->io + REG_LCM_INT_CS;


	/* Stop the LCD */
	writel(0, fbi->io + REG_LCM_DCCS);

	/* fill the fbinfo*/
	strcpy(fbinfo->fix.id, driver_name);
	fbinfo->fix.type		= FB_TYPE_PACKED_PIXELS;
	fbinfo->fix.type_aux		= 0;
	fbinfo->fix.xpanstep		= 0;
	fbinfo->fix.ypanstep		= 0;
	fbinfo->fix.ywrapstep		= 0;
	fbinfo->fix.accel		= FB_ACCEL_NONE;
	fbinfo->var.nonstd		= 0;
	fbinfo->var.activate		= FB_ACTIVATE_NOW;
	fbinfo->var.accel_flags		= 0;
	fbinfo->var.vmode		= FB_VMODE_NONINTERLACED;
	fbinfo->fbops			= &nuc900fb_ops;
	fbinfo->flags			= FBINFO_FLAG_DEFAULT;
	fbinfo->pseudo_palette		= &fbi->pseudo_pal;

	ret = request_irq(irq, nuc900fb_irqhandler, 0,
			  pdev->name, fbinfo);
	if (ret) {
		dev_err(&pdev->dev, "cannot register irq handler %d -err %d\n",
			irq, ret);
		ret = -EBUSY;
		goto release_regs;
	}

	fbi->clk = clk_get(&pdev->dev, NULL);
	if (IS_ERR(fbi->clk)) {
		printk(KERN_ERR "nuc900-lcd:failed to get lcd clock source\n");
		ret = PTR_ERR(fbi->clk);
		goto release_irq;
	}

	clk_enable(fbi->clk);
	dev_dbg(&pdev->dev, "got and enabled clock\n");

	fbi->clk_rate = clk_get_rate(fbi->clk);

	/* calutate the video buffer size */
	for (i = 0; i < mach_info->num_displays; i++) {
		unsigned long smem_len = mach_info->displays[i].xres;
		smem_len *= mach_info->displays[i].yres;
		smem_len *= mach_info->displays[i].bpp;
		smem_len >>= 3;
		if (fbinfo->fix.smem_len < smem_len)
			fbinfo->fix.smem_len = smem_len;
	}

	/* Initialize Video Memory */
	ret = nuc900fb_map_video_memory(fbinfo);
	if (ret) {
		printk(KERN_ERR "Failed to allocate video RAM: %x\n", ret);
		goto release_clock;
	}

	dev_dbg(&pdev->dev, "got video memory\n");

	fbinfo->var.xres = display->xres;
	fbinfo->var.yres = display->yres;
	fbinfo->var.bits_per_pixel = display->bpp;

	nuc900fb_init_registers(fbinfo);

	nuc900fb_check_var(&fbinfo->var, fbinfo);

	ret = nuc900fb_cpufreq_register(fbi);
	if (ret < 0) {
		dev_err(&pdev->dev, "Failed to register cpufreq\n");
		goto free_video_memory;
	}

	ret = register_framebuffer(fbinfo);
	if (ret) {
		printk(KERN_ERR "failed to register framebuffer device: %d\n",
			ret);
		goto free_cpufreq;
	}

	printk(KERN_INFO "fb%d: %s frame buffer device\n",
		fbinfo->node, fbinfo->fix.id);

	return 0;

free_cpufreq:
	nuc900fb_cpufreq_deregister(fbi);
free_video_memory:
	nuc900fb_unmap_video_memory(fbinfo);
release_clock:
	clk_disable(fbi->clk);
	clk_put(fbi->clk);
release_irq:
	free_irq(irq, fbi);
release_regs:
	iounmap(fbi->io);
release_mem_region:
	release_mem_region(res->start, size);
free_fb:
	framebuffer_release(fbinfo);
	return ret;
}
Пример #16
0
static int sprdfb_probe(struct platform_device *pdev)
{
	struct fb_info *fb = NULL;
	struct sprdfb_device *dev = NULL;
	int ret = 0;
#ifdef CONFIG_OF
	struct resource r;

#ifdef CONFIG_FB_LOW_RES_SIMU
	uint32_t display_size_array[2];
#endif

	pr_debug(KERN_INFO "sprdfb: [%s]\n", __FUNCTION__);
#else
	pr_debug(KERN_INFO "sprdfb: [%s], id = %d\n", __FUNCTION__, pdev->id);
#endif

	fb = framebuffer_alloc(sizeof(struct sprdfb_device), &pdev->dev);
	if (!fb) {
		printk(KERN_ERR "sprdfb: sprdfb_probe allocate buffer fail.\n");
		ret = -ENOMEM;
		goto err0;
	}

	dev = fb->par;
	dev->fb = fb;
#ifdef CONFIG_OF
	dev->of_dev = &(pdev->dev);

	dev->dev_id = of_alias_get_id(pdev->dev.of_node, "lcd");
	printk("sprdfb: [%s] id = %d\n", __FUNCTION__, dev->dev_id);
#else
	dev->dev_id = pdev->id;
#endif
	if((SPRDFB_MAINLCD_ID != dev->dev_id) &&(SPRDFB_SUBLCD_ID != dev->dev_id)){
		printk(KERN_ERR "sprdfb: sprdfb_probe fail. (unsupported device id)\n");
		goto err0;
	}

	switch(SPRDFB_IN_DATA_TYPE){
	case SPRD_IN_DATA_TYPE_ABGR888:
		dev->bpp = 32;
		break;
	case SPRD_IN_DATA_TYPE_BGR565:
		dev->bpp = 16;
		break;
	default:
		dev->bpp = 32;
		break;
	}

	if(SPRDFB_MAINLCD_ID == dev->dev_id){
		dev->ctrl = &sprdfb_dispc_ctrl;
#ifdef CONFIG_OF
		if(0 != of_address_to_resource(pdev->dev.of_node, 0, &r)){
			printk(KERN_ERR "sprdfb: sprdfb_probe fail. (can't get register base address)\n");
			goto err0;
		}
		g_dispc_base_addr = (unsigned long)ioremap_nocache(r.start,
				resource_size(&r));
		if(!g_dispc_base_addr)
			BUG();
		printk("sprdfb: set g_dispc_base_addr = %ld\n", g_dispc_base_addr);
#endif
	}

	dev->frame_count = 0;
	dev->logo_buffer_addr_v = 0;
	dev->capability = sprdfb_config_capability();

	if(sprdfb_panel_get(dev)){
		dev->panel_ready = true;

#ifdef CONFIG_OF
#ifdef CONFIG_FB_LOW_RES_SIMU
		ret = of_property_read_u32_array(pdev->dev.of_node, "sprd,fb_display_size", display_size_array, 2);
		if (0 != ret) {
			printk("sprdfb: read display_size from dts fail (%d)\n", ret);
			dev->display_width = dev->panel->width;
			dev->display_height = dev->panel->height;
		} else {
			dev->display_width = display_size_array[0];
			dev->display_height = display_size_array[1];
		}
#endif
#endif

		dev->ctrl->logo_proc(dev);
	}else{
		dev->panel_ready = false;
	}

	dev->ctrl->early_init(dev);

	if(!dev->panel_ready){
		if (!sprdfb_panel_probe(dev)) {
			ret = -EIO;
			goto cleanup;
		}
	}

	ret = setup_fb_mem(dev, pdev);
	if (ret) {
		goto cleanup;
	}

	setup_fb_info(dev);
	/* register framebuffer device */
	ret = register_framebuffer(fb);
	if (ret) {
		printk(KERN_ERR "sprdfb: sprdfb_probe register framebuffer fail.\n");
		goto cleanup;
	}
	platform_set_drvdata(pdev, dev);
	sprdfb_create_sysfs(dev);
	dev->ctrl->init(dev);

#ifdef CONFIG_HAS_EARLYSUSPEND
	dev->early_suspend.suspend = sprdfb_early_suspend;
	dev->early_suspend.resume  = sprdfb_late_resume;
	dev->early_suspend.level   = EARLY_SUSPEND_LEVEL_DISABLE_FB;
	register_early_suspend(&dev->early_suspend);
#endif

#ifdef CONFIG_FB_ESD_SUPPORT
	pr_debug("sprdfb: Init ESD work queue!\n");
	INIT_DELAYED_WORK(&dev->ESD_work, ESD_work_func);
//	sema_init(&dev->ESD_lock, 1);

	if(SPRDFB_PANEL_IF_DPI == dev->panel_if_type){
		dev->ESD_timeout_val = SPRDFB_ESD_TIME_OUT_VIDEO;
	}else{
		dev->ESD_timeout_val = SPRDFB_ESD_TIME_OUT_CMD;
	}

	dev->ESD_work_start = false;
	dev->check_esd_time = 0;
	dev->reset_dsi_time = 0;
	dev->panel_reset_time = 0;
#endif

	return 0;

cleanup:
	sprdfb_panel_remove(dev);
	dev->ctrl->uninit(dev);
	fb_free_resources(dev);
err0:
	dev_err(&pdev->dev, "failed to probe sprdfb\n");
	return ret;
}
Пример #17
0
static int mxc_elcdif_fb_probe(struct platform_device *pdev)
{
	int ret = 0;
	struct mxc_elcdif_fb_data *data;
	struct resource *res;
	struct fb_info *fbi;
	struct mxc_fb_platform_data *pdata = pdev->dev.platform_data;

	fbi = framebuffer_alloc(sizeof(struct mxc_elcdif_fb_data), &pdev->dev);
	if (fbi == NULL) {
		ret = -ENOMEM;
		goto out;
	}

	data = (struct mxc_elcdif_fb_data *)fbi->par;
	data->cur_blank = data->next_blank = FB_BLANK_UNBLANK;

	fbi->var.activate = FB_ACTIVATE_NOW;
	fbi->fbops = &mxc_elcdif_fb_ops;
	fbi->flags = FBINFO_FLAG_DEFAULT;
	fbi->pseudo_palette = data->pseudo_palette;

	ret = fb_alloc_cmap(&fbi->cmap, 16, 0);
	if (ret)
		goto out;

	g_elcdif_dev = &pdev->dev;

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (res == NULL) {
		dev_err(&pdev->dev, "cannot get IRQ resource\n");
		ret = -ENODEV;
		goto err0;
	}
	data->dma_irq = res->start;

	ret = request_irq(data->dma_irq, lcd_irq_handler, 0,
			  "mxc_elcdif_fb", data);
	if (ret) {
		dev_err(&pdev->dev, "request_irq (%d) failed with error %d\n",
				data->dma_irq, ret);
		goto err0;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res == NULL) {
		ret = -ENODEV;
		goto err1;
	}
	elcdif_base = ioremap(res->start, SZ_4K);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	if (res) {
		fbi->fix.smem_len = res->end - res->start + 1;
		fbi->fix.smem_start = res->start;
		fbi->screen_base = ioremap(fbi->fix.smem_start,
					   fbi->fix.smem_len);
	}

	strcpy(fbi->fix.id, "mxc_elcdif_fb");

	fbi->var.xres = 800;
	fbi->var.yres = 480;

	if (pdata && !data->output_pix_fmt)
		data->output_pix_fmt = pdata->interface_pix_fmt;

	if (pdata && pdata->mode && pdata->num_modes)
		fb_videomode_to_modelist(pdata->mode, pdata->num_modes,
				&fbi->modelist);

	if (!fb_mode && pdata && pdata->mode_str)
		fb_mode = pdata->mode_str;

	if (fb_mode) {
		ret = fb_find_mode(&fbi->var, fbi, fb_mode, NULL, 0, NULL,
				   default_bpp);
		if ((!ret || (ret > 2)) && pdata && pdata->mode &&
		    pdata->num_modes)
			fb_find_mode(&fbi->var, fbi, fb_mode, pdata->mode,
					pdata->num_modes, NULL, default_bpp);
	}

	mxc_elcdif_fb_check_var(&fbi->var, fbi);

	fbi->var.xres_virtual = fbi->var.xres;
	fbi->var.yres_virtual = fbi->var.yres * 3;

	mxc_elcdif_fb_set_fix(fbi);

	if (!res || !res->end)
		if (mxc_elcdif_fb_map_video_memory(fbi) < 0) {
			ret = -ENOMEM;
			goto err2;
		}

	g_elcdif_axi_clk = clk_get(g_elcdif_dev, "elcdif_axi");
	if (g_elcdif_axi_clk == NULL) {
		dev_err(&pdev->dev, "can't get ELCDIF axi clk\n");
		ret = -ENODEV;
		goto err3;
	}
	g_elcdif_pix_clk = clk_get(g_elcdif_dev, "elcdif_pix");
	if (g_elcdif_pix_clk == NULL) {
		dev_err(&pdev->dev, "can't get ELCDIF pix clk\n");
		ret = -ENODEV;
		goto err3;
	}
	/*
	 * Set an appropriate pixel clk rate first, so that we can
	 * access ELCDIF registers.
	 */
	clk_set_rate(g_elcdif_pix_clk, 25000000);

	ret = register_framebuffer(fbi);
	if (ret)
		goto err3;

	platform_set_drvdata(pdev, fbi);

	return 0;
err3:
	mxc_elcdif_fb_unmap_video_memory(fbi);
err2:
	iounmap(elcdif_base);
err1:
	free_irq(data->dma_irq, data);
err0:
	fb_dealloc_cmap(&fbi->cmap);
	framebuffer_release(fbi);
out:
	return ret;
}
Пример #18
0
static int intelfb_create(struct intel_fbdev *ifbdev,
                          struct drm_fb_helper_surface_size *sizes)
{
    struct drm_device *dev = ifbdev->helper.dev;
    struct drm_i915_private *dev_priv = dev->dev_private;
    struct fb_info *info;
    struct drm_framebuffer *fb;
    struct drm_mode_fb_cmd2 mode_cmd;
    struct drm_i915_gem_object *obj;
    struct device *device = &dev->pdev->dev;
    int size, ret;


    if (sizes->surface_bpp == 24)
        sizes->surface_bpp = 32;

    mode_cmd.width = sizes->surface_width;
    mode_cmd.height = sizes->surface_height;

    mode_cmd.pitches[0] = ALIGN(mode_cmd.width * ((sizes->surface_bpp + 7) /
                                8), 64);
    mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
                            sizes->surface_depth);

    size = mode_cmd.pitches[0] * mode_cmd.height;
    size = ALIGN(size, PAGE_SIZE);
    obj = i915_gem_alloc_object(dev, size);
    if (!obj) {
        DRM_ERROR("failed to allocate framebuffer\n");
        ret = -ENOMEM;
        goto out;
    }

    mutex_lock(&dev->struct_mutex);


    ret = intel_pin_and_fence_fb_obj(dev, obj, false);
    if (ret) {
        DRM_ERROR("failed to pin fb: %d\n", ret);
        goto out_unref;
    }

    info = framebuffer_alloc(0, device);
    if (!info) {
        ret = -ENOMEM;
        goto out_unpin;
    }

    info->par = ifbdev;

    ret = intel_framebuffer_init(dev, &ifbdev->ifb, &mode_cmd, obj);
    if (ret)
        goto out_unpin;

    fb = &ifbdev->ifb.base;

    ifbdev->helper.fb = fb;
    ifbdev->helper.fbdev = info;

    strcpy(info->fix.id, "inteldrmfb");

    info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
    info->fbops = &intelfb_ops;

    ret = fb_alloc_cmap(&info->cmap, 256, 0);
    if (ret) {
        ret = -ENOMEM;
        goto out_unpin;
    }

    info->apertures = alloc_apertures(1);
    if (!info->apertures) {
        ret = -ENOMEM;
        goto out_unpin;
    }
    info->apertures->ranges[0].base = dev->mode_config.fb_base;
    info->apertures->ranges[0].size =
        dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT;

    info->fix.smem_start = dev->mode_config.fb_base + obj->gtt_offset;
    info->fix.smem_len = size;

    info->screen_base = ioremap_wc(dev->agp->base + obj->gtt_offset, size);
    if (!info->screen_base) {
        ret = -ENOSPC;
        goto out_unpin;
    }
    info->screen_size = size;


    drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth);
    drm_fb_helper_fill_var(info, &ifbdev->helper, sizes->fb_width, sizes->fb_height);



    DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08x, bo %p\n",
                  fb->width, fb->height,
                  obj->gtt_offset, obj);


    mutex_unlock(&dev->struct_mutex);
    vga_switcheroo_client_fb_set(dev->pdev, info);
    return 0;

out_unpin:
    i915_gem_object_unpin(obj);
out_unref:
    drm_gem_object_unreference(&obj->base);
    mutex_unlock(&dev->struct_mutex);
out:
    return ret;
}
Пример #19
0
static int __devinit fm2fb_probe(struct zorro_dev *z,
				 const struct zorro_device_id *id)
{
	struct fb_info *info;
	unsigned long *ptr;
	int is_fm;
	int x, y;

	is_fm = z->id == ZORRO_PROD_BSC_FRAMEMASTER_II;

	if (!zorro_request_device(z,"fm2fb"))
		return -ENXIO;

	info = framebuffer_alloc(256 * sizeof(u32), &z->dev);
	if (!info) {
		zorro_release_device(z);
		return -ENOMEM;
	}

	if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
		framebuffer_release(info);
		zorro_release_device(z);
		return -ENOMEM;
	}

	/* assigning memory to kernel space */
	fb_fix.smem_start = zorro_resource_start(z);
	info->screen_base = ioremap(fb_fix.smem_start, FRAMEMASTER_SIZE);
	fb_fix.mmio_start = fb_fix.smem_start + FRAMEMASTER_REG;
	fm2fb_reg  = (unsigned char *)(info->screen_base+FRAMEMASTER_REG);

	strcpy(fb_fix.id, is_fm ? "FrameMaster II" : "Rainbow II");

	/* make EBU color bars on display */
	ptr = (unsigned long *)fb_fix.smem_start;
	for (y = 0; y < 576; y++) {
		for (x = 0; x < 96; x++) *ptr++ = 0xffffff;/* white */
		for (x = 0; x < 96; x++) *ptr++ = 0xffff00;/* yellow */
		for (x = 0; x < 96; x++) *ptr++ = 0x00ffff;/* cyan */
		for (x = 0; x < 96; x++) *ptr++ = 0x00ff00;/* green */
		for (x = 0; x < 96; x++) *ptr++ = 0xff00ff;/* magenta */
		for (x = 0; x < 96; x++) *ptr++ = 0xff0000;/* red */
		for (x = 0; x < 96; x++) *ptr++ = 0x0000ff;/* blue */
		for (x = 0; x < 96; x++) *ptr++ = 0x000000;/* black */
	}
	fm2fb_blank(0, info);

	if (fm2fb_mode == -1)
		fm2fb_mode = FM2FB_MODE_PAL;

	info->fbops = &fm2fb_ops;
	info->var = fb_var_modes[fm2fb_mode];
	info->pseudo_palette = info->par;
	info->par = NULL;
	info->fix = fb_fix;
	info->flags = FBINFO_DEFAULT;

	if (register_framebuffer(info) < 0) {
		fb_dealloc_cmap(&info->cmap);
		framebuffer_release(info);
		zorro_release_device(z);
		return -EINVAL;
	}
	printk("fb%d: %s frame buffer device\n", info->node, fb_fix.id);
	return 0;
}
Пример #20
0
static int evdifb_create(struct drm_fb_helper *helper,
			 struct drm_fb_helper_surface_size *sizes)
{
	struct evdi_fbdev *ufbdev = (struct evdi_fbdev *)helper;
	struct drm_device *dev = ufbdev->helper.dev;
	struct fb_info *info;
	struct device *device = dev->dev;
	struct drm_framebuffer *fb;
	struct drm_mode_fb_cmd2 mode_cmd;
	struct evdi_gem_object *obj;
	uint32_t size;
	int ret = 0;

	if (sizes->surface_bpp == 24) {
		sizes->surface_bpp = 32;
	} else if (sizes->surface_bpp != 32) {
		EVDI_ERROR("Not supported pixel format (bpp=%d)\n",
			   sizes->surface_bpp);
		return -EINVAL;
	}

	mode_cmd.width = sizes->surface_width;
	mode_cmd.height = sizes->surface_height;
	mode_cmd.pitches[0] = mode_cmd.width * ((sizes->surface_bpp + 7) / 8);

	mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
							  sizes->surface_depth);

	size = mode_cmd.pitches[0] * mode_cmd.height;
	size = ALIGN(size, PAGE_SIZE);

	obj = evdi_gem_alloc_object(dev, size);
	if (!obj)
		goto out;

	ret = evdi_gem_vmap(obj);
	if (ret) {
		DRM_ERROR("failed to vmap fb\n");
		goto out_gfree;
	}

	info = framebuffer_alloc(0, device);
	if (!info) {
		ret = -ENOMEM;
		goto out_gfree;
	}
	info->par = ufbdev;

	ret = evdi_framebuffer_init(dev, &ufbdev->ufb, &mode_cmd, obj);
	if (ret)
		goto out_gfree;

	fb = &ufbdev->ufb.base;

	ufbdev->helper.fb = fb;
	ufbdev->helper.fbdev = info;

	strcpy(info->fix.id, "evdidrmfb");

	info->screen_base = ufbdev->ufb.obj->vmapping;
	info->fix.smem_len = size;
	info->fix.smem_start = (unsigned long)ufbdev->ufb.obj->vmapping;

	info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
	info->fbops = &evdifb_ops;
	drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth);
	drm_fb_helper_fill_var(info, &ufbdev->helper, sizes->fb_width,
			       sizes->fb_height);

	ret = fb_alloc_cmap(&info->cmap, 256, 0);
	if (ret) {
		ret = -ENOMEM;
		goto out_gfree;
	}

	DRM_DEBUG_KMS("allocated %dx%d vmal %p\n",
		      fb->width, fb->height, ufbdev->ufb.obj->vmapping);

	return ret;
 out_gfree:
	drm_gem_object_unreference(&ufbdev->ufb.obj->base);
 out:
	return ret;
}
Пример #21
0
static void __init offb_init_fb(const char *name, const char *full_name,
				int width, int height, int depth,
				int pitch, unsigned long address,
				int foreign_endian, struct device_node *dp)
{
	unsigned long res_size = pitch * height * (depth + 7) / 8;
	struct offb_par *par = &default_par;
	unsigned long res_start = address;
	struct fb_fix_screeninfo *fix;
	struct fb_var_screeninfo *var;
	struct fb_info *info;

	if (!request_mem_region(res_start, res_size, "offb"))
		return;

	printk(KERN_INFO
	       "Using unsupported %dx%d %s at %lx, depth=%d, pitch=%d\n",
	       width, height, name, address, depth, pitch);
	if (depth != 8 && depth != 15 && depth != 16 && depth != 32) {
		printk(KERN_ERR "%s: can't use depth = %d\n", full_name,
		       depth);
		release_mem_region(res_start, res_size);
		return;
	}

	info = framebuffer_alloc(sizeof(u32) * 16, NULL);
	
	if (info == 0) {
		release_mem_region(res_start, res_size);
		return;
	}

	fix = &info->fix;
	var = &info->var;
	info->par = par;

	strcpy(fix->id, "OFfb ");
	strncat(fix->id, name, sizeof(fix->id) - sizeof("OFfb "));
	fix->id[sizeof(fix->id) - 1] = '\0';

	var->xres = var->xres_virtual = width;
	var->yres = var->yres_virtual = height;
	fix->line_length = pitch;

	fix->smem_start = address;
	fix->smem_len = pitch * height;
	fix->type = FB_TYPE_PACKED_PIXELS;
	fix->type_aux = 0;

	par->cmap_type = cmap_unknown;
	if (depth == 8)
		offb_init_palette_hacks(info, dp, name, address);
	else
		fix->visual = FB_VISUAL_TRUECOLOR;

	var->xoffset = var->yoffset = 0;
	switch (depth) {
	case 8:
		var->bits_per_pixel = 8;
		var->red.offset = 0;
		var->red.length = 8;
		var->green.offset = 0;
		var->green.length = 8;
		var->blue.offset = 0;
		var->blue.length = 8;
		var->transp.offset = 0;
		var->transp.length = 0;
		break;
	case 15:		/* RGB 555 */
		var->bits_per_pixel = 16;
		var->red.offset = 10;
		var->red.length = 5;
		var->green.offset = 5;
		var->green.length = 5;
		var->blue.offset = 0;
		var->blue.length = 5;
		var->transp.offset = 0;
		var->transp.length = 0;
		break;
	case 16:		/* RGB 565 */
		var->bits_per_pixel = 16;
		var->red.offset = 11;
		var->red.length = 5;
		var->green.offset = 5;
		var->green.length = 6;
		var->blue.offset = 0;
		var->blue.length = 5;
		var->transp.offset = 0;
		var->transp.length = 0;
		break;
	case 32:		/* RGB 888 */
		var->bits_per_pixel = 32;
		var->red.offset = 16;
		var->red.length = 8;
		var->green.offset = 8;
		var->green.length = 8;
		var->blue.offset = 0;
		var->blue.length = 8;
		var->transp.offset = 24;
		var->transp.length = 8;
		break;
	}
	var->red.msb_right = var->green.msb_right = var->blue.msb_right =
	    var->transp.msb_right = 0;
	var->grayscale = 0;
	var->nonstd = 0;
	var->activate = 0;
	var->height = var->width = -1;
	var->pixclock = 10000;
	var->left_margin = var->right_margin = 16;
	var->upper_margin = var->lower_margin = 16;
	var->hsync_len = var->vsync_len = 8;
	var->sync = 0;
	var->vmode = FB_VMODE_NONINTERLACED;

	/* set offb aperture size for generic probing */
	info->apertures = alloc_apertures(1);
	if (!info->apertures)
		goto out_aper;
	info->apertures->ranges[0].base = address;
	info->apertures->ranges[0].size = fix->smem_len;

	info->fbops = &offb_ops;
	info->screen_base = ioremap(address, fix->smem_len);
	info->pseudo_palette = (void *) (info + 1);
	info->flags = FBINFO_DEFAULT | FBINFO_MISC_FIRMWARE | foreign_endian;

	fb_alloc_cmap(&info->cmap, 256, 0);

	if (register_framebuffer(info) < 0)
		goto out_err;

	printk(KERN_INFO "fb%d: Open Firmware frame buffer device on %s\n",
	       info->node, full_name);
	return;

out_err:
	iounmap(info->screen_base);
out_aper:
	iounmap(par->cmap_adr);
	par->cmap_adr = NULL;
	framebuffer_release(info);
	release_mem_region(res_start, res_size);
}
Пример #22
0
static int intelfb_create(struct drm_fb_helper *helper,
			  struct drm_fb_helper_surface_size *sizes)
{
	struct intel_fbdev *ifbdev =
		container_of(helper, struct intel_fbdev, helper);
	struct intel_framebuffer *intel_fb = &ifbdev->ifb;
	struct drm_device *dev = helper->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct fb_info *info;
	struct drm_framebuffer *fb;
	struct drm_i915_gem_object *obj;
	int size, ret;

	mutex_lock(&dev->struct_mutex);

	if (!intel_fb->obj) {
		DRM_DEBUG_KMS("no BIOS fb, allocating a new one\n");
		ret = intelfb_alloc(helper, sizes);
		if (ret)
			goto out_unlock;
	} else {
		DRM_DEBUG_KMS("re-using BIOS fb\n");
		sizes->fb_width = intel_fb->base.width;
		sizes->fb_height = intel_fb->base.height;
	}

	obj = intel_fb->obj;
	size = obj->base.size;

	info = framebuffer_alloc(0, &dev->pdev->dev);
	if (!info) {
		ret = -ENOMEM;
		goto out_unpin;
	}

	info->par = helper;

	fb = &ifbdev->ifb.base;

	ifbdev->helper.fb = fb;
	ifbdev->helper.fbdev = info;

	strcpy(info->fix.id, "inteldrmfb");

	info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
	info->fbops = &intelfb_ops;

	ret = fb_alloc_cmap(&info->cmap, 256, 0);
	if (ret) {
		ret = -ENOMEM;
		goto out_unpin;
	}

	info->fix.smem_start = dev->mode_config.fb_base + i915_gem_obj_ggtt_offset(obj);
	info->fix.smem_len = size;

	info->screen_base =
		ioremap_wc(dev_priv->gtt.mappable_base + i915_gem_obj_ggtt_offset(obj),
			   size);
	if (!info->screen_base) {
		ret = -ENOSPC;
		goto out_unpin;
	}
	info->screen_size = size;

	drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth);
	drm_fb_helper_fill_var(info, &ifbdev->helper, sizes->fb_width, sizes->fb_height);

	/* If the object is shmemfs backed, it will have given us zeroed pages.
	 * If the object is stolen however, it will be full of whatever
	 * garbage was left in there.
	 */
	if (ifbdev->ifb.obj->stolen)
		memset_io(info->screen_base, 0, info->screen_size);

	/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */

	DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08lx, bo %p\n",
		      fb->width, fb->height,
		      i915_gem_obj_ggtt_offset(obj), obj);

	mutex_unlock(&dev->struct_mutex);
	vga_switcheroo_client_fb_set(dev->pdev, info);
	return 0;

out_unpin:
	i915_gem_object_unpin(obj);
	drm_gem_object_unreference(&obj->base);
out_unlock:
	mutex_unlock(&dev->struct_mutex);
	return ret;
}
Пример #23
0
__s32 Fb_Init()
{
	__disp_fb_create_para_t fb_para;
	__s32 i;
	__bool need_open_hdmi = 0;
	__u32 num_screens;

	num_screens = bsp_disp_feat_get_num_screens();

	pr_info("[DISP]==Fb_Init==\n");

	INIT_WORK(&g_fbi.vsync_work[0], send_vsync_work_0);
	INIT_WORK(&g_fbi.vsync_work[1], send_vsync_work_1);
	INIT_WORK(&g_fbi.post2_cb_work, post2_cb);
	mutex_init(&g_fbi.runtime_lock);

	for(i=0; i<8; i++) {
		g_fbi.fbinfo[i] = framebuffer_alloc(0, g_fbi.dev);
		g_fbi.fbinfo[i]->fbops   = &dispfb_ops;
		g_fbi.fbinfo[i]->flags   = 0;
		g_fbi.fbinfo[i]->device  = g_fbi.dev;
		g_fbi.fbinfo[i]->par     = &g_fbi;
		g_fbi.fbinfo[i]->var.xoffset         = 0;
		g_fbi.fbinfo[i]->var.yoffset         = 0;
		g_fbi.fbinfo[i]->var.xres            = 800;
		g_fbi.fbinfo[i]->var.yres            = 480;
		g_fbi.fbinfo[i]->var.xres_virtual    = 800;
		g_fbi.fbinfo[i]->var.yres_virtual    = 480*2;
		g_fbi.fbinfo[i]->var.nonstd = 0;
		g_fbi.fbinfo[i]->var.bits_per_pixel = 32;
		g_fbi.fbinfo[i]->var.transp.length = 8;
		g_fbi.fbinfo[i]->var.red.length = 8;
		g_fbi.fbinfo[i]->var.green.length = 8;
		g_fbi.fbinfo[i]->var.blue.length = 8;
		g_fbi.fbinfo[i]->var.transp.offset = 24;
		g_fbi.fbinfo[i]->var.red.offset = 16;
		g_fbi.fbinfo[i]->var.green.offset = 8;
		g_fbi.fbinfo[i]->var.blue.offset = 0;
		g_fbi.fbinfo[i]->var.activate = FB_ACTIVATE_FORCE;
		g_fbi.fbinfo[i]->fix.type	    = FB_TYPE_PACKED_PIXELS;
		g_fbi.fbinfo[i]->fix.type_aux	= 0;
		g_fbi.fbinfo[i]->fix.visual 	= FB_VISUAL_TRUECOLOR;
		g_fbi.fbinfo[i]->fix.xpanstep	= 1;
		g_fbi.fbinfo[i]->fix.ypanstep	= 1;
		g_fbi.fbinfo[i]->fix.ywrapstep	= 0;
		g_fbi.fbinfo[i]->fix.accel	    = FB_ACCEL_NONE;
		g_fbi.fbinfo[i]->fix.line_length = g_fbi.fbinfo[i]->var.xres_virtual * 4;
		g_fbi.fbinfo[i]->fix.smem_len = g_fbi.fbinfo[i]->fix.line_length * g_fbi.fbinfo[i]->var.yres_virtual * 2;
		g_fbi.fbinfo[i]->screen_base = 0x0;
		g_fbi.fbinfo[i]->fix.smem_start = 0x0;

		register_framebuffer(g_fbi.fbinfo[i]);
	}
	parser_disp_init_para(&(g_fbi.disp_init));


	if(g_fbi.disp_init.b_init) {
		__u32 sel = 0;

		for(sel = 0; sel<num_screens; sel++) {
			if((sel==0) && (g_fbi.disp_init.disp_mode == DISP_INIT_MODE_SCREEN0))	{
				if(g_fbi.disp_init.output_type[sel] == DISP_OUTPUT_TYPE_HDMI)	{
					need_open_hdmi = 1;
				}
			}
		}
	}

	if(g_fbi.disp_init.b_init) {
		__u32 fb_num = 0;

		fb_num = (g_fbi.disp_init.disp_mode==DISP_INIT_MODE_TWO_DIFF_SCREEN)?2:1;
		for(i = 0; i<fb_num; i++)	{
			__u32 screen_id = i;

			disp_fb_to_var(g_fbi.disp_init.format[i], g_fbi.disp_init.seq[i], g_fbi.disp_init.br_swap[i], &(g_fbi.fbinfo[i]->var));

			if(g_fbi.disp_init.disp_mode == DISP_INIT_MODE_SCREEN1)	{
				screen_id = 1;
			}
			fb_para.buffer_num= g_fbi.disp_init.buffer_num[i];
			if((g_fbi.disp_init.fb_width[i] == 0) || (g_fbi.disp_init.fb_height[i] == 0))	{
				fb_para.width = bsp_disp_get_screen_width_from_output_type(screen_id,
				    g_fbi.disp_init.output_type[screen_id], g_fbi.disp_init.output_mode[screen_id]);
				fb_para.height = bsp_disp_get_screen_height_from_output_type(screen_id,
				    g_fbi.disp_init.output_type[screen_id], g_fbi.disp_init.output_mode[screen_id]);
			}	else {
				fb_para.width = g_fbi.disp_init.fb_width[i];
				fb_para.height = g_fbi.disp_init.fb_height[i];
			}
			fb_para.output_width = bsp_disp_get_screen_width_from_output_type(screen_id,
				    g_fbi.disp_init.output_type[screen_id], g_fbi.disp_init.output_mode[screen_id]);
			fb_para.output_height = bsp_disp_get_screen_height_from_output_type(screen_id,
				    g_fbi.disp_init.output_type[screen_id], g_fbi.disp_init.output_mode[screen_id]);
			fb_para.mode = (g_fbi.disp_init.scaler_mode[i]==0)?DISP_LAYER_WORK_MODE_NORMAL:DISP_LAYER_WORK_MODE_SCALER;
			if(g_fbi.disp_init.disp_mode == DISP_INIT_MODE_SCREEN0)	{
				fb_para.fb_mode = FB_MODE_SCREEN0;
			}	else if(g_fbi.disp_init.disp_mode == DISP_INIT_MODE_SCREEN1) {
				fb_para.fb_mode = FB_MODE_SCREEN1;
			}	else if(g_fbi.disp_init.disp_mode == DISP_INIT_MODE_TWO_DIFF_SCREEN) {
				if(i == 0) {
					fb_para.fb_mode = FB_MODE_SCREEN0;
				}	else {
					fb_para.fb_mode = FB_MODE_SCREEN1;
				}
			}
			else if(g_fbi.disp_init.disp_mode == DISP_INIT_MODE_TWO_SAME_SCREEN) {
				fb_para.fb_mode = FB_MODE_DUAL_SAME_SCREEN_TB;
				fb_para.height *= 2;
				fb_para.output_height *= 2;
			}	else if(g_fbi.disp_init.disp_mode == DISP_INIT_MODE_TWO_DIFF_SCREEN_SAME_CONTENTS) {
				fb_para.fb_mode = FB_MODE_DUAL_DIFF_SCREEN_SAME_CONTENTS;
				fb_para.output_width = bsp_disp_get_screen_width_from_output_type(fb_para.primary_screen_id,
				    g_fbi.disp_init.output_type[fb_para.primary_screen_id], g_fbi.disp_init.output_mode[fb_para.primary_screen_id]);
				fb_para.output_height = bsp_disp_get_screen_height_from_output_type(fb_para.primary_screen_id,
				    g_fbi.disp_init.output_type[fb_para.primary_screen_id], g_fbi.disp_init.output_mode[fb_para.primary_screen_id]);
				fb_para.aux_output_width = bsp_disp_get_screen_width(1 - fb_para.primary_screen_id);
				fb_para.aux_output_height = bsp_disp_get_screen_width_from_output_type(1 - fb_para.primary_screen_id,
				    g_fbi.disp_init.output_type[1 - fb_para.primary_screen_id], g_fbi.disp_init.output_mode[1 - fb_para.primary_screen_id]);
			}
			Display_Fb_Request(i, &fb_para);
#if defined (CONFIG_FPGA_V4_PLATFORM)
			fb_draw_colorbar((__u32)g_fbi.fbinfo[i]->screen_base, fb_para.width, fb_para.height*fb_para.buffer_num, &(g_fbi.fbinfo[i]->var));
#endif
		}
#if 0
		if(g_fbi.disp_init.scaler_mode[0])	{
			bsp_disp_print_reg(0, DISP_MOD_FE0, 0);
		}
		if(g_fbi.disp_init.scaler_mode[1]) {
			bsp_disp_print_reg(0, DISP_MOD_FE1, 0);
		}
		if(g_fbi.disp_init.disp_mode != DISP_INIT_MODE_SCREEN1)	{
			bsp_disp_print_reg(0, DISP_MOD_BE0, 0);
			bsp_disp_print_reg(0, DISP_MOD_LCD0, 0);
			if((g_fbi.disp_init.output_type[0] == DISP_OUTPUT_TYPE_TV) || (g_fbi.disp_init.output_type[0] == DISP_OUTPUT_TYPE_VGA))	{
				bsp_disp_print_reg(0, DISP_MOD_TVE0, 0);
			}
		}
		if(g_fbi.disp_init.disp_mode != DISP_INIT_MODE_SCREEN0)	{
			bsp_disp_print_reg(0, DISP_MOD_BE1, 0);
			bsp_disp_print_reg(0, DISP_MOD_LCD1, 0);
			if((g_fbi.disp_init.output_type[1] == DISP_OUTPUT_TYPE_TV) || (g_fbi.disp_init.output_type[1] == DISP_OUTPUT_TYPE_VGA))	{
				bsp_disp_print_reg(0, DISP_MOD_TVE1, 0);
			}
		}
		bsp_disp_print_reg(0, DISP_MOD_CCMU, 0);
		bsp_disp_print_reg(0, DISP_MOD_PWM, 0);
		bsp_disp_print_reg(0, DISP_MOD_PIOC, 0);
		#endif
	}

	return 0;
}
Пример #24
0
static int intelfb_create(struct intel_fbdev *ifbdev,
			  struct drm_fb_helper_surface_size *sizes)
{
	struct drm_device *dev = ifbdev->helper.dev;
	struct fb_info *info;
	struct drm_framebuffer *fb;
	struct drm_mode_fb_cmd mode_cmd;
	struct drm_i915_gem_object *obj;
	struct device *device = &dev->pdev->dev;
	int size, ret;

	/* we don't do packed 24bpp */
	if (sizes->surface_bpp == 24)
		sizes->surface_bpp = 32;

	mode_cmd.width = sizes->surface_width;
	mode_cmd.height = sizes->surface_height;

	mode_cmd.bpp = sizes->surface_bpp;
	mode_cmd.pitch = ALIGN(mode_cmd.width * ((mode_cmd.bpp + 7) / 8), 64);
	mode_cmd.depth = sizes->surface_depth;

	size = mode_cmd.pitch * mode_cmd.height;
	size = ALIGN(size, PAGE_SIZE);
	obj = i915_gem_alloc_object(dev, size);
	if (!obj) {
		DRM_ERROR("failed to allocate framebuffer\n");
		ret = -ENOMEM;
		goto out;
	}

	mutex_lock(&dev->struct_mutex);

	/* Flush everything out, we'll be doing GTT only from now on */
	ret = intel_pin_and_fence_fb_obj(dev, obj, false);
	if (ret) {
		DRM_ERROR("failed to pin fb: %d\n", ret);
		goto out_unref;
	}

	info = framebuffer_alloc(0, device);
	if (!info) {
		ret = -ENOMEM;
		goto out_unpin;
	}

	info->par = ifbdev;

	ret = intel_framebuffer_init(dev, &ifbdev->ifb, &mode_cmd, obj);
	if (ret)
		goto out_unpin;

	fb = &ifbdev->ifb.base;

	ifbdev->helper.fb = fb;
	ifbdev->helper.fbdev = info;

	strcpy(info->fix.id, "inteldrmfb");

	info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
	info->fbops = &intelfb_ops;

	ret = fb_alloc_cmap(&info->cmap, 256, 0);
	if (ret) {
		ret = -ENOMEM;
		goto out_unpin;
	}
	/* setup aperture base/size for vesafb takeover */
	info->aperture_base = dev->mode_config.fb_base;
	if (!IS_GEN2(dev))
		info->aperture_size = pci_resource_len(dev->pdev, 2);
	else
		info->aperture_size = pci_resource_len(dev->pdev, 0);

	info->fix.smem_start = dev->mode_config.fb_base + obj->gtt_offset;
	info->fix.smem_len = size;

	info->screen_base = ioremap_wc(dev->agp->base + obj->gtt_offset, size);
	if (!info->screen_base) {
		ret = -ENOSPC;
		goto out_unpin;
	}
	info->screen_size = size;

//	memset(info->screen_base, 0, size);

	drm_fb_helper_fill_fix(info, fb->pitch, fb->depth);
	drm_fb_helper_fill_var(info, &ifbdev->helper, sizes->fb_width, sizes->fb_height);

	info->pixmap.size = 64*1024;
	info->pixmap.buf_align = 8;
	info->pixmap.access_align = 32;
	info->pixmap.flags = FB_PIXMAP_SYSTEM;
	info->pixmap.scan_align = 1;

	DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08x, bo %p\n",
		      fb->width, fb->height,
		      obj->gtt_offset, obj);


	mutex_unlock(&dev->struct_mutex);
	vga_switcheroo_client_fb_set(dev->pdev, info);
	return 0;

out_unpin:
	i915_gem_object_unpin(obj);
out_unref:
	drm_gem_object_unreference(&obj->base);
	mutex_unlock(&dev->struct_mutex);
out:
	return ret;
}
Пример #25
0
static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
{
	struct fb_info *info;
	struct sh_mobile_lcdc_priv *priv;
	struct sh_mobile_lcdc_info *pdata = pdev->dev.platform_data;
	struct resource *res;
	int error;
	void *buf;
	int i, j;

	if (!pdata) {
		dev_err(&pdev->dev, "no platform data defined\n");
		return -EINVAL;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	i = platform_get_irq(pdev, 0);
	if (!res || i < 0) {
		dev_err(&pdev->dev, "cannot get platform resources\n");
		return -ENOENT;
	}

	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
	if (!priv) {
		dev_err(&pdev->dev, "cannot allocate device data\n");
		return -ENOMEM;
	}

	platform_set_drvdata(pdev, priv);

	error = request_irq(i, sh_mobile_lcdc_irq, IRQF_DISABLED,
			    dev_name(&pdev->dev), priv);
	if (error) {
		dev_err(&pdev->dev, "unable to request irq\n");
		goto err1;
	}

	priv->irq = i;
	atomic_set(&priv->hw_usecnt, -1);

	j = 0;
	for (i = 0; i < ARRAY_SIZE(pdata->ch); i++) {
		struct sh_mobile_lcdc_chan *ch = priv->ch + j;

		ch->lcdc = priv;
		memcpy(&ch->cfg, &pdata->ch[i], sizeof(pdata->ch[i]));

		error = sh_mobile_lcdc_check_interface(ch);
		if (error) {
			dev_err(&pdev->dev, "unsupported interface type\n");
			goto err1;
		}
		init_waitqueue_head(&ch->frame_end_wait);
		init_completion(&ch->vsync_completion);
		ch->pan_offset = 0;

		/* probe the backlight is there is one defined */
		if (ch->cfg.bl_info.max_brightness)
			ch->bl = sh_mobile_lcdc_bl_probe(&pdev->dev, ch);

		switch (pdata->ch[i].chan) {
		case LCDC_CHAN_MAINLCD:
			ch->enabled = 1 << 1;
			ch->reg_offs = lcdc_offs_mainlcd;
			j++;
			break;
		case LCDC_CHAN_SUBLCD:
			ch->enabled = 1 << 2;
			ch->reg_offs = lcdc_offs_sublcd;
			j++;
			break;
		}
	}

	if (!j) {
		dev_err(&pdev->dev, "no channels defined\n");
		error = -EINVAL;
		goto err1;
	}

	/* for dual channel LCDC (MAIN + SUB) force shared bpp setting */
	if (j == 2)
		priv->forced_bpp = pdata->ch[0].bpp;

	priv->base = ioremap_nocache(res->start, resource_size(res));
	if (!priv->base)
		goto err1;

	error = sh_mobile_lcdc_setup_clocks(pdev, pdata->clock_source, priv);
	if (error) {
		dev_err(&pdev->dev, "unable to setup clocks\n");
		goto err1;
	}

	priv->meram_dev = pdata->meram_dev;

	for (i = 0; i < j; i++) {
		struct fb_var_screeninfo *var;
		const struct fb_videomode *lcd_cfg, *max_cfg = NULL;
		struct sh_mobile_lcdc_chan *ch = priv->ch + i;
		struct sh_mobile_lcdc_chan_cfg *cfg = &ch->cfg;
		const struct fb_videomode *mode = cfg->lcd_cfg;
		unsigned long max_size = 0;
		int k;
		int num_cfg;

		ch->info = framebuffer_alloc(0, &pdev->dev);
		if (!ch->info) {
			dev_err(&pdev->dev, "unable to allocate fb_info\n");
			error = -ENOMEM;
			break;
		}

		info = ch->info;
		var = &info->var;
		info->fbops = &sh_mobile_lcdc_ops;
		info->par = ch;

		mutex_init(&ch->open_lock);

		for (k = 0, lcd_cfg = mode;
		     k < cfg->num_cfg && lcd_cfg;
		     k++, lcd_cfg++) {
			unsigned long size = lcd_cfg->yres * lcd_cfg->xres;
			/* NV12 buffers must have even number of lines */
			if ((cfg->nonstd) && cfg->bpp == 12 &&
					(lcd_cfg->yres & 0x1)) {
				dev_err(&pdev->dev, "yres must be multiple of 2"
						" for YCbCr420 mode.\n");
				error = -EINVAL;
				goto err1;
			}

			if (size > max_size) {
				max_cfg = lcd_cfg;
				max_size = size;
			}
		}

		if (!mode)
			max_size = MAX_XRES * MAX_YRES;
		else if (max_cfg)
			dev_dbg(&pdev->dev, "Found largest videomode %ux%u\n",
				max_cfg->xres, max_cfg->yres);

		info->fix = sh_mobile_lcdc_fix;
		info->fix.smem_len = max_size * 2 * cfg->bpp / 8;

		 /* Only pan in 2 line steps for NV12 */
		if (cfg->nonstd && cfg->bpp == 12)
			info->fix.ypanstep = 2;

		if (!mode) {
			mode = &default_720p;
			num_cfg = 1;
		} else {
			num_cfg = cfg->num_cfg;
		}

		fb_videomode_to_modelist(mode, num_cfg, &info->modelist);

		fb_videomode_to_var(var, mode);
		var->width = cfg->lcd_size_cfg.width;
		var->height = cfg->lcd_size_cfg.height;
		/* Default Y virtual resolution is 2x panel size */
		var->yres_virtual = var->yres * 2;
		var->activate = FB_ACTIVATE_NOW;

		error = sh_mobile_lcdc_set_bpp(var, cfg->bpp, cfg->nonstd);
		if (error)
			break;

		buf = dma_alloc_coherent(&pdev->dev, info->fix.smem_len,
					 &ch->dma_handle, GFP_KERNEL);
		if (!buf) {
			dev_err(&pdev->dev, "unable to allocate buffer\n");
			error = -ENOMEM;
			break;
		}

		info->pseudo_palette = &ch->pseudo_palette;
		info->flags = FBINFO_FLAG_DEFAULT;

		error = fb_alloc_cmap(&info->cmap, PALETTE_NR, 0);
		if (error < 0) {
			dev_err(&pdev->dev, "unable to allocate cmap\n");
			dma_free_coherent(&pdev->dev, info->fix.smem_len,
					  buf, ch->dma_handle);
			break;
		}

		info->fix.smem_start = ch->dma_handle;
		if (var->nonstd)
			info->fix.line_length = var->xres;
		else
			info->fix.line_length = var->xres * (cfg->bpp / 8);

		info->screen_base = buf;
		info->device = &pdev->dev;
		ch->display_var = *var;
	}

	if (error)
		goto err1;

	error = sh_mobile_lcdc_start(priv);
	if (error) {
		dev_err(&pdev->dev, "unable to start hardware\n");
		goto err1;
	}

	for (i = 0; i < j; i++) {
		struct sh_mobile_lcdc_chan *ch = priv->ch + i;

		info = ch->info;

		if (info->fbdefio) {
			ch->sglist = vmalloc(sizeof(struct scatterlist) *
					info->fix.smem_len >> PAGE_SHIFT);
			if (!ch->sglist) {
				dev_err(&pdev->dev, "cannot allocate sglist\n");
				goto err1;
			}
		}

		info->bl_dev = ch->bl;

		error = register_framebuffer(info);
		if (error < 0)
			goto err1;

		dev_info(info->dev,
			 "registered %s/%s as %dx%d %dbpp.\n",
			 pdev->name,
			 (ch->cfg.chan == LCDC_CHAN_MAINLCD) ?
			 "mainlcd" : "sublcd",
			 info->var.xres, info->var.yres,
			 ch->cfg.bpp);

		/* deferred io mode: disable clock to save power */
		if (info->fbdefio || info->state == FBINFO_STATE_SUSPENDED)
			sh_mobile_lcdc_clk_off(priv);
	}
Пример #26
0
struct fb_info* einkfb_probe(struct platform_device *dev)
{
    einkfb_init_err_t err = einkfb_init_err_none;
    struct fb_var_screeninfo var;
    struct fb_fix_screeninfo fix;
    struct fb_info *info = NULL;

    boot_milestone_write(EINK_HAL_STARTED_BOM, EINK_HAL_STARTED_BOM_SZ);

    if ( !(info = framebuffer_alloc(sizeof(struct fb_info), &dev->dev)) )
        goto err1; // einkfb_init_err_framebuffer_alloc

    einkfb_fbinfo = info;
    info->fbops = &einkfb_ops;

    /*
     * Get the module's variable & fixed screeninfo.
     */
    if ( EINKFB_FAILURE == HAL_SW_INIT(&var, &fix) )
        goto err2; // einkfb_init_err_hw_sw_init

    /*
     * Allocate an address space for our real, virtual, and scratch buffers.
     */
    einkfb_blen = BPP_SIZE((var.xres * (var.yres + 1)), var.bits_per_pixel);
    einkfb_size = BPP_SIZE((var.xres * var.yres), var.bits_per_pixel);
    einkfb_mem  = FB_ROUNDUP(einkfb_blen, PAGE_SIZE) * 3;
    einkfb_dma  = HAL_NEEDS_DMA();

    if ( !(einkfb = EINKFB_MALLOC_HAL(einkfb_mem, einkfb_dma ? &einkfb_phys : NULL)) )
        goto err3; // einkfb_init_err_einkfb_malloc_hal

    /*
     * Clear memory to prevent kernel info from "leaking"
     * into userspace.
     */
    einkfb_memset(einkfb, einkfb_white(var.bits_per_pixel), einkfb_mem);

    fix.smem_start = einkfb_dma ? (unsigned long)einkfb_phys.addr : (unsigned long)einkfb;
    fix.smem_len = (einkfb_mem/3) << 1;	/* real & virtual */

    info->screen_base = (char __iomem *)einkfb;
    info->screen_size = einkfb_mem/3;	/* just real */

    info->var = var;
    info->fix = fix;
    info->pseudo_palette = NULL;		/* info->par */
    info->par = NULL;
    info->flags = FBINFO_FLAG_DEFAULT;

    if ( fb_alloc_cmap(&info->cmap, BPP_MAX(var.bits_per_pixel), 0) < 0 )
        goto err4; // einkfb_init_err_fb_alloc_cmap

    switch ( var.bits_per_pixel )
    {
    case EINKFB_1BPP:
        fb_copy_cmap(&einkfb_1bpp_cmap, &info->cmap);
        break;

    case EINKFB_2BPP:
        fb_copy_cmap(&einkfb_2bpp_cmap, &info->cmap);
        break;

    case EINKFB_4BPP:
        fb_copy_cmap(&einkfb_4bpp_cmap, &info->cmap);
        break;

    case EINKFB_8BPP:
        fb_copy_cmap(&einkfb_8bpp_cmap, &info->cmap);
        break;
    }

    einkfb_bpp   = info->var.bits_per_pixel;
    einkfb_xres  = info->var.xres;
    einkfb_yres  = info->var.yres;
    einkfb_vfb   = einkfb + info->screen_size;
    einkfb_buf   = einkfb_vfb + info->screen_size;

    einkfb_hw_bringup_mode_actual = HAL_HW_INIT(info, einkfb_hw_bringup_mode);
    einkfb_align_x = einkfb_set_byte_alignment_x(einkfb_bpp);
    einkfb_align_y = einkfb_set_byte_alignment_y(einkfb_bpp);

    if ( register_framebuffer(info) < 0 )
        goto err5; // einkfb_init_err_register_framebuffer

    BLANK_INIT();

    boot_milestone_write(EINK_HAL_LOADED_BOM, EINK_HAL_LOADED_BOM_SZ);

    return info;

err5:
    err++; // err = einkfb_init_err_register_framebuffer
err4:
    err++; // err = einkfb_init_err_fb_alloc_cmap
err3:
    err++; // err = einkfb_init_err_einkfb_malloc_hal
err2:
    err++; // err = einkfb_init_err_hw_sw_init
err1:
    err++; // err = einkfb_init_err_fb_info_alloc

    einkfb_remove(info, err);
    return NULL;
}
Пример #27
0
static int mmpfb_overlay_probe(struct platform_device *pdev)
{
	struct mmp_buffer_driver_mach_info *mi;
	struct fb_info *info = 0;
	struct mmpfb_info *fbi = 0;
	const char *path_name;
	int overlay_id = 0, ret;

	/* initialize fb */
	info = framebuffer_alloc(sizeof(struct mmpfb_info), &pdev->dev);
	if (info == NULL)
		return -ENOMEM;
	fbi = info->par;
	if (!fbi) {
		ret = -EINVAL;
		goto failed;
	}

	if (IS_ENABLED(CONFIG_OF)) {
		struct device_node *np = pdev->dev.of_node;

		if (!np)
			return -EINVAL;
		if (of_property_read_string(np, "marvell,fb-name", &fbi->name))
			return -EINVAL;
		if (of_property_read_string(np, "marvell,path-name",
					    &path_name))
			return -EINVAL;
		if (of_property_read_u32(np, "marvell,overlay-id",
					 &overlay_id))
			return -EINVAL;
	} else {
		mi = pdev->dev.platform_data;
		if (mi == NULL) {
			dev_err(&pdev->dev, "no platform data defined\n");
			return -EINVAL;
		}

		fbi->name = mi->name;
		path_name = mi->path_name;
		overlay_id = mi->overlay_id;
	}

	info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_DISABLED;
	info->node = -1;
	strcpy(info->fix.id, fbi->name);
	info->fix.accel = FB_ACCEL_NONE;
	info->fbops = &mmpfb_overlay_ops;
	/* init fb */
	fbi->fb_info = info;
	platform_set_drvdata(pdev, fbi);
	fbi->dev = &pdev->dev;
	mutex_init(&fbi->access_ok);
	mutex_init(&fbi->fence_mutex);

	/* get display path by name */
	fbi->path = mmp_get_path(path_name);
	if (!fbi->path) {
		dev_err(&pdev->dev, "can't get the path %s\n", path_name);
		ret = -EINVAL;
		goto failed_destroy_mutex;
	}

	dev_info(fbi->dev, "path %s get\n", fbi->path->name);

	/* get overlay */
	fbi->overlay = mmp_path_get_overlay(fbi->path, overlay_id);
	if (!fbi->overlay) {
		ret = -EINVAL;
		goto failed_destroy_mutex;
	}

	/* If path has master path, need initialize this path*/
	if (fbi->path->slave && fbi->path->master &&
		(!strcmp(fbi->path->slave->name, fbi->path->name)))
		mmpfb_overlay_path_init(fbi);

	ret = register_framebuffer(info);
	if (ret < 0) {
		dev_err(&pdev->dev, "Failed to register fb: %d\n", ret);
		ret = -ENXIO;
		goto failed_destroy_mutex;
	}

	mmpfb_overlay_vsync_notify_init(fbi);

	/* Disable Graphic layer after boot up, becaues uboot use graphic for logo */
	if (fbi->overlay->id == PN_GRA)
		mmp_overlay_set_status(fbi->overlay, MMP_OFF_DMA);

	dev_info(fbi->dev, "loaded to /dev/fb%d <%s>.\n",
		info->node, info->fix.id);

	return 0;

failed_destroy_mutex:
	mutex_destroy(&fbi->access_ok);
	mutex_destroy(&fbi->fence_mutex);
failed:
	if (fbi)
		dev_err(fbi->dev, "mmp-fb: frame buffer device init failed\n");
	platform_set_drvdata(pdev, NULL);

	framebuffer_release(info);

	return ret;
}
Пример #28
0
static int
nouveau_fbcon_create(struct nouveau_fbdev *nfbdev,
		     struct drm_fb_helper_surface_size *sizes)
{
	struct drm_device *dev = nfbdev->dev;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct fb_info *info;
	struct drm_framebuffer *fb;
	struct nouveau_framebuffer *nouveau_fb;
	struct nouveau_channel *chan;
	struct nouveau_bo *nvbo;
	struct drm_mode_fb_cmd mode_cmd;
	struct pci_dev *pdev = dev->pdev;
	struct device *device = &pdev->dev;
	int size, ret;

	mode_cmd.width = sizes->surface_width;
	mode_cmd.height = sizes->surface_height;

	mode_cmd.bpp = sizes->surface_bpp;
	mode_cmd.pitch = mode_cmd.width * (mode_cmd.bpp >> 3);
	mode_cmd.pitch = roundup(mode_cmd.pitch, 256);
	mode_cmd.depth = sizes->surface_depth;

	size = mode_cmd.pitch * mode_cmd.height;
	size = roundup(size, PAGE_SIZE);

	ret = nouveau_gem_new(dev, size, 0, NOUVEAU_GEM_DOMAIN_VRAM,
			      0, 0x0000, &nvbo);
	if (ret) {
		NV_ERROR(dev, "failed to allocate framebuffer\n");
		goto out;
	}

	ret = nouveau_bo_pin(nvbo, TTM_PL_FLAG_VRAM);
	if (ret) {
		NV_ERROR(dev, "failed to pin fb: %d\n", ret);
		nouveau_bo_ref(NULL, &nvbo);
		goto out;
	}

	ret = nouveau_bo_map(nvbo);
	if (ret) {
		NV_ERROR(dev, "failed to map fb: %d\n", ret);
		nouveau_bo_unpin(nvbo);
		nouveau_bo_ref(NULL, &nvbo);
		goto out;
	}

	chan = nouveau_nofbaccel ? NULL : dev_priv->channel;
	if (chan && dev_priv->card_type >= NV_50) {
		ret = nouveau_bo_vma_add(nvbo, chan->vm, &nfbdev->nouveau_fb.vma);
		if (ret) {
			NV_ERROR(dev, "failed to map fb into chan: %d\n", ret);
			chan = NULL;
		}
	}

	mutex_lock(&dev->struct_mutex);

	info = framebuffer_alloc(0, device);
	if (!info) {
		ret = -ENOMEM;
		goto out_unref;
	}

	ret = fb_alloc_cmap(&info->cmap, 256, 0);
	if (ret) {
		ret = -ENOMEM;
		goto out_unref;
	}

	info->par = nfbdev;

	nouveau_framebuffer_init(dev, &nfbdev->nouveau_fb, &mode_cmd, nvbo);

	nouveau_fb = &nfbdev->nouveau_fb;
	fb = &nouveau_fb->base;

	/* setup helper */
	nfbdev->helper.fb = fb;
	nfbdev->helper.fbdev = info;

	strcpy(info->fix.id, "nouveaufb");
	if (nouveau_nofbaccel)
		info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_DISABLED;
	else
		info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA |
			      FBINFO_HWACCEL_FILLRECT |
			      FBINFO_HWACCEL_IMAGEBLIT;
	info->flags |= FBINFO_CAN_FORCE_OUTPUT;
	info->fbops = &nouveau_fbcon_sw_ops;
	info->fix.smem_start = nvbo->bo.mem.bus.base +
			       nvbo->bo.mem.bus.offset;
	info->fix.smem_len = size;

	info->screen_base = nvbo_kmap_obj_iovirtual(nouveau_fb->nvbo);
	info->screen_size = size;

	drm_fb_helper_fill_fix(info, fb->pitch, fb->depth);
	drm_fb_helper_fill_var(info, &nfbdev->helper, sizes->fb_width, sizes->fb_height);

	/* Set aperture base/size for vesafb takeover */
	info->apertures = dev_priv->apertures;
	if (!info->apertures) {
		ret = -ENOMEM;
		goto out_unref;
	}

	info->pixmap.size = 64*1024;
	info->pixmap.buf_align = 8;
	info->pixmap.access_align = 32;
	info->pixmap.flags = FB_PIXMAP_SYSTEM;
	info->pixmap.scan_align = 1;

	mutex_unlock(&dev->struct_mutex);

	if (dev_priv->channel && !nouveau_nofbaccel) {
		ret = -ENODEV;
		if (dev_priv->card_type < NV_50)
			ret = nv04_fbcon_accel_init(info);
		else
		if (dev_priv->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;
	}

	nouveau_fbcon_zfill(dev, nfbdev);

	/* To allow resizeing without swapping buffers */
	NV_INFO(dev, "allocated %dx%d fb: 0x%lx, bo %p\n",
						nouveau_fb->base.width,
						nouveau_fb->base.height,
						nvbo->bo.offset, nvbo);

	vga_switcheroo_client_fb_set(dev->pdev, info);
	return 0;

out_unref:
	mutex_unlock(&dev->struct_mutex);
out:
	return ret;
}
Пример #29
0
static int hecubafb_probe(struct platform_device *dev)
{
	struct fb_info *info;
	struct hecuba_board *board;
	int retval = -ENOMEM;
	int videomemorysize;
	unsigned char *videomemory;
	struct hecubafb_par *par;

	/* pick up board specific routines */
	board = dev->dev.platform_data;
	if (!board)
		return -EINVAL;

	/* try to count device specific driver, if can't, platform recalls */
	if (!try_module_get(board->owner))
		return -ENODEV;

	videomemorysize = (DPY_W*DPY_H)/8;

	videomemory = vzalloc(videomemorysize);
	if (!videomemory)
		goto err_videomem_alloc;

	info = framebuffer_alloc(sizeof(struct hecubafb_par), &dev->dev);
	if (!info)
		goto err_fballoc;

	info->screen_base = (char __force __iomem *)videomemory;
	info->fbops = &hecubafb_ops;

	info->var = hecubafb_var;
	info->fix = hecubafb_fix;
	info->fix.smem_len = videomemorysize;
	par = info->par;
	par->info = info;
	par->board = board;
	par->send_command = apollo_send_command;
	par->send_data = apollo_send_data;

	info->flags = FBINFO_FLAG_DEFAULT | FBINFO_VIRTFB;

	info->fbdefio = &hecubafb_defio;
	fb_deferred_io_init(info);

	retval = register_framebuffer(info);
	if (retval < 0)
		goto err_fbreg;
	platform_set_drvdata(dev, info);

	printk(KERN_INFO
	       "fb%d: Hecuba frame buffer device, using %dK of video memory\n",
	       info->node, videomemorysize >> 10);

	/* this inits the dpy */
	retval = par->board->init(par);
	if (retval < 0)
		goto err_fbreg;

	return 0;
err_fbreg:
	framebuffer_release(info);
err_fballoc:
	vfree(videomemory);
err_videomem_alloc:
	module_put(board->owner);
	return retval;
}
Пример #30
0
Файл: bw2.c Проект: 3null/linux
static int bw2_probe(struct platform_device *op)
{
	struct device_node *dp = op->dev.of_node;
	struct fb_info *info;
	struct bw2_par *par;
	int linebytes, err;

	info = framebuffer_alloc(sizeof(struct bw2_par), &op->dev);

	err = -ENOMEM;
	if (!info)
		goto out_err;
	par = info->par;

	spin_lock_init(&par->lock);

	info->fix.smem_start = op->resource[0].start;
	par->which_io = op->resource[0].flags & IORESOURCE_BITS;

	sbusfb_fill_var(&info->var, dp, 1);
	linebytes = of_getintprop_default(dp, "linebytes",
					  info->var.xres);

	info->var.red.length = info->var.green.length =
		info->var.blue.length = info->var.bits_per_pixel;
	info->var.red.offset = info->var.green.offset =
		info->var.blue.offset = 0;

	par->regs = of_ioremap(&op->resource[0], BWTWO_REGISTER_OFFSET,
			       sizeof(struct bw2_regs), "bw2 regs");
	if (!par->regs)
		goto out_release_fb;

	if (!of_find_property(dp, "width", NULL)) {
		err = bw2_do_default_mode(par, info, &linebytes);
		if (err)
			goto out_unmap_regs;
	}

	info->fix.smem_len = PAGE_ALIGN(linebytes * info->var.yres);

	info->flags = FBINFO_DEFAULT;
	info->fbops = &bw2_ops;

	info->screen_base = of_ioremap(&op->resource[0], 0,
				       info->fix.smem_len, "bw2 ram");
	if (!info->screen_base) {
		err = -ENOMEM;
		goto out_unmap_regs;
	}

	bw2_blank(FB_BLANK_UNBLANK, info);

	bw2_init_fix(info, linebytes);

	err = register_framebuffer(info);
	if (err < 0)
		goto out_unmap_screen;

	dev_set_drvdata(&op->dev, info);

	printk(KERN_INFO "%s: bwtwo at %lx:%lx\n",
	       dp->full_name, par->which_io, info->fix.smem_start);

	return 0;

out_unmap_screen:
	of_iounmap(&op->resource[0], info->screen_base, info->fix.smem_len);

out_unmap_regs:
	of_iounmap(&op->resource[0], par->regs, sizeof(struct bw2_regs));

out_release_fb:
	framebuffer_release(info);

out_err:
	return err;
}