diff options
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/Kconfig | 19 | ||||
-rw-r--r-- | drivers/video/Makefile | 1 | ||||
-rw-r--r-- | drivers/video/asiliantfb.c | 1 | ||||
-rw-r--r-- | drivers/video/console/Kconfig | 3 | ||||
-rw-r--r-- | drivers/video/console/fbcon.c | 5 | ||||
-rw-r--r-- | drivers/video/fbmem.c | 3 | ||||
-rw-r--r-- | drivers/video/i810/i810_main.c | 4 | ||||
-rw-r--r-- | drivers/video/logo/logo.c | 4 | ||||
-rw-r--r-- | drivers/video/mmp/core.c | 9 | ||||
-rw-r--r-- | drivers/video/mx3fb.c | 2 | ||||
-rw-r--r-- | drivers/video/mxsfb.c | 126 | ||||
-rw-r--r-- | drivers/video/nvidia/nvidia.c | 1 | ||||
-rw-r--r-- | drivers/video/ocfb.c | 440 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dpi.c | 15 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss.c | 163 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss.h | 17 | ||||
-rw-r--r-- | drivers/video/omap2/dss/sdi.c | 21 | ||||
-rw-r--r-- | drivers/video/riva/fbdev.c | 1 | ||||
-rw-r--r-- | drivers/video/sh_mobile_lcdcfb.c | 2 | ||||
-rw-r--r-- | drivers/video/tgafb.c | 21 | ||||
-rw-r--r-- | drivers/video/vermilion/vermilion.c | 1 |
21 files changed, 609 insertions, 250 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 4f2e1b35eb38..22262a3a0e2d 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -312,7 +312,8 @@ config FB_PM2_FIFO_DISCONNECT config FB_ARMCLCD tristate "ARM PrimeCell PL110 support" - depends on FB && ARM && ARM_AMBA + depends on ARM || ARM64 || COMPILE_TEST + depends on FB && ARM_AMBA select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT @@ -979,6 +980,22 @@ config FB_PVR2 (<file:drivers/video/pvr2fb.c>). Please see the file <file:Documentation/fb/pvr2fb.txt>. +config FB_OPENCORES + tristate "OpenCores VGA/LCD core 2.0 framebuffer support" + depends on FB + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This enables support for the OpenCores VGA/LCD core. + + The OpenCores VGA/LCD core is typically used together with + softcore CPUs (e.g. OpenRISC or Microblaze) or hard processor + systems (e.g. Altera socfpga or Xilinx Zynq) on FPGAs. + + The source code and specification for the core is available at + <http://opencores.org/project,vga_lcd> + config FB_S1D13XXX tristate "Epson S1D13XXX framebuffer support" depends on FB diff --git a/drivers/video/Makefile b/drivers/video/Makefile index e8bae8dd4804..ae17ddf49a00 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -150,6 +150,7 @@ obj-$(CONFIG_FB_NUC900) += nuc900fb.o obj-$(CONFIG_FB_JZ4740) += jz4740_fb.o obj-$(CONFIG_FB_PUV3_UNIGFX) += fb-puv3.o obj-$(CONFIG_FB_HYPERV) += hyperv_fb.o +obj-$(CONFIG_FB_OPENCORES) += ocfb.o # Platform or fallback drivers go here obj-$(CONFIG_FB_UVESA) += uvesafb.o diff --git a/drivers/video/asiliantfb.c b/drivers/video/asiliantfb.c index d611f1a1ac53..7e8ddf00ccc2 100644 --- a/drivers/video/asiliantfb.c +++ b/drivers/video/asiliantfb.c @@ -589,7 +589,6 @@ static void asiliantfb_remove(struct pci_dev *dp) fb_dealloc_cmap(&p->cmap); iounmap(p->screen_base); release_mem_region(pci_resource_start(dp, 0), pci_resource_len(dp, 0)); - pci_set_drvdata(dp, NULL); framebuffer_release(p); } diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index 846caab75a46..fe1cd0148e13 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -8,7 +8,8 @@ config VGA_CONSOLE bool "VGA text console" if EXPERT || !X86 depends on !4xx && !8xx && !SPARC && !M68K && !PARISC && !FRV && \ !SUPERH && !BLACKFIN && !AVR32 && !MN10300 && !CRIS && \ - (!ARM || ARCH_FOOTBRIDGE || ARCH_INTEGRATOR || ARCH_NETWINDER) + (!ARM || ARCH_FOOTBRIDGE || ARCH_INTEGRATOR || ARCH_NETWINDER) && \ + !ARM64 default y help Saying Y here will allow you to use Linux in text mode through a diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index cd8a8027f8ae..4e39291ac8b4 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -3547,8 +3547,10 @@ static void fbcon_exit(void) "no")); for (j = first_fb_vc; j <= last_fb_vc; j++) { - if (con2fb_map[j] == i) + if (con2fb_map[j] == i) { mapped = 1; + break; + } } if (mapped) { @@ -3561,6 +3563,7 @@ static void fbcon_exit(void) fbcon_del_cursor_timer(info); kfree(ops->cursor_src); + kfree(ops->cursor_state.mask); kfree(info->fbcon_par); info->fbcon_par = NULL; } diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 010d19105ebc..cde461932760 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -1930,6 +1930,9 @@ int fb_get_options(const char *name, char **option) options = opt + name_len + 1; } } + /* No match, pass global option */ + if (!options && option && fb_mode_option) + options = kstrdup(fb_mode_option, GFP_KERNEL); if (options && !strncmp(options, "off", 3)) retval = 1; diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c index 038192ac7369..bb674e431741 100644 --- a/drivers/video/i810/i810_main.c +++ b/drivers/video/i810/i810_main.c @@ -2011,9 +2011,7 @@ static int i810fb_init_pci(struct pci_dev *dev, struct fb_info *info; struct i810fb_par *par = NULL; struct fb_videomode mode; - int i, err = -1, vfreq, hfreq, pixclock; - - i = 0; + int err = -1, vfreq, hfreq, pixclock; info = framebuffer_alloc(sizeof(struct i810fb_par), &dev->dev); if (!info) diff --git a/drivers/video/logo/logo.c b/drivers/video/logo/logo.c index 080c35b34bbb..b670cbda38e3 100644 --- a/drivers/video/logo/logo.c +++ b/drivers/video/logo/logo.c @@ -17,10 +17,6 @@ #include <asm/setup.h> #endif -#ifdef CONFIG_MIPS -#include <asm/bootinfo.h> -#endif - static bool nologo; module_param(nologo, bool, 0); MODULE_PARM_DESC(nologo, "Disables startup logo"); diff --git a/drivers/video/mmp/core.c b/drivers/video/mmp/core.c index 84de2632857a..b563b920f159 100644 --- a/drivers/video/mmp/core.c +++ b/drivers/video/mmp/core.c @@ -30,7 +30,7 @@ static struct mmp_overlay *path_get_overlay(struct mmp_path *path, { if (path && overlay_id < path->overlay_num) return &path->overlays[overlay_id]; - return 0; + return NULL; } static int path_check_status(struct mmp_path *path) @@ -173,7 +173,7 @@ struct mmp_path *mmp_register_path(struct mmp_path_info *info) + sizeof(struct mmp_overlay) * info->overlay_num; path = kzalloc(size, GFP_KERNEL); if (!path) - goto failed; + return NULL; /* path set */ mutex_init(&path->access_ok); @@ -219,11 +219,6 @@ struct mmp_path *mmp_register_path(struct mmp_path_info *info) mutex_unlock(&disp_lock); return path; - -failed: - kfree(path); - mutex_unlock(&disp_lock); - return NULL; } EXPORT_SYMBOL_GPL(mmp_register_path); diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c index 804f874d32d3..142e860fb527 100644 --- a/drivers/video/mx3fb.c +++ b/drivers/video/mx3fb.c @@ -1263,7 +1263,7 @@ static int mx3fb_map_video_memory(struct fb_info *fbi, unsigned int mem_len, fbi->screen_base = dma_alloc_writecombine(fbi->device, mem_len, - &addr, GFP_DMA); + &addr, GFP_DMA | GFP_KERNEL); if (!fbi->screen_base) { dev_err(fbi->device, "Cannot allocate %u bytes framebuffer memory\n", diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c index 27197a8048c0..accf48a2cce4 100644 --- a/drivers/video/mxsfb.c +++ b/drivers/video/mxsfb.c @@ -49,6 +49,7 @@ #include <linux/fb.h> #include <linux/regulator/consumer.h> #include <video/of_display_timing.h> +#include <video/of_videomode.h> #include <video/videomode.h> #define REG_SET 4 @@ -297,7 +298,7 @@ static int mxsfb_check_var(struct fb_var_screeninfo *var, } break; default: - pr_debug("Unsupported colour depth: %u\n", var->bits_per_pixel); + pr_err("Unsupported colour depth: %u\n", var->bits_per_pixel); return -EINVAL; } @@ -426,7 +427,7 @@ static int mxsfb_set_par(struct fb_info *fb_info) ctrl |= CTRL_SET_WORD_LENGTH(3); switch (host->ld_intf_width) { case STMLCDIF_8BIT: - dev_dbg(&host->pdev->dev, + dev_err(&host->pdev->dev, "Unsupported LCD bus width mapping\n"); return -EINVAL; case STMLCDIF_16BIT: @@ -439,7 +440,7 @@ static int mxsfb_set_par(struct fb_info *fb_info) writel(CTRL1_SET_BYTE_PACKAGING(0x7), host->base + LCDC_CTRL1); break; default: - dev_dbg(&host->pdev->dev, "Unhandled color depth of %u\n", + dev_err(&host->pdev->dev, "Unhandled color depth of %u\n", fb_info->var.bits_per_pixel); return -EINVAL; } @@ -589,7 +590,8 @@ static struct fb_ops mxsfb_ops = { .fb_imageblit = cfb_imageblit, }; -static int mxsfb_restore_mode(struct mxsfb_info *host) +static int mxsfb_restore_mode(struct mxsfb_info *host, + struct fb_videomode *vmode) { struct fb_info *fb_info = &host->fb_info; unsigned line_count; @@ -597,7 +599,6 @@ static int mxsfb_restore_mode(struct mxsfb_info *host) unsigned long pa, fbsize; int bits_per_pixel, ofs; u32 transfer_count, vdctrl0, vdctrl2, vdctrl3, vdctrl4, ctrl; - struct fb_videomode vmode; /* Only restore the mode when the controller is running */ ctrl = readl(host->base + LCDC_CTRL); @@ -611,8 +612,8 @@ static int mxsfb_restore_mode(struct mxsfb_info *host) transfer_count = readl(host->base + host->devdata->transfer_count); - vmode.xres = TRANSFER_COUNT_GET_HCOUNT(transfer_count); - vmode.yres = TRANSFER_COUNT_GET_VCOUNT(transfer_count); + vmode->xres = TRANSFER_COUNT_GET_HCOUNT(transfer_count); + vmode->yres = TRANSFER_COUNT_GET_VCOUNT(transfer_count); switch (CTRL_GET_WORD_LENGTH(ctrl)) { case 0: @@ -628,40 +629,39 @@ static int mxsfb_restore_mode(struct mxsfb_info *host) fb_info->var.bits_per_pixel = bits_per_pixel; - vmode.pixclock = KHZ2PICOS(clk_get_rate(host->clk) / 1000U); - vmode.hsync_len = get_hsync_pulse_width(host, vdctrl2); - vmode.left_margin = GET_HOR_WAIT_CNT(vdctrl3) - vmode.hsync_len; - vmode.right_margin = VDCTRL2_GET_HSYNC_PERIOD(vdctrl2) - vmode.hsync_len - - vmode.left_margin - vmode.xres; - vmode.vsync_len = VDCTRL0_GET_VSYNC_PULSE_WIDTH(vdctrl0); + vmode->pixclock = KHZ2PICOS(clk_get_rate(host->clk) / 1000U); + vmode->hsync_len = get_hsync_pulse_width(host, vdctrl2); + vmode->left_margin = GET_HOR_WAIT_CNT(vdctrl3) - vmode->hsync_len; + vmode->right_margin = VDCTRL2_GET_HSYNC_PERIOD(vdctrl2) - + vmode->hsync_len - vmode->left_margin - vmode->xres; + vmode->vsync_len = VDCTRL0_GET_VSYNC_PULSE_WIDTH(vdctrl0); period = readl(host->base + LCDC_VDCTRL1); - vmode.upper_margin = GET_VERT_WAIT_CNT(vdctrl3) - vmode.vsync_len; - vmode.lower_margin = period - vmode.vsync_len - vmode.upper_margin - vmode.yres; + vmode->upper_margin = GET_VERT_WAIT_CNT(vdctrl3) - vmode->vsync_len; + vmode->lower_margin = period - vmode->vsync_len - + vmode->upper_margin - vmode->yres; - vmode.vmode = FB_VMODE_NONINTERLACED; + vmode->vmode = FB_VMODE_NONINTERLACED; - vmode.sync = 0; + vmode->sync = 0; if (vdctrl0 & VDCTRL0_HSYNC_ACT_HIGH) - vmode.sync |= FB_SYNC_HOR_HIGH_ACT; + vmode->sync |= FB_SYNC_HOR_HIGH_ACT; if (vdctrl0 & VDCTRL0_VSYNC_ACT_HIGH) - vmode.sync |= FB_SYNC_VERT_HIGH_ACT; + vmode->sync |= FB_SYNC_VERT_HIGH_ACT; pr_debug("Reconstructed video mode:\n"); pr_debug("%dx%d, hsync: %u left: %u, right: %u, vsync: %u, upper: %u, lower: %u\n", - vmode.xres, vmode.yres, - vmode.hsync_len, vmode.left_margin, vmode.right_margin, - vmode.vsync_len, vmode.upper_margin, vmode.lower_margin); - pr_debug("pixclk: %ldkHz\n", PICOS2KHZ(vmode.pixclock)); - - fb_add_videomode(&vmode, &fb_info->modelist); + vmode->xres, vmode->yres, vmode->hsync_len, vmode->left_margin, + vmode->right_margin, vmode->vsync_len, vmode->upper_margin, + vmode->lower_margin); + pr_debug("pixclk: %ldkHz\n", PICOS2KHZ(vmode->pixclock)); host->ld_intf_width = CTRL_GET_BUS_WIDTH(ctrl); host->dotclk_delay = VDCTRL4_GET_DOTCLK_DLY(vdctrl4); - fb_info->fix.line_length = vmode.xres * (bits_per_pixel >> 3); + fb_info->fix.line_length = vmode->xres * (bits_per_pixel >> 3); pa = readl(host->base + host->devdata->cur_buf); - fbsize = fb_info->fix.line_length * vmode.yres; + fbsize = fb_info->fix.line_length * vmode->yres; if (pa < fb_info->fix.smem_start) return -EINVAL; if (pa + fbsize > fb_info->fix.smem_start + fb_info->fix.smem_len) @@ -681,18 +681,17 @@ static int mxsfb_restore_mode(struct mxsfb_info *host) return 0; } -static int mxsfb_init_fbinfo_dt(struct mxsfb_info *host) +static int mxsfb_init_fbinfo_dt(struct mxsfb_info *host, + struct fb_videomode *vmode) { struct fb_info *fb_info = &host->fb_info; struct fb_var_screeninfo *var = &fb_info->var; struct device *dev = &host->pdev->dev; struct device_node *np = host->pdev->dev.of_node; struct device_node *display_np; - struct device_node *timings_np; - struct display_timings *timings; + struct videomode vm; u32 width; - int i; - int ret = 0; + int ret; display_np = of_parse_phandle(np, "display", 0); if (!display_np) { @@ -732,54 +731,35 @@ static int mxsfb_init_fbinfo_dt(struct mxsfb_info *host) goto put_display_node; } - timings = of_get_display_timings(display_np); - if (!timings) { - dev_err(dev, "failed to get display timings\n"); - ret = -ENOENT; + ret = of_get_videomode(display_np, &vm, OF_USE_NATIVE_MODE); + if (ret) { + dev_err(dev, "failed to get videomode from DT\n"); goto put_display_node; } - timings_np = of_find_node_by_name(display_np, - "display-timings"); - if (!timings_np) { - dev_err(dev, "failed to find display-timings node\n"); - ret = -ENOENT; + ret = fb_videomode_from_videomode(&vm, vmode); + if (ret < 0) goto put_display_node; - } - for (i = 0; i < of_get_child_count(timings_np); i++) { - struct videomode vm; - struct fb_videomode fb_vm; - - ret = videomode_from_timings(timings, &vm, i); - if (ret < 0) - goto put_timings_node; - ret = fb_videomode_from_videomode(&vm, &fb_vm); - if (ret < 0) - goto put_timings_node; - - if (vm.flags & DISPLAY_FLAGS_DE_HIGH) - host->sync |= MXSFB_SYNC_DATA_ENABLE_HIGH_ACT; - if (vm.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE) - host->sync |= MXSFB_SYNC_DOTCLK_FALLING_ACT; - fb_add_videomode(&fb_vm, &fb_info->modelist); - } + if (vm.flags & DISPLAY_FLAGS_DE_HIGH) + host->sync |= MXSFB_SYNC_DATA_ENABLE_HIGH_ACT; + if (vm.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE) + host->sync |= MXSFB_SYNC_DOTCLK_FALLING_ACT; -put_timings_node: - of_node_put(timings_np); put_display_node: of_node_put(display_np); return ret; } -static int mxsfb_init_fbinfo(struct mxsfb_info *host) +static int mxsfb_init_fbinfo(struct mxsfb_info *host, + struct fb_videomode *vmode) { + int ret; struct fb_info *fb_info = &host->fb_info; struct fb_var_screeninfo *var = &fb_info->var; dma_addr_t fb_phys; void *fb_virt; unsigned fb_size; - int ret; fb_info->fbops = &mxsfb_ops; fb_info->flags = FBINFO_FLAG_DEFAULT | FBINFO_READS_FAST; @@ -789,7 +769,7 @@ static int mxsfb_init_fbinfo(struct mxsfb_info *host) fb_info->fix.visual = FB_VISUAL_TRUECOLOR, fb_info->fix.accel = FB_ACCEL_NONE; - ret = mxsfb_init_fbinfo_dt(host); + ret = mxsfb_init_fbinfo_dt(host, vmode); if (ret) return ret; @@ -810,7 +790,7 @@ static int mxsfb_init_fbinfo(struct mxsfb_info *host) fb_info->screen_base = fb_virt; fb_info->screen_size = fb_info->fix.smem_len = fb_size; - if (mxsfb_restore_mode(host)) + if (mxsfb_restore_mode(host, vmode)) memset(fb_virt, 0, fb_size); return 0; @@ -850,7 +830,7 @@ static int mxsfb_probe(struct platform_device *pdev) struct resource *res; struct mxsfb_info *host; struct fb_info *fb_info; - struct fb_modelist *modelist; + struct fb_videomode *mode; int ret; if (of_id) @@ -862,6 +842,11 @@ static int mxsfb_probe(struct platform_device *pdev) return -ENOMEM; } + mode = devm_kzalloc(&pdev->dev, sizeof(struct fb_videomode), + GFP_KERNEL); + if (mode == NULL) + return -ENOMEM; + host = to_imxfb_host(fb_info); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -893,15 +878,11 @@ static int mxsfb_probe(struct platform_device *pdev) goto fb_release; } - INIT_LIST_HEAD(&fb_info->modelist); - - ret = mxsfb_init_fbinfo(host); + ret = mxsfb_init_fbinfo(host, mode); if (ret != 0) goto fb_release; - modelist = list_first_entry(&fb_info->modelist, - struct fb_modelist, list); - fb_videomode_to_var(&fb_info->var, &modelist->mode); + fb_videomode_to_var(&fb_info->var, mode); /* init the color fields */ mxsfb_check_var(&fb_info->var, fb_info); @@ -927,7 +908,6 @@ static int mxsfb_probe(struct platform_device *pdev) fb_destroy: if (host->enabled) clk_disable_unprepare(host->clk); - fb_destroy_modelist(&fb_info->modelist); fb_release: framebuffer_release(fb_info); diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c index ff228713425e..def041204676 100644 --- a/drivers/video/nvidia/nvidia.c +++ b/drivers/video/nvidia/nvidia.c @@ -1461,7 +1461,6 @@ static void nvidiafb_remove(struct pci_dev *pd) pci_release_regions(pd); kfree(info->pixmap.addr); framebuffer_release(info); - pci_set_drvdata(pd, NULL); NVTRACE_LEAVE(); } diff --git a/drivers/video/ocfb.c b/drivers/video/ocfb.c new file mode 100644 index 000000000000..7f9dc9bec309 --- /dev/null +++ b/drivers/video/ocfb.c @@ -0,0 +1,440 @@ +/* + * OpenCores VGA/LCD 2.0 core frame buffer driver + * + * Copyright (C) 2013 Stefan Kristiansson, stefan.kristiansson@saunalahti.fi + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#include <linux/delay.h> +#include <linux/dma-mapping.h> +#include <linux/errno.h> +#include <linux/fb.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/string.h> +#include <linux/slab.h> + +/* OCFB register defines */ +#define OCFB_CTRL 0x000 +#define OCFB_STAT 0x004 +#define OCFB_HTIM 0x008 +#define OCFB_VTIM 0x00c +#define OCFB_HVLEN 0x010 +#define OCFB_VBARA 0x014 +#define OCFB_PALETTE 0x800 + +#define OCFB_CTRL_VEN 0x00000001 /* Video Enable */ +#define OCFB_CTRL_HIE 0x00000002 /* HSync Interrupt Enable */ +#define OCFB_CTRL_PC 0x00000800 /* 8-bit Pseudo Color Enable*/ +#define OCFB_CTRL_CD8 0x00000000 /* Color Depth 8 */ +#define OCFB_CTRL_CD16 0x00000200 /* Color Depth 16 */ +#define OCFB_CTRL_CD24 0x00000400 /* Color Depth 24 */ +#define OCFB_CTRL_CD32 0x00000600 /* Color Depth 32 */ +#define OCFB_CTRL_VBL1 0x00000000 /* Burst Length 1 */ +#define OCFB_CTRL_VBL2 0x00000080 /* Burst Length 2 */ +#define OCFB_CTRL_VBL4 0x00000100 /* Burst Length 4 */ +#define OCFB_CTRL_VBL8 0x00000180 /* Burst Length 8 */ + +#define PALETTE_SIZE 256 + +#define OCFB_NAME "OC VGA/LCD" + +static char *mode_option; + +static const struct fb_videomode default_mode = { + /* 640x480 @ 60 Hz, 31.5 kHz hsync */ + NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2, + 0, FB_VMODE_NONINTERLACED +}; + +struct ocfb_dev { + struct fb_info info; + void __iomem *regs; + /* flag indicating whether the regs are little endian accessed */ + int little_endian; + /* Physical and virtual addresses of framebuffer */ + phys_addr_t fb_phys; + void __iomem *fb_virt; + u32 pseudo_palette[PALETTE_SIZE]; +}; + +#ifndef MODULE +static int __init ocfb_setup(char *options) +{ + char *curr_opt; + + if (!options || !*options) + return 0; + + while ((curr_opt = strsep(&options, ",")) != NULL) { + if (!*curr_opt) + continue; + mode_option = curr_opt; + } + + return 0; +} +#endif + +static inline u32 ocfb_readreg(struct ocfb_dev *fbdev, loff_t offset) +{ + if (fbdev->little_endian) + return ioread32(fbdev->regs + offset); + else + return ioread32be(fbdev->regs + offset); +} + +static void ocfb_writereg(struct ocfb_dev *fbdev, loff_t offset, u32 data) +{ + if (fbdev->little_endian) + iowrite32(data, fbdev->regs + offset); + else + iowrite32be(data, fbdev->regs + offset); +} + +static int ocfb_setupfb(struct ocfb_dev *fbdev) +{ + unsigned long bpp_config; + struct fb_var_screeninfo *var = &fbdev->info.var; + struct device *dev = fbdev->info.device; + u32 hlen; + u32 vlen; + + /* Disable display */ + ocfb_writereg(fbdev, OCFB_CTRL, 0); + + /* Register framebuffer address */ + fbdev->little_endian = 0; + ocfb_writereg(fbdev, OCFB_VBARA, fbdev->fb_phys); + + /* Detect endianess */ + if (ocfb_readreg(fbdev, OCFB_VBARA) != fbdev->fb_phys) { + fbdev->little_endian = 1; + ocfb_writereg(fbdev, OCFB_VBARA, fbdev->fb_phys); + } + + /* Horizontal timings */ + ocfb_writereg(fbdev, OCFB_HTIM, (var->hsync_len - 1) << 24 | + (var->right_margin - 1) << 16 | (var->xres - 1)); + + /* Vertical timings */ + ocfb_writereg(fbdev, OCFB_VTIM, (var->vsync_len - 1) << 24 | + (var->lower_margin - 1) << 16 | (var->yres - 1)); + + /* Total length of frame */ + hlen = var->left_margin + var->right_margin + var->hsync_len + + var->xres; + + vlen = var->upper_margin + var->lower_margin + var->vsync_len + + var->yres; + + ocfb_writereg(fbdev, OCFB_HVLEN, (hlen - 1) << 16 | (vlen - 1)); + + bpp_config = OCFB_CTRL_CD8; + switch (var->bits_per_pixel) { + case 8: + if (!var->grayscale) + bpp_config |= OCFB_CTRL_PC; /* enable palette */ + break; + + case 16: + bpp_config |= OCFB_CTRL_CD16; + break; + + case 24: + bpp_config |= OCFB_CTRL_CD24; + break; + + case 32: + bpp_config |= OCFB_CTRL_CD32; + break; + + default: + dev_err(dev, "no bpp specified\n"); + break; + } + + /* maximum (8) VBL (video memory burst length) */ + bpp_config |= OCFB_CTRL_VBL8; + + /* Enable output */ + ocfb_writereg(fbdev, OCFB_CTRL, (OCFB_CTRL_VEN | bpp_config)); + + return 0; +} + +static int ocfb_setcolreg(unsigned regno, unsigned red, unsigned green, + unsigned blue, unsigned transp, + struct fb_info *info) +{ + struct ocfb_dev *fbdev = (struct ocfb_dev *)info->par; + u32 color; + + if (regno >= info->cmap.len) { + dev_err(info->device, "regno >= cmap.len\n"); + return 1; + } + + if (info->var.grayscale) { + /* grayscale = 0.30*R + 0.59*G + 0.11*B */ + red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8; + } + + red >>= (16 - info->var.red.length); + green >>= (16 - info->var.green.length); + blue >>= (16 - info->var.blue.length); + transp >>= (16 - info->var.transp.length); + + if (info->var.bits_per_pixel == 8 && !info->var.grayscale) { + regno <<= 2; + color = (red << 16) | (green << 8) | blue; + ocfb_writereg(fbdev, OCFB_PALETTE + regno, color); + } else { + ((u32 *)(info->pseudo_palette))[regno] = + (red << info->var.red.offset) | + (green << info->var.green.offset) | + (blue << info->var.blue.offset) | + (transp << info->var.transp.offset); + } + + return 0; +} + +static int ocfb_init_fix(struct ocfb_dev *fbdev) +{ + struct fb_var_screeninfo *var = &fbdev->info.var; + struct fb_fix_screeninfo *fix = &fbdev->info.fix; + + strcpy(fix->id, OCFB_NAME); + + fix->line_length = var->xres * var->bits_per_pixel/8; + fix->smem_len = fix->line_length * var->yres; + fix->type = FB_TYPE_PACKED_PIXELS; + + if (var->bits_per_pixel == 8 && !var->grayscale) + fix->visual = FB_VISUAL_PSEUDOCOLOR; + else + fix->visual = FB_VISUAL_TRUECOLOR; + + return 0; +} + +static int ocfb_init_var(struct ocfb_dev *fbdev) +{ + struct fb_var_screeninfo *var = &fbdev->info.var; + + var->accel_flags = FB_ACCEL_NONE; + var->activate = FB_ACTIVATE_NOW; + var->xres_virtual = var->xres; + var->yres_virtual = var->yres; + + switch (var->bits_per_pixel) { + case 8: + var->transp.offset = 0; + var->transp.length = 0; + var->red.offset = 0; + var->red.length = 8; + var->green.offset = 0; + var->green.length = 8; + var->blue.offset = 0; + var->blue.length = 8; + break; + + case 16: + var->transp.offset = 0; + var->transp.length = 0; + var->red.offset = 11; + var->red.length = 5; + var->green.offset = 5; + var->green.length = 6; + var->blue.offset = 0; + var->blue.length = 5; + break; + + case 24: + var->transp.offset = 0; + var->transp.length = 0; + var->red.offset = 16; + var->red.length = 8; + var->green.offset = 8; + var->green.length = 8; + var->blue.offset = 0; + var->blue.length = 8; + break; + + case 32: + var->transp.offset = 24; + var->transp.length = 8; + var->red.offset = 16; + var->red.length = 8; + var->green.offset = 8; + var->green.length = 8; + var->blue.offset = 0; + var->blue.length = 8; + break; + } + + return 0; +} + +static struct fb_ops ocfb_ops = { + .owner = THIS_MODULE, + .fb_setcolreg = ocfb_setcolreg, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, +}; + +static int ocfb_probe(struct platform_device *pdev) +{ + int ret = 0; + struct ocfb_dev *fbdev; + struct resource *res; + int fbsize; + + fbdev = devm_kzalloc(&pdev->dev, sizeof(*fbdev), GFP_KERNEL); + if (!fbdev) + return -ENOMEM; + + platform_set_drvdata(pdev, fbdev); + + fbdev->info.fbops = &ocfb_ops; + fbdev->info.device = &pdev->dev; + fbdev->info.par = fbdev; + + /* Video mode setup */ + if (!fb_find_mode(&fbdev->info.var, &fbdev->info, mode_option, + NULL, 0, &default_mode, 16)) { + dev_err(&pdev->dev, "No valid video modes found\n"); + return -EINVAL; + } + ocfb_init_var(fbdev); + ocfb_init_fix(fbdev); + + /* Request I/O resource */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "I/O resource request failed\n"); + return -ENXIO; + } + res->flags &= ~IORESOURCE_CACHEABLE; + fbdev->regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(fbdev->regs)) + return PTR_ERR(fbdev->regs); + + /* Allocate framebuffer memory */ + fbsize = fbdev->info.fix.smem_len; + fbdev->fb_virt = dma_alloc_coherent(&pdev->dev, PAGE_ALIGN(fbsize), + &fbdev->fb_phys, GFP_KERNEL); + if (!fbdev->fb_virt) { + dev_err(&pdev->dev, + "Frame buffer memory allocation failed\n"); + return -ENOMEM; + } + fbdev->info.fix.smem_start = fbdev->fb_phys; + fbdev->info.screen_base = fbdev->fb_virt; + fbdev->info.pseudo_palette = fbdev->pseudo_palette; + + /* Clear framebuffer */ + memset_io(fbdev->fb_virt, 0, fbsize); + + /* Setup and enable the framebuffer */ + ocfb_setupfb(fbdev); + + if (fbdev->little_endian) + fbdev->info.flags |= FBINFO_FOREIGN_ENDIAN; + + /* Allocate color map */ + ret = fb_alloc_cmap(&fbdev->info.cmap, PALETTE_SIZE, 0); + if (ret) { + dev_err(&pdev->dev, "Color map allocation failed\n"); + goto err_dma_free; + } + + /* Register framebuffer */ + ret = register_framebuffer(&fbdev->info); + if (ret) { + dev_err(&pdev->dev, "Framebuffer registration failed\n"); + goto err_dealloc_cmap; + } + + return 0; + +err_dealloc_cmap: + fb_dealloc_cmap(&fbdev->info.cmap); + +err_dma_free: + dma_free_coherent(&pdev->dev, PAGE_ALIGN(fbsize), fbdev->fb_virt, + fbdev->fb_phys); + + return ret; +} + +static int ocfb_remove(struct platform_device *pdev) +{ + struct ocfb_dev *fbdev = platform_get_drvdata(pdev); + + unregister_framebuffer(&fbdev->info); + fb_dealloc_cmap(&fbdev->info.cmap); + dma_free_coherent(&pdev->dev, PAGE_ALIGN(fbdev->info.fix.smem_len), + fbdev->fb_virt, fbdev->fb_phys); + + /* Disable display */ + ocfb_writereg(fbdev, OCFB_CTRL, 0); + + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static struct of_device_id ocfb_match[] = { + { .compatible = "opencores,ocfb", }, + {}, +}; +MODULE_DEVICE_TABLE(of, ocfb_match); + +static struct platform_driver ocfb_driver = { + .probe = ocfb_probe, + .remove = ocfb_remove, + .driver = { + .name = "ocfb_fb", + .of_match_table = ocfb_match, + } +}; + +/* + * Init and exit routines + */ +static int __init ocfb_init(void) +{ +#ifndef MODULE + char *option = NULL; + + if (fb_get_options("ocfb", &option)) + return -ENODEV; + ocfb_setup(option); +#endif + return platform_driver_register(&ocfb_driver); +} + +static void __exit ocfb_exit(void) +{ + platform_driver_unregister(&ocfb_driver); +} + +module_init(ocfb_init); +module_exit(ocfb_exit); + +MODULE_AUTHOR("Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>"); +MODULE_DESCRIPTION("OpenCores VGA/LCD 2.0 frame buffer driver"); +MODULE_LICENSE("GPL v2"); +module_param(mode_option, charp, 0); +MODULE_PARM_DESC(mode_option, "Video mode ('<xres>x<yres>[-<bpp>][@refresh]')"); diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index fcba3c129efb..7411f2674e16 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -117,7 +117,7 @@ struct dpi_clk_calc_ctx { /* outputs */ struct dsi_clock_info dsi_cinfo; - struct dss_clock_info dss_cinfo; + unsigned long long fck; struct dispc_clock_info dispc_cinfo; }; @@ -184,12 +184,11 @@ static bool dpi_calc_pll_cb(int regn, int regm, unsigned long fint, dpi_calc_hsdiv_cb, ctx); } -static bool dpi_calc_dss_cb(int fckd, unsigned long fck, void *data) +static bool dpi_calc_dss_cb(unsigned long fck, void *data) { struct dpi_clk_calc_ctx *ctx = data; - ctx->dss_cinfo.fck = fck; - ctx->dss_cinfo.fck_div = fckd; + ctx->fck = fck; return dispc_div_calc(fck, ctx->pck_min, ctx->pck_max, dpi_calc_dispc_cb, ctx); @@ -237,7 +236,7 @@ static bool dpi_dss_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx) ctx->pck_min = 0; ctx->pck_max = pck + 1000 * i * i * i; - ok = dss_div_calc(ctx->pck_min, dpi_calc_dss_cb, ctx); + ok = dss_div_calc(pck, ctx->pck_min, dpi_calc_dss_cb, ctx); if (ok) return ok; } @@ -286,13 +285,13 @@ static int dpi_set_dispc_clk(unsigned long pck_req, unsigned long *fck, if (!ok) return -EINVAL; - r = dss_set_clock_div(&ctx.dss_cinfo); + r = dss_set_fck_rate(ctx.fck); if (r) return r; dpi.mgr_config.clock_info = ctx.dispc_cinfo; - *fck = ctx.dss_cinfo.fck; + *fck = ctx.fck; *lck_div = ctx.dispc_cinfo.lck_div; *pck_div = ctx.dispc_cinfo.pck_div; @@ -495,7 +494,7 @@ static int dpi_check_timings(struct omap_dss_device *dssdev, if (!ok) return -EINVAL; - fck = ctx.dss_cinfo.fck; + fck = ctx.fck; } lck_div = ctx.dispc_cinfo.lck_div; diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index bd01608e67e2..9a145da35ad3 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -67,7 +67,7 @@ static void dss_runtime_put(void); struct dss_features { u8 fck_div_max; u8 dss_fck_multiplier; - const char *clk_name; + const char *parent_clk_name; int (*dpi_select_source)(enum omap_channel channel); }; @@ -75,13 +75,12 @@ static struct { struct platform_device *pdev; void __iomem *base; - struct clk *dpll4_m4_ck; + struct clk *parent_clk; struct clk *dss_clk; unsigned long dss_clk_rate; unsigned long cache_req_pck; unsigned long cache_prate; - struct dss_clock_info cache_dss_cinfo; struct dispc_clock_info cache_dispc_cinfo; enum omap_dss_clk_source dsi_clk_source[MAX_NUM_DSI]; @@ -265,8 +264,6 @@ const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src) void dss_dump_clocks(struct seq_file *s) { - unsigned long dpll4_ck_rate; - unsigned long dpll4_m4_ck_rate; const char *fclk_name, *fclk_real_name; unsigned long fclk_rate; @@ -279,21 +276,9 @@ void dss_dump_clocks(struct seq_file *s) fclk_real_name = dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_FCK); fclk_rate = clk_get_rate(dss.dss_clk); - if (dss.dpll4_m4_ck) { - dpll4_ck_rate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); - dpll4_m4_ck_rate = clk_get_rate(dss.dpll4_m4_ck); - - seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate); - - seq_printf(s, "%s (%s) = %lu / %lu * %d = %lu\n", - fclk_name, fclk_real_name, dpll4_ck_rate, - dpll4_ck_rate / dpll4_m4_ck_rate, - dss.feat->dss_fck_multiplier, fclk_rate); - } else { - seq_printf(s, "%s (%s) = %lu\n", - fclk_name, fclk_real_name, - fclk_rate); - } + seq_printf(s, "%s (%s) = %lu\n", + fclk_name, fclk_real_name, + fclk_rate); dss_runtime_put(); } @@ -451,30 +436,8 @@ enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel) } } -/* calculate clock rates using dividers in cinfo */ -int dss_calc_clock_rates(struct dss_clock_info *cinfo) -{ - if (dss.dpll4_m4_ck) { - unsigned long prate; - - if (cinfo->fck_div > dss.feat->fck_div_max || - cinfo->fck_div == 0) - return -EINVAL; - - prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); - - cinfo->fck = prate / cinfo->fck_div * - dss.feat->dss_fck_multiplier; - } else { - if (cinfo->fck_div != 0) - return -EINVAL; - cinfo->fck = clk_get_rate(dss.dss_clk); - } - - return 0; -} - -bool dss_div_calc(unsigned long fck_min, dss_div_calc_func func, void *data) +bool dss_div_calc(unsigned long pck, unsigned long fck_min, + dss_div_calc_func func, void *data) { int fckd, fckd_start, fckd_stop; unsigned long fck; @@ -483,22 +446,24 @@ bool dss_div_calc(unsigned long fck_min, dss_div_calc_func func, void *data) unsigned long prate; unsigned m; - if (dss.dpll4_m4_ck == NULL) { - /* - * TODO: dss1_fclk can be changed on OMAP2, but the available - * dividers are not continuous. We just use the pre-set rate for - * now. - */ - fck = clk_get_rate(dss.dss_clk); - fckd = 1; - return func(fckd, fck, data); + fck_hw_max = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); + + if (dss.parent_clk == NULL) { + unsigned pckd; + + pckd = fck_hw_max / pck; + + fck = pck * pckd; + + fck = clk_round_rate(dss.dss_clk, fck); + + return func(fck, data); } - fck_hw_max = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); fckd_hw_max = dss.feat->fck_div_max; m = dss.feat->dss_fck_multiplier; - prate = dss_get_dpll4_rate(); + prate = clk_get_rate(dss.parent_clk); fck_min = fck_min ? fck_min : 1; @@ -508,50 +473,32 @@ bool dss_div_calc(unsigned long fck_min, dss_div_calc_func func, void *data) for (fckd = fckd_start; fckd >= fckd_stop; --fckd) { fck = prate / fckd * m; - if (func(fckd, fck, data)) + if (func(fck, data)) return true; } return false; } -int dss_set_clock_div(struct dss_clock_info *cinfo) +int dss_set_fck_rate(unsigned long rate) { - if (dss.dpll4_m4_ck) { - unsigned long prate; - int r; + int r; - prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); - DSSDBG("dpll4_m4 = %ld\n", prate); + DSSDBG("set fck to %lu\n", rate); - r = clk_set_rate(dss.dpll4_m4_ck, - DIV_ROUND_UP(prate, cinfo->fck_div)); - if (r) - return r; - } else { - if (cinfo->fck_div != 0) - return -EINVAL; - } + r = clk_set_rate(dss.dss_clk, rate); + if (r) + return r; dss.dss_clk_rate = clk_get_rate(dss.dss_clk); - WARN_ONCE(dss.dss_clk_rate != cinfo->fck, + WARN_ONCE(dss.dss_clk_rate != rate, "clk rate mismatch: %lu != %lu", dss.dss_clk_rate, - cinfo->fck); - - DSSDBG("fck = %ld (%d)\n", cinfo->fck, cinfo->fck_div); + rate); return 0; } -unsigned long dss_get_dpll4_rate(void) -{ - if (dss.dpll4_m4_ck) - return clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); - else - return 0; -} - unsigned long dss_get_dispc_clk_rate(void) { return dss.dss_clk_rate; @@ -560,27 +507,23 @@ unsigned long dss_get_dispc_clk_rate(void) static int dss_setup_default_clock(void) { unsigned long max_dss_fck, prate; + unsigned long fck; unsigned fck_div; - struct dss_clock_info dss_cinfo = { 0 }; int r; - if (dss.dpll4_m4_ck == NULL) - return 0; - max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); - prate = dss_get_dpll4_rate(); - - fck_div = DIV_ROUND_UP(prate * dss.feat->dss_fck_multiplier, - max_dss_fck); - - dss_cinfo.fck_div = fck_div; + if (dss.parent_clk == NULL) { + fck = clk_round_rate(dss.dss_clk, max_dss_fck); + } else { + prate = clk_get_rate(dss.parent_clk); - r = dss_calc_clock_rates(&dss_cinfo); - if (r) - return r; + fck_div = DIV_ROUND_UP(prate * dss.feat->dss_fck_multiplier, + max_dss_fck); + fck = prate / fck_div * dss.feat->dss_fck_multiplier; + } - r = dss_set_clock_div(&dss_cinfo); + r = dss_set_fck_rate(fck); if (r) return r; @@ -706,25 +649,25 @@ static int dss_get_clocks(void) dss.dss_clk = clk; - if (dss.feat->clk_name) { - clk = clk_get(NULL, dss.feat->clk_name); + if (dss.feat->parent_clk_name) { + clk = clk_get(NULL, dss.feat->parent_clk_name); if (IS_ERR(clk)) { - DSSERR("Failed to get %s\n", dss.feat->clk_name); + DSSERR("Failed to get %s\n", dss.feat->parent_clk_name); return PTR_ERR(clk); } } else { clk = NULL; } - dss.dpll4_m4_ck = clk; + dss.parent_clk = clk; return 0; } static void dss_put_clocks(void) { - if (dss.dpll4_m4_ck) - clk_put(dss.dpll4_m4_ck); + if (dss.parent_clk) + clk_put(dss.parent_clk); } static int dss_runtime_get(void) @@ -761,37 +704,41 @@ void dss_debug_dump_clocks(struct seq_file *s) #endif static const struct dss_features omap24xx_dss_feats __initconst = { - .fck_div_max = 16, + /* + * fck div max is really 16, but the divider range has gaps. The range + * from 1 to 6 has no gaps, so let's use that as a max. + */ + .fck_div_max = 6, .dss_fck_multiplier = 2, - .clk_name = NULL, + .parent_clk_name = "core_ck", .dpi_select_source = &dss_dpi_select_source_omap2_omap3, }; static const struct dss_features omap34xx_dss_feats __initconst = { .fck_div_max = 16, .dss_fck_multiplier = 2, - .clk_name = "dpll4_m4_ck", + .parent_clk_name = "dpll4_ck", .dpi_select_source = &dss_dpi_select_source_omap2_omap3, }; static const struct dss_features omap3630_dss_feats __initconst = { .fck_div_max = 32, .dss_fck_multiplier = 1, - .clk_name = "dpll4_m4_ck", + .parent_clk_name = "dpll4_ck", .dpi_select_source = &dss_dpi_select_source_omap2_omap3, }; static const struct dss_features omap44xx_dss_feats __initconst = { .fck_div_max = 32, .dss_fck_multiplier = 1, - .clk_name = "dpll_per_m5x2_ck", + .parent_clk_name = "dpll_per_x2_ck", .dpi_select_source = &dss_dpi_select_source_omap4, }; static const struct dss_features omap54xx_dss_feats __initconst = { .fck_div_max = 64, .dss_fck_multiplier = 1, - .clk_name = "dpll_per_h12x2_ck", + .parent_clk_name = "dpll_per_x2_ck", .dpi_select_source = &dss_dpi_select_source_omap5, }; diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index f538e867c0f8..057f24c8a332 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -100,14 +100,6 @@ enum dss_writeback_channel { DSS_WB_LCD3_MGR = 7, }; -struct dss_clock_info { - /* rates that we get with dividers below */ - unsigned long fck; - - /* dividers */ - u16 fck_div; -}; - struct dispc_clock_info { /* rates that we get with dividers below */ unsigned long lck; @@ -250,12 +242,11 @@ enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel); void dss_set_venc_output(enum omap_dss_venc_type type); void dss_set_dac_pwrdn_bgz(bool enable); -unsigned long dss_get_dpll4_rate(void); -int dss_calc_clock_rates(struct dss_clock_info *cinfo); -int dss_set_clock_div(struct dss_clock_info *cinfo); +int dss_set_fck_rate(unsigned long rate); -typedef bool (*dss_div_calc_func)(int fckd, unsigned long fck, void *data); -bool dss_div_calc(unsigned long fck_min, dss_div_calc_func func, void *data); +typedef bool (*dss_div_calc_func)(unsigned long fck, void *data); +bool dss_div_calc(unsigned long pck, unsigned long fck_min, + dss_div_calc_func func, void *data); /* SDI */ int sdi_init_platform_driver(void) __init; diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c index 156d146a72a6..efb9ee9e3c96 100644 --- a/drivers/video/omap2/dss/sdi.c +++ b/drivers/video/omap2/dss/sdi.c @@ -46,7 +46,7 @@ static struct { struct sdi_clk_calc_ctx { unsigned long pck_min, pck_max; - struct dss_clock_info dss_cinfo; + unsigned long long fck; struct dispc_clock_info dispc_cinfo; }; @@ -63,19 +63,18 @@ static bool dpi_calc_dispc_cb(int lckd, int pckd, unsigned long lck, return true; } -static bool dpi_calc_dss_cb(int fckd, unsigned long fck, void *data) +static bool dpi_calc_dss_cb(unsigned long fck, void *data) { struct sdi_clk_calc_ctx *ctx = data; - ctx->dss_cinfo.fck = fck; - ctx->dss_cinfo.fck_div = fckd; + ctx->fck = fck; return dispc_div_calc(fck, ctx->pck_min, ctx->pck_max, dpi_calc_dispc_cb, ctx); } static int sdi_calc_clock_div(unsigned long pclk, - struct dss_clock_info *dss_cinfo, + unsigned long *fck, struct dispc_clock_info *dispc_cinfo) { int i; @@ -98,9 +97,9 @@ static int sdi_calc_clock_div(unsigned long pclk, ctx.pck_min = 0; ctx.pck_max = pclk + 1000 * i * i * i; - ok = dss_div_calc(ctx.pck_min, dpi_calc_dss_cb, &ctx); + ok = dss_div_calc(pclk, ctx.pck_min, dpi_calc_dss_cb, &ctx); if (ok) { - *dss_cinfo = ctx.dss_cinfo; + *fck = ctx.fck; *dispc_cinfo = ctx.dispc_cinfo; return 0; } @@ -128,7 +127,7 @@ static int sdi_display_enable(struct omap_dss_device *dssdev) { struct omap_dss_device *out = &sdi.output; struct omap_video_timings *t = &sdi.timings; - struct dss_clock_info dss_cinfo; + unsigned long fck; struct dispc_clock_info dispc_cinfo; unsigned long pck; int r; @@ -150,13 +149,13 @@ static int sdi_display_enable(struct omap_dss_device *dssdev) t->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; t->sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; - r = sdi_calc_clock_div(t->pixel_clock * 1000, &dss_cinfo, &dispc_cinfo); + r = sdi_calc_clock_div(t->pixel_clock * 1000, &fck, &dispc_cinfo); if (r) goto err_calc_clock_div; sdi.mgr_config.clock_info = dispc_cinfo; - pck = dss_cinfo.fck / dispc_cinfo.lck_div / dispc_cinfo.pck_div / 1000; + pck = fck / dispc_cinfo.lck_div / dispc_cinfo.pck_div / 1000; if (pck != t->pixel_clock) { DSSWARN("Could not find exact pixel clock. Requested %d kHz, " @@ -169,7 +168,7 @@ static int sdi_display_enable(struct omap_dss_device *dssdev) dss_mgr_set_timings(out->manager, t); - r = dss_set_clock_div(&dss_cinfo); + r = dss_set_fck_rate(fck); if (r) goto err_set_dss_clock_div; diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c index a5514acd2ac6..8a8d7f060784 100644 --- a/drivers/video/riva/fbdev.c +++ b/drivers/video/riva/fbdev.c @@ -2128,7 +2128,6 @@ static void rivafb_remove(struct pci_dev *pd) pci_release_regions(pd); kfree(info->pixmap.addr); framebuffer_release(info); - pci_set_drvdata(pd, NULL); NVTRACE_LEAVE(); } diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index ab85ad6c25ec..2bcc84ac18c7 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c @@ -1227,7 +1227,7 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv) /* Free the MERAM cache. */ if (ch->cache) { sh_mobile_meram_cache_free(priv->meram_dev, ch->cache); - ch->cache = 0; + ch->cache = NULL; } } diff --git a/drivers/video/tgafb.c b/drivers/video/tgafb.c index f28674fea909..07c7df9ee77b 100644 --- a/drivers/video/tgafb.c +++ b/drivers/video/tgafb.c @@ -32,12 +32,6 @@ #include <video/tgafb.h> -#ifdef CONFIG_PCI -#define TGA_BUS_PCI(dev) (dev->bus == &pci_bus_type) -#else -#define TGA_BUS_PCI(dev) 0 -#endif - #ifdef CONFIG_TC #define TGA_BUS_TC(dev) (dev->bus == &tc_bus_type) #else @@ -236,7 +230,7 @@ tgafb_set_par(struct fb_info *info) }; struct tga_par *par = (struct tga_par *) info->par; - int tga_bus_pci = TGA_BUS_PCI(par->dev); + int tga_bus_pci = dev_is_pci(par->dev); int tga_bus_tc = TGA_BUS_TC(par->dev); u32 htimings, vtimings, pll_freq; u8 tga_type; @@ -519,7 +513,7 @@ tgafb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info) { struct tga_par *par = (struct tga_par *) info->par; - int tga_bus_pci = TGA_BUS_PCI(par->dev); + int tga_bus_pci = dev_is_pci(par->dev); int tga_bus_tc = TGA_BUS_TC(par->dev); if (regno > 255) @@ -1472,7 +1466,7 @@ static void tgafb_init_fix(struct fb_info *info) { struct tga_par *par = (struct tga_par *)info->par; - int tga_bus_pci = TGA_BUS_PCI(par->dev); + int tga_bus_pci = dev_is_pci(par->dev); int tga_bus_tc = TGA_BUS_TC(par->dev); u8 tga_type = par->tga_type; const char *tga_type_name = NULL; @@ -1496,10 +1490,9 @@ tgafb_init_fix(struct fb_info *info) if (tga_bus_tc) tga_type_name = "Digital ZLX-E3"; break; - default: - tga_type_name = "Unknown"; - break; } + if (!tga_type_name) + tga_type_name = "Unknown"; strlcpy(info->fix.id, tga_type_name, sizeof(info->fix.id)); @@ -1560,7 +1553,7 @@ static int tgafb_register(struct device *dev) const struct fb_videomode *modedb_tga = NULL; resource_size_t bar0_start = 0, bar0_len = 0; const char *mode_option_tga = NULL; - int tga_bus_pci = TGA_BUS_PCI(dev); + int tga_bus_pci = dev_is_pci(dev); int tga_bus_tc = TGA_BUS_TC(dev); unsigned int modedbsize_tga = 0; void __iomem *mem_base; @@ -1690,7 +1683,7 @@ static int tgafb_register(struct device *dev) static void tgafb_unregister(struct device *dev) { resource_size_t bar0_start = 0, bar0_len = 0; - int tga_bus_pci = TGA_BUS_PCI(dev); + int tga_bus_pci = dev_is_pci(dev); int tga_bus_tc = TGA_BUS_TC(dev); struct fb_info *info = NULL; struct tga_par *par; diff --git a/drivers/video/vermilion/vermilion.c b/drivers/video/vermilion/vermilion.c index 09a136633f35..048a66640b03 100644 --- a/drivers/video/vermilion/vermilion.c +++ b/drivers/video/vermilion/vermilion.c @@ -383,7 +383,6 @@ static void vmlfb_disable_mmio(struct vml_par *par) static void vmlfb_release_devices(struct vml_par *par) { if (atomic_dec_and_test(&par->refcount)) { - pci_set_drvdata(par->vdc, NULL); pci_disable_device(par->gpu); pci_disable_device(par->vdc); } |