fbdev changes for 3.14

This is a rather boring pull request. There is one new fb driver, OpenCores
 VGA/LCD, but other than that it's just minor cleanups and fixes.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.14 (GNU/Linux)
 
 iQIcBAABAgAGBQJS4kg5AAoJEPo9qoy8lh71ng0P/jmi0rDF5+0D+L3EjE1tLN9M
 +0DhoUdkSXweSRLk0TxF4vkHmlStykTEbBkdKGqFa6yKvq+V7wFtgv2lchraZmJv
 TsTiZ60J6JnA0xbHurt+GntWRgzIGWIHF9QBk/hxn1QB3oIscR2I6K9z+YVKStXH
 ywyBOmvfyghDkPG8taqXuDCtWFKYMwuoUP+YfqvVT1Ey4J+pEJ8EpBM9nvLJmvuW
 ZrARDqkntoQZOzfW52HVis0hzrQLi8bJQp5BEu+yd2Q3sSOXV7kV8HOCkhiGwHCE
 zEtPM5KavmHRECoZtCtNTRvf+e0byKibuAnKSvnuwdfxRurvh4T3I7YUf3VsnIoL
 +obxad3737zvIY0yDx3PIU/dbCtv63sy+6Gl/E7HAn9Q0t1fGml1Y0XC8Ohy6rR5
 b9WmSGcF0nxPBxHeyjJLXJMxiv8iclvBLhZc5CUeKYB+teLEGorRpMsuElPmizOh
 elMus/f6NHxbaJoS6FJPTMm3QfdjqG3SLGAOpNkZgFtCsNGaqyexVQViEV/PgEJI
 Qe67KeuUGdJhvko7ct19u1d/ZHs19LXnUmtLsD/xbs6YcUCQZ106B9ZP+YRc+ie0
 9QDcfI+WEc82xL18L3bge+xYc45jdPhCOn6zwAKIYqNq5ITkjdt0jHLv5dtfPkbI
 Hv/P2Peuc6u3KSDFyrwe
 =RmAl
 -----END PGP SIGNATURE-----

Merge tag 'fbdev-3.14' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux

Pull fbdev changes from Tomi Valkeinen:
 "This is a rather boring pull request.  There is one new fb driver,
  OpenCores VGA/LCD, but other than that it's just minor cleanups and
  fixes"

* tag 'fbdev-3.14' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux: (51 commits)
  i810: delete useless variable
  video: add OpenCores VGA/LCD framebuffer driver
  video/logo: Remove MIPS-specific include section
  tgafb: potential NULL dereference in init
  video: mmp: Using plain integer as NULL pointer
  video: mmp: delete a stray mutex_unlock()
  video: amba-clcd: Make CLCD driver available on more platforms
  video: Replace local macro with PCI standard macro
  fbmem: really support wildcard video=options for all fbdev drivers
  video: vgacon: Don't build on arm64
  video: mx3fb: Allow blocking during framebuffer allocation
  fbcon: Fix memory leak in fbcon_exit().
  fbcon: trivial optimization for fbcon_exit
  video: pxa168fb: Cleanup pxa168fb.h file
  video: pxa: Cleanup video-pxafb.h header
  video: msm: Cleanup video-msm_fb.h header
  video: ep93xx: Cleanup video-ep93xx.h header
  video: mxsfb: fix broken videomode selection
  video: mxsfb: convert pr_debug()/dev_dbg() to pr_err()/dev_err() for error messages
  video: vmlfb: remove unnecessary pci_set_drvdata()
  ...
This commit is contained in:
Linus Torvalds 2014-01-24 17:16:31 -08:00
commit b788769e06
43 changed files with 949 additions and 413 deletions

View file

@ -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

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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;
}

View file

@ -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;

View file

@ -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)

View file

@ -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");

View file

@ -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);

View file

@ -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",

View file

@ -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;
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;
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);
}
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);

View file

@ -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();
}

440
drivers/video/ocfb.c Normal file
View file

@ -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]')");

View file

@ -346,28 +346,22 @@ static int acx565akm_get_actual_brightness(struct panel_drv_data *ddata)
static int acx565akm_bl_update_status(struct backlight_device *dev)
{
struct panel_drv_data *ddata = dev_get_drvdata(&dev->dev);
int r;
int level;
dev_dbg(&ddata->spi->dev, "%s\n", __func__);
mutex_lock(&ddata->mutex);
if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
dev->props.power == FB_BLANK_UNBLANK)
level = dev->props.brightness;
else
level = 0;
r = 0;
if (ddata->has_bc)
acx565akm_set_brightness(ddata, level);
else
r = -ENODEV;
return -ENODEV;
mutex_unlock(&ddata->mutex);
return r;
return 0;
}
static int acx565akm_bl_get_intensity(struct backlight_device *dev)
@ -390,9 +384,33 @@ static int acx565akm_bl_get_intensity(struct backlight_device *dev)
return 0;
}
static int acx565akm_bl_update_status_locked(struct backlight_device *dev)
{
struct panel_drv_data *ddata = dev_get_drvdata(&dev->dev);
int r;
mutex_lock(&ddata->mutex);
r = acx565akm_bl_update_status(dev);
mutex_unlock(&ddata->mutex);
return r;
}
static int acx565akm_bl_get_intensity_locked(struct backlight_device *dev)
{
struct panel_drv_data *ddata = dev_get_drvdata(&dev->dev);
int r;
mutex_lock(&ddata->mutex);
r = acx565akm_bl_get_intensity(dev);
mutex_unlock(&ddata->mutex);
return r;
}
static const struct backlight_ops acx565akm_bl_ops = {
.get_brightness = acx565akm_bl_get_intensity,
.update_status = acx565akm_bl_update_status,
.get_brightness = acx565akm_bl_get_intensity_locked,
.update_status = acx565akm_bl_update_status_locked,
};
/*--------------------Auto Brightness control via Sysfs---------------------*/
@ -526,8 +544,6 @@ static int acx565akm_panel_power_on(struct omap_dss_device *dssdev)
struct omap_dss_device *in = ddata->in;
int r;
mutex_lock(&ddata->mutex);
dev_dbg(&ddata->spi->dev, "%s\n", __func__);
in->ops.sdi->set_timings(in, &ddata->videomode);
@ -568,8 +584,6 @@ static int acx565akm_panel_power_on(struct omap_dss_device *dssdev)
set_display_state(ddata, 1);
set_cabc_mode(ddata, ddata->cabc_mode);
mutex_unlock(&ddata->mutex);
return acx565akm_bl_update_status(ddata->bl_dev);
}
@ -616,7 +630,9 @@ static int acx565akm_enable(struct omap_dss_device *dssdev)
if (omapdss_device_is_enabled(dssdev))
return 0;
mutex_lock(&ddata->mutex);
r = acx565akm_panel_power_on(dssdev);
mutex_unlock(&ddata->mutex);
if (r)
return r;

View file

@ -149,6 +149,9 @@ static void apply_init_priv(void)
op = &dss_data.ovl_priv_data_array[i];
op->info.color_mode = OMAP_DSS_COLOR_RGB16;
op->info.rotation_type = OMAP_DSS_ROT_DMA;
op->info.global_alpha = 255;
switch (i) {
@ -629,7 +632,7 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl)
struct mgr_priv_data *mp;
int r;
DSSDBG("writing ovl %d regs", ovl->id);
DSSDBG("writing ovl %d regs\n", ovl->id);
if (!op->enabled || !op->info_dirty)
return;
@ -664,7 +667,7 @@ static void dss_ovl_write_regs_extra(struct omap_overlay *ovl)
struct ovl_priv_data *op = get_ovl_priv(ovl);
struct mgr_priv_data *mp;
DSSDBG("writing ovl %d regs extra", ovl->id);
DSSDBG("writing ovl %d regs extra\n", ovl->id);
if (!op->extra_info_dirty)
return;
@ -687,7 +690,7 @@ static void dss_mgr_write_regs(struct omap_overlay_manager *mgr)
struct mgr_priv_data *mp = get_mgr_priv(mgr);
struct omap_overlay *ovl;
DSSDBG("writing mgr %d regs", mgr->id);
DSSDBG("writing mgr %d regs\n", mgr->id);
if (!mp->enabled)
return;
@ -713,7 +716,7 @@ static void dss_mgr_write_regs_extra(struct omap_overlay_manager *mgr)
{
struct mgr_priv_data *mp = get_mgr_priv(mgr);
DSSDBG("writing mgr %d regs extra", mgr->id);
DSSDBG("writing mgr %d regs extra\n", mgr->id);
if (!mp->extra_info_dirty)
return;

View file

@ -90,6 +90,8 @@ struct dispc_features {
/* revert to the OMAP4 mechanism of DISPC Smart Standby operation */
bool mstandby_workaround:1;
bool set_max_preload:1;
};
#define DISPC_MAX_NR_FIFOS 5
@ -1200,7 +1202,17 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high)
dispc_write_reg(DISPC_OVL_FIFO_THRESHOLD(plane),
FLD_VAL(high, hi_start, hi_end) |
FLD_VAL(low, lo_start, lo_end));
/*
* configure the preload to the pipeline's high threhold, if HT it's too
* large for the preload field, set the threshold to the maximum value
* that can be held by the preload register
*/
if (dss_has_feature(FEAT_PRELOAD) && dispc.feat->set_max_preload &&
plane != OMAP_DSS_WB)
dispc_write_reg(DISPC_OVL_PRELOAD(plane), min(high, 0xfffu));
}
EXPORT_SYMBOL(dispc_ovl_set_fifo_threshold);
void dispc_enable_fifomerge(bool enable)
{
@ -1259,6 +1271,7 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane,
*fifo_high = total_fifo_size - buf_unit;
}
}
EXPORT_SYMBOL(dispc_ovl_compute_fifo_thresholds);
static void dispc_ovl_set_fir(enum omap_plane plane,
int hinc, int vinc,
@ -1988,7 +2001,8 @@ static void calc_tiler_rotation_offset(u16 screen_width, u16 width,
*/
static int check_horiz_timing_omap3(unsigned long pclk, unsigned long lclk,
const struct omap_video_timings *t, u16 pos_x,
u16 width, u16 height, u16 out_width, u16 out_height)
u16 width, u16 height, u16 out_width, u16 out_height,
bool five_taps)
{
const int ds = DIV_ROUND_UP(height, out_height);
unsigned long nonactive;
@ -2008,6 +2022,10 @@ static int check_horiz_timing_omap3(unsigned long pclk, unsigned long lclk,
if (blank <= limits[i])
return -EINVAL;
/* FIXME add checks for 3-tap filter once the limitations are known */
if (!five_taps)
return 0;
/*
* Pixel data should be prepared before visible display point starts.
* So, atleast DS-2 lines must have already been fetched by DISPC
@ -2183,22 +2201,30 @@ static int dispc_ovl_calc_scaling_34xx(unsigned long pclk, unsigned long lclk,
do {
in_height = DIV_ROUND_UP(height, *decim_y);
in_width = DIV_ROUND_UP(width, *decim_x);
*core_clk = calc_core_clk_five_taps(pclk, mgr_timings,
in_width, in_height, out_width, out_height, color_mode);
error = check_horiz_timing_omap3(pclk, lclk, mgr_timings,
pos_x, in_width, in_height, out_width,
out_height);
*five_taps = in_height > out_height;
if (in_width > maxsinglelinewidth)
if (in_height > out_height &&
in_height < out_height * 2)
*five_taps = false;
if (!*five_taps)
again:
if (*five_taps)
*core_clk = calc_core_clk_five_taps(pclk, mgr_timings,
in_width, in_height, out_width,
out_height, color_mode);
else
*core_clk = dispc.feat->calc_core_clk(pclk, in_width,
in_height, out_width, out_height,
mem_to_mem);
error = check_horiz_timing_omap3(pclk, lclk, mgr_timings,
pos_x, in_width, in_height, out_width,
out_height, *five_taps);
if (error && *five_taps) {
*five_taps = false;
goto again;
}
error = (error || in_width > maxsinglelinewidth * 2 ||
(in_width > maxsinglelinewidth && *five_taps) ||
!*core_clk || *core_clk > dispc_core_clk_rate());
@ -2215,7 +2241,7 @@ static int dispc_ovl_calc_scaling_34xx(unsigned long pclk, unsigned long lclk,
} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
if (check_horiz_timing_omap3(pclk, lclk, mgr_timings, pos_x, width,
height, out_width, out_height)){
height, out_width, out_height, *five_taps)) {
DSSERR("horizontal timing too tight\n");
return -EINVAL;
}
@ -3211,6 +3237,8 @@ static void dispc_dump_regs(struct seq_file *s)
DUMPREG(DISPC_CONTROL3);
DUMPREG(DISPC_CONFIG3);
}
if (dss_has_feature(FEAT_MFLAG))
DUMPREG(DISPC_GLOBAL_MFLAG_ATTRIBUTE);
#undef DUMPREG
@ -3285,6 +3313,8 @@ static void dispc_dump_regs(struct seq_file *s)
DUMPREG(i, DISPC_OVL_ATTRIBUTES2);
if (dss_has_feature(FEAT_PRELOAD))
DUMPREG(i, DISPC_OVL_PRELOAD);
if (dss_has_feature(FEAT_MFLAG))
DUMPREG(i, DISPC_OVL_MFLAG_THRESHOLD);
}
#undef DISPC_REG
@ -3520,6 +3550,7 @@ static const struct dispc_features omap24xx_dispc_feats __initconst = {
.calc_core_clk = calc_core_clk_24xx,
.num_fifos = 3,
.no_framedone_tv = true,
.set_max_preload = false,
};
static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {
@ -3539,6 +3570,7 @@ static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {
.calc_core_clk = calc_core_clk_34xx,
.num_fifos = 3,
.no_framedone_tv = true,
.set_max_preload = false,
};
static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {
@ -3558,6 +3590,7 @@ static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {
.calc_core_clk = calc_core_clk_34xx,
.num_fifos = 3,
.no_framedone_tv = true,
.set_max_preload = false,
};
static const struct dispc_features omap44xx_dispc_feats __initconst = {
@ -3577,6 +3610,7 @@ static const struct dispc_features omap44xx_dispc_feats __initconst = {
.calc_core_clk = calc_core_clk_44xx,
.num_fifos = 5,
.gfx_fifo_workaround = true,
.set_max_preload = true,
};
static const struct dispc_features omap54xx_dispc_feats __initconst = {
@ -3597,6 +3631,7 @@ static const struct dispc_features omap54xx_dispc_feats __initconst = {
.num_fifos = 5,
.gfx_fifo_workaround = true,
.mstandby_workaround = true,
.set_max_preload = true,
};
static int __init dispc_init_features(struct platform_device *pdev)
@ -3734,6 +3769,8 @@ static int dispc_runtime_suspend(struct device *dev)
static int dispc_runtime_resume(struct device *dev)
{
_omap_dispc_initial_config();
dispc_restore_context();
return 0;

View file

@ -40,6 +40,7 @@
#define DISPC_CONTROL3 0x0848
#define DISPC_CONFIG3 0x084C
#define DISPC_MSTANDBY_CTRL 0x0858
#define DISPC_GLOBAL_MFLAG_ATTRIBUTE 0x085C
/* DISPC overlay registers */
#define DISPC_OVL_BA0(n) (DISPC_OVL_BASE(n) + \
@ -100,6 +101,8 @@
DISPC_FIR_COEF_V2_OFFSET(n, i))
#define DISPC_OVL_PRELOAD(n) (DISPC_OVL_BASE(n) + \
DISPC_PRELOAD_OFFSET(n))
#define DISPC_OVL_MFLAG_THRESHOLD(n) (DISPC_OVL_BASE(n) + \
DISPC_MFLAG_THRESHOLD_OFFSET(n))
/* DISPC up/downsampling FIR filter coefficient structure */
struct dispc_coef {
@ -894,4 +897,21 @@ static inline u16 DISPC_PRELOAD_OFFSET(enum omap_plane plane)
return 0;
}
}
static inline u16 DISPC_MFLAG_THRESHOLD_OFFSET(enum omap_plane plane)
{
switch (plane) {
case OMAP_DSS_GFX:
return 0x0860;
case OMAP_DSS_VIDEO1:
return 0x0864;
case OMAP_DSS_VIDEO2:
return 0x0868;
case OMAP_DSS_VIDEO3:
return 0x086c;
default:
BUG();
return 0;
}
}
#endif

View file

@ -277,7 +277,7 @@ static ssize_t display_wss_store(struct device *dev,
return size;
}
static DEVICE_ATTR(name, S_IRUGO, display_name_show, NULL);
static DEVICE_ATTR(display_name, S_IRUGO, display_name_show, NULL);
static DEVICE_ATTR(enabled, S_IRUGO|S_IWUSR,
display_enabled_show, display_enabled_store);
static DEVICE_ATTR(tear_elim, S_IRUGO|S_IWUSR,
@ -292,7 +292,7 @@ static DEVICE_ATTR(wss, S_IRUGO|S_IWUSR,
display_wss_show, display_wss_store);
static const struct attribute *display_sysfs_attrs[] = {
&dev_attr_name.attr,
&dev_attr_display_name.attr,
&dev_attr_enabled.attr,
&dev_attr_tear_elim.attr,
&dev_attr_timings.attr,

View file

@ -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;
@ -551,7 +550,8 @@ static int dpi_init_regulator(void)
vdds_dsi = devm_regulator_get(&dpi.pdev->dev, "vdds_dsi");
if (IS_ERR(vdds_dsi)) {
DSSERR("can't get VDDS_DSI regulator\n");
if (PTR_ERR(vdds_dsi) != -EPROBE_DEFER)
DSSERR("can't get VDDS_DSI regulator\n");
return PTR_ERR(vdds_dsi);
}

View file

@ -47,63 +47,73 @@
#define DSI_CATCH_MISSING_TE
struct dsi_reg { u16 idx; };
struct dsi_reg { u16 module; u16 idx; };
#define DSI_REG(idx) ((const struct dsi_reg) { idx })
#define DSI_REG(mod, idx) ((const struct dsi_reg) { mod, idx })
#define DSI_SZ_REGS SZ_1K
/* DSI Protocol Engine */
#define DSI_REVISION DSI_REG(0x0000)
#define DSI_SYSCONFIG DSI_REG(0x0010)
#define DSI_SYSSTATUS DSI_REG(0x0014)
#define DSI_IRQSTATUS DSI_REG(0x0018)
#define DSI_IRQENABLE DSI_REG(0x001C)
#define DSI_CTRL DSI_REG(0x0040)
#define DSI_GNQ DSI_REG(0x0044)
#define DSI_COMPLEXIO_CFG1 DSI_REG(0x0048)
#define DSI_COMPLEXIO_IRQ_STATUS DSI_REG(0x004C)
#define DSI_COMPLEXIO_IRQ_ENABLE DSI_REG(0x0050)
#define DSI_CLK_CTRL DSI_REG(0x0054)
#define DSI_TIMING1 DSI_REG(0x0058)
#define DSI_TIMING2 DSI_REG(0x005C)
#define DSI_VM_TIMING1 DSI_REG(0x0060)
#define DSI_VM_TIMING2 DSI_REG(0x0064)
#define DSI_VM_TIMING3 DSI_REG(0x0068)
#define DSI_CLK_TIMING DSI_REG(0x006C)
#define DSI_TX_FIFO_VC_SIZE DSI_REG(0x0070)
#define DSI_RX_FIFO_VC_SIZE DSI_REG(0x0074)
#define DSI_COMPLEXIO_CFG2 DSI_REG(0x0078)
#define DSI_RX_FIFO_VC_FULLNESS DSI_REG(0x007C)
#define DSI_VM_TIMING4 DSI_REG(0x0080)
#define DSI_TX_FIFO_VC_EMPTINESS DSI_REG(0x0084)
#define DSI_VM_TIMING5 DSI_REG(0x0088)
#define DSI_VM_TIMING6 DSI_REG(0x008C)
#define DSI_VM_TIMING7 DSI_REG(0x0090)
#define DSI_STOPCLK_TIMING DSI_REG(0x0094)
#define DSI_VC_CTRL(n) DSI_REG(0x0100 + (n * 0x20))
#define DSI_VC_TE(n) DSI_REG(0x0104 + (n * 0x20))
#define DSI_VC_LONG_PACKET_HEADER(n) DSI_REG(0x0108 + (n * 0x20))
#define DSI_VC_LONG_PACKET_PAYLOAD(n) DSI_REG(0x010C + (n * 0x20))
#define DSI_VC_SHORT_PACKET_HEADER(n) DSI_REG(0x0110 + (n * 0x20))
#define DSI_VC_IRQSTATUS(n) DSI_REG(0x0118 + (n * 0x20))
#define DSI_VC_IRQENABLE(n) DSI_REG(0x011C + (n * 0x20))
#define DSI_PROTO 0
#define DSI_PROTO_SZ 0x200
#define DSI_REVISION DSI_REG(DSI_PROTO, 0x0000)
#define DSI_SYSCONFIG DSI_REG(DSI_PROTO, 0x0010)
#define DSI_SYSSTATUS DSI_REG(DSI_PROTO, 0x0014)
#define DSI_IRQSTATUS DSI_REG(DSI_PROTO, 0x0018)
#define DSI_IRQENABLE DSI_REG(DSI_PROTO, 0x001C)
#define DSI_CTRL DSI_REG(DSI_PROTO, 0x0040)
#define DSI_GNQ DSI_REG(DSI_PROTO, 0x0044)
#define DSI_COMPLEXIO_CFG1 DSI_REG(DSI_PROTO, 0x0048)
#define DSI_COMPLEXIO_IRQ_STATUS DSI_REG(DSI_PROTO, 0x004C)
#define DSI_COMPLEXIO_IRQ_ENABLE DSI_REG(DSI_PROTO, 0x0050)
#define DSI_CLK_CTRL DSI_REG(DSI_PROTO, 0x0054)
#define DSI_TIMING1 DSI_REG(DSI_PROTO, 0x0058)
#define DSI_TIMING2 DSI_REG(DSI_PROTO, 0x005C)
#define DSI_VM_TIMING1 DSI_REG(DSI_PROTO, 0x0060)
#define DSI_VM_TIMING2 DSI_REG(DSI_PROTO, 0x0064)
#define DSI_VM_TIMING3 DSI_REG(DSI_PROTO, 0x0068)
#define DSI_CLK_TIMING DSI_REG(DSI_PROTO, 0x006C)
#define DSI_TX_FIFO_VC_SIZE DSI_REG(DSI_PROTO, 0x0070)
#define DSI_RX_FIFO_VC_SIZE DSI_REG(DSI_PROTO, 0x0074)
#define DSI_COMPLEXIO_CFG2 DSI_REG(DSI_PROTO, 0x0078)
#define DSI_RX_FIFO_VC_FULLNESS DSI_REG(DSI_PROTO, 0x007C)
#define DSI_VM_TIMING4 DSI_REG(DSI_PROTO, 0x0080)
#define DSI_TX_FIFO_VC_EMPTINESS DSI_REG(DSI_PROTO, 0x0084)
#define DSI_VM_TIMING5 DSI_REG(DSI_PROTO, 0x0088)
#define DSI_VM_TIMING6 DSI_REG(DSI_PROTO, 0x008C)
#define DSI_VM_TIMING7 DSI_REG(DSI_PROTO, 0x0090)
#define DSI_STOPCLK_TIMING DSI_REG(DSI_PROTO, 0x0094)
#define DSI_VC_CTRL(n) DSI_REG(DSI_PROTO, 0x0100 + (n * 0x20))
#define DSI_VC_TE(n) DSI_REG(DSI_PROTO, 0x0104 + (n * 0x20))
#define DSI_VC_LONG_PACKET_HEADER(n) DSI_REG(DSI_PROTO, 0x0108 + (n * 0x20))
#define DSI_VC_LONG_PACKET_PAYLOAD(n) DSI_REG(DSI_PROTO, 0x010C + (n * 0x20))
#define DSI_VC_SHORT_PACKET_HEADER(n) DSI_REG(DSI_PROTO, 0x0110 + (n * 0x20))
#define DSI_VC_IRQSTATUS(n) DSI_REG(DSI_PROTO, 0x0118 + (n * 0x20))
#define DSI_VC_IRQENABLE(n) DSI_REG(DSI_PROTO, 0x011C + (n * 0x20))
/* DSIPHY_SCP */
#define DSI_DSIPHY_CFG0 DSI_REG(0x200 + 0x0000)
#define DSI_DSIPHY_CFG1 DSI_REG(0x200 + 0x0004)
#define DSI_DSIPHY_CFG2 DSI_REG(0x200 + 0x0008)
#define DSI_DSIPHY_CFG5 DSI_REG(0x200 + 0x0014)
#define DSI_DSIPHY_CFG10 DSI_REG(0x200 + 0x0028)
#define DSI_PHY 1
#define DSI_PHY_OFFSET 0x200
#define DSI_PHY_SZ 0x40
#define DSI_DSIPHY_CFG0 DSI_REG(DSI_PHY, 0x0000)
#define DSI_DSIPHY_CFG1 DSI_REG(DSI_PHY, 0x0004)
#define DSI_DSIPHY_CFG2 DSI_REG(DSI_PHY, 0x0008)
#define DSI_DSIPHY_CFG5 DSI_REG(DSI_PHY, 0x0014)
#define DSI_DSIPHY_CFG10 DSI_REG(DSI_PHY, 0x0028)
/* DSI_PLL_CTRL_SCP */
#define DSI_PLL_CONTROL DSI_REG(0x300 + 0x0000)
#define DSI_PLL_STATUS DSI_REG(0x300 + 0x0004)
#define DSI_PLL_GO DSI_REG(0x300 + 0x0008)
#define DSI_PLL_CONFIGURATION1 DSI_REG(0x300 + 0x000C)
#define DSI_PLL_CONFIGURATION2 DSI_REG(0x300 + 0x0010)
#define DSI_PLL 2
#define DSI_PLL_OFFSET 0x300
#define DSI_PLL_SZ 0x20
#define DSI_PLL_CONTROL DSI_REG(DSI_PLL, 0x0000)
#define DSI_PLL_STATUS DSI_REG(DSI_PLL, 0x0004)
#define DSI_PLL_GO DSI_REG(DSI_PLL, 0x0008)
#define DSI_PLL_CONFIGURATION1 DSI_REG(DSI_PLL, 0x000C)
#define DSI_PLL_CONFIGURATION2 DSI_REG(DSI_PLL, 0x0010)
#define REG_GET(dsidev, idx, start, end) \
FLD_GET(dsi_read_reg(dsidev, idx), start, end)
@ -277,7 +287,9 @@ struct dsi_clk_calc_ctx {
struct dsi_data {
struct platform_device *pdev;
void __iomem *base;
void __iomem *proto_base;
void __iomem *phy_base;
void __iomem *pll_base;
int module_id;
@ -297,7 +309,8 @@ struct dsi_data {
struct {
enum dsi_vc_source source;
struct omap_dss_device *dssdev;
enum fifo_size fifo_size;
enum fifo_size tx_fifo_size;
enum fifo_size rx_fifo_size;
int vc_id;
} vc[4];
@ -413,16 +426,32 @@ static inline void dsi_write_reg(struct platform_device *dsidev,
const struct dsi_reg idx, u32 val)
{
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
void __iomem *base;
__raw_writel(val, dsi->base + idx.idx);
switch(idx.module) {
case DSI_PROTO: base = dsi->proto_base; break;
case DSI_PHY: base = dsi->phy_base; break;
case DSI_PLL: base = dsi->pll_base; break;
default: return;
}
__raw_writel(val, base + idx.idx);
}
static inline u32 dsi_read_reg(struct platform_device *dsidev,
const struct dsi_reg idx)
{
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
void __iomem *base;
return __raw_readl(dsi->base + idx.idx);
switch(idx.module) {
case DSI_PROTO: base = dsi->proto_base; break;
case DSI_PHY: base = dsi->phy_base; break;
case DSI_PLL: base = dsi->pll_base; break;
default: return 0;
}
return __raw_readl(base + idx.idx);
}
static void dsi_bus_lock(struct omap_dss_device *dssdev)
@ -1129,7 +1158,8 @@ static int dsi_regulator_init(struct platform_device *dsidev)
vdds_dsi = devm_regulator_get(&dsi->pdev->dev, "VCXIO");
if (IS_ERR(vdds_dsi)) {
DSSERR("can't get VDDS_DSI regulator\n");
if (PTR_ERR(vdds_dsi) != -EPROBE_DEFER)
DSSERR("can't get VDDS_DSI regulator\n");
return PTR_ERR(vdds_dsi);
}
@ -2427,14 +2457,14 @@ static void dsi_config_tx_fifo(struct platform_device *dsidev,
int add = 0;
int i;
dsi->vc[0].fifo_size = size1;
dsi->vc[1].fifo_size = size2;
dsi->vc[2].fifo_size = size3;
dsi->vc[3].fifo_size = size4;
dsi->vc[0].tx_fifo_size = size1;
dsi->vc[1].tx_fifo_size = size2;
dsi->vc[2].tx_fifo_size = size3;
dsi->vc[3].tx_fifo_size = size4;
for (i = 0; i < 4; i++) {
u8 v;
int size = dsi->vc[i].fifo_size;
int size = dsi->vc[i].tx_fifo_size;
if (add + size > 4) {
DSSERR("Illegal FIFO configuration\n");
@ -2460,14 +2490,14 @@ static void dsi_config_rx_fifo(struct platform_device *dsidev,
int add = 0;
int i;
dsi->vc[0].fifo_size = size1;
dsi->vc[1].fifo_size = size2;
dsi->vc[2].fifo_size = size3;
dsi->vc[3].fifo_size = size4;
dsi->vc[0].rx_fifo_size = size1;
dsi->vc[1].rx_fifo_size = size2;
dsi->vc[2].rx_fifo_size = size3;
dsi->vc[3].rx_fifo_size = size4;
for (i = 0; i < 4; i++) {
u8 v;
int size = dsi->vc[i].fifo_size;
int size = dsi->vc[i].rx_fifo_size;
if (add + size > 4) {
DSSERR("Illegal FIFO configuration\n");
@ -2920,7 +2950,7 @@ static int dsi_vc_send_long(struct platform_device *dsidev, int channel,
DSSDBG("dsi_vc_send_long, %d bytes\n", len);
/* len + header */
if (dsi->vc[channel].fifo_size * 32 * 4 < len + 4) {
if (dsi->vc[channel].tx_fifo_size * 32 * 4 < len + 4) {
DSSERR("unable to send long packet: packet too long.\n");
return -EINVAL;
}
@ -5345,8 +5375,9 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
{
u32 rev;
int r, i;
struct resource *dsi_mem;
struct dsi_data *dsi;
struct resource *res;
struct resource temp_res;
dsi = devm_kzalloc(&dsidev->dev, sizeof(*dsi), GFP_KERNEL);
if (!dsi)
@ -5376,16 +5407,64 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
dsi->te_timer.function = dsi_te_timeout;
dsi->te_timer.data = 0;
#endif
dsi_mem = platform_get_resource(dsi->pdev, IORESOURCE_MEM, 0);
if (!dsi_mem) {
DSSERR("can't get IORESOURCE_MEM DSI\n");
return -EINVAL;
res = platform_get_resource_byname(dsidev, IORESOURCE_MEM, "proto");
if (!res) {
res = platform_get_resource(dsidev, IORESOURCE_MEM, 0);
if (!res) {
DSSERR("can't get IORESOURCE_MEM DSI\n");
return -EINVAL;
}
temp_res.start = res->start;
temp_res.end = temp_res.start + DSI_PROTO_SZ - 1;
res = &temp_res;
}
dsi->base = devm_ioremap(&dsidev->dev, dsi_mem->start,
resource_size(dsi_mem));
if (!dsi->base) {
DSSERR("can't ioremap DSI\n");
dsi->proto_base = devm_ioremap(&dsidev->dev, res->start,
resource_size(res));
if (!dsi->proto_base) {
DSSERR("can't ioremap DSI protocol engine\n");
return -ENOMEM;
}
res = platform_get_resource_byname(dsidev, IORESOURCE_MEM, "phy");
if (!res) {
res = platform_get_resource(dsidev, IORESOURCE_MEM, 0);
if (!res) {
DSSERR("can't get IORESOURCE_MEM DSI\n");
return -EINVAL;
}
temp_res.start = res->start + DSI_PHY_OFFSET;
temp_res.end = temp_res.start + DSI_PHY_SZ - 1;
res = &temp_res;
}
dsi->phy_base = devm_ioremap(&dsidev->dev, res->start,
resource_size(res));
if (!dsi->proto_base) {
DSSERR("can't ioremap DSI PHY\n");
return -ENOMEM;
}
res = platform_get_resource_byname(dsidev, IORESOURCE_MEM, "pll");
if (!res) {
res = platform_get_resource(dsidev, IORESOURCE_MEM, 0);
if (!res) {
DSSERR("can't get IORESOURCE_MEM DSI\n");
return -EINVAL;
}
temp_res.start = res->start + DSI_PLL_OFFSET;
temp_res.end = temp_res.start + DSI_PLL_SZ - 1;
res = &temp_res;
}
dsi->pll_base = devm_ioremap(&dsidev->dev, res->start,
resource_size(res));
if (!dsi->proto_base) {
DSSERR("can't ioremap DSI PLL\n");
return -ENOMEM;
}

View file

@ -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();
if (dss.parent_clk == NULL) {
fck = clk_round_rate(dss.dss_clk, max_dss_fck);
} else {
prate = clk_get_rate(dss.parent_clk);
fck_div = DIV_ROUND_UP(prate * dss.feat->dss_fck_multiplier,
max_dss_fck);
fck_div = DIV_ROUND_UP(prate * dss.feat->dss_fck_multiplier,
max_dss_fck);
fck = prate / fck_div * dss.feat->dss_fck_multiplier;
}
dss_cinfo.fck_div = fck_div;
r = dss_calc_clock_rates(&dss_cinfo);
if (r)
return r;
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,
};

View file

@ -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;

View file

@ -613,6 +613,7 @@ static const enum dss_feat_id omap5_dss_feat_list[] = {
FEAT_DSI_PLL_SELFREQDCO,
FEAT_DSI_PLL_REFSEL,
FEAT_DSI_PHY_DCC,
FEAT_MFLAG,
};
/* OMAP2 DSS Features */

View file

@ -64,6 +64,7 @@ enum dss_feat_id {
FEAT_DSI_PLL_SELFREQDCO,
FEAT_DSI_PLL_REFSEL,
FEAT_DSI_PHY_DCC,
FEAT_MFLAG,
};
/* DSS register field id */

View file

@ -41,14 +41,14 @@
#define HDMI_WP_VIDEO_SIZE 0x60
#define HDMI_WP_VIDEO_TIMING_H 0x68
#define HDMI_WP_VIDEO_TIMING_V 0x6C
#define HDMI_WP_WP_CLK 0x70
#define HDMI_WP_CLK 0x70
#define HDMI_WP_AUDIO_CFG 0x80
#define HDMI_WP_AUDIO_CFG2 0x84
#define HDMI_WP_AUDIO_CTRL 0x88
#define HDMI_WP_AUDIO_DATA 0x8C
/* HDMI WP IRQ flags */
#define HDMI_IRQ_CORE (1 << 0)
#define HDMI_IRQ_OCP_TIMEOUT (1 << 4)
#define HDMI_IRQ_AUDIO_FIFO_UNDERFLOW (1 << 8)
#define HDMI_IRQ_AUDIO_FIFO_OVERFLOW (1 << 9)
@ -378,15 +378,15 @@ static inline u32 hdmi_read_reg(void __iomem *base_addr, const u16 idx)
FLD_GET(hdmi_read_reg(base, idx), start, end)
static inline int hdmi_wait_for_bit_change(void __iomem *base_addr,
const u16 idx, int b2, int b1, u32 val)
const u32 idx, int b2, int b1, u32 val)
{
u32 t = 0;
while (val != REG_GET(base_addr, idx, b2, b1)) {
udelay(1);
u32 t = 0, v;
while (val != (v = REG_GET(base_addr, idx, b2, b1))) {
if (t++ > 10000)
return !val;
return v;
udelay(1);
}
return val;
return v;
}
/* HDMI wrapper funcs */

View file

@ -95,7 +95,8 @@ static int hdmi_init_regulator(void)
reg = devm_regulator_get(&hdmi.pdev->dev, "VDAC");
if (IS_ERR(reg)) {
DSSERR("can't get VDDA_HDMI_DAC regulator\n");
if (PTR_ERR(reg) != -EPROBE_DEFER)
DSSERR("can't get VDDA_HDMI_DAC regulator\n");
return PTR_ERR(reg);
}
@ -148,8 +149,6 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
if (r)
return r;
dss_mgr_disable(mgr);
p = &hdmi.cfg.timings;
DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);
@ -158,8 +157,6 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
hdmi_pll_compute(&hdmi.pll, clk_get_rate(hdmi.sys_clk), phy);
hdmi_wp_video_stop(&hdmi.wp);
/* config the PLL and PHY hdmi_set_pll_pwrfirst */
r = hdmi_pll_enable(&hdmi.pll, &hdmi.wp);
if (r) {
@ -218,14 +215,12 @@ static void hdmi_power_off_full(struct omap_dss_device *dssdev)
static int hdmi_display_check_timing(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
struct hdmi_cm cm;
struct omap_dss_device *out = &hdmi.output;
cm = hdmi_get_code(timings);
if (cm.code == -1)
if (!dispc_mgr_timings_ok(out->dispc_channel, timings))
return -EINVAL;
return 0;
}
static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
@ -244,8 +239,17 @@ static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
hdmi.cfg = *t;
dispc_set_tv_pclk(t->timings.pixel_clock * 1000);
} else {
hdmi.cfg.timings = *timings;
hdmi.cfg.cm.code = 0;
hdmi.cfg.cm.mode = HDMI_DVI;
dispc_set_tv_pclk(timings->pixel_clock * 1000);
}
DSSDBG("using mode: %s, code %d\n", hdmi.cfg.cm.mode == HDMI_DVI ?
"DVI" : "HDMI", hdmi.cfg.cm.code);
mutex_unlock(&hdmi.lock);
}

View file

@ -19,6 +19,8 @@
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define DSS_SUBSYS_NAME "HDMICORE"
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/err.h>
@ -125,12 +127,12 @@ static int hdmi_core_ddc_edid(struct hdmi_core_data *core,
/* HDMI_CORE_DDC_STATUS_BUS_LOW */
if (REG_GET(base, HDMI_CORE_DDC_STATUS, 6, 6) == 1) {
pr_err("I2C Bus Low?\n");
DSSERR("I2C Bus Low?\n");
return -EIO;
}
/* HDMI_CORE_DDC_STATUS_NO_ACK */
if (REG_GET(base, HDMI_CORE_DDC_STATUS, 5, 5) == 1) {
pr_err("I2C No Ack\n");
DSSERR("I2C No Ack\n");
return -EIO;
}
@ -161,7 +163,7 @@ static int hdmi_core_ddc_edid(struct hdmi_core_data *core,
checksum += pedid[i];
if (checksum != 0) {
pr_err("E-EDID checksum failed!!\n");
DSSERR("E-EDID checksum failed!!\n");
return -EIO;
}
@ -199,7 +201,7 @@ static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
struct hdmi_core_infoframe_avi *avi_cfg,
struct hdmi_core_packet_enable_repeat *repeat_cfg)
{
pr_debug("Enter hdmi_core_init\n");
DSSDBG("Enter hdmi_core_init\n");
/* video core */
video_cfg->ip_bus_width = HDMI_INPUT_8BIT;
@ -241,19 +243,19 @@ static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
static void hdmi_core_powerdown_disable(struct hdmi_core_data *core)
{
pr_debug("Enter hdmi_core_powerdown_disable\n");
DSSDBG("Enter hdmi_core_powerdown_disable\n");
REG_FLD_MOD(core->base, HDMI_CORE_SYS_SYS_CTRL1, 0x0, 0, 0);
}
static void hdmi_core_swreset_release(struct hdmi_core_data *core)
{
pr_debug("Enter hdmi_core_swreset_release\n");
DSSDBG("Enter hdmi_core_swreset_release\n");
REG_FLD_MOD(core->base, HDMI_CORE_SYS_SRST, 0x0, 0, 0);
}
static void hdmi_core_swreset_assert(struct hdmi_core_data *core)
{
pr_debug("Enter hdmi_core_swreset_assert\n");
DSSDBG("Enter hdmi_core_swreset_assert\n");
REG_FLD_MOD(core->base, HDMI_CORE_SYS_SRST, 0x1, 0, 0);
}
@ -1004,7 +1006,7 @@ int hdmi4_core_init(struct platform_device *pdev, struct hdmi_core_data *core)
struct resource *res;
struct resource temp_res;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi_core");
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core");
if (!res) {
DSSDBG("can't get CORE mem resource by name\n");
/*

View file

@ -13,6 +13,8 @@
* map it to corresponding CEA or VESA index.
*/
#define DSS_SUBSYS_NAME "HDMI"
#include <linux/kernel.h>
#include <linux/err.h>
#include <video/omapdss.h>

View file

@ -124,7 +124,7 @@ int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy)
struct resource *res;
struct resource temp_res;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi_txphy");
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy");
if (!res) {
DSSDBG("can't get PHY mem resource by name\n");
/*

View file

@ -8,6 +8,8 @@
* the Free Software Foundation.
*/
#define DSS_SUBSYS_NAME "HDMIPLL"
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/err.h>
@ -127,24 +129,24 @@ static int hdmi_pll_config(struct hdmi_pll_data *pll)
/* wait for bit change */
if (hdmi_wait_for_bit_change(pll->base, PLLCTRL_PLL_GO,
0, 0, 1) != 1) {
pr_err("PLL GO bit not set\n");
DSSERR("PLL GO bit not set\n");
return -ETIMEDOUT;
}
/* Wait till the lock bit is set in PLL status */
if (hdmi_wait_for_bit_change(pll->base,
PLLCTRL_PLL_STATUS, 1, 1, 1) != 1) {
pr_err("cannot lock PLL\n");
pr_err("CFG1 0x%x\n",
DSSERR("cannot lock PLL\n");
DSSERR("CFG1 0x%x\n",
hdmi_read_reg(pll->base, PLLCTRL_CFG1));
pr_err("CFG2 0x%x\n",
DSSERR("CFG2 0x%x\n",
hdmi_read_reg(pll->base, PLLCTRL_CFG2));
pr_err("CFG4 0x%x\n",
DSSERR("CFG4 0x%x\n",
hdmi_read_reg(pll->base, PLLCTRL_CFG4));
return -ETIMEDOUT;
}
pr_debug("PLL locked!\n");
DSSDBG("PLL locked!\n");
return 0;
}
@ -157,7 +159,7 @@ static int hdmi_pll_reset(struct hdmi_pll_data *pll)
/* READ 0x0 reset is in progress */
if (hdmi_wait_for_bit_change(pll->base, PLLCTRL_PLL_STATUS, 0, 0, 1)
!= 1) {
pr_err("Failed to sysreset PLL\n");
DSSERR("Failed to sysreset PLL\n");
return -ETIMEDOUT;
}
@ -200,7 +202,7 @@ int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll)
struct resource *res;
struct resource temp_res;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi_pllctrl");
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll");
if (!res) {
DSSDBG("can't get PLL mem resource by name\n");
/*

View file

@ -8,6 +8,8 @@
* the Free Software Foundation.
*/
#define DSS_SUBSYS_NAME "HDMIWP"
#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/io.h>
@ -34,7 +36,7 @@ void hdmi_wp_dump(struct hdmi_wp_data *wp, struct seq_file *s)
DUMPREG(HDMI_WP_VIDEO_SIZE);
DUMPREG(HDMI_WP_VIDEO_TIMING_H);
DUMPREG(HDMI_WP_VIDEO_TIMING_V);
DUMPREG(HDMI_WP_WP_CLK);
DUMPREG(HDMI_WP_CLK);
DUMPREG(HDMI_WP_AUDIO_CFG);
DUMPREG(HDMI_WP_AUDIO_CFG2);
DUMPREG(HDMI_WP_AUDIO_CTRL);
@ -76,7 +78,7 @@ int hdmi_wp_set_phy_pwr(struct hdmi_wp_data *wp, enum hdmi_phy_pwr val)
/* Status of the power control of HDMI PHY */
if (hdmi_wait_for_bit_change(wp->base, HDMI_WP_PWR_CTRL, 5, 4, val)
!= val) {
pr_err("Failed to set PHY power mode to %d\n", val);
DSSERR("Failed to set PHY power mode to %d\n", val);
return -ETIMEDOUT;
}
@ -92,7 +94,7 @@ int hdmi_wp_set_pll_pwr(struct hdmi_wp_data *wp, enum hdmi_pll_pwr val)
/* wait till PHY_PWR_STATUS is set */
if (hdmi_wait_for_bit_change(wp->base, HDMI_WP_PWR_CTRL, 1, 0, val)
!= val) {
pr_err("Failed to set PLL_PWR_STATUS\n");
DSSERR("Failed to set PLL_PWR_STATUS\n");
return -ETIMEDOUT;
}
@ -129,7 +131,7 @@ void hdmi_wp_video_config_interface(struct hdmi_wp_data *wp,
{
u32 r;
bool vsync_pol, hsync_pol;
pr_debug("Enter hdmi_wp_video_config_interface\n");
DSSDBG("Enter hdmi_wp_video_config_interface\n");
vsync_pol = timings->vsync_level == OMAPDSS_SIG_ACTIVE_HIGH;
hsync_pol = timings->hsync_level == OMAPDSS_SIG_ACTIVE_HIGH;
@ -148,7 +150,7 @@ void hdmi_wp_video_config_timing(struct hdmi_wp_data *wp,
u32 timing_h = 0;
u32 timing_v = 0;
pr_debug("Enter hdmi_wp_video_config_timing\n");
DSSDBG("Enter hdmi_wp_video_config_timing\n");
timing_h |= FLD_VAL(timings->hbp, 31, 20);
timing_h |= FLD_VAL(timings->hfp, 19, 8);
@ -164,7 +166,7 @@ void hdmi_wp_video_config_timing(struct hdmi_wp_data *wp,
void hdmi_wp_init_vid_fmt_timings(struct hdmi_video_format *video_fmt,
struct omap_video_timings *timings, struct hdmi_config *param)
{
pr_debug("Enter hdmi_wp_video_init_format\n");
DSSDBG("Enter hdmi_wp_video_init_format\n");
video_fmt->packing_mode = HDMI_PACK_10b_RGB_YUV444;
video_fmt->y_res = param->timings.y_res;
@ -241,7 +243,7 @@ int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp)
struct resource *res;
struct resource temp_res;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi_wp");
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "wp");
if (!res) {
DSSDBG("can't get WP mem resource by name\n");
/*

View file

@ -113,11 +113,6 @@ void dss_uninit_overlays(struct platform_device *pdev)
int dss_ovl_simple_check(struct omap_overlay *ovl,
const struct omap_overlay_info *info)
{
if (info->paddr == 0) {
DSSERR("check_overlay: paddr cannot be 0\n");
return -EINVAL;
}
if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) {
if (info->out_width != 0 && info->width != info->out_width) {
DSSERR("check_overlay: overlay %d doesn't support "

View file

@ -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;
@ -265,7 +264,8 @@ static int sdi_init_regulator(void)
vdds_sdi = devm_regulator_get(&sdi.pdev->dev, "vdds_sdi");
if (IS_ERR(vdds_sdi)) {
DSSERR("can't get VDDS_SDI regulator\n");
if (PTR_ERR(vdds_sdi) != -EPROBE_DEFER)
DSSERR("can't get VDDS_SDI regulator\n");
return PTR_ERR(vdds_sdi);
}

View file

@ -639,7 +639,8 @@ static int venc_init_regulator(void)
vdda_dac = devm_regulator_get(&venc.pdev->dev, "vdda_dac");
if (IS_ERR(vdda_dac)) {
DSSERR("can't get VDDA_DAC regulator\n");
if (PTR_ERR(vdda_dac) != -EPROBE_DEFER)
DSSERR("can't get VDDA_DAC regulator\n");
return PTR_ERR(vdda_dac);
}

View file

@ -1833,6 +1833,16 @@ static void omapfb_free_resources(struct omapfb2_device *fbdev)
if (fbdev == NULL)
return;
for (i = 0; i < fbdev->num_fbs; i++) {
struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[i]);
int j;
for (j = 0; j < ofbi->num_overlays; j++) {
struct omap_overlay *ovl = ofbi->overlays[j];
ovl->disable(ovl);
}
}
for (i = 0; i < fbdev->num_fbs; i++)
unregister_framebuffer(fbdev->fbs[i]);
@ -2557,6 +2567,15 @@ static int omapfb_probe(struct platform_device *pdev)
goto cleanup;
}
if (def_display) {
u16 w, h;
def_display->driver->get_resolution(def_display, &w, &h);
dev_info(fbdev->dev, "using display '%s' mode %dx%d\n",
def_display->name, w, h);
}
return 0;
cleanup:

View file

@ -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();
}

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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);
}

View file

@ -1,9 +1,5 @@
/*
* arch/arm/mach-ep93xx/include/mach/fb.h
*/
#ifndef __ASM_ARCH_EP93XXFB_H
#define __ASM_ARCH_EP93XXFB_H
#ifndef __VIDEO_EP93XX_H
#define __VIDEO_EP93XX_H
struct platform_device;
struct fb_videomode;
@ -53,4 +49,4 @@ struct ep93xxfb_mach_info {
void (*blank)(int blank_mode, struct fb_info *info);
};
#endif /* __ASM_ARCH_EP93XXFB_H */
#endif /* __VIDEO_EP93XX_H */

View file

@ -1,5 +1,4 @@
/* arch/arm/mach-msm/include/mach/msm_fb.h
*
/*
* Internal shared definitions for various MSM framebuffer parts.
*
* Copyright (C) 2007 Google Incorporated

View file

@ -1,6 +1,4 @@
/*
* arch/arm/mach-pxa/include/mach/pxafb.h
*
* Support for the xscale frame buffer.
*
* Author: Jean-Frederic Clere

View file

@ -1,6 +1,4 @@
/*
* linux/arch/arm/mach-mmp/include/mach/pxa168fb.h
*
* Copyright (C) 2009 Marvell International Ltd.
*
* This program is free software; you can redistribute it and/or modify