mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 10:41:38 -04:00
Merge branch 'fbdev-next' of git://github.com/schandinat/linux-2.6
* 'fbdev-next' of git://github.com/schandinat/linux-2.6: (270 commits)
video: platinumfb: Add __devexit_p at necessary place
drivers/video: fsl-diu-fb: merge diu_pool into fsl_diu_data
drivers/video: fsl-diu-fb: merge diu_hw into fsl_diu_data
drivers/video: fsl-diu-fb: only DIU modes 0 and 1 are supported
drivers/video: fsl-diu-fb: remove unused panel operating mode support
drivers/video: fsl-diu-fb: use an enum for the AOI index
drivers/video: fsl-diu-fb: add several new video modes
drivers/video: fsl-diu-fb: remove broken screen blanking support
drivers/video: fsl-diu-fb: move some definitions out of the header file
drivers/video: fsl-diu-fb: fix some ioctls
video: da8xx-fb: Increased resolution configuration of revised LCDC IP
OMAPDSS: picodlp: add missing #include <linux/module.h>
fb: fix au1100fb bitrot.
mx3fb: fix NULL pointer dereference in screen blanking.
video: irq: Remove IRQF_DISABLED
smscufx: change edid data to u8 instead of char
OMAPDSS: DISPC: zorder support for DSS overlays
OMAPDSS: DISPC: VIDEO3 pipeline support
OMAPDSS/OMAP_VOUT: Fix incorrect OMAP3-alpha compatibility setting
video/omap: fix build dependencies
...
Fix up conflicts in:
- drivers/staging/xgifb/XGI_main_26.c
Changes to XGIfb_pan_var()
- drivers/video/omap/{lcd_apollon.c,lcd_ldp.c,lcd_overo.c}
Removed (or in the case of apollon.c, merged into the generic
DSS panel in drivers/video/omap2/displays/panel-generic-dpi.c)
This commit is contained in:
commit
acff987d94
163 changed files with 12023 additions and 7620 deletions
|
|
@ -378,8 +378,8 @@ static int mc68x328fb_pan_display(struct fb_var_screeninfo *var,
|
|||
|| var->xoffset)
|
||||
return -EINVAL;
|
||||
} else {
|
||||
if (var->xoffset + var->xres > info->var.xres_virtual ||
|
||||
var->yoffset + var->yres > info->var.yres_virtual)
|
||||
if (var->xoffset + info->var.xres > info->var.xres_virtual ||
|
||||
var->yoffset + info->var.yres > info->var.yres_virtual)
|
||||
return -EINVAL;
|
||||
}
|
||||
info->var.xoffset = var->xoffset;
|
||||
|
|
|
|||
|
|
@ -259,6 +259,15 @@ config FB_TILEBLITTING
|
|||
comment "Frame buffer hardware drivers"
|
||||
depends on FB
|
||||
|
||||
config FB_GRVGA
|
||||
tristate "Aeroflex Gaisler framebuffer support"
|
||||
depends on FB && SPARC
|
||||
select FB_CFB_FILLRECT
|
||||
select FB_CFB_COPYAREA
|
||||
select FB_CFB_IMAGEBLIT
|
||||
---help---
|
||||
This enables support for the SVGACTRL framebuffer in the GRLIB IP library from Aeroflex Gaisler.
|
||||
|
||||
config FB_CIRRUS
|
||||
tristate "Cirrus Logic support"
|
||||
depends on FB && (ZORRO || PCI)
|
||||
|
|
@ -1756,9 +1765,10 @@ config FB_AU1100
|
|||
config FB_AU1200
|
||||
bool "Au1200 LCD Driver"
|
||||
depends on (FB = y) && MIPS && SOC_AU1200
|
||||
select FB_CFB_FILLRECT
|
||||
select FB_CFB_COPYAREA
|
||||
select FB_CFB_IMAGEBLIT
|
||||
select FB_SYS_FILLRECT
|
||||
select FB_SYS_COPYAREA
|
||||
select FB_SYS_IMAGEBLIT
|
||||
select FB_SYS_FOPS
|
||||
help
|
||||
This is the framebuffer driver for the AMD Au1200 SOC. It can drive
|
||||
various panels and CRTs by passing in kernel cmd line option
|
||||
|
|
@ -2027,7 +2037,7 @@ config FB_TMIO_ACCELL
|
|||
|
||||
config FB_S3C
|
||||
tristate "Samsung S3C framebuffer support"
|
||||
depends on FB && S3C_DEV_FB
|
||||
depends on FB && (S3C_DEV_FB || S5P_DEV_FIMD0)
|
||||
select FB_CFB_FILLRECT
|
||||
select FB_CFB_COPYAREA
|
||||
select FB_CFB_IMAGEBLIT
|
||||
|
|
@ -2110,6 +2120,22 @@ config FB_SM501
|
|||
|
||||
If unsure, say N.
|
||||
|
||||
config FB_SMSCUFX
|
||||
tristate "SMSC UFX6000/7000 USB Framebuffer support"
|
||||
depends on FB && USB
|
||||
select FB_MODE_HELPERS
|
||||
select FB_SYS_FILLRECT
|
||||
select FB_SYS_COPYAREA
|
||||
select FB_SYS_IMAGEBLIT
|
||||
select FB_SYS_FOPS
|
||||
select FB_DEFERRED_IO
|
||||
---help---
|
||||
This is a kernel framebuffer driver for SMSC UFX USB devices.
|
||||
Supports fbdev clients like xf86-video-fbdev, kdrive, fbi, and
|
||||
mplayer -vo fbdev. Supports both UFX6000 (USB 2.0) and UFX7000
|
||||
(USB 3.0) devices.
|
||||
To compile as a module, choose M here: the module name is smscufx.
|
||||
|
||||
config FB_UDL
|
||||
tristate "Displaylink USB Framebuffer support"
|
||||
depends on FB && USB
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ obj-$(CONFIG_FB_AMIGA) += amifb.o c2p_planar.o
|
|||
obj-$(CONFIG_FB_ARC) += arcfb.o
|
||||
obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o
|
||||
obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o
|
||||
obj-$(CONFIG_FB_GRVGA) += grvga.o
|
||||
obj-$(CONFIG_FB_PM2) += pm2fb.o
|
||||
obj-$(CONFIG_FB_PM3) += pm3fb.o
|
||||
|
||||
|
|
@ -127,6 +128,7 @@ obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o
|
|||
obj-$(CONFIG_FB_PS3) += ps3fb.o
|
||||
obj-$(CONFIG_FB_SM501) += sm501fb.o
|
||||
obj-$(CONFIG_FB_UDL) += udlfb.o
|
||||
obj-$(CONFIG_FB_SMSCUFX) += smscufx.o
|
||||
obj-$(CONFIG_FB_XILINX) += xilinxfb.o
|
||||
obj-$(CONFIG_SH_MIPI_DSI) += sh_mipi_dsi.o
|
||||
obj-$(CONFIG_FB_SH_MOBILE_HDMI) += sh_mobile_hdmi.o
|
||||
|
|
|
|||
|
|
@ -850,9 +850,10 @@ acornfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
|
|||
u_int y_bottom = var->yoffset;
|
||||
|
||||
if (!(var->vmode & FB_VMODE_YWRAP))
|
||||
y_bottom += var->yres;
|
||||
y_bottom += info->var.yres;
|
||||
|
||||
BUG_ON(y_bottom > var->yres_virtual);
|
||||
if (y_bottom > info->var.yres_virtual)
|
||||
return -EINVAL;
|
||||
|
||||
acornfb_update_dma(info, var);
|
||||
|
||||
|
|
|
|||
|
|
@ -908,13 +908,14 @@ static int arkfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info
|
|||
unsigned int offset;
|
||||
|
||||
/* Calculate the offset */
|
||||
if (var->bits_per_pixel == 0) {
|
||||
offset = (var->yoffset / 16) * (var->xres_virtual / 2) + (var->xoffset / 2);
|
||||
if (info->var.bits_per_pixel == 0) {
|
||||
offset = (var->yoffset / 16) * (info->var.xres_virtual / 2)
|
||||
+ (var->xoffset / 2);
|
||||
offset = offset >> 2;
|
||||
} else {
|
||||
offset = (var->yoffset * info->fix.line_length) +
|
||||
(var->xoffset * var->bits_per_pixel / 8);
|
||||
offset = offset >> ((var->bits_per_pixel == 4) ? 2 : 3);
|
||||
(var->xoffset * info->var.bits_per_pixel / 8);
|
||||
offset = offset >> ((info->var.bits_per_pixel == 4) ? 2 : 3);
|
||||
}
|
||||
|
||||
/* Set the offset */
|
||||
|
|
|
|||
|
|
@ -39,7 +39,8 @@
|
|||
| FBINFO_HWACCEL_YPAN)
|
||||
|
||||
static inline void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo,
|
||||
struct fb_var_screeninfo *var)
|
||||
struct fb_var_screeninfo *var,
|
||||
struct fb_info *info)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -50,14 +51,16 @@ static inline void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo,
|
|||
| FBINFO_HWACCEL_YPAN)
|
||||
|
||||
static void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo,
|
||||
struct fb_var_screeninfo *var)
|
||||
struct fb_var_screeninfo *var,
|
||||
struct fb_info *info)
|
||||
{
|
||||
u32 dma2dcfg;
|
||||
u32 pixeloff;
|
||||
|
||||
pixeloff = (var->xoffset * var->bits_per_pixel) & 0x1f;
|
||||
pixeloff = (var->xoffset * info->var.bits_per_pixel) & 0x1f;
|
||||
|
||||
dma2dcfg = ((var->xres_virtual - var->xres) * var->bits_per_pixel) / 8;
|
||||
dma2dcfg = (info->var.xres_virtual - info->var.xres)
|
||||
* info->var.bits_per_pixel / 8;
|
||||
dma2dcfg |= pixeloff << ATMEL_LCDC_PIXELOFF_OFFSET;
|
||||
lcdc_writel(sinfo, ATMEL_LCDC_DMA2DCFG, dma2dcfg);
|
||||
|
||||
|
|
@ -249,14 +252,14 @@ static void atmel_lcdfb_update_dma(struct fb_info *info,
|
|||
unsigned long dma_addr;
|
||||
|
||||
dma_addr = (fix->smem_start + var->yoffset * fix->line_length
|
||||
+ var->xoffset * var->bits_per_pixel / 8);
|
||||
+ var->xoffset * info->var.bits_per_pixel / 8);
|
||||
|
||||
dma_addr &= ~3UL;
|
||||
|
||||
/* Set framebuffer DMA base address and pixel offset */
|
||||
lcdc_writel(sinfo, ATMEL_LCDC_DMABADDR1, dma_addr);
|
||||
|
||||
atmel_lcdfb_update_dma2d(sinfo, var);
|
||||
atmel_lcdfb_update_dma2d(sinfo, var, info);
|
||||
}
|
||||
|
||||
static inline void atmel_lcdfb_free_video_memory(struct atmel_lcdfb_info *sinfo)
|
||||
|
|
|
|||
|
|
@ -845,16 +845,16 @@ static int radeonfb_pan_display (struct fb_var_screeninfo *var,
|
|||
{
|
||||
struct radeonfb_info *rinfo = info->par;
|
||||
|
||||
if ((var->xoffset + var->xres > var->xres_virtual)
|
||||
|| (var->yoffset + var->yres > var->yres_virtual))
|
||||
return -EINVAL;
|
||||
if ((var->xoffset + info->var.xres > info->var.xres_virtual)
|
||||
|| (var->yoffset + info->var.yres > info->var.yres_virtual))
|
||||
return -EINVAL;
|
||||
|
||||
if (rinfo->asleep)
|
||||
return 0;
|
||||
|
||||
radeon_fifo_wait(2);
|
||||
OUTREG(CRTC_OFFSET, ((var->yoffset * var->xres_virtual + var->xoffset)
|
||||
* var->bits_per_pixel / 8) & ~7);
|
||||
OUTREG(CRTC_OFFSET, (var->yoffset * info->fix.line_length +
|
||||
var->xoffset * info->var.bits_per_pixel / 8) & ~7);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -110,12 +110,6 @@ static struct fb_var_screeninfo au1100fb_var __devinitdata = {
|
|||
.vmode = FB_VMODE_NONINTERLACED,
|
||||
};
|
||||
|
||||
static struct au1100fb_drv_info drv_info;
|
||||
|
||||
static int nocursor = 0;
|
||||
module_param(nocursor, int, 0644);
|
||||
MODULE_PARM_DESC(nocursor, "cursor enable/disable");
|
||||
|
||||
/* fb_blank
|
||||
* Blank the screen. Depending on the mode, the screen will be
|
||||
* activated with the backlight color, or desactivated
|
||||
|
|
@ -132,7 +126,7 @@ static int au1100fb_fb_blank(int blank_mode, struct fb_info *fbi)
|
|||
/* Turn on panel */
|
||||
fbdev->regs->lcd_control |= LCD_CONTROL_GO;
|
||||
#ifdef CONFIG_MIPS_PB1100
|
||||
if (drv_info.panel_idx == 1) {
|
||||
if (fbdev->panel_idx == 1) {
|
||||
au_writew(au_readw(PB1100_G_CONTROL)
|
||||
| (PB1100_G_CONTROL_BL | PB1100_G_CONTROL_VDD),
|
||||
PB1100_G_CONTROL);
|
||||
|
|
@ -147,7 +141,7 @@ static int au1100fb_fb_blank(int blank_mode, struct fb_info *fbi)
|
|||
/* Turn off panel */
|
||||
fbdev->regs->lcd_control &= ~LCD_CONTROL_GO;
|
||||
#ifdef CONFIG_MIPS_PB1100
|
||||
if (drv_info.panel_idx == 1) {
|
||||
if (fbdev->panel_idx == 1) {
|
||||
au_writew(au_readw(PB1100_G_CONTROL)
|
||||
& ~(PB1100_G_CONTROL_BL | PB1100_G_CONTROL_VDD),
|
||||
PB1100_G_CONTROL);
|
||||
|
|
@ -428,17 +422,6 @@ int au1100fb_fb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* fb_cursor
|
||||
* Used to disable cursor drawing...
|
||||
*/
|
||||
int au1100fb_fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
|
||||
{
|
||||
if (nocursor)
|
||||
return 0;
|
||||
else
|
||||
return -EINVAL; /* just to force soft_cursor() call */
|
||||
}
|
||||
|
||||
static struct fb_ops au1100fb_ops =
|
||||
{
|
||||
.owner = THIS_MODULE,
|
||||
|
|
@ -450,13 +433,53 @@ static struct fb_ops au1100fb_ops =
|
|||
.fb_imageblit = cfb_imageblit,
|
||||
.fb_rotate = au1100fb_fb_rotate,
|
||||
.fb_mmap = au1100fb_fb_mmap,
|
||||
.fb_cursor = au1100fb_fb_cursor,
|
||||
};
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* AU1100 LCD controller device driver */
|
||||
static int au1100fb_setup(struct au1100fb_device *fbdev)
|
||||
{
|
||||
char *this_opt, *options;
|
||||
int num_panels = ARRAY_SIZE(known_lcd_panels);
|
||||
|
||||
if (num_panels <= 0) {
|
||||
print_err("No LCD panels supported by driver!");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (fb_get_options(DRIVER_NAME, &options))
|
||||
return -ENODEV;
|
||||
if (!options)
|
||||
return -ENODEV;
|
||||
|
||||
while ((this_opt = strsep(&options, ",")) != NULL) {
|
||||
/* Panel option */
|
||||
if (!strncmp(this_opt, "panel:", 6)) {
|
||||
int i;
|
||||
this_opt += 6;
|
||||
for (i = 0; i < num_panels; i++) {
|
||||
if (!strncmp(this_opt, known_lcd_panels[i].name,
|
||||
strlen(this_opt))) {
|
||||
fbdev->panel = &known_lcd_panels[i];
|
||||
fbdev->panel_idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i >= num_panels) {
|
||||
print_warn("Panel '%s' not supported!", this_opt);
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
/* Unsupported option */
|
||||
else
|
||||
print_warn("Unsupported option \"%s\"", this_opt);
|
||||
}
|
||||
|
||||
print_info("Panel=%s", fbdev->panel->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit au1100fb_drv_probe(struct platform_device *dev)
|
||||
{
|
||||
|
|
@ -465,22 +488,21 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev)
|
|||
unsigned long page;
|
||||
u32 sys_clksrc;
|
||||
|
||||
if (!dev)
|
||||
return -EINVAL;
|
||||
|
||||
/* Allocate new device private */
|
||||
if (!(fbdev = kzalloc(sizeof(struct au1100fb_device), GFP_KERNEL))) {
|
||||
fbdev = kzalloc(sizeof(struct au1100fb_device), GFP_KERNEL);
|
||||
if (!fbdev) {
|
||||
print_err("fail to allocate device private record");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
fbdev->panel = &known_lcd_panels[drv_info.panel_idx];
|
||||
if (au1100fb_setup(fbdev))
|
||||
goto failed;
|
||||
|
||||
platform_set_drvdata(dev, (void *)fbdev);
|
||||
|
||||
/* Allocate region for our registers and map them */
|
||||
if (!(regs_res = platform_get_resource(to_platform_device(dev),
|
||||
IORESOURCE_MEM, 0))) {
|
||||
regs_res = platform_get_resource(dev, IORESOURCE_MEM, 0);
|
||||
if (!regs_res) {
|
||||
print_err("fail to retrieve registers resource");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
|
@ -500,13 +522,11 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev)
|
|||
print_dbg("Register memory map at %p", fbdev->regs);
|
||||
print_dbg("phys=0x%08x, size=%d", fbdev->regs_phys, fbdev->regs_len);
|
||||
|
||||
|
||||
|
||||
/* Allocate the framebuffer to the maximum screen size * nbr of video buffers */
|
||||
fbdev->fb_len = fbdev->panel->xres * fbdev->panel->yres *
|
||||
(fbdev->panel->bpp >> 3) * AU1100FB_NBR_VIDEO_BUFFERS;
|
||||
|
||||
fbdev->fb_mem = dma_alloc_coherent(dev, PAGE_ALIGN(fbdev->fb_len),
|
||||
fbdev->fb_mem = dma_alloc_coherent(&dev->dev, PAGE_ALIGN(fbdev->fb_len),
|
||||
&fbdev->fb_phys, GFP_KERNEL);
|
||||
if (!fbdev->fb_mem) {
|
||||
print_err("fail to allocate frambuffer (size: %dK))",
|
||||
|
|
@ -525,7 +545,7 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev)
|
|||
page < PAGE_ALIGN((unsigned long)fbdev->fb_mem + fbdev->fb_len);
|
||||
page += PAGE_SIZE) {
|
||||
#if CONFIG_DMA_NONCOHERENT
|
||||
SetPageReserved(virt_to_page(CAC_ADDR(page)));
|
||||
SetPageReserved(virt_to_page(CAC_ADDR((void *)page)));
|
||||
#else
|
||||
SetPageReserved(virt_to_page(page));
|
||||
#endif
|
||||
|
|
@ -578,7 +598,8 @@ failed:
|
|||
release_mem_region(fbdev->regs_phys, fbdev->regs_len);
|
||||
}
|
||||
if (fbdev->fb_mem) {
|
||||
dma_free_noncoherent(dev, fbdev->fb_len, fbdev->fb_mem, fbdev->fb_phys);
|
||||
dma_free_noncoherent(&dev->dev, fbdev->fb_len, fbdev->fb_mem,
|
||||
fbdev->fb_phys);
|
||||
}
|
||||
if (fbdev->info.cmap.len != 0) {
|
||||
fb_dealloc_cmap(&fbdev->info.cmap);
|
||||
|
|
@ -608,7 +629,8 @@ int au1100fb_drv_remove(struct platform_device *dev)
|
|||
|
||||
release_mem_region(fbdev->regs_phys, fbdev->regs_len);
|
||||
|
||||
dma_free_coherent(dev, PAGE_ALIGN(fbdev->fb_len), fbdev->fb_mem, fbdev->fb_phys);
|
||||
dma_free_coherent(&dev->dev, PAGE_ALIGN(fbdev->fb_len), fbdev->fb_mem,
|
||||
fbdev->fb_phys);
|
||||
|
||||
fb_dealloc_cmap(&fbdev->info.cmap);
|
||||
kfree(fbdev->info.pseudo_palette);
|
||||
|
|
@ -675,101 +697,18 @@ static struct platform_driver au1100fb_driver = {
|
|||
.resume = au1100fb_drv_resume,
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* Kernel driver */
|
||||
|
||||
int au1100fb_setup(char *options)
|
||||
static int __init au1100fb_load(void)
|
||||
{
|
||||
char* this_opt;
|
||||
int num_panels = ARRAY_SIZE(known_lcd_panels);
|
||||
char* mode = NULL;
|
||||
int panel_idx = 0;
|
||||
|
||||
if (num_panels <= 0) {
|
||||
print_err("No LCD panels supported by driver!");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (options) {
|
||||
while ((this_opt = strsep(&options,",")) != NULL) {
|
||||
/* Panel option */
|
||||
if (!strncmp(this_opt, "panel:", 6)) {
|
||||
int i;
|
||||
this_opt += 6;
|
||||
for (i = 0; i < num_panels; i++) {
|
||||
if (!strncmp(this_opt,
|
||||
known_lcd_panels[i].name,
|
||||
strlen(this_opt))) {
|
||||
panel_idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i >= num_panels) {
|
||||
print_warn("Panel %s not supported!", this_opt);
|
||||
}
|
||||
}
|
||||
if (!strncmp(this_opt, "nocursor", 8)) {
|
||||
this_opt += 8;
|
||||
nocursor = 1;
|
||||
print_info("Cursor disabled");
|
||||
}
|
||||
/* Mode option (only option that start with digit) */
|
||||
else if (isdigit(this_opt[0])) {
|
||||
mode = kstrdup(this_opt, GFP_KERNEL);
|
||||
if (!mode) {
|
||||
print_err("memory allocation failed");
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
/* Unsupported option */
|
||||
else {
|
||||
print_warn("Unsupported option \"%s\"", this_opt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
drv_info.panel_idx = panel_idx;
|
||||
drv_info.opt_mode = mode;
|
||||
|
||||
print_info("Panel=%s Mode=%s",
|
||||
known_lcd_panels[drv_info.panel_idx].name,
|
||||
drv_info.opt_mode ? drv_info.opt_mode : "default");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __init au1100fb_init(void)
|
||||
{
|
||||
char* options;
|
||||
int ret;
|
||||
|
||||
print_info("" DRIVER_DESC "");
|
||||
|
||||
memset(&drv_info, 0, sizeof(drv_info));
|
||||
|
||||
if (fb_get_options(DRIVER_NAME, &options))
|
||||
return -ENODEV;
|
||||
|
||||
/* Setup driver with options */
|
||||
ret = au1100fb_setup(options);
|
||||
if (ret < 0) {
|
||||
print_err("Fail to setup driver");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return platform_driver_register(&au1100fb_driver);
|
||||
}
|
||||
|
||||
void __exit au1100fb_cleanup(void)
|
||||
static void __exit au1100fb_unload(void)
|
||||
{
|
||||
platform_driver_unregister(&au1100fb_driver);
|
||||
|
||||
kfree(drv_info.opt_mode);
|
||||
}
|
||||
|
||||
module_init(au1100fb_init);
|
||||
module_exit(au1100fb_cleanup);
|
||||
module_init(au1100fb_load);
|
||||
module_exit(au1100fb_unload);
|
||||
|
||||
MODULE_DESCRIPTION(DRIVER_DESC);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ struct au1100fb_device {
|
|||
unsigned char* fb_mem; /* FrameBuffer memory map */
|
||||
size_t fb_len;
|
||||
dma_addr_t fb_phys;
|
||||
int panel_idx;
|
||||
};
|
||||
|
||||
/********************************************************************/
|
||||
|
|
@ -364,11 +365,6 @@ static struct au1100fb_panel known_lcd_panels[] =
|
|||
},
|
||||
};
|
||||
|
||||
struct au1100fb_drv_info {
|
||||
int panel_idx;
|
||||
char *opt_mode;
|
||||
};
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
/* Inline helpers */
|
||||
|
|
|
|||
|
|
@ -46,18 +46,10 @@
|
|||
#include <asm/mach-au1x00/au1000.h>
|
||||
#include "au1200fb.h"
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
#include <asm/mach-au1x00/au1xxx_pm.h>
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_FB_AU1200_DEVS
|
||||
#define CONFIG_FB_AU1200_DEVS 4
|
||||
#endif
|
||||
|
||||
#define DRIVER_NAME "au1200fb"
|
||||
#define DRIVER_DESC "LCD controller driver for AU1200 processors"
|
||||
|
||||
#define DEBUG 1
|
||||
#define DEBUG 0
|
||||
|
||||
#define print_err(f, arg...) printk(KERN_ERR DRIVER_NAME ": " f "\n", ## arg)
|
||||
#define print_warn(f, arg...) printk(KERN_WARNING DRIVER_NAME ": " f "\n", ## arg)
|
||||
|
|
@ -150,7 +142,7 @@ struct au1200_lcd_iodata_t {
|
|||
|
||||
/* Private, per-framebuffer management information (independent of the panel itself) */
|
||||
struct au1200fb_device {
|
||||
struct fb_info fb_info; /* FB driver info record */
|
||||
struct fb_info *fb_info; /* FB driver info record */
|
||||
|
||||
int plane;
|
||||
unsigned char* fb_mem; /* FrameBuffer memory map */
|
||||
|
|
@ -158,7 +150,6 @@ struct au1200fb_device {
|
|||
dma_addr_t fb_phys;
|
||||
};
|
||||
|
||||
static struct au1200fb_device _au1200fb_devices[CONFIG_FB_AU1200_DEVS];
|
||||
/********************************************************************/
|
||||
|
||||
/* LCD controller restrictions */
|
||||
|
|
@ -171,10 +162,18 @@ static struct au1200fb_device _au1200fb_devices[CONFIG_FB_AU1200_DEVS];
|
|||
/* Default number of visible screen buffer to allocate */
|
||||
#define AU1200FB_NBR_VIDEO_BUFFERS 1
|
||||
|
||||
/* Default maximum number of fb devices to create */
|
||||
#define MAX_DEVICE_COUNT 4
|
||||
|
||||
/* Default window configuration entry to use (see windows[]) */
|
||||
#define DEFAULT_WINDOW_INDEX 2
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
static struct fb_info *_au1200fb_infos[MAX_DEVICE_COUNT];
|
||||
static struct au1200_lcd *lcd = (struct au1200_lcd *) AU1200_LCD_ADDR;
|
||||
static int window_index = 2; /* default is zero */
|
||||
static int device_count = MAX_DEVICE_COUNT;
|
||||
static int window_index = DEFAULT_WINDOW_INDEX; /* default is zero */
|
||||
static int panel_index = 2; /* default is zero */
|
||||
static struct window_settings *win;
|
||||
static struct panel_settings *panel;
|
||||
|
|
@ -205,12 +204,6 @@ struct window_settings {
|
|||
extern int board_au1200fb_panel_init (void);
|
||||
extern int board_au1200fb_panel_shutdown (void);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
int au1200fb_pm_callback(au1xxx_power_dev_t *dev,
|
||||
au1xxx_request_t request, void *data);
|
||||
au1xxx_power_dev_t *LCD_pm_dev;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Default window configurations
|
||||
*/
|
||||
|
|
@ -652,25 +645,6 @@ static struct panel_settings known_lcd_panels[] =
|
|||
|
||||
/********************************************************************/
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int set_brightness(unsigned int brightness)
|
||||
{
|
||||
unsigned int hi1, divider;
|
||||
|
||||
/* limit brightness pwm duty to >= 30/1600 */
|
||||
if (brightness < 30) {
|
||||
brightness = 30;
|
||||
}
|
||||
divider = (lcd->pwmdiv & 0x3FFFF) + 1;
|
||||
hi1 = (lcd->pwmhi >> 16) + 1;
|
||||
hi1 = (((brightness & 0xFF) + 1) * divider >> 8);
|
||||
lcd->pwmhi &= 0xFFFF;
|
||||
lcd->pwmhi |= (hi1 << 16);
|
||||
|
||||
return brightness;
|
||||
}
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static int winbpp (unsigned int winctrl1)
|
||||
{
|
||||
int bits = 0;
|
||||
|
|
@ -712,8 +686,8 @@ static int fbinfo2index (struct fb_info *fb_info)
|
|||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CONFIG_FB_AU1200_DEVS; ++i) {
|
||||
if (fb_info == (struct fb_info *)(&_au1200fb_devices[i].fb_info))
|
||||
for (i = 0; i < device_count; ++i) {
|
||||
if (fb_info == _au1200fb_infos[i])
|
||||
return i;
|
||||
}
|
||||
printk("au1200fb: ERROR: fbinfo2index failed!\n");
|
||||
|
|
@ -962,7 +936,7 @@ static void au1200_setmode(struct au1200fb_device *fbdev)
|
|||
lcd->window[plane].winctrl2 = ( 0
|
||||
| LCD_WINCTRL2_CKMODE_00
|
||||
| LCD_WINCTRL2_DBM
|
||||
| LCD_WINCTRL2_BX_N( fbdev->fb_info.fix.line_length)
|
||||
| LCD_WINCTRL2_BX_N(fbdev->fb_info->fix.line_length)
|
||||
| LCD_WINCTRL2_SCX_1
|
||||
| LCD_WINCTRL2_SCY_1
|
||||
) ;
|
||||
|
|
@ -1050,7 +1024,7 @@ static void au1200fb_update_fbinfo(struct fb_info *fbi)
|
|||
static int au1200fb_fb_check_var(struct fb_var_screeninfo *var,
|
||||
struct fb_info *fbi)
|
||||
{
|
||||
struct au1200fb_device *fbdev = (struct au1200fb_device *)fbi;
|
||||
struct au1200fb_device *fbdev = fbi->par;
|
||||
u32 pixclock;
|
||||
int screen_size, plane;
|
||||
|
||||
|
|
@ -1142,7 +1116,7 @@ static int au1200fb_fb_check_var(struct fb_var_screeninfo *var,
|
|||
*/
|
||||
static int au1200fb_fb_set_par(struct fb_info *fbi)
|
||||
{
|
||||
struct au1200fb_device *fbdev = (struct au1200fb_device *)fbi;
|
||||
struct au1200fb_device *fbdev = fbi->par;
|
||||
|
||||
au1200fb_update_fbinfo(fbi);
|
||||
au1200_setmode(fbdev);
|
||||
|
|
@ -1246,11 +1220,7 @@ static int au1200fb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
|
|||
{
|
||||
unsigned int len;
|
||||
unsigned long start=0, off;
|
||||
struct au1200fb_device *fbdev = (struct au1200fb_device *) info;
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
au1xxx_pm_access(LCD_pm_dev);
|
||||
#endif
|
||||
struct au1200fb_device *fbdev = info->par;
|
||||
|
||||
if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) {
|
||||
return -EINVAL;
|
||||
|
|
@ -1461,10 +1431,6 @@ static int au1200fb_ioctl(struct fb_info *info, unsigned int cmd,
|
|||
int plane;
|
||||
int val;
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
au1xxx_pm_access(LCD_pm_dev);
|
||||
#endif
|
||||
|
||||
plane = fbinfo2index(info);
|
||||
print_dbg("au1200fb: ioctl %d on plane %d\n", cmd, plane);
|
||||
|
||||
|
|
@ -1536,9 +1502,11 @@ static struct fb_ops au1200fb_fb_ops = {
|
|||
.fb_set_par = au1200fb_fb_set_par,
|
||||
.fb_setcolreg = au1200fb_fb_setcolreg,
|
||||
.fb_blank = au1200fb_fb_blank,
|
||||
.fb_fillrect = cfb_fillrect,
|
||||
.fb_copyarea = cfb_copyarea,
|
||||
.fb_imageblit = cfb_imageblit,
|
||||
.fb_fillrect = sys_fillrect,
|
||||
.fb_copyarea = sys_copyarea,
|
||||
.fb_imageblit = sys_imageblit,
|
||||
.fb_read = fb_sys_read,
|
||||
.fb_write = fb_sys_write,
|
||||
.fb_sync = NULL,
|
||||
.fb_ioctl = au1200fb_ioctl,
|
||||
.fb_mmap = au1200fb_fb_mmap,
|
||||
|
|
@ -1561,10 +1529,9 @@ static irqreturn_t au1200fb_handle_irq(int irq, void* dev_id)
|
|||
|
||||
static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev)
|
||||
{
|
||||
struct fb_info *fbi = &fbdev->fb_info;
|
||||
struct fb_info *fbi = fbdev->fb_info;
|
||||
int bpp;
|
||||
|
||||
memset(fbi, 0, sizeof(struct fb_info));
|
||||
fbi->fbops = &au1200fb_fb_ops;
|
||||
|
||||
bpp = winbpp(win->w[fbdev->plane].mode_winctrl1);
|
||||
|
|
@ -1623,24 +1590,36 @@ static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev)
|
|||
|
||||
/* AU1200 LCD controller device driver */
|
||||
|
||||
static int au1200fb_drv_probe(struct platform_device *dev)
|
||||
static int __devinit au1200fb_drv_probe(struct platform_device *dev)
|
||||
{
|
||||
struct au1200fb_device *fbdev;
|
||||
struct fb_info *fbi = NULL;
|
||||
unsigned long page;
|
||||
int bpp, plane, ret;
|
||||
int bpp, plane, ret, irq;
|
||||
|
||||
if (!dev)
|
||||
return -EINVAL;
|
||||
/* shut gcc up */
|
||||
ret = 0;
|
||||
fbdev = NULL;
|
||||
|
||||
for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) {
|
||||
/* Kickstart the panel */
|
||||
au1200_setpanel(panel);
|
||||
|
||||
for (plane = 0; plane < device_count; ++plane) {
|
||||
bpp = winbpp(win->w[plane].mode_winctrl1);
|
||||
if (win->w[plane].xres == 0)
|
||||
win->w[plane].xres = panel->Xres;
|
||||
if (win->w[plane].yres == 0)
|
||||
win->w[plane].yres = panel->Yres;
|
||||
|
||||
fbdev = &_au1200fb_devices[plane];
|
||||
memset(fbdev, 0, sizeof(struct au1200fb_device));
|
||||
fbi = framebuffer_alloc(sizeof(struct au1200fb_device),
|
||||
&dev->dev);
|
||||
if (!fbi)
|
||||
goto failed;
|
||||
|
||||
_au1200fb_infos[plane] = fbi;
|
||||
fbdev = fbi->par;
|
||||
fbdev->fb_info = fbi;
|
||||
|
||||
fbdev->plane = plane;
|
||||
|
||||
/* Allocate the framebuffer to the maximum screen size */
|
||||
|
|
@ -1673,30 +1652,31 @@ static int au1200fb_drv_probe(struct platform_device *dev)
|
|||
goto failed;
|
||||
|
||||
/* Register new framebuffer */
|
||||
if ((ret = register_framebuffer(&fbdev->fb_info)) < 0) {
|
||||
ret = register_framebuffer(fbi);
|
||||
if (ret < 0) {
|
||||
print_err("cannot register new framebuffer");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
au1200fb_fb_set_par(&fbdev->fb_info);
|
||||
au1200fb_fb_set_par(fbi);
|
||||
|
||||
#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
|
||||
if (plane == 0)
|
||||
if (fb_prepare_logo(&fbdev->fb_info, FB_ROTATE_UR)) {
|
||||
if (fb_prepare_logo(fbi, FB_ROTATE_UR)) {
|
||||
/* Start display and show logo on boot */
|
||||
fb_set_cmap(&fbdev->fb_info.cmap,
|
||||
&fbdev->fb_info);
|
||||
|
||||
fb_show_logo(&fbdev->fb_info, FB_ROTATE_UR);
|
||||
fb_set_cmap(&fbi->cmap, fbi);
|
||||
fb_show_logo(fbi, FB_ROTATE_UR);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Now hook interrupt too */
|
||||
if ((ret = request_irq(AU1200_LCD_INT, au1200fb_handle_irq,
|
||||
IRQF_DISABLED | IRQF_SHARED, "lcd", (void *)dev)) < 0) {
|
||||
irq = platform_get_irq(dev, 0);
|
||||
ret = request_irq(irq, au1200fb_handle_irq,
|
||||
IRQF_SHARED, "lcd", (void *)dev);
|
||||
if (ret) {
|
||||
print_err("fail to request interrupt line %d (err: %d)",
|
||||
AU1200_LCD_INT, ret);
|
||||
irq, ret);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
|
@ -1705,84 +1685,108 @@ static int au1200fb_drv_probe(struct platform_device *dev)
|
|||
failed:
|
||||
/* NOTE: This only does the current plane/window that failed; others are still active */
|
||||
if (fbdev->fb_mem)
|
||||
dma_free_noncoherent(dev, PAGE_ALIGN(fbdev->fb_len),
|
||||
dma_free_noncoherent(&dev->dev, PAGE_ALIGN(fbdev->fb_len),
|
||||
fbdev->fb_mem, fbdev->fb_phys);
|
||||
if (fbdev->fb_info.cmap.len != 0)
|
||||
fb_dealloc_cmap(&fbdev->fb_info.cmap);
|
||||
if (fbdev->fb_info.pseudo_palette)
|
||||
kfree(fbdev->fb_info.pseudo_palette);
|
||||
if (fbi) {
|
||||
if (fbi->cmap.len != 0)
|
||||
fb_dealloc_cmap(&fbi->cmap);
|
||||
kfree(fbi->pseudo_palette);
|
||||
}
|
||||
if (plane == 0)
|
||||
free_irq(AU1200_LCD_INT, (void*)dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int au1200fb_drv_remove(struct platform_device *dev)
|
||||
static int __devexit au1200fb_drv_remove(struct platform_device *dev)
|
||||
{
|
||||
struct au1200fb_device *fbdev;
|
||||
struct fb_info *fbi;
|
||||
int plane;
|
||||
|
||||
if (!dev)
|
||||
return -ENODEV;
|
||||
|
||||
/* Turn off the panel */
|
||||
au1200_setpanel(NULL);
|
||||
|
||||
for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane)
|
||||
{
|
||||
fbdev = &_au1200fb_devices[plane];
|
||||
for (plane = 0; plane < device_count; ++plane) {
|
||||
fbi = _au1200fb_infos[plane];
|
||||
fbdev = fbi->par;
|
||||
|
||||
/* Clean up all probe data */
|
||||
unregister_framebuffer(&fbdev->fb_info);
|
||||
unregister_framebuffer(fbi);
|
||||
if (fbdev->fb_mem)
|
||||
dma_free_noncoherent(&dev->dev,
|
||||
PAGE_ALIGN(fbdev->fb_len),
|
||||
fbdev->fb_mem, fbdev->fb_phys);
|
||||
if (fbdev->fb_info.cmap.len != 0)
|
||||
fb_dealloc_cmap(&fbdev->fb_info.cmap);
|
||||
if (fbdev->fb_info.pseudo_palette)
|
||||
kfree(fbdev->fb_info.pseudo_palette);
|
||||
if (fbi->cmap.len != 0)
|
||||
fb_dealloc_cmap(&fbi->cmap);
|
||||
kfree(fbi->pseudo_palette);
|
||||
|
||||
framebuffer_release(fbi);
|
||||
_au1200fb_infos[plane] = NULL;
|
||||
}
|
||||
|
||||
free_irq(AU1200_LCD_INT, (void *)dev);
|
||||
free_irq(platform_get_irq(dev, 0), (void *)dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int au1200fb_drv_suspend(struct platform_device *dev, u32 state)
|
||||
static int au1200fb_drv_suspend(struct device *dev)
|
||||
{
|
||||
/* TODO */
|
||||
au1200_setpanel(NULL);
|
||||
|
||||
lcd->outmask = 0;
|
||||
au_sync();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int au1200fb_drv_resume(struct platform_device *dev)
|
||||
static int au1200fb_drv_resume(struct device *dev)
|
||||
{
|
||||
/* TODO */
|
||||
struct fb_info *fbi;
|
||||
int i;
|
||||
|
||||
/* Kickstart the panel */
|
||||
au1200_setpanel(panel);
|
||||
|
||||
for (i = 0; i < device_count; i++) {
|
||||
fbi = _au1200fb_infos[i];
|
||||
au1200fb_fb_set_par(fbi);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops au1200fb_pmops = {
|
||||
.suspend = au1200fb_drv_suspend,
|
||||
.resume = au1200fb_drv_resume,
|
||||
.freeze = au1200fb_drv_suspend,
|
||||
.thaw = au1200fb_drv_resume,
|
||||
};
|
||||
|
||||
#define AU1200FB_PMOPS (&au1200fb_pmops)
|
||||
|
||||
#else
|
||||
#define AU1200FB_PMOPS NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static struct platform_driver au1200fb_driver = {
|
||||
.driver = {
|
||||
.name = "au1200-lcd",
|
||||
.owner = THIS_MODULE,
|
||||
.name = "au1200-lcd",
|
||||
.owner = THIS_MODULE,
|
||||
.pm = AU1200FB_PMOPS,
|
||||
},
|
||||
.probe = au1200fb_drv_probe,
|
||||
.remove = au1200fb_drv_remove,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = au1200fb_drv_suspend,
|
||||
.resume = au1200fb_drv_resume,
|
||||
#endif
|
||||
.remove = __devexit_p(au1200fb_drv_remove),
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* Kernel driver */
|
||||
|
||||
static void au1200fb_setup(void)
|
||||
static int au1200fb_setup(void)
|
||||
{
|
||||
char* options = NULL;
|
||||
char* this_opt;
|
||||
char *options = NULL;
|
||||
char *this_opt, *endptr;
|
||||
int num_panels = ARRAY_SIZE(known_lcd_panels);
|
||||
int panel_idx = -1;
|
||||
|
||||
|
|
@ -1827,70 +1831,42 @@ static void au1200fb_setup(void)
|
|||
nohwcursor = 1;
|
||||
}
|
||||
|
||||
else if (strncmp(this_opt, "devices:", 8) == 0) {
|
||||
this_opt += 8;
|
||||
device_count = simple_strtol(this_opt,
|
||||
&endptr, 0);
|
||||
if ((device_count < 0) ||
|
||||
(device_count > MAX_DEVICE_COUNT))
|
||||
device_count = MAX_DEVICE_COUNT;
|
||||
}
|
||||
|
||||
else if (strncmp(this_opt, "wincfg:", 7) == 0) {
|
||||
this_opt += 7;
|
||||
window_index = simple_strtol(this_opt,
|
||||
&endptr, 0);
|
||||
if ((window_index < 0) ||
|
||||
(window_index >= ARRAY_SIZE(windows)))
|
||||
window_index = DEFAULT_WINDOW_INDEX;
|
||||
}
|
||||
|
||||
else if (strncmp(this_opt, "off", 3) == 0)
|
||||
return 1;
|
||||
/* Unsupported option */
|
||||
else {
|
||||
print_warn("Unsupported option \"%s\"", this_opt);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int au1200fb_pm_callback(au1xxx_power_dev_t *dev,
|
||||
au1xxx_request_t request, void *data) {
|
||||
int retval = -1;
|
||||
unsigned int d = 0;
|
||||
unsigned int brightness = 0;
|
||||
|
||||
if (request == AU1XXX_PM_SLEEP) {
|
||||
board_au1200fb_panel_shutdown();
|
||||
}
|
||||
else if (request == AU1XXX_PM_WAKEUP) {
|
||||
if(dev->prev_state == SLEEP_STATE)
|
||||
{
|
||||
int plane;
|
||||
au1200_setpanel(panel);
|
||||
for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) {
|
||||
struct au1200fb_device *fbdev;
|
||||
fbdev = &_au1200fb_devices[plane];
|
||||
au1200fb_fb_set_par(&fbdev->fb_info);
|
||||
}
|
||||
}
|
||||
|
||||
d = *((unsigned int*)data);
|
||||
if(d <=10) brightness = 26;
|
||||
else if(d<=20) brightness = 51;
|
||||
else if(d<=30) brightness = 77;
|
||||
else if(d<=40) brightness = 102;
|
||||
else if(d<=50) brightness = 128;
|
||||
else if(d<=60) brightness = 153;
|
||||
else if(d<=70) brightness = 179;
|
||||
else if(d<=80) brightness = 204;
|
||||
else if(d<=90) brightness = 230;
|
||||
else brightness = 255;
|
||||
set_brightness(brightness);
|
||||
} else if (request == AU1XXX_PM_GETSTATUS) {
|
||||
return dev->cur_state;
|
||||
} else if (request == AU1XXX_PM_ACCESS) {
|
||||
if (dev->cur_state != SLEEP_STATE)
|
||||
return retval;
|
||||
else {
|
||||
au1200_setpanel(panel);
|
||||
}
|
||||
} else if (request == AU1XXX_PM_IDLE) {
|
||||
} else if (request == AU1XXX_PM_CLEANUP) {
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int __init au1200fb_init(void)
|
||||
{
|
||||
print_info("" DRIVER_DESC "");
|
||||
|
||||
/* Setup driver with options */
|
||||
au1200fb_setup();
|
||||
if (au1200fb_setup())
|
||||
return -ENODEV;
|
||||
|
||||
/* Point to the panel selected */
|
||||
panel = &known_lcd_panels[panel_index];
|
||||
|
|
@ -1899,17 +1875,6 @@ static int __init au1200fb_init(void)
|
|||
printk(DRIVER_NAME ": Panel %d %s\n", panel_index, panel->name);
|
||||
printk(DRIVER_NAME ": Win %d %s\n", window_index, win->name);
|
||||
|
||||
/* Kickstart the panel, the framebuffers/windows come soon enough */
|
||||
au1200_setpanel(panel);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
LCD_pm_dev = new_au1xxx_power_device("LCD", &au1200fb_pm_callback, NULL);
|
||||
if ( LCD_pm_dev == NULL)
|
||||
printk(KERN_INFO "Unable to create a power management device entry for the au1200fb.\n");
|
||||
else
|
||||
printk(KERN_INFO "Power management device entry for the au1200fb loaded.\n");
|
||||
#endif
|
||||
|
||||
return platform_driver_register(&au1200fb_driver);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/pm.h>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/pm.h>
|
||||
|
|
|
|||
|
|
@ -633,7 +633,7 @@ static int __devinit bfin_bf54x_probe(struct platform_device *pdev)
|
|||
goto out7;
|
||||
}
|
||||
|
||||
if (request_irq(info->irq, bfin_bf54x_irq_error, IRQF_DISABLED,
|
||||
if (request_irq(info->irq, bfin_bf54x_irq_error, 0,
|
||||
"PPI ERROR", info) < 0) {
|
||||
printk(KERN_ERR DRIVER_NAME
|
||||
": unable to request PPI ERROR IRQ\n");
|
||||
|
|
|
|||
|
|
@ -695,7 +695,7 @@ static int __devinit bfin_lq035q1_probe(struct platform_device *pdev)
|
|||
goto out7;
|
||||
}
|
||||
|
||||
ret = request_irq(info->irq, bfin_lq035q1_irq_error, IRQF_DISABLED,
|
||||
ret = request_irq(info->irq, bfin_lq035q1_irq_error, 0,
|
||||
DRIVER_NAME" PPI ERROR", info);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "unable to request PPI ERROR IRQ\n");
|
||||
|
|
|
|||
|
|
@ -529,7 +529,7 @@ static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev)
|
|||
goto out7;
|
||||
}
|
||||
|
||||
ret = request_irq(info->irq, bfin_t350mcqb_irq_error, IRQF_DISABLED,
|
||||
ret = request_irq(info->irq, bfin_t350mcqb_irq_error, 0,
|
||||
"PPI ERROR", info);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR DRIVER_NAME
|
||||
|
|
|
|||
|
|
@ -481,7 +481,7 @@ static int __devinit bfin_adv7393_fb_probe(struct i2c_client *client,
|
|||
goto out_4;
|
||||
}
|
||||
|
||||
if (request_irq(IRQ_PPI_ERROR, ppi_irq_error, IRQF_DISABLED,
|
||||
if (request_irq(IRQ_PPI_ERROR, ppi_irq_error, 0,
|
||||
"PPI ERROR", fbdev) < 0) {
|
||||
dev_err(&client->dev, "unable to request PPI ERROR IRQ\n");
|
||||
ret = -EFAULT;
|
||||
|
|
|
|||
|
|
@ -32,11 +32,11 @@
|
|||
#define CARMINEFB_DEFAULT_VIDEO_MODE 1
|
||||
|
||||
static unsigned int fb_mode = CARMINEFB_DEFAULT_VIDEO_MODE;
|
||||
module_param(fb_mode, uint, 444);
|
||||
module_param(fb_mode, uint, 0444);
|
||||
MODULE_PARM_DESC(fb_mode, "Initial video mode as integer.");
|
||||
|
||||
static char *fb_mode_str;
|
||||
module_param(fb_mode_str, charp, 444);
|
||||
module_param(fb_mode_str, charp, 0444);
|
||||
MODULE_PARM_DESC(fb_mode_str, "Initial video mode in characters.");
|
||||
|
||||
/*
|
||||
|
|
@ -46,7 +46,7 @@ MODULE_PARM_DESC(fb_mode_str, "Initial video mode in characters.");
|
|||
* 0b010 Display 1
|
||||
*/
|
||||
static int fb_displays = CARMINE_USE_DISPLAY0 | CARMINE_USE_DISPLAY1;
|
||||
module_param(fb_displays, int, 444);
|
||||
module_param(fb_displays, int, 0444);
|
||||
MODULE_PARM_DESC(fb_displays, "Bit mode, which displays are used");
|
||||
|
||||
struct carmine_hw {
|
||||
|
|
|
|||
|
|
@ -550,7 +550,7 @@ static void control_set_hardware(struct fb_info_control *p, struct fb_par_contro
|
|||
|
||||
|
||||
/*
|
||||
* Parse user speficied options (`video=controlfb:')
|
||||
* Parse user specified options (`video=controlfb:')
|
||||
*/
|
||||
static void __init control_setup(char *options)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -35,6 +35,9 @@
|
|||
|
||||
#define DRIVER_NAME "da8xx_lcdc"
|
||||
|
||||
#define LCD_VERSION_1 1
|
||||
#define LCD_VERSION_2 2
|
||||
|
||||
/* LCD Status Register */
|
||||
#define LCD_END_OF_FRAME1 BIT(9)
|
||||
#define LCD_END_OF_FRAME0 BIT(8)
|
||||
|
|
@ -49,7 +52,9 @@
|
|||
#define LCD_DMA_BURST_4 0x2
|
||||
#define LCD_DMA_BURST_8 0x3
|
||||
#define LCD_DMA_BURST_16 0x4
|
||||
#define LCD_END_OF_FRAME_INT_ENA BIT(2)
|
||||
#define LCD_V1_END_OF_FRAME_INT_ENA BIT(2)
|
||||
#define LCD_V2_END_OF_FRAME0_INT_ENA BIT(8)
|
||||
#define LCD_V2_END_OF_FRAME1_INT_ENA BIT(9)
|
||||
#define LCD_DUAL_FRAME_BUFFER_ENABLE BIT(0)
|
||||
|
||||
/* LCD Control Register */
|
||||
|
|
@ -65,12 +70,18 @@
|
|||
#define LCD_MONO_8BIT_MODE BIT(9)
|
||||
#define LCD_RASTER_ORDER BIT(8)
|
||||
#define LCD_TFT_MODE BIT(7)
|
||||
#define LCD_UNDERFLOW_INT_ENA BIT(6)
|
||||
#define LCD_PL_ENABLE BIT(4)
|
||||
#define LCD_V1_UNDERFLOW_INT_ENA BIT(6)
|
||||
#define LCD_V2_UNDERFLOW_INT_ENA BIT(5)
|
||||
#define LCD_V1_PL_INT_ENA BIT(4)
|
||||
#define LCD_V2_PL_INT_ENA BIT(6)
|
||||
#define LCD_MONOCHROME_MODE BIT(1)
|
||||
#define LCD_RASTER_ENABLE BIT(0)
|
||||
#define LCD_TFT_ALT_ENABLE BIT(23)
|
||||
#define LCD_STN_565_ENABLE BIT(24)
|
||||
#define LCD_V2_DMA_CLK_EN BIT(2)
|
||||
#define LCD_V2_LIDD_CLK_EN BIT(1)
|
||||
#define LCD_V2_CORE_CLK_EN BIT(0)
|
||||
#define LCD_V2_LPP_B10 26
|
||||
|
||||
/* LCD Raster Timing 2 Register */
|
||||
#define LCD_AC_BIAS_TRANSITIONS_PER_INT(x) ((x) << 16)
|
||||
|
|
@ -82,6 +93,7 @@
|
|||
#define LCD_INVERT_FRAME_CLOCK BIT(20)
|
||||
|
||||
/* LCD Block */
|
||||
#define LCD_PID_REG 0x0
|
||||
#define LCD_CTRL_REG 0x4
|
||||
#define LCD_STAT_REG 0x8
|
||||
#define LCD_RASTER_CTRL_REG 0x28
|
||||
|
|
@ -94,6 +106,17 @@
|
|||
#define LCD_DMA_FRM_BUF_BASE_ADDR_1_REG 0x4C
|
||||
#define LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG 0x50
|
||||
|
||||
/* Interrupt Registers available only in Version 2 */
|
||||
#define LCD_RAW_STAT_REG 0x58
|
||||
#define LCD_MASKED_STAT_REG 0x5c
|
||||
#define LCD_INT_ENABLE_SET_REG 0x60
|
||||
#define LCD_INT_ENABLE_CLR_REG 0x64
|
||||
#define LCD_END_OF_INT_IND_REG 0x68
|
||||
|
||||
/* Clock registers available only on Version 2 */
|
||||
#define LCD_CLK_ENABLE_REG 0x6c
|
||||
#define LCD_CLK_RESET_REG 0x70
|
||||
|
||||
#define LCD_NUM_BUFFERS 2
|
||||
|
||||
#define WSI_TIMEOUT 50
|
||||
|
|
@ -105,6 +128,8 @@
|
|||
|
||||
static resource_size_t da8xx_fb_reg_base;
|
||||
static struct resource *lcdc_regs;
|
||||
static unsigned int lcd_revision;
|
||||
static irq_handler_t lcdc_irq_handler;
|
||||
|
||||
static inline unsigned int lcdc_read(unsigned int addr)
|
||||
{
|
||||
|
|
@ -240,6 +265,7 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
|
|||
u32 end;
|
||||
u32 reg_ras;
|
||||
u32 reg_dma;
|
||||
u32 reg_int;
|
||||
|
||||
/* init reg to clear PLM (loading mode) fields */
|
||||
reg_ras = lcdc_read(LCD_RASTER_CTRL_REG);
|
||||
|
|
@ -252,7 +278,14 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
|
|||
end = par->dma_end;
|
||||
|
||||
reg_ras |= LCD_PALETTE_LOAD_MODE(DATA_ONLY);
|
||||
reg_dma |= LCD_END_OF_FRAME_INT_ENA;
|
||||
if (lcd_revision == LCD_VERSION_1) {
|
||||
reg_dma |= LCD_V1_END_OF_FRAME_INT_ENA;
|
||||
} else {
|
||||
reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
|
||||
LCD_V2_END_OF_FRAME0_INT_ENA |
|
||||
LCD_V2_END_OF_FRAME1_INT_ENA;
|
||||
lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
|
||||
}
|
||||
reg_dma |= LCD_DUAL_FRAME_BUFFER_ENABLE;
|
||||
|
||||
lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
|
||||
|
|
@ -264,7 +297,14 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
|
|||
end = start + par->palette_sz - 1;
|
||||
|
||||
reg_ras |= LCD_PALETTE_LOAD_MODE(PALETTE_ONLY);
|
||||
reg_ras |= LCD_PL_ENABLE;
|
||||
|
||||
if (lcd_revision == LCD_VERSION_1) {
|
||||
reg_ras |= LCD_V1_PL_INT_ENA;
|
||||
} else {
|
||||
reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
|
||||
LCD_V2_PL_INT_ENA;
|
||||
lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
|
||||
}
|
||||
|
||||
lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
|
||||
lcdc_write(end, LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
|
||||
|
|
@ -348,6 +388,7 @@ static void lcd_cfg_vertical_sync(int back_porch, int pulse_width,
|
|||
static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)
|
||||
{
|
||||
u32 reg;
|
||||
u32 reg_int;
|
||||
|
||||
reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(LCD_TFT_MODE |
|
||||
LCD_MONO_8BIT_MODE |
|
||||
|
|
@ -375,7 +416,13 @@ static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)
|
|||
}
|
||||
|
||||
/* enable additional interrupts here */
|
||||
reg |= LCD_UNDERFLOW_INT_ENA;
|
||||
if (lcd_revision == LCD_VERSION_1) {
|
||||
reg |= LCD_V1_UNDERFLOW_INT_ENA;
|
||||
} else {
|
||||
reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
|
||||
LCD_V2_UNDERFLOW_INT_ENA;
|
||||
lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
|
||||
}
|
||||
|
||||
lcdc_write(reg, LCD_RASTER_CTRL_REG);
|
||||
|
||||
|
|
@ -413,18 +460,43 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
|
|||
|
||||
/* Set the Panel Width */
|
||||
/* Pixels per line = (PPL + 1)*16 */
|
||||
/*0x3F in bits 4..9 gives max horisontal resolution = 1024 pixels*/
|
||||
width &= 0x3f0;
|
||||
if (lcd_revision == LCD_VERSION_1) {
|
||||
/*
|
||||
* 0x3F in bits 4..9 gives max horizontal resolution = 1024
|
||||
* pixels.
|
||||
*/
|
||||
width &= 0x3f0;
|
||||
} else {
|
||||
/*
|
||||
* 0x7F in bits 4..10 gives max horizontal resolution = 2048
|
||||
* pixels.
|
||||
*/
|
||||
width &= 0x7f0;
|
||||
}
|
||||
|
||||
reg = lcdc_read(LCD_RASTER_TIMING_0_REG);
|
||||
reg &= 0xfffffc00;
|
||||
reg |= ((width >> 4) - 1) << 4;
|
||||
if (lcd_revision == LCD_VERSION_1) {
|
||||
reg |= ((width >> 4) - 1) << 4;
|
||||
} else {
|
||||
width = (width >> 4) - 1;
|
||||
reg |= ((width & 0x3f) << 4) | ((width & 0x40) >> 3);
|
||||
}
|
||||
lcdc_write(reg, LCD_RASTER_TIMING_0_REG);
|
||||
|
||||
/* Set the Panel Height */
|
||||
/* Set bits 9:0 of Lines Per Pixel */
|
||||
reg = lcdc_read(LCD_RASTER_TIMING_1_REG);
|
||||
reg = ((height - 1) & 0x3ff) | (reg & 0xfffffc00);
|
||||
lcdc_write(reg, LCD_RASTER_TIMING_1_REG);
|
||||
|
||||
/* Set bit 10 of Lines Per Pixel */
|
||||
if (lcd_revision == LCD_VERSION_2) {
|
||||
reg = lcdc_read(LCD_RASTER_TIMING_2_REG);
|
||||
reg |= ((height - 1) & 0x400) << 16;
|
||||
lcdc_write(reg, LCD_RASTER_TIMING_2_REG);
|
||||
}
|
||||
|
||||
/* Set the Raster Order of the Frame Buffer */
|
||||
reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(1 << 8);
|
||||
if (raster_order)
|
||||
|
|
@ -511,6 +583,9 @@ static void lcd_reset(struct da8xx_fb_par *par)
|
|||
/* DMA has to be disabled */
|
||||
lcdc_write(0, LCD_DMA_CTRL_REG);
|
||||
lcdc_write(0, LCD_RASTER_CTRL_REG);
|
||||
|
||||
if (lcd_revision == LCD_VERSION_2)
|
||||
lcdc_write(0, LCD_INT_ENABLE_SET_REG);
|
||||
}
|
||||
|
||||
static void lcd_calc_clk_divider(struct da8xx_fb_par *par)
|
||||
|
|
@ -523,6 +598,11 @@ static void lcd_calc_clk_divider(struct da8xx_fb_par *par)
|
|||
/* Configure the LCD clock divisor. */
|
||||
lcdc_write(LCD_CLK_DIVISOR(div) |
|
||||
(LCD_RASTER_MODE & 0x1), LCD_CTRL_REG);
|
||||
|
||||
if (lcd_revision == LCD_VERSION_2)
|
||||
lcdc_write(LCD_V2_DMA_CLK_EN | LCD_V2_LIDD_CLK_EN |
|
||||
LCD_V2_CORE_CLK_EN, LCD_CLK_ENABLE_REG);
|
||||
|
||||
}
|
||||
|
||||
static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
|
||||
|
|
@ -583,7 +663,63 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static irqreturn_t lcdc_irq_handler(int irq, void *arg)
|
||||
/* IRQ handler for version 2 of LCDC */
|
||||
static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
|
||||
{
|
||||
struct da8xx_fb_par *par = arg;
|
||||
u32 stat = lcdc_read(LCD_MASKED_STAT_REG);
|
||||
u32 reg_int;
|
||||
|
||||
if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
|
||||
lcd_disable_raster();
|
||||
lcdc_write(stat, LCD_MASKED_STAT_REG);
|
||||
lcd_enable_raster();
|
||||
} else if (stat & LCD_PL_LOAD_DONE) {
|
||||
/*
|
||||
* Must disable raster before changing state of any control bit.
|
||||
* And also must be disabled before clearing the PL loading
|
||||
* interrupt via the following write to the status register. If
|
||||
* this is done after then one gets multiple PL done interrupts.
|
||||
*/
|
||||
lcd_disable_raster();
|
||||
|
||||
lcdc_write(stat, LCD_MASKED_STAT_REG);
|
||||
|
||||
/* Disable PL completion inerrupt */
|
||||
reg_int = lcdc_read(LCD_INT_ENABLE_CLR_REG) |
|
||||
(LCD_V2_PL_INT_ENA);
|
||||
lcdc_write(reg_int, LCD_INT_ENABLE_CLR_REG);
|
||||
|
||||
/* Setup and start data loading mode */
|
||||
lcd_blit(LOAD_DATA, par);
|
||||
} else {
|
||||
lcdc_write(stat, LCD_MASKED_STAT_REG);
|
||||
|
||||
if (stat & LCD_END_OF_FRAME0) {
|
||||
lcdc_write(par->dma_start,
|
||||
LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
|
||||
lcdc_write(par->dma_end,
|
||||
LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
|
||||
par->vsync_flag = 1;
|
||||
wake_up_interruptible(&par->vsync_wait);
|
||||
}
|
||||
|
||||
if (stat & LCD_END_OF_FRAME1) {
|
||||
lcdc_write(par->dma_start,
|
||||
LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
|
||||
lcdc_write(par->dma_end,
|
||||
LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
|
||||
par->vsync_flag = 1;
|
||||
wake_up_interruptible(&par->vsync_wait);
|
||||
}
|
||||
}
|
||||
|
||||
lcdc_write(0, LCD_END_OF_INT_IND_REG);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/* IRQ handler for version 1 LCDC */
|
||||
static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg)
|
||||
{
|
||||
struct da8xx_fb_par *par = arg;
|
||||
u32 stat = lcdc_read(LCD_STAT_REG);
|
||||
|
|
@ -606,7 +742,7 @@ static irqreturn_t lcdc_irq_handler(int irq, void *arg)
|
|||
|
||||
/* Disable PL completion inerrupt */
|
||||
reg_ras = lcdc_read(LCD_RASTER_CTRL_REG);
|
||||
reg_ras &= ~LCD_PL_ENABLE;
|
||||
reg_ras &= ~LCD_V1_PL_INT_ENA;
|
||||
lcdc_write(reg_ras, LCD_RASTER_CTRL_REG);
|
||||
|
||||
/* Setup and start data loading mode */
|
||||
|
|
@ -877,8 +1013,8 @@ static int da8xx_pan_display(struct fb_var_screeninfo *var,
|
|||
|
||||
start = fix->smem_start +
|
||||
new_var.yoffset * fix->line_length +
|
||||
new_var.xoffset * var->bits_per_pixel / 8;
|
||||
end = start + var->yres * fix->line_length - 1;
|
||||
new_var.xoffset * fbi->var.bits_per_pixel / 8;
|
||||
end = start + fbi->var.yres * fix->line_length - 1;
|
||||
par->dma_start = start;
|
||||
par->dma_end = end;
|
||||
}
|
||||
|
|
@ -945,6 +1081,22 @@ static int __devinit fb_probe(struct platform_device *device)
|
|||
if (ret)
|
||||
goto err_clk_put;
|
||||
|
||||
/* Determine LCD IP Version */
|
||||
switch (lcdc_read(LCD_PID_REG)) {
|
||||
case 0x4C100102:
|
||||
lcd_revision = LCD_VERSION_1;
|
||||
break;
|
||||
case 0x4F200800:
|
||||
lcd_revision = LCD_VERSION_2;
|
||||
break;
|
||||
default:
|
||||
dev_warn(&device->dev, "Unknown PID Reg value 0x%x, "
|
||||
"defaulting to LCD revision 1\n",
|
||||
lcdc_read(LCD_PID_REG));
|
||||
lcd_revision = LCD_VERSION_1;
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0, lcdc_info = known_lcd_panels;
|
||||
i < ARRAY_SIZE(known_lcd_panels);
|
||||
i++, lcdc_info++) {
|
||||
|
|
@ -1085,7 +1237,13 @@ static int __devinit fb_probe(struct platform_device *device)
|
|||
}
|
||||
#endif
|
||||
|
||||
ret = request_irq(par->irq, lcdc_irq_handler, 0, DRIVER_NAME, par);
|
||||
if (lcd_revision == LCD_VERSION_1)
|
||||
lcdc_irq_handler = lcdc_irq_handler_rev01;
|
||||
else
|
||||
lcdc_irq_handler = lcdc_irq_handler_rev02;
|
||||
|
||||
ret = request_irq(par->irq, lcdc_irq_handler, 0,
|
||||
DRIVER_NAME, par);
|
||||
if (ret)
|
||||
goto irq_freq;
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -624,8 +624,8 @@ static int unifb_pan_display(struct fb_var_screeninfo *var,
|
|||
|| var->xoffset)
|
||||
return -EINVAL;
|
||||
} else {
|
||||
if (var->xoffset + var->xres > info->var.xres_virtual ||
|
||||
var->yoffset + var->yres > info->var.yres_virtual)
|
||||
if (var->xoffset + info->var.xres > info->var.xres_virtual ||
|
||||
var->yoffset + info->var.yres > info->var.yres_virtual)
|
||||
return -EINVAL;
|
||||
}
|
||||
info->var.xoffset = var->xoffset;
|
||||
|
|
|
|||
|
|
@ -223,8 +223,7 @@ void fb_deferred_io_cleanup(struct fb_info *info)
|
|||
int i;
|
||||
|
||||
BUG_ON(!fbdefio);
|
||||
cancel_delayed_work(&info->deferred_work);
|
||||
flush_scheduled_work();
|
||||
cancel_delayed_work_sync(&info->deferred_work);
|
||||
|
||||
/* clear out the mapping that we setup */
|
||||
for (i = 0 ; i < info->fix.smem_len; i += PAGE_SIZE) {
|
||||
|
|
|
|||
|
|
@ -1738,8 +1738,6 @@ void fb_set_suspend(struct fb_info *info, int state)
|
|||
{
|
||||
struct fb_event event;
|
||||
|
||||
if (!lock_fb_info(info))
|
||||
return;
|
||||
event.info = info;
|
||||
if (state) {
|
||||
fb_notifier_call_chain(FB_EVENT_SUSPEND, &event);
|
||||
|
|
@ -1748,7 +1746,6 @@ void fb_set_suspend(struct fb_info *info, int state)
|
|||
info->state = FBINFO_STATE_RUNNING;
|
||||
fb_notifier_call_chain(FB_EVENT_RESUME, &event);
|
||||
}
|
||||
unlock_fb_info(info);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -493,7 +493,8 @@ static int get_est_timing(unsigned char *block, struct fb_videomode *mode)
|
|||
return num;
|
||||
}
|
||||
|
||||
static int get_std_timing(unsigned char *block, struct fb_videomode *mode)
|
||||
static int get_std_timing(unsigned char *block, struct fb_videomode *mode,
|
||||
int ver, int rev)
|
||||
{
|
||||
int xres, yres = 0, refresh, ratio, i;
|
||||
|
||||
|
|
@ -504,7 +505,11 @@ static int get_std_timing(unsigned char *block, struct fb_videomode *mode)
|
|||
ratio = (block[1] & 0xc0) >> 6;
|
||||
switch (ratio) {
|
||||
case 0:
|
||||
yres = xres;
|
||||
/* in EDID 1.3 the meaning of 0 changed to 16:10 (prior 1:1) */
|
||||
if (ver < 1 || (ver == 1 && rev < 3))
|
||||
yres = xres;
|
||||
else
|
||||
yres = (xres * 10)/16;
|
||||
break;
|
||||
case 1:
|
||||
yres = (xres * 3)/4;
|
||||
|
|
@ -533,12 +538,12 @@ static int get_std_timing(unsigned char *block, struct fb_videomode *mode)
|
|||
}
|
||||
|
||||
static int get_dst_timing(unsigned char *block,
|
||||
struct fb_videomode *mode)
|
||||
struct fb_videomode *mode, int ver, int rev)
|
||||
{
|
||||
int j, num = 0;
|
||||
|
||||
for (j = 0; j < 6; j++, block += STD_TIMING_DESCRIPTION_SIZE)
|
||||
num += get_std_timing(block, &mode[num]);
|
||||
num += get_std_timing(block, &mode[num], ver, rev);
|
||||
|
||||
return num;
|
||||
}
|
||||
|
|
@ -599,6 +604,10 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize)
|
|||
struct fb_videomode *mode, *m;
|
||||
unsigned char *block;
|
||||
int num = 0, i, first = 1;
|
||||
int ver, rev;
|
||||
|
||||
ver = edid[EDID_STRUCT_VERSION];
|
||||
rev = edid[EDID_STRUCT_REVISION];
|
||||
|
||||
mode = kzalloc(50 * sizeof(struct fb_videomode), GFP_KERNEL);
|
||||
if (mode == NULL)
|
||||
|
|
@ -632,12 +641,12 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize)
|
|||
DPRINTK(" Standard Timings\n");
|
||||
block = edid + STD_TIMING_DESCRIPTIONS_START;
|
||||
for (i = 0; i < STD_TIMING; i++, block += STD_TIMING_DESCRIPTION_SIZE)
|
||||
num += get_std_timing(block, &mode[num]);
|
||||
num += get_std_timing(block, &mode[num], ver, rev);
|
||||
|
||||
block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
|
||||
for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) {
|
||||
if (block[0] == 0x00 && block[1] == 0x00 && block[3] == 0xfa)
|
||||
num += get_dst_timing(block + 5, &mode[num]);
|
||||
num += get_dst_timing(block + 5, &mode[num], ver, rev);
|
||||
}
|
||||
|
||||
/* Yikes, EDID data is totally useless */
|
||||
|
|
|
|||
|
|
@ -399,9 +399,12 @@ static ssize_t store_fbstate(struct device *device,
|
|||
|
||||
state = simple_strtoul(buf, &last, 0);
|
||||
|
||||
if (!lock_fb_info(fb_info))
|
||||
return -ENODEV;
|
||||
console_lock();
|
||||
fb_set_suspend(fb_info, (int)state);
|
||||
console_unlock();
|
||||
unlock_fb_info(fb_info);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -149,10 +149,11 @@ int g364fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
|
|||
static int g364fb_pan_display(struct fb_var_screeninfo *var,
|
||||
struct fb_info *info)
|
||||
{
|
||||
if (var->xoffset || var->yoffset + var->yres > var->yres_virtual)
|
||||
if (var->xoffset ||
|
||||
var->yoffset + info->var.yres > info->var.yres_virtual)
|
||||
return -EINVAL;
|
||||
|
||||
*(unsigned int *) TOP_REG = var->yoffset * var->xres;
|
||||
*(unsigned int *) TOP_REG = var->yoffset * info->var.xres;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
579
drivers/video/grvga.c
Normal file
579
drivers/video/grvga.c
Normal file
|
|
@ -0,0 +1,579 @@
|
|||
/*
|
||||
* Driver for Aeroflex Gaisler SVGACTRL framebuffer device.
|
||||
*
|
||||
* 2011 (c) Aeroflex Gaisler AB
|
||||
*
|
||||
* Full documentation of the core can be found here:
|
||||
* http://www.gaisler.com/products/grlib/grip.pdf
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* Contributors: Kristoffer Glembo <kristoffer@gaisler.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
struct grvga_regs {
|
||||
u32 status; /* 0x00 */
|
||||
u32 video_length; /* 0x04 */
|
||||
u32 front_porch; /* 0x08 */
|
||||
u32 sync_length; /* 0x0C */
|
||||
u32 line_length; /* 0x10 */
|
||||
u32 fb_pos; /* 0x14 */
|
||||
u32 clk_vector[4]; /* 0x18 */
|
||||
u32 clut; /* 0x20 */
|
||||
};
|
||||
|
||||
struct grvga_par {
|
||||
struct grvga_regs *regs;
|
||||
u32 color_palette[16]; /* 16 entry pseudo palette used by fbcon in true color mode */
|
||||
int clk_sel;
|
||||
int fb_alloced; /* = 1 if framebuffer is allocated in main memory */
|
||||
};
|
||||
|
||||
|
||||
static const struct fb_videomode grvga_modedb[] = {
|
||||
{
|
||||
/* 640x480 @ 60 Hz */
|
||||
NULL, 60, 640, 480, 40000, 48, 16, 39, 11, 96, 2,
|
||||
0, FB_VMODE_NONINTERLACED
|
||||
}, {
|
||||
/* 800x600 @ 60 Hz */
|
||||
NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
|
||||
0, FB_VMODE_NONINTERLACED
|
||||
}, {
|
||||
/* 800x600 @ 72 Hz */
|
||||
NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
|
||||
0, FB_VMODE_NONINTERLACED
|
||||
}, {
|
||||
/* 1024x768 @ 60 Hz */
|
||||
NULL, 60, 1024, 768, 15385, 160, 24, 29, 3, 136, 6,
|
||||
0, FB_VMODE_NONINTERLACED
|
||||
}
|
||||
};
|
||||
|
||||
static struct fb_fix_screeninfo grvga_fix __initdata = {
|
||||
.id = "AG SVGACTRL",
|
||||
.type = FB_TYPE_PACKED_PIXELS,
|
||||
.visual = FB_VISUAL_PSEUDOCOLOR,
|
||||
.xpanstep = 0,
|
||||
.ypanstep = 1,
|
||||
.ywrapstep = 0,
|
||||
.accel = FB_ACCEL_NONE,
|
||||
};
|
||||
|
||||
static int grvga_check_var(struct fb_var_screeninfo *var,
|
||||
struct fb_info *info)
|
||||
{
|
||||
struct grvga_par *par = info->par;
|
||||
int i;
|
||||
|
||||
if (!var->xres)
|
||||
var->xres = 1;
|
||||
if (!var->yres)
|
||||
var->yres = 1;
|
||||
if (var->bits_per_pixel <= 8)
|
||||
var->bits_per_pixel = 8;
|
||||
else if (var->bits_per_pixel <= 16)
|
||||
var->bits_per_pixel = 16;
|
||||
else if (var->bits_per_pixel <= 24)
|
||||
var->bits_per_pixel = 24;
|
||||
else if (var->bits_per_pixel <= 32)
|
||||
var->bits_per_pixel = 32;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
var->xres_virtual = var->xres;
|
||||
var->yres_virtual = 2*var->yres;
|
||||
|
||||
if (info->fix.smem_len) {
|
||||
if ((var->yres_virtual*var->xres_virtual*var->bits_per_pixel/8) > info->fix.smem_len)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Which clocks that are available can be read out in these registers */
|
||||
for (i = 0; i <= 3 ; i++) {
|
||||
if (var->pixclock == par->regs->clk_vector[i])
|
||||
break;
|
||||
}
|
||||
if (i <= 3)
|
||||
par->clk_sel = i;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
switch (info->var.bits_per_pixel) {
|
||||
case 8:
|
||||
var->red = (struct fb_bitfield) {0, 8, 0}; /* offset, length, msb-right */
|
||||
var->green = (struct fb_bitfield) {0, 8, 0};
|
||||
var->blue = (struct fb_bitfield) {0, 8, 0};
|
||||
var->transp = (struct fb_bitfield) {0, 0, 0};
|
||||
break;
|
||||
case 16:
|
||||
var->red = (struct fb_bitfield) {11, 5, 0};
|
||||
var->green = (struct fb_bitfield) {5, 6, 0};
|
||||
var->blue = (struct fb_bitfield) {0, 5, 0};
|
||||
var->transp = (struct fb_bitfield) {0, 0, 0};
|
||||
break;
|
||||
case 24:
|
||||
case 32:
|
||||
var->red = (struct fb_bitfield) {16, 8, 0};
|
||||
var->green = (struct fb_bitfield) {8, 8, 0};
|
||||
var->blue = (struct fb_bitfield) {0, 8, 0};
|
||||
var->transp = (struct fb_bitfield) {24, 8, 0};
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int grvga_set_par(struct fb_info *info)
|
||||
{
|
||||
|
||||
u32 func = 0;
|
||||
struct grvga_par *par = info->par;
|
||||
|
||||
__raw_writel(((info->var.yres - 1) << 16) | (info->var.xres - 1),
|
||||
&par->regs->video_length);
|
||||
|
||||
__raw_writel((info->var.lower_margin << 16) | (info->var.right_margin),
|
||||
&par->regs->front_porch);
|
||||
|
||||
__raw_writel((info->var.vsync_len << 16) | (info->var.hsync_len),
|
||||
&par->regs->sync_length);
|
||||
|
||||
__raw_writel(((info->var.yres + info->var.lower_margin + info->var.upper_margin + info->var.vsync_len - 1) << 16) |
|
||||
(info->var.xres + info->var.right_margin + info->var.left_margin + info->var.hsync_len - 1),
|
||||
&par->regs->line_length);
|
||||
|
||||
switch (info->var.bits_per_pixel) {
|
||||
case 8:
|
||||
info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
|
||||
func = 1;
|
||||
break;
|
||||
case 16:
|
||||
info->fix.visual = FB_VISUAL_TRUECOLOR;
|
||||
func = 2;
|
||||
break;
|
||||
case 24:
|
||||
case 32:
|
||||
info->fix.visual = FB_VISUAL_TRUECOLOR;
|
||||
func = 3;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
__raw_writel((par->clk_sel << 6) | (func << 4) | 1,
|
||||
&par->regs->status);
|
||||
|
||||
info->fix.line_length = (info->var.xres_virtual*info->var.bits_per_pixel)/8;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int grvga_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info)
|
||||
{
|
||||
struct grvga_par *par;
|
||||
par = info->par;
|
||||
|
||||
if (regno >= 256) /* Size of CLUT */
|
||||
return -EINVAL;
|
||||
|
||||
if (info->var.grayscale) {
|
||||
/* grayscale = 0.30*R + 0.59*G + 0.11*B */
|
||||
red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define CNVT_TOHW(val, width) ((((val)<<(width))+0x7FFF-(val))>>16)
|
||||
|
||||
red = CNVT_TOHW(red, info->var.red.length);
|
||||
green = CNVT_TOHW(green, info->var.green.length);
|
||||
blue = CNVT_TOHW(blue, info->var.blue.length);
|
||||
transp = CNVT_TOHW(transp, info->var.transp.length);
|
||||
|
||||
#undef CNVT_TOHW
|
||||
|
||||
/* In PSEUDOCOLOR we use the hardware CLUT */
|
||||
if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR)
|
||||
__raw_writel((regno << 24) | (red << 16) | (green << 8) | blue,
|
||||
&par->regs->clut);
|
||||
|
||||
/* Truecolor uses the pseudo palette */
|
||||
else if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
|
||||
u32 v;
|
||||
if (regno >= 16)
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
v = (red << info->var.red.offset) |
|
||||
(green << info->var.green.offset) |
|
||||
(blue << info->var.blue.offset) |
|
||||
(transp << info->var.transp.offset);
|
||||
|
||||
((u32 *) (info->pseudo_palette))[regno] = v;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int grvga_pan_display(struct fb_var_screeninfo *var,
|
||||
struct fb_info *info)
|
||||
{
|
||||
struct grvga_par *par = info->par;
|
||||
struct fb_fix_screeninfo *fix = &info->fix;
|
||||
u32 base_addr;
|
||||
|
||||
if (var->xoffset != 0)
|
||||
return -EINVAL;
|
||||
|
||||
base_addr = fix->smem_start + (var->yoffset * fix->line_length);
|
||||
base_addr &= ~3UL;
|
||||
|
||||
/* Set framebuffer base address */
|
||||
__raw_writel(base_addr,
|
||||
&par->regs->fb_pos);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct fb_ops grvga_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.fb_check_var = grvga_check_var,
|
||||
.fb_set_par = grvga_set_par,
|
||||
.fb_setcolreg = grvga_setcolreg,
|
||||
.fb_pan_display = grvga_pan_display,
|
||||
.fb_fillrect = cfb_fillrect,
|
||||
.fb_copyarea = cfb_copyarea,
|
||||
.fb_imageblit = cfb_imageblit
|
||||
};
|
||||
|
||||
static int __init grvga_parse_custom(char *options,
|
||||
struct fb_var_screeninfo *screendata)
|
||||
{
|
||||
char *this_opt;
|
||||
int count = 0;
|
||||
if (!options || !*options)
|
||||
return -1;
|
||||
|
||||
while ((this_opt = strsep(&options, " ")) != NULL) {
|
||||
if (!*this_opt)
|
||||
continue;
|
||||
|
||||
switch (count) {
|
||||
case 0:
|
||||
screendata->pixclock = simple_strtoul(this_opt, NULL, 0);
|
||||
count++;
|
||||
break;
|
||||
case 1:
|
||||
screendata->xres = screendata->xres_virtual = simple_strtoul(this_opt, NULL, 0);
|
||||
count++;
|
||||
break;
|
||||
case 2:
|
||||
screendata->right_margin = simple_strtoul(this_opt, NULL, 0);
|
||||
count++;
|
||||
break;
|
||||
case 3:
|
||||
screendata->hsync_len = simple_strtoul(this_opt, NULL, 0);
|
||||
count++;
|
||||
break;
|
||||
case 4:
|
||||
screendata->left_margin = simple_strtoul(this_opt, NULL, 0);
|
||||
count++;
|
||||
break;
|
||||
case 5:
|
||||
screendata->yres = screendata->yres_virtual = simple_strtoul(this_opt, NULL, 0);
|
||||
count++;
|
||||
break;
|
||||
case 6:
|
||||
screendata->lower_margin = simple_strtoul(this_opt, NULL, 0);
|
||||
count++;
|
||||
break;
|
||||
case 7:
|
||||
screendata->vsync_len = simple_strtoul(this_opt, NULL, 0);
|
||||
count++;
|
||||
break;
|
||||
case 8:
|
||||
screendata->upper_margin = simple_strtoul(this_opt, NULL, 0);
|
||||
count++;
|
||||
break;
|
||||
case 9:
|
||||
screendata->bits_per_pixel = simple_strtoul(this_opt, NULL, 0);
|
||||
count++;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
screendata->activate = FB_ACTIVATE_NOW;
|
||||
screendata->vmode = FB_VMODE_NONINTERLACED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit grvga_probe(struct platform_device *dev)
|
||||
{
|
||||
struct fb_info *info;
|
||||
int retval = -ENOMEM;
|
||||
unsigned long virtual_start;
|
||||
unsigned long grvga_fix_addr = 0;
|
||||
unsigned long physical_start = 0;
|
||||
unsigned long grvga_mem_size = 0;
|
||||
struct grvga_par *par = NULL;
|
||||
char *options = NULL, *mode_opt = NULL;
|
||||
|
||||
info = framebuffer_alloc(sizeof(struct grvga_par), &dev->dev);
|
||||
if (!info) {
|
||||
dev_err(&dev->dev, "framebuffer_alloc failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Expecting: "grvga: modestring, [addr:<framebuffer physical address>], [size:<framebuffer size>]
|
||||
*
|
||||
* If modestring is custom:<custom mode string> we parse the string which then contains all videoparameters
|
||||
* If address is left out, we allocate memory,
|
||||
* if size is left out we only allocate enough to support the given mode.
|
||||
*/
|
||||
if (fb_get_options("grvga", &options)) {
|
||||
retval = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!options || !*options)
|
||||
options = "640x480-8@60";
|
||||
|
||||
while (1) {
|
||||
char *this_opt = strsep(&options, ",");
|
||||
|
||||
if (!this_opt)
|
||||
break;
|
||||
|
||||
if (!strncmp(this_opt, "custom", 6)) {
|
||||
if (grvga_parse_custom(this_opt, &info->var) < 0) {
|
||||
dev_err(&dev->dev, "Failed to parse custom mode (%s).\n", this_opt);
|
||||
retval = -EINVAL;
|
||||
goto err1;
|
||||
}
|
||||
} else if (!strncmp(this_opt, "addr", 4))
|
||||
grvga_fix_addr = simple_strtoul(this_opt + 5, NULL, 16);
|
||||
else if (!strncmp(this_opt, "size", 4))
|
||||
grvga_mem_size = simple_strtoul(this_opt + 5, NULL, 0);
|
||||
else
|
||||
mode_opt = this_opt;
|
||||
}
|
||||
|
||||
par = info->par;
|
||||
info->fbops = &grvga_ops;
|
||||
info->fix = grvga_fix;
|
||||
info->pseudo_palette = par->color_palette;
|
||||
info->flags = FBINFO_DEFAULT | FBINFO_PARTIAL_PAN_OK | FBINFO_HWACCEL_YPAN;
|
||||
info->fix.smem_len = grvga_mem_size;
|
||||
|
||||
if (!request_mem_region(dev->resource[0].start, resource_size(&dev->resource[0]), "grlib-svgactrl regs")) {
|
||||
dev_err(&dev->dev, "registers already mapped\n");
|
||||
retval = -EBUSY;
|
||||
goto err;
|
||||
}
|
||||
|
||||
par->regs = of_ioremap(&dev->resource[0], 0,
|
||||
resource_size(&dev->resource[0]),
|
||||
"grlib-svgactrl regs");
|
||||
|
||||
if (!par->regs) {
|
||||
dev_err(&dev->dev, "failed to map registers\n");
|
||||
retval = -ENOMEM;
|
||||
goto err1;
|
||||
}
|
||||
|
||||
retval = fb_alloc_cmap(&info->cmap, 256, 0);
|
||||
if (retval < 0) {
|
||||
dev_err(&dev->dev, "failed to allocate mem with fb_alloc_cmap\n");
|
||||
retval = -ENOMEM;
|
||||
goto err2;
|
||||
}
|
||||
|
||||
if (mode_opt) {
|
||||
retval = fb_find_mode(&info->var, info, mode_opt,
|
||||
grvga_modedb, sizeof(grvga_modedb), &grvga_modedb[0], 8);
|
||||
if (!retval || retval == 4) {
|
||||
retval = -EINVAL;
|
||||
goto err3;
|
||||
}
|
||||
}
|
||||
|
||||
if (!grvga_mem_size)
|
||||
grvga_mem_size = info->var.xres_virtual * info->var.yres_virtual * info->var.bits_per_pixel/8;
|
||||
|
||||
if (grvga_fix_addr) {
|
||||
/* Got framebuffer base address from argument list */
|
||||
|
||||
physical_start = grvga_fix_addr;
|
||||
|
||||
if (!request_mem_region(physical_start, grvga_mem_size, dev->name)) {
|
||||
dev_err(&dev->dev, "failed to request memory region\n");
|
||||
retval = -ENOMEM;
|
||||
goto err3;
|
||||
}
|
||||
|
||||
virtual_start = (unsigned long) ioremap(physical_start, grvga_mem_size);
|
||||
|
||||
if (!virtual_start) {
|
||||
dev_err(&dev->dev, "error mapping framebuffer memory\n");
|
||||
retval = -ENOMEM;
|
||||
goto err4;
|
||||
}
|
||||
} else { /* Allocate frambuffer memory */
|
||||
|
||||
unsigned long page;
|
||||
|
||||
virtual_start = (unsigned long) __get_free_pages(GFP_DMA,
|
||||
get_order(grvga_mem_size));
|
||||
if (!virtual_start) {
|
||||
dev_err(&dev->dev,
|
||||
"unable to allocate framebuffer memory (%lu bytes)\n",
|
||||
grvga_mem_size);
|
||||
retval = -ENOMEM;
|
||||
goto err3;
|
||||
}
|
||||
|
||||
physical_start = dma_map_single(&dev->dev, (void *)virtual_start, grvga_mem_size, DMA_TO_DEVICE);
|
||||
|
||||
/* Set page reserved so that mmap will work. This is necessary
|
||||
* since we'll be remapping normal memory.
|
||||
*/
|
||||
for (page = virtual_start;
|
||||
page < PAGE_ALIGN(virtual_start + grvga_mem_size);
|
||||
page += PAGE_SIZE) {
|
||||
SetPageReserved(virt_to_page(page));
|
||||
}
|
||||
|
||||
par->fb_alloced = 1;
|
||||
}
|
||||
|
||||
memset((unsigned long *) virtual_start, 0, grvga_mem_size);
|
||||
|
||||
info->screen_base = (char __iomem *) virtual_start;
|
||||
info->fix.smem_start = physical_start;
|
||||
info->fix.smem_len = grvga_mem_size;
|
||||
|
||||
dev_set_drvdata(&dev->dev, info);
|
||||
|
||||
dev_info(&dev->dev,
|
||||
"Aeroflex Gaisler framebuffer device (fb%d), %dx%d-%d, using %luK of video memory @ %p\n",
|
||||
info->node, info->var.xres, info->var.yres, info->var.bits_per_pixel,
|
||||
grvga_mem_size >> 10, info->screen_base);
|
||||
|
||||
retval = register_framebuffer(info);
|
||||
if (retval < 0) {
|
||||
dev_err(&dev->dev, "failed to register framebuffer\n");
|
||||
goto err4;
|
||||
}
|
||||
|
||||
__raw_writel(physical_start, &par->regs->fb_pos);
|
||||
__raw_writel(__raw_readl(&par->regs->status) | 1, /* Enable framebuffer */
|
||||
&par->regs->status);
|
||||
|
||||
return 0;
|
||||
|
||||
err4:
|
||||
dev_set_drvdata(&dev->dev, NULL);
|
||||
if (grvga_fix_addr) {
|
||||
release_mem_region(physical_start, grvga_mem_size);
|
||||
iounmap((void *)virtual_start);
|
||||
} else
|
||||
kfree((void *)virtual_start);
|
||||
err3:
|
||||
fb_dealloc_cmap(&info->cmap);
|
||||
err2:
|
||||
of_iounmap(&dev->resource[0], par->regs,
|
||||
resource_size(&dev->resource[0]));
|
||||
err1:
|
||||
release_mem_region(dev->resource[0].start, resource_size(&dev->resource[0]));
|
||||
err:
|
||||
framebuffer_release(info);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int __devexit grvga_remove(struct platform_device *device)
|
||||
{
|
||||
struct fb_info *info = dev_get_drvdata(&device->dev);
|
||||
struct grvga_par *par = info->par;
|
||||
|
||||
if (info) {
|
||||
unregister_framebuffer(info);
|
||||
fb_dealloc_cmap(&info->cmap);
|
||||
|
||||
of_iounmap(&device->resource[0], par->regs,
|
||||
resource_size(&device->resource[0]));
|
||||
release_mem_region(device->resource[0].start, resource_size(&device->resource[0]));
|
||||
|
||||
if (!par->fb_alloced) {
|
||||
release_mem_region(info->fix.smem_start, info->fix.smem_len);
|
||||
iounmap(info->screen_base);
|
||||
} else
|
||||
kfree((void *)info->screen_base);
|
||||
|
||||
framebuffer_release(info);
|
||||
dev_set_drvdata(&device->dev, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct of_device_id svgactrl_of_match[] = {
|
||||
{
|
||||
.name = "GAISLER_SVGACTRL",
|
||||
},
|
||||
{
|
||||
.name = "01_063",
|
||||
},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, svgactrl_of_match);
|
||||
|
||||
static struct platform_driver grvga_driver = {
|
||||
.driver = {
|
||||
.name = "grlib-svgactrl",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = svgactrl_of_match,
|
||||
},
|
||||
.probe = grvga_probe,
|
||||
.remove = __devexit_p(grvga_remove),
|
||||
};
|
||||
|
||||
|
||||
static int __init grvga_init(void)
|
||||
{
|
||||
return platform_driver_register(&grvga_driver);
|
||||
}
|
||||
|
||||
static void __exit grvga_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&grvga_driver);
|
||||
}
|
||||
|
||||
module_init(grvga_init);
|
||||
module_exit(grvga_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Aeroflex Gaisler");
|
||||
MODULE_DESCRIPTION("Aeroflex Gaisler framebuffer device driver");
|
||||
|
|
@ -543,8 +543,8 @@ static int gxt4500_pan_display(struct fb_var_screeninfo *var,
|
|||
|
||||
if (var->xoffset & 7)
|
||||
return -EINVAL;
|
||||
if (var->xoffset + var->xres > var->xres_virtual ||
|
||||
var->yoffset + var->yres > var->yres_virtual)
|
||||
if (var->xoffset + info->var.xres > info->var.xres_virtual ||
|
||||
var->yoffset + info->var.yres > info->var.yres_virtual)
|
||||
return -EINVAL;
|
||||
|
||||
writereg(par, REFRESH_START, (var->xoffset << 16) | var->yoffset);
|
||||
|
|
|
|||
|
|
@ -422,8 +422,8 @@ static int hgafb_pan_display(struct fb_var_screeninfo *var,
|
|||
var->xoffset)
|
||||
return -EINVAL;
|
||||
} else {
|
||||
if (var->xoffset + var->xres > info->var.xres_virtual
|
||||
|| var->yoffset + var->yres > info->var.yres_virtual
|
||||
if (var->xoffset + info->var.xres > info->var.xres_virtual
|
||||
|| var->yoffset + info->var.yres > info->var.yres_virtual
|
||||
|| var->yoffset % 8)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -749,7 +749,7 @@ set_offset (struct fb_var_screeninfo *var, struct fb_info *info)
|
|||
{
|
||||
struct imstt_par *par = info->par;
|
||||
__u32 off = var->yoffset * (info->fix.line_length >> 3)
|
||||
+ ((var->xoffset * (var->bits_per_pixel >> 3)) >> 3);
|
||||
+ ((var->xoffset * (info->var.bits_per_pixel >> 3)) >> 3);
|
||||
write_reg_le32(par->dc_regs, SSR, off);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -390,12 +390,12 @@ int intelfbhw_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
|
|||
xoffset = ROUND_DOWN_TO(var->xoffset, 8);
|
||||
yoffset = var->yoffset;
|
||||
|
||||
if ((xoffset + var->xres > var->xres_virtual) ||
|
||||
(yoffset + var->yres > var->yres_virtual))
|
||||
if ((xoffset + info->var.xres > info->var.xres_virtual) ||
|
||||
(yoffset + info->var.yres > info->var.yres_virtual))
|
||||
return -EINVAL;
|
||||
|
||||
offset = (yoffset * dinfo->pitch) +
|
||||
(xoffset * var->bits_per_pixel) / 8;
|
||||
(xoffset * info->var.bits_per_pixel) / 8;
|
||||
|
||||
offset += dinfo->fb.offset << 12;
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ static int mb862xx_i2c_wait_event(struct i2c_adapter *adap)
|
|||
u32 reg;
|
||||
|
||||
do {
|
||||
udelay(1);
|
||||
udelay(10);
|
||||
reg = inreg(i2c, GC_I2C_BCR);
|
||||
if (reg & (I2C_INT | I2C_BER))
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -278,7 +278,7 @@ static int mb862xxfb_pan(struct fb_var_screeninfo *var,
|
|||
reg = pack(var->yoffset, var->xoffset);
|
||||
outreg(disp, GC_L0WY_L0WX, reg);
|
||||
|
||||
reg = pack(var->yres_virtual, var->xres_virtual);
|
||||
reg = pack(info->var.yres_virtual, info->var.xres_virtual);
|
||||
outreg(disp, GC_L0WH_L0WW, reg);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -737,7 +737,7 @@ static int __devinit of_platform_mb862xx_probe(struct platform_device *ofdev)
|
|||
if (mb862xx_gdc_init(par))
|
||||
goto io_unmap;
|
||||
|
||||
if (request_irq(par->irq, mb862xx_intr, IRQF_DISABLED,
|
||||
if (request_irq(par->irq, mb862xx_intr, 0,
|
||||
DRV_NAME, (void *)par)) {
|
||||
dev_err(dev, "Cannot request irq\n");
|
||||
goto io_unmap;
|
||||
|
|
@ -1073,7 +1073,7 @@ static int __devinit mb862xx_pci_probe(struct pci_dev *pdev,
|
|||
if (mb862xx_pci_gdc_init(par))
|
||||
goto io_unmap;
|
||||
|
||||
if (request_irq(par->irq, mb862xx_intr, IRQF_DISABLED | IRQF_SHARED,
|
||||
if (request_irq(par->irq, mb862xx_intr, IRQF_SHARED,
|
||||
DRV_NAME, (void *)par)) {
|
||||
dev_err(dev, "Cannot request irq\n");
|
||||
goto io_unmap;
|
||||
|
|
|
|||
|
|
@ -491,55 +491,56 @@ EXPORT_SYMBOL(vesa_modes);
|
|||
static int fb_try_mode(struct fb_var_screeninfo *var, struct fb_info *info,
|
||||
const struct fb_videomode *mode, unsigned int bpp)
|
||||
{
|
||||
int err = 0;
|
||||
int err = 0;
|
||||
|
||||
DPRINTK("Trying mode %s %dx%d-%d@%d\n", mode->name ? mode->name : "noname",
|
||||
mode->xres, mode->yres, bpp, mode->refresh);
|
||||
var->xres = mode->xres;
|
||||
var->yres = mode->yres;
|
||||
var->xres_virtual = mode->xres;
|
||||
var->yres_virtual = mode->yres;
|
||||
var->xoffset = 0;
|
||||
var->yoffset = 0;
|
||||
var->bits_per_pixel = bpp;
|
||||
var->activate |= FB_ACTIVATE_TEST;
|
||||
var->pixclock = mode->pixclock;
|
||||
var->left_margin = mode->left_margin;
|
||||
var->right_margin = mode->right_margin;
|
||||
var->upper_margin = mode->upper_margin;
|
||||
var->lower_margin = mode->lower_margin;
|
||||
var->hsync_len = mode->hsync_len;
|
||||
var->vsync_len = mode->vsync_len;
|
||||
var->sync = mode->sync;
|
||||
var->vmode = mode->vmode;
|
||||
if (info->fbops->fb_check_var)
|
||||
err = info->fbops->fb_check_var(var, info);
|
||||
var->activate &= ~FB_ACTIVATE_TEST;
|
||||
return err;
|
||||
DPRINTK("Trying mode %s %dx%d-%d@%d\n",
|
||||
mode->name ? mode->name : "noname",
|
||||
mode->xres, mode->yres, bpp, mode->refresh);
|
||||
var->xres = mode->xres;
|
||||
var->yres = mode->yres;
|
||||
var->xres_virtual = mode->xres;
|
||||
var->yres_virtual = mode->yres;
|
||||
var->xoffset = 0;
|
||||
var->yoffset = 0;
|
||||
var->bits_per_pixel = bpp;
|
||||
var->activate |= FB_ACTIVATE_TEST;
|
||||
var->pixclock = mode->pixclock;
|
||||
var->left_margin = mode->left_margin;
|
||||
var->right_margin = mode->right_margin;
|
||||
var->upper_margin = mode->upper_margin;
|
||||
var->lower_margin = mode->lower_margin;
|
||||
var->hsync_len = mode->hsync_len;
|
||||
var->vsync_len = mode->vsync_len;
|
||||
var->sync = mode->sync;
|
||||
var->vmode = mode->vmode;
|
||||
if (info->fbops->fb_check_var)
|
||||
err = info->fbops->fb_check_var(var, info);
|
||||
var->activate &= ~FB_ACTIVATE_TEST;
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* fb_find_mode - finds a valid video mode
|
||||
* @var: frame buffer user defined part of display
|
||||
* @info: frame buffer info structure
|
||||
* @mode_option: string video mode to find
|
||||
* @db: video mode database
|
||||
* @dbsize: size of @db
|
||||
* @default_mode: default video mode to fall back to
|
||||
* @default_bpp: default color depth in bits per pixel
|
||||
* fb_find_mode - finds a valid video mode
|
||||
* @var: frame buffer user defined part of display
|
||||
* @info: frame buffer info structure
|
||||
* @mode_option: string video mode to find
|
||||
* @db: video mode database
|
||||
* @dbsize: size of @db
|
||||
* @default_mode: default video mode to fall back to
|
||||
* @default_bpp: default color depth in bits per pixel
|
||||
*
|
||||
* Finds a suitable video mode, starting with the specified mode
|
||||
* in @mode_option with fallback to @default_mode. If
|
||||
* @default_mode fails, all modes in the video mode database will
|
||||
* be tried.
|
||||
* Finds a suitable video mode, starting with the specified mode
|
||||
* in @mode_option with fallback to @default_mode. If
|
||||
* @default_mode fails, all modes in the video mode database will
|
||||
* be tried.
|
||||
*
|
||||
* Valid mode specifiers for @mode_option:
|
||||
* Valid mode specifiers for @mode_option:
|
||||
*
|
||||
* <xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m] or
|
||||
* <name>[-<bpp>][@<refresh>]
|
||||
* <xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m] or
|
||||
* <name>[-<bpp>][@<refresh>]
|
||||
*
|
||||
* with <xres>, <yres>, <bpp> and <refresh> decimal numbers and
|
||||
* <name> a string.
|
||||
* with <xres>, <yres>, <bpp> and <refresh> decimal numbers and
|
||||
* <name> a string.
|
||||
*
|
||||
* If 'M' is present after yres (and before refresh/bpp if present),
|
||||
* the function will compute the timings using VESA(tm) Coordinated
|
||||
|
|
@ -551,12 +552,12 @@ static int fb_try_mode(struct fb_var_screeninfo *var, struct fb_info *info,
|
|||
*
|
||||
* 1024x768MR-8@60m - Reduced blank with margins at 60Hz.
|
||||
*
|
||||
* NOTE: The passed struct @var is _not_ cleared! This allows you
|
||||
* to supply values for e.g. the grayscale and accel_flags fields.
|
||||
* NOTE: The passed struct @var is _not_ cleared! This allows you
|
||||
* to supply values for e.g. the grayscale and accel_flags fields.
|
||||
*
|
||||
* Returns zero for failure, 1 if using specified @mode_option,
|
||||
* 2 if using specified @mode_option with an ignored refresh rate,
|
||||
* 3 if default mode is used, 4 if fall back to any valid mode.
|
||||
* Returns zero for failure, 1 if using specified @mode_option,
|
||||
* 2 if using specified @mode_option with an ignored refresh rate,
|
||||
* 3 if default mode is used, 4 if fall back to any valid mode.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -566,198 +567,203 @@ int fb_find_mode(struct fb_var_screeninfo *var,
|
|||
const struct fb_videomode *default_mode,
|
||||
unsigned int default_bpp)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
/* Set up defaults */
|
||||
if (!db) {
|
||||
db = modedb;
|
||||
dbsize = ARRAY_SIZE(modedb);
|
||||
}
|
||||
|
||||
if (!default_mode)
|
||||
default_mode = &db[0];
|
||||
|
||||
if (!default_bpp)
|
||||
default_bpp = 8;
|
||||
|
||||
/* Did the user specify a video mode? */
|
||||
if (!mode_option)
|
||||
mode_option = fb_mode_option;
|
||||
if (mode_option) {
|
||||
const char *name = mode_option;
|
||||
unsigned int namelen = strlen(name);
|
||||
int res_specified = 0, bpp_specified = 0, refresh_specified = 0;
|
||||
unsigned int xres = 0, yres = 0, bpp = default_bpp, refresh = 0;
|
||||
int yres_specified = 0, cvt = 0, rb = 0, interlace = 0, margins = 0;
|
||||
u32 best, diff, tdiff;
|
||||
|
||||
for (i = namelen-1; i >= 0; i--) {
|
||||
switch (name[i]) {
|
||||
case '@':
|
||||
namelen = i;
|
||||
if (!refresh_specified && !bpp_specified &&
|
||||
!yres_specified) {
|
||||
refresh = simple_strtol(&name[i+1], NULL, 10);
|
||||
refresh_specified = 1;
|
||||
if (cvt || rb)
|
||||
cvt = 0;
|
||||
} else
|
||||
goto done;
|
||||
break;
|
||||
case '-':
|
||||
namelen = i;
|
||||
if (!bpp_specified && !yres_specified) {
|
||||
bpp = simple_strtol(&name[i+1], NULL, 10);
|
||||
bpp_specified = 1;
|
||||
if (cvt || rb)
|
||||
cvt = 0;
|
||||
} else
|
||||
goto done;
|
||||
break;
|
||||
case 'x':
|
||||
if (!yres_specified) {
|
||||
yres = simple_strtol(&name[i+1], NULL, 10);
|
||||
yres_specified = 1;
|
||||
} else
|
||||
goto done;
|
||||
break;
|
||||
case '0' ... '9':
|
||||
break;
|
||||
case 'M':
|
||||
if (!yres_specified)
|
||||
cvt = 1;
|
||||
break;
|
||||
case 'R':
|
||||
if (!cvt)
|
||||
rb = 1;
|
||||
break;
|
||||
case 'm':
|
||||
if (!cvt)
|
||||
margins = 1;
|
||||
break;
|
||||
case 'i':
|
||||
if (!cvt)
|
||||
interlace = 1;
|
||||
break;
|
||||
default:
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if (i < 0 && yres_specified) {
|
||||
xres = simple_strtol(name, NULL, 10);
|
||||
res_specified = 1;
|
||||
}
|
||||
done:
|
||||
if (cvt) {
|
||||
struct fb_videomode cvt_mode;
|
||||
int ret;
|
||||
|
||||
DPRINTK("CVT mode %dx%d@%dHz%s%s%s\n", xres, yres,
|
||||
(refresh) ? refresh : 60, (rb) ? " reduced blanking" :
|
||||
"", (margins) ? " with margins" : "", (interlace) ?
|
||||
" interlaced" : "");
|
||||
|
||||
memset(&cvt_mode, 0, sizeof(cvt_mode));
|
||||
cvt_mode.xres = xres;
|
||||
cvt_mode.yres = yres;
|
||||
cvt_mode.refresh = (refresh) ? refresh : 60;
|
||||
|
||||
if (interlace)
|
||||
cvt_mode.vmode |= FB_VMODE_INTERLACED;
|
||||
else
|
||||
cvt_mode.vmode &= ~FB_VMODE_INTERLACED;
|
||||
|
||||
ret = fb_find_mode_cvt(&cvt_mode, margins, rb);
|
||||
|
||||
if (!ret && !fb_try_mode(var, info, &cvt_mode, bpp)) {
|
||||
DPRINTK("modedb CVT: CVT mode ok\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
DPRINTK("CVT mode invalid, getting mode from database\n");
|
||||
/* Set up defaults */
|
||||
if (!db) {
|
||||
db = modedb;
|
||||
dbsize = ARRAY_SIZE(modedb);
|
||||
}
|
||||
|
||||
DPRINTK("Trying specified video mode%s %ix%i\n",
|
||||
refresh_specified ? "" : " (ignoring refresh rate)", xres, yres);
|
||||
if (!default_mode)
|
||||
default_mode = &db[0];
|
||||
|
||||
if (!refresh_specified) {
|
||||
/*
|
||||
* If the caller has provided a custom mode database and a
|
||||
* valid monspecs structure, we look for the mode with the
|
||||
* highest refresh rate. Otherwise we play it safe it and
|
||||
* try to find a mode with a refresh rate closest to the
|
||||
* standard 60 Hz.
|
||||
*/
|
||||
if (db != modedb &&
|
||||
info->monspecs.vfmin && info->monspecs.vfmax &&
|
||||
info->monspecs.hfmin && info->monspecs.hfmax &&
|
||||
info->monspecs.dclkmax) {
|
||||
refresh = 1000;
|
||||
} else {
|
||||
refresh = 60;
|
||||
if (!default_bpp)
|
||||
default_bpp = 8;
|
||||
|
||||
/* Did the user specify a video mode? */
|
||||
if (!mode_option)
|
||||
mode_option = fb_mode_option;
|
||||
if (mode_option) {
|
||||
const char *name = mode_option;
|
||||
unsigned int namelen = strlen(name);
|
||||
int res_specified = 0, bpp_specified = 0, refresh_specified = 0;
|
||||
unsigned int xres = 0, yres = 0, bpp = default_bpp, refresh = 0;
|
||||
int yres_specified = 0, cvt = 0, rb = 0, interlace = 0;
|
||||
int margins = 0;
|
||||
u32 best, diff, tdiff;
|
||||
|
||||
for (i = namelen-1; i >= 0; i--) {
|
||||
switch (name[i]) {
|
||||
case '@':
|
||||
namelen = i;
|
||||
if (!refresh_specified && !bpp_specified &&
|
||||
!yres_specified) {
|
||||
refresh = simple_strtol(&name[i+1], NULL,
|
||||
10);
|
||||
refresh_specified = 1;
|
||||
if (cvt || rb)
|
||||
cvt = 0;
|
||||
} else
|
||||
goto done;
|
||||
break;
|
||||
case '-':
|
||||
namelen = i;
|
||||
if (!bpp_specified && !yres_specified) {
|
||||
bpp = simple_strtol(&name[i+1], NULL,
|
||||
10);
|
||||
bpp_specified = 1;
|
||||
if (cvt || rb)
|
||||
cvt = 0;
|
||||
} else
|
||||
goto done;
|
||||
break;
|
||||
case 'x':
|
||||
if (!yres_specified) {
|
||||
yres = simple_strtol(&name[i+1], NULL,
|
||||
10);
|
||||
yres_specified = 1;
|
||||
} else
|
||||
goto done;
|
||||
break;
|
||||
case '0' ... '9':
|
||||
break;
|
||||
case 'M':
|
||||
if (!yres_specified)
|
||||
cvt = 1;
|
||||
break;
|
||||
case 'R':
|
||||
if (!cvt)
|
||||
rb = 1;
|
||||
break;
|
||||
case 'm':
|
||||
if (!cvt)
|
||||
margins = 1;
|
||||
break;
|
||||
case 'i':
|
||||
if (!cvt)
|
||||
interlace = 1;
|
||||
break;
|
||||
default:
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i < 0 && yres_specified) {
|
||||
xres = simple_strtol(name, NULL, 10);
|
||||
res_specified = 1;
|
||||
}
|
||||
done:
|
||||
if (cvt) {
|
||||
struct fb_videomode cvt_mode;
|
||||
int ret;
|
||||
|
||||
diff = -1;
|
||||
best = -1;
|
||||
for (i = 0; i < dbsize; i++) {
|
||||
if ((name_matches(db[i], name, namelen) ||
|
||||
(res_specified && res_matches(db[i], xres, yres))) &&
|
||||
!fb_try_mode(var, info, &db[i], bpp)) {
|
||||
if (refresh_specified && db[i].refresh == refresh) {
|
||||
DPRINTK("CVT mode %dx%d@%dHz%s%s%s\n", xres, yres,
|
||||
(refresh) ? refresh : 60,
|
||||
(rb) ? " reduced blanking" : "",
|
||||
(margins) ? " with margins" : "",
|
||||
(interlace) ? " interlaced" : "");
|
||||
|
||||
memset(&cvt_mode, 0, sizeof(cvt_mode));
|
||||
cvt_mode.xres = xres;
|
||||
cvt_mode.yres = yres;
|
||||
cvt_mode.refresh = (refresh) ? refresh : 60;
|
||||
|
||||
if (interlace)
|
||||
cvt_mode.vmode |= FB_VMODE_INTERLACED;
|
||||
else
|
||||
cvt_mode.vmode &= ~FB_VMODE_INTERLACED;
|
||||
|
||||
ret = fb_find_mode_cvt(&cvt_mode, margins, rb);
|
||||
|
||||
if (!ret && !fb_try_mode(var, info, &cvt_mode, bpp)) {
|
||||
DPRINTK("modedb CVT: CVT mode ok\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
DPRINTK("CVT mode invalid, getting mode from database\n");
|
||||
}
|
||||
|
||||
DPRINTK("Trying specified video mode%s %ix%i\n",
|
||||
refresh_specified ? "" : " (ignoring refresh rate)",
|
||||
xres, yres);
|
||||
|
||||
if (!refresh_specified) {
|
||||
/*
|
||||
* If the caller has provided a custom mode database and
|
||||
* a valid monspecs structure, we look for the mode with
|
||||
* the highest refresh rate. Otherwise we play it safe
|
||||
* it and try to find a mode with a refresh rate closest
|
||||
* to the standard 60 Hz.
|
||||
*/
|
||||
if (db != modedb &&
|
||||
info->monspecs.vfmin && info->monspecs.vfmax &&
|
||||
info->monspecs.hfmin && info->monspecs.hfmax &&
|
||||
info->monspecs.dclkmax) {
|
||||
refresh = 1000;
|
||||
} else {
|
||||
refresh = 60;
|
||||
}
|
||||
}
|
||||
|
||||
diff = -1;
|
||||
best = -1;
|
||||
for (i = 0; i < dbsize; i++) {
|
||||
if ((name_matches(db[i], name, namelen) ||
|
||||
(res_specified && res_matches(db[i], xres, yres))) &&
|
||||
!fb_try_mode(var, info, &db[i], bpp)) {
|
||||
if (refresh_specified && db[i].refresh == refresh)
|
||||
return 1;
|
||||
|
||||
if (abs(db[i].refresh - refresh) < diff) {
|
||||
diff = abs(db[i].refresh - refresh);
|
||||
best = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (best != -1) {
|
||||
fb_try_mode(var, info, &db[best], bpp);
|
||||
return (refresh_specified) ? 2 : 1;
|
||||
}
|
||||
if (best != -1) {
|
||||
fb_try_mode(var, info, &db[best], bpp);
|
||||
return (refresh_specified) ? 2 : 1;
|
||||
}
|
||||
|
||||
diff = 2 * (xres + yres);
|
||||
best = -1;
|
||||
DPRINTK("Trying best-fit modes\n");
|
||||
for (i = 0; i < dbsize; i++) {
|
||||
DPRINTK("Trying %ix%i\n", db[i].xres, db[i].yres);
|
||||
if (!fb_try_mode(var, info, &db[i], bpp)) {
|
||||
tdiff = abs(db[i].xres - xres) +
|
||||
abs(db[i].yres - yres);
|
||||
diff = 2 * (xres + yres);
|
||||
best = -1;
|
||||
DPRINTK("Trying best-fit modes\n");
|
||||
for (i = 0; i < dbsize; i++) {
|
||||
DPRINTK("Trying %ix%i\n", db[i].xres, db[i].yres);
|
||||
if (!fb_try_mode(var, info, &db[i], bpp)) {
|
||||
tdiff = abs(db[i].xres - xres) +
|
||||
abs(db[i].yres - yres);
|
||||
|
||||
/*
|
||||
* Penalize modes with resolutions smaller
|
||||
* than requested.
|
||||
*/
|
||||
if (xres > db[i].xres || yres > db[i].yres)
|
||||
tdiff += xres + yres;
|
||||
/*
|
||||
* Penalize modes with resolutions smaller
|
||||
* than requested.
|
||||
*/
|
||||
if (xres > db[i].xres || yres > db[i].yres)
|
||||
tdiff += xres + yres;
|
||||
|
||||
if (diff > tdiff) {
|
||||
diff = tdiff;
|
||||
best = i;
|
||||
if (diff > tdiff) {
|
||||
diff = tdiff;
|
||||
best = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (best != -1) {
|
||||
fb_try_mode(var, info, &db[best], bpp);
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
if (best != -1) {
|
||||
fb_try_mode(var, info, &db[best], bpp);
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
|
||||
DPRINTK("Trying default video mode\n");
|
||||
if (!fb_try_mode(var, info, default_mode, default_bpp))
|
||||
return 3;
|
||||
DPRINTK("Trying default video mode\n");
|
||||
if (!fb_try_mode(var, info, default_mode, default_bpp))
|
||||
return 3;
|
||||
|
||||
DPRINTK("Trying all modes\n");
|
||||
for (i = 0; i < dbsize; i++)
|
||||
if (!fb_try_mode(var, info, &db[i], default_bpp))
|
||||
return 4;
|
||||
DPRINTK("Trying all modes\n");
|
||||
for (i = 0; i < dbsize; i++)
|
||||
if (!fb_try_mode(var, info, &db[i], default_bpp))
|
||||
return 4;
|
||||
|
||||
DPRINTK("No valid mode found\n");
|
||||
return 0;
|
||||
DPRINTK("No valid mode found\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -715,7 +715,7 @@ static int __devinit mddi_probe(struct platform_device *pdev)
|
|||
|
||||
mddi->int_enable = 0;
|
||||
mddi_writel(mddi->int_enable, INTEN);
|
||||
ret = request_irq(mddi->irq, mddi_isr, IRQF_DISABLED, "mddi",
|
||||
ret = request_irq(mddi->irq, mddi_isr, 0, "mddi",
|
||||
&mddi->client_data);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "mddi: failed to request enable irq!\n");
|
||||
|
|
|
|||
|
|
@ -421,10 +421,11 @@ int mdp_probe(struct platform_device *pdev)
|
|||
clk = clk_get(&pdev->dev, "mdp_clk");
|
||||
if (IS_ERR(clk)) {
|
||||
printk(KERN_INFO "mdp: failed to get mdp clk");
|
||||
return PTR_ERR(clk);
|
||||
ret = PTR_ERR(clk);
|
||||
goto error_get_clk;
|
||||
}
|
||||
|
||||
ret = request_irq(mdp->irq, mdp_isr, IRQF_DISABLED, "msm_mdp", mdp);
|
||||
ret = request_irq(mdp->irq, mdp_isr, 0, "msm_mdp", mdp);
|
||||
if (ret)
|
||||
goto error_request_irq;
|
||||
disable_irq(mdp->irq);
|
||||
|
|
@ -495,6 +496,7 @@ int mdp_probe(struct platform_device *pdev)
|
|||
error_device_register:
|
||||
free_irq(mdp->irq, mdp);
|
||||
error_request_irq:
|
||||
error_get_clk:
|
||||
iounmap(mdp->base);
|
||||
error_get_irq:
|
||||
error_ioremap:
|
||||
|
|
|
|||
|
|
@ -382,6 +382,9 @@ static void sdc_disable_channel(struct mx3fb_info *mx3_fbi)
|
|||
uint32_t enabled;
|
||||
unsigned long flags;
|
||||
|
||||
if (mx3_fbi->txd == NULL)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&mx3fb->lock, flags);
|
||||
|
||||
enabled = sdc_fb_uninit(mx3_fbi);
|
||||
|
|
@ -986,9 +989,19 @@ static void __blank(int blank, struct fb_info *fbi)
|
|||
{
|
||||
struct mx3fb_info *mx3_fbi = fbi->par;
|
||||
struct mx3fb_data *mx3fb = mx3_fbi->mx3fb;
|
||||
int was_blank = mx3_fbi->blank;
|
||||
|
||||
mx3_fbi->blank = blank;
|
||||
|
||||
/* Attention!
|
||||
* Do not call sdc_disable_channel() for a channel that is disabled
|
||||
* already! This will result in a kernel NULL pointer dereference
|
||||
* (mx3_fbi->txd is NULL). Hide the fact, that all blank modes are
|
||||
* handled equally by this driver.
|
||||
*/
|
||||
if (blank > FB_BLANK_UNBLANK && was_blank > FB_BLANK_UNBLANK)
|
||||
return;
|
||||
|
||||
switch (blank) {
|
||||
case FB_BLANK_POWERDOWN:
|
||||
case FB_BLANK_VSYNC_SUSPEND:
|
||||
|
|
@ -1062,15 +1075,15 @@ static int mx3fb_pan_display(struct fb_var_screeninfo *var,
|
|||
y_bottom = var->yoffset;
|
||||
|
||||
if (!(var->vmode & FB_VMODE_YWRAP))
|
||||
y_bottom += var->yres;
|
||||
y_bottom += fbi->var.yres;
|
||||
|
||||
if (y_bottom > fbi->var.yres_virtual)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&mx3_fbi->mutex);
|
||||
|
||||
offset = (var->yoffset * var->xres_virtual + var->xoffset) *
|
||||
(var->bits_per_pixel / 8);
|
||||
offset = var->yoffset * fbi->fix.line_length
|
||||
+ var->xoffset * (fbi->var.bits_per_pixel / 8);
|
||||
base = fbi->fix.smem_start + offset;
|
||||
|
||||
dev_dbg(fbi->device, "Updating SDC BG buf %d address=0x%08lX\n",
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
* the required value in the imx_fb_videomode structure.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/clk.h>
|
||||
|
|
|
|||
|
|
@ -1185,8 +1185,8 @@ static int neofb_pan_display(struct fb_var_screeninfo *var,
|
|||
|
||||
DBG("neofb_update_start");
|
||||
|
||||
Base = (var->yoffset * var->xres_virtual + var->xoffset) >> 2;
|
||||
Base *= (var->bits_per_pixel + 7) / 8;
|
||||
Base = (var->yoffset * info->var.xres_virtual + var->xoffset) >> 2;
|
||||
Base *= (info->var.bits_per_pixel + 7) / 8;
|
||||
|
||||
neoUnlock();
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@
|
|||
#include <mach/regs-clock.h>
|
||||
#include <mach/regs-ldm.h>
|
||||
#include <mach/fb.h>
|
||||
#include <mach/clkdev.h>
|
||||
|
||||
#include "nuc900fb.h"
|
||||
|
||||
|
|
@ -588,7 +587,7 @@ static int __devinit nuc900fb_probe(struct platform_device *pdev)
|
|||
fbinfo->flags = FBINFO_FLAG_DEFAULT;
|
||||
fbinfo->pseudo_palette = &fbi->pseudo_pal;
|
||||
|
||||
ret = request_irq(irq, nuc900fb_irqhandler, IRQF_DISABLED,
|
||||
ret = request_irq(irq, nuc900fb_irqhandler, 0,
|
||||
pdev->name, fbinfo);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "cannot register irq handler %d -err %d\n",
|
||||
|
|
|
|||
|
|
@ -9,35 +9,6 @@ config FB_OMAP
|
|||
help
|
||||
Frame buffer driver for OMAP based boards.
|
||||
|
||||
config FB_OMAP_LCD_VGA
|
||||
bool "Use LCD in VGA mode"
|
||||
depends on MACH_OMAP_3430SDP || MACH_OMAP_LDP
|
||||
help
|
||||
Set LCD resolution as VGA (640 X 480).
|
||||
Default resolution without this option is QVGA(320 X 240).
|
||||
Please take a look at drivers/video/omap/lcd_ldp.c file
|
||||
for lcd driver code.
|
||||
choice
|
||||
depends on FB_OMAP && MACH_OVERO
|
||||
prompt "Screen resolution"
|
||||
default FB_OMAP_079M3R
|
||||
help
|
||||
Selected desired screen resolution
|
||||
|
||||
config FB_OMAP_031M3R
|
||||
boolean "640 x 480 @ 60 Hz Reduced blanking"
|
||||
|
||||
config FB_OMAP_048M3R
|
||||
boolean "800 x 600 @ 60 Hz Reduced blanking"
|
||||
|
||||
config FB_OMAP_079M3R
|
||||
boolean "1024 x 768 @ 60 Hz Reduced blanking"
|
||||
|
||||
config FB_OMAP_092M9R
|
||||
boolean "1280 x 720 @ 60 Hz Reduced blanking"
|
||||
|
||||
endchoice
|
||||
|
||||
config FB_OMAP_LCDC_EXTERNAL
|
||||
bool "External LCD controller support"
|
||||
depends on FB_OMAP
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ objs-y$(CONFIG_FB_OMAP_LCDC_HWA742) += hwa742.o
|
|||
objs-y$(CONFIG_FB_OMAP_LCDC_BLIZZARD) += blizzard.o
|
||||
|
||||
objs-y$(CONFIG_MACH_AMS_DELTA) += lcd_ams_delta.o
|
||||
objs-y$(CONFIG_MACH_OMAP_H4) += lcd_h4.o
|
||||
objs-y$(CONFIG_MACH_OMAP_H3) += lcd_h3.o
|
||||
objs-y$(CONFIG_MACH_OMAP_PALMTE) += lcd_palmte.o
|
||||
objs-y$(CONFIG_MACH_OMAP_PALMTT) += lcd_palmtt.o
|
||||
|
|
@ -26,14 +25,7 @@ objs-$(CONFIG_ARCH_OMAP16XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1610.o
|
|||
objs-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1510.o
|
||||
objs-y$(CONFIG_MACH_OMAP_OSK) += lcd_osk.o
|
||||
|
||||
objs-y$(CONFIG_MACH_OMAP_APOLLON) += lcd_apollon.o
|
||||
objs-y$(CONFIG_MACH_OMAP_2430SDP) += lcd_2430sdp.o
|
||||
objs-y$(CONFIG_MACH_OMAP_3430SDP) += lcd_2430sdp.o
|
||||
objs-y$(CONFIG_MACH_OMAP_LDP) += lcd_ldp.o
|
||||
objs-y$(CONFIG_MACH_OMAP3EVM) += lcd_omap3evm.o
|
||||
objs-y$(CONFIG_MACH_OMAP3_BEAGLE) += lcd_omap3beagle.o
|
||||
objs-y$(CONFIG_FB_OMAP_LCD_MIPID) += lcd_mipid.o
|
||||
objs-y$(CONFIG_MACH_OVERO) += lcd_overo.o
|
||||
objs-y$(CONFIG_MACH_HERALD) += lcd_htcherald.o
|
||||
|
||||
omapfb-objs := $(objs-yy)
|
||||
|
|
|
|||
|
|
@ -1,203 +0,0 @@
|
|||
/*
|
||||
* LCD panel support for the TI 2430SDP board
|
||||
*
|
||||
* Copyright (C) 2007 MontaVista
|
||||
* Author: Hunyue Yau <hyau@mvista.com>
|
||||
*
|
||||
* Derived from drivers/video/omap/lcd-apollon.c
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/i2c/twl.h>
|
||||
|
||||
#include <plat/mux.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include "omapfb.h"
|
||||
|
||||
#define SDP2430_LCD_PANEL_BACKLIGHT_GPIO 91
|
||||
#define SDP2430_LCD_PANEL_ENABLE_GPIO 154
|
||||
#define SDP3430_LCD_PANEL_BACKLIGHT_GPIO 24
|
||||
#define SDP3430_LCD_PANEL_ENABLE_GPIO 28
|
||||
|
||||
static unsigned backlight_gpio;
|
||||
static unsigned enable_gpio;
|
||||
|
||||
#define LCD_PIXCLOCK_MAX 5400 /* freq 5.4 MHz */
|
||||
#define PM_RECEIVER TWL4030_MODULE_PM_RECEIVER
|
||||
#define ENABLE_VAUX2_DEDICATED 0x09
|
||||
#define ENABLE_VAUX2_DEV_GRP 0x20
|
||||
#define ENABLE_VAUX3_DEDICATED 0x03
|
||||
#define ENABLE_VAUX3_DEV_GRP 0x20
|
||||
|
||||
#define ENABLE_VPLL2_DEDICATED 0x05
|
||||
#define ENABLE_VPLL2_DEV_GRP 0xE0
|
||||
#define TWL4030_VPLL2_DEV_GRP 0x33
|
||||
#define TWL4030_VPLL2_DEDICATED 0x36
|
||||
|
||||
#define t2_out(c, r, v) twl_i2c_write_u8(c, r, v)
|
||||
|
||||
|
||||
static int sdp2430_panel_init(struct lcd_panel *panel,
|
||||
struct omapfb_device *fbdev)
|
||||
{
|
||||
if (machine_is_omap_3430sdp()) {
|
||||
enable_gpio = SDP3430_LCD_PANEL_ENABLE_GPIO;
|
||||
backlight_gpio = SDP3430_LCD_PANEL_BACKLIGHT_GPIO;
|
||||
} else {
|
||||
enable_gpio = SDP2430_LCD_PANEL_ENABLE_GPIO;
|
||||
backlight_gpio = SDP2430_LCD_PANEL_BACKLIGHT_GPIO;
|
||||
}
|
||||
|
||||
gpio_request(enable_gpio, "LCD enable"); /* LCD panel */
|
||||
gpio_request(backlight_gpio, "LCD bl"); /* LCD backlight */
|
||||
gpio_direction_output(enable_gpio, 0);
|
||||
gpio_direction_output(backlight_gpio, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sdp2430_panel_cleanup(struct lcd_panel *panel)
|
||||
{
|
||||
gpio_free(backlight_gpio);
|
||||
gpio_free(enable_gpio);
|
||||
}
|
||||
|
||||
static int sdp2430_panel_enable(struct lcd_panel *panel)
|
||||
{
|
||||
u8 ded_val, ded_reg;
|
||||
u8 grp_val, grp_reg;
|
||||
|
||||
if (machine_is_omap_3430sdp()) {
|
||||
ded_reg = TWL4030_VAUX3_DEDICATED;
|
||||
ded_val = ENABLE_VAUX3_DEDICATED;
|
||||
grp_reg = TWL4030_VAUX3_DEV_GRP;
|
||||
grp_val = ENABLE_VAUX3_DEV_GRP;
|
||||
|
||||
if (omap_rev() > OMAP3430_REV_ES1_0) {
|
||||
t2_out(PM_RECEIVER, ENABLE_VPLL2_DEDICATED,
|
||||
TWL4030_VPLL2_DEDICATED);
|
||||
t2_out(PM_RECEIVER, ENABLE_VPLL2_DEV_GRP,
|
||||
TWL4030_VPLL2_DEV_GRP);
|
||||
}
|
||||
} else {
|
||||
ded_reg = TWL4030_VAUX2_DEDICATED;
|
||||
ded_val = ENABLE_VAUX2_DEDICATED;
|
||||
grp_reg = TWL4030_VAUX2_DEV_GRP;
|
||||
grp_val = ENABLE_VAUX2_DEV_GRP;
|
||||
}
|
||||
|
||||
gpio_set_value(enable_gpio, 1);
|
||||
gpio_set_value(backlight_gpio, 1);
|
||||
|
||||
if (0 != t2_out(PM_RECEIVER, ded_val, ded_reg))
|
||||
return -EIO;
|
||||
if (0 != t2_out(PM_RECEIVER, grp_val, grp_reg))
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sdp2430_panel_disable(struct lcd_panel *panel)
|
||||
{
|
||||
gpio_set_value(enable_gpio, 0);
|
||||
gpio_set_value(backlight_gpio, 0);
|
||||
if (omap_rev() > OMAP3430_REV_ES1_0) {
|
||||
t2_out(PM_RECEIVER, 0x0, TWL4030_VPLL2_DEDICATED);
|
||||
t2_out(PM_RECEIVER, 0x0, TWL4030_VPLL2_DEV_GRP);
|
||||
msleep(4);
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned long sdp2430_panel_get_caps(struct lcd_panel *panel)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct lcd_panel sdp2430_panel = {
|
||||
.name = "sdp2430",
|
||||
.config = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC |
|
||||
OMAP_LCDC_INV_HSYNC,
|
||||
|
||||
.bpp = 16,
|
||||
.data_lines = 16,
|
||||
.x_res = 240,
|
||||
.y_res = 320,
|
||||
.hsw = 3, /* hsync_len (4) - 1 */
|
||||
.hfp = 3, /* right_margin (4) - 1 */
|
||||
.hbp = 39, /* left_margin (40) - 1 */
|
||||
.vsw = 1, /* vsync_len (2) - 1 */
|
||||
.vfp = 2, /* lower_margin */
|
||||
.vbp = 7, /* upper_margin (8) - 1 */
|
||||
|
||||
.pixel_clock = LCD_PIXCLOCK_MAX,
|
||||
|
||||
.init = sdp2430_panel_init,
|
||||
.cleanup = sdp2430_panel_cleanup,
|
||||
.enable = sdp2430_panel_enable,
|
||||
.disable = sdp2430_panel_disable,
|
||||
.get_caps = sdp2430_panel_get_caps,
|
||||
};
|
||||
|
||||
static int sdp2430_panel_probe(struct platform_device *pdev)
|
||||
{
|
||||
omapfb_register_panel(&sdp2430_panel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sdp2430_panel_remove(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sdp2430_panel_suspend(struct platform_device *pdev,
|
||||
pm_message_t mesg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sdp2430_panel_resume(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct platform_driver sdp2430_panel_driver = {
|
||||
.probe = sdp2430_panel_probe,
|
||||
.remove = sdp2430_panel_remove,
|
||||
.suspend = sdp2430_panel_suspend,
|
||||
.resume = sdp2430_panel_resume,
|
||||
.driver = {
|
||||
.name = "sdp2430_lcd",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init sdp2430_panel_drv_init(void)
|
||||
{
|
||||
return platform_driver_register(&sdp2430_panel_driver);
|
||||
}
|
||||
|
||||
static void __exit sdp2430_panel_drv_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&sdp2430_panel_driver);
|
||||
}
|
||||
|
||||
module_init(sdp2430_panel_drv_init);
|
||||
module_exit(sdp2430_panel_drv_exit);
|
||||
|
|
@ -1,136 +0,0 @@
|
|||
/*
|
||||
* LCD panel support for the Samsung OMAP2 Apollon board
|
||||
*
|
||||
* Copyright (C) 2005,2006 Samsung Electronics
|
||||
* Author: Kyungmin Park <kyungmin.park@samsung.com>
|
||||
*
|
||||
* Derived from drivers/video/omap/lcd-h4.c
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <asm/gpio.h>
|
||||
|
||||
#include "omapfb.h"
|
||||
|
||||
/* #define USE_35INCH_LCD 1 */
|
||||
|
||||
static int apollon_panel_init(struct lcd_panel *panel,
|
||||
struct omapfb_device *fbdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void apollon_panel_cleanup(struct lcd_panel *panel)
|
||||
{
|
||||
}
|
||||
|
||||
static int apollon_panel_enable(struct lcd_panel *panel)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void apollon_panel_disable(struct lcd_panel *panel)
|
||||
{
|
||||
}
|
||||
|
||||
static unsigned long apollon_panel_get_caps(struct lcd_panel *panel)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct lcd_panel apollon_panel = {
|
||||
.name = "apollon",
|
||||
.config = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC |
|
||||
OMAP_LCDC_INV_HSYNC,
|
||||
|
||||
.bpp = 16,
|
||||
.data_lines = 18,
|
||||
#ifdef USE_35INCH_LCD
|
||||
.x_res = 240,
|
||||
.y_res = 320,
|
||||
.hsw = 2,
|
||||
.hfp = 3,
|
||||
.hbp = 9,
|
||||
.vsw = 4,
|
||||
.vfp = 3,
|
||||
.vbp = 5,
|
||||
#else
|
||||
.x_res = 480,
|
||||
.y_res = 272,
|
||||
.hsw = 41,
|
||||
.hfp = 2,
|
||||
.hbp = 2,
|
||||
.vsw = 10,
|
||||
.vfp = 2,
|
||||
.vbp = 2,
|
||||
#endif
|
||||
.pixel_clock = 6250,
|
||||
|
||||
.init = apollon_panel_init,
|
||||
.cleanup = apollon_panel_cleanup,
|
||||
.enable = apollon_panel_enable,
|
||||
.disable = apollon_panel_disable,
|
||||
.get_caps = apollon_panel_get_caps,
|
||||
};
|
||||
|
||||
static int apollon_panel_probe(struct platform_device *pdev)
|
||||
{
|
||||
omapfb_register_panel(&apollon_panel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int apollon_panel_remove(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int apollon_panel_suspend(struct platform_device *pdev,
|
||||
pm_message_t mesg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int apollon_panel_resume(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct platform_driver apollon_panel_driver = {
|
||||
.probe = apollon_panel_probe,
|
||||
.remove = apollon_panel_remove,
|
||||
.suspend = apollon_panel_suspend,
|
||||
.resume = apollon_panel_resume,
|
||||
.driver = {
|
||||
.name = "apollon_lcd",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init apollon_panel_drv_init(void)
|
||||
{
|
||||
return platform_driver_register(&apollon_panel_driver);
|
||||
}
|
||||
|
||||
static void __exit apollon_panel_drv_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&apollon_panel_driver);
|
||||
}
|
||||
|
||||
module_init(apollon_panel_drv_init);
|
||||
module_exit(apollon_panel_drv_exit);
|
||||
|
|
@ -1,117 +0,0 @@
|
|||
/*
|
||||
* LCD panel support for the TI OMAP H4 board
|
||||
*
|
||||
* Copyright (C) 2004 Nokia Corporation
|
||||
* Author: Imre Deak <imre.deak@nokia.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "omapfb.h"
|
||||
|
||||
static int h4_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void h4_panel_cleanup(struct lcd_panel *panel)
|
||||
{
|
||||
}
|
||||
|
||||
static int h4_panel_enable(struct lcd_panel *panel)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void h4_panel_disable(struct lcd_panel *panel)
|
||||
{
|
||||
}
|
||||
|
||||
static unsigned long h4_panel_get_caps(struct lcd_panel *panel)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct lcd_panel h4_panel = {
|
||||
.name = "h4",
|
||||
.config = OMAP_LCDC_PANEL_TFT,
|
||||
|
||||
.bpp = 16,
|
||||
.data_lines = 16,
|
||||
.x_res = 240,
|
||||
.y_res = 320,
|
||||
.pixel_clock = 6250,
|
||||
.hsw = 15,
|
||||
.hfp = 15,
|
||||
.hbp = 60,
|
||||
.vsw = 1,
|
||||
.vfp = 1,
|
||||
.vbp = 1,
|
||||
|
||||
.init = h4_panel_init,
|
||||
.cleanup = h4_panel_cleanup,
|
||||
.enable = h4_panel_enable,
|
||||
.disable = h4_panel_disable,
|
||||
.get_caps = h4_panel_get_caps,
|
||||
};
|
||||
|
||||
static int h4_panel_probe(struct platform_device *pdev)
|
||||
{
|
||||
omapfb_register_panel(&h4_panel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int h4_panel_remove(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int h4_panel_suspend(struct platform_device *pdev, pm_message_t mesg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int h4_panel_resume(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver h4_panel_driver = {
|
||||
.probe = h4_panel_probe,
|
||||
.remove = h4_panel_remove,
|
||||
.suspend = h4_panel_suspend,
|
||||
.resume = h4_panel_resume,
|
||||
.driver = {
|
||||
.name = "lcd_h4",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init h4_panel_drv_init(void)
|
||||
{
|
||||
return platform_driver_register(&h4_panel_driver);
|
||||
}
|
||||
|
||||
static void __exit h4_panel_drv_cleanup(void)
|
||||
{
|
||||
platform_driver_unregister(&h4_panel_driver);
|
||||
}
|
||||
|
||||
module_init(h4_panel_drv_init);
|
||||
module_exit(h4_panel_drv_cleanup);
|
||||
|
||||
|
|
@ -1,201 +0,0 @@
|
|||
/*
|
||||
* LCD panel support for the TI LDP board
|
||||
*
|
||||
* Copyright (C) 2007 WindRiver
|
||||
* Author: Stanley Miao <stanley.miao@windriver.com>
|
||||
*
|
||||
* Derived from drivers/video/omap/lcd-2430sdp.c
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/i2c/twl.h>
|
||||
|
||||
#include <asm/gpio.h>
|
||||
#include <plat/mux.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include "omapfb.h"
|
||||
|
||||
#define LCD_PANEL_BACKLIGHT_GPIO (15 + OMAP_MAX_GPIO_LINES)
|
||||
#define LCD_PANEL_ENABLE_GPIO (7 + OMAP_MAX_GPIO_LINES)
|
||||
|
||||
#define LCD_PANEL_RESET_GPIO 55
|
||||
#define LCD_PANEL_QVGA_GPIO 56
|
||||
|
||||
#ifdef CONFIG_FB_OMAP_LCD_VGA
|
||||
#define LCD_XRES 480
|
||||
#define LCD_YRES 640
|
||||
#define LCD_PIXCLOCK_MAX 41700
|
||||
#else
|
||||
#define LCD_XRES 240
|
||||
#define LCD_YRES 320
|
||||
#define LCD_PIXCLOCK_MAX 185186
|
||||
#endif
|
||||
|
||||
#define PM_RECEIVER TWL4030_MODULE_PM_RECEIVER
|
||||
#define ENABLE_VAUX2_DEDICATED 0x09
|
||||
#define ENABLE_VAUX2_DEV_GRP 0x20
|
||||
#define ENABLE_VAUX3_DEDICATED 0x03
|
||||
#define ENABLE_VAUX3_DEV_GRP 0x20
|
||||
|
||||
#define ENABLE_VPLL2_DEDICATED 0x05
|
||||
#define ENABLE_VPLL2_DEV_GRP 0xE0
|
||||
#define TWL4030_VPLL2_DEV_GRP 0x33
|
||||
#define TWL4030_VPLL2_DEDICATED 0x36
|
||||
|
||||
#define t2_out(c, r, v) twl_i2c_write_u8(c, r, v)
|
||||
|
||||
|
||||
static int ldp_panel_init(struct lcd_panel *panel,
|
||||
struct omapfb_device *fbdev)
|
||||
{
|
||||
gpio_request(LCD_PANEL_RESET_GPIO, "lcd reset");
|
||||
gpio_request(LCD_PANEL_QVGA_GPIO, "lcd qvga");
|
||||
gpio_request(LCD_PANEL_ENABLE_GPIO, "lcd panel");
|
||||
gpio_request(LCD_PANEL_BACKLIGHT_GPIO, "lcd backlight");
|
||||
|
||||
gpio_direction_output(LCD_PANEL_QVGA_GPIO, 0);
|
||||
gpio_direction_output(LCD_PANEL_RESET_GPIO, 0);
|
||||
gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 0);
|
||||
gpio_direction_output(LCD_PANEL_BACKLIGHT_GPIO, 0);
|
||||
|
||||
#ifdef CONFIG_FB_OMAP_LCD_VGA
|
||||
gpio_set_value(LCD_PANEL_QVGA_GPIO, 0);
|
||||
#else
|
||||
gpio_set_value(LCD_PANEL_QVGA_GPIO, 1);
|
||||
#endif
|
||||
gpio_set_value(LCD_PANEL_RESET_GPIO, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ldp_panel_cleanup(struct lcd_panel *panel)
|
||||
{
|
||||
gpio_free(LCD_PANEL_BACKLIGHT_GPIO);
|
||||
gpio_free(LCD_PANEL_ENABLE_GPIO);
|
||||
gpio_free(LCD_PANEL_QVGA_GPIO);
|
||||
gpio_free(LCD_PANEL_RESET_GPIO);
|
||||
}
|
||||
|
||||
static int ldp_panel_enable(struct lcd_panel *panel)
|
||||
{
|
||||
if (0 != t2_out(PM_RECEIVER, ENABLE_VPLL2_DEDICATED,
|
||||
TWL4030_VPLL2_DEDICATED))
|
||||
return -EIO;
|
||||
if (0 != t2_out(PM_RECEIVER, ENABLE_VPLL2_DEV_GRP,
|
||||
TWL4030_VPLL2_DEV_GRP))
|
||||
return -EIO;
|
||||
|
||||
gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 1);
|
||||
gpio_direction_output(LCD_PANEL_BACKLIGHT_GPIO, 1);
|
||||
|
||||
if (0 != t2_out(PM_RECEIVER, ENABLE_VAUX3_DEDICATED,
|
||||
TWL4030_VAUX3_DEDICATED))
|
||||
return -EIO;
|
||||
if (0 != t2_out(PM_RECEIVER, ENABLE_VAUX3_DEV_GRP,
|
||||
TWL4030_VAUX3_DEV_GRP))
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ldp_panel_disable(struct lcd_panel *panel)
|
||||
{
|
||||
gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 0);
|
||||
gpio_direction_output(LCD_PANEL_BACKLIGHT_GPIO, 0);
|
||||
|
||||
t2_out(PM_RECEIVER, 0x0, TWL4030_VPLL2_DEDICATED);
|
||||
t2_out(PM_RECEIVER, 0x0, TWL4030_VPLL2_DEV_GRP);
|
||||
msleep(4);
|
||||
}
|
||||
|
||||
static unsigned long ldp_panel_get_caps(struct lcd_panel *panel)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct lcd_panel ldp_panel = {
|
||||
.name = "ldp",
|
||||
.config = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC |
|
||||
OMAP_LCDC_INV_HSYNC,
|
||||
|
||||
.bpp = 16,
|
||||
.data_lines = 18,
|
||||
.x_res = LCD_XRES,
|
||||
.y_res = LCD_YRES,
|
||||
.hsw = 3, /* hsync_len (4) - 1 */
|
||||
.hfp = 3, /* right_margin (4) - 1 */
|
||||
.hbp = 39, /* left_margin (40) - 1 */
|
||||
.vsw = 1, /* vsync_len (2) - 1 */
|
||||
.vfp = 2, /* lower_margin */
|
||||
.vbp = 7, /* upper_margin (8) - 1 */
|
||||
|
||||
.pixel_clock = LCD_PIXCLOCK_MAX,
|
||||
|
||||
.init = ldp_panel_init,
|
||||
.cleanup = ldp_panel_cleanup,
|
||||
.enable = ldp_panel_enable,
|
||||
.disable = ldp_panel_disable,
|
||||
.get_caps = ldp_panel_get_caps,
|
||||
};
|
||||
|
||||
static int ldp_panel_probe(struct platform_device *pdev)
|
||||
{
|
||||
omapfb_register_panel(&ldp_panel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ldp_panel_remove(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ldp_panel_suspend(struct platform_device *pdev, pm_message_t mesg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ldp_panel_resume(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct platform_driver ldp_panel_driver = {
|
||||
.probe = ldp_panel_probe,
|
||||
.remove = ldp_panel_remove,
|
||||
.suspend = ldp_panel_suspend,
|
||||
.resume = ldp_panel_resume,
|
||||
.driver = {
|
||||
.name = "ldp_lcd",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init ldp_panel_drv_init(void)
|
||||
{
|
||||
return platform_driver_register(&ldp_panel_driver);
|
||||
}
|
||||
|
||||
static void __exit ldp_panel_drv_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&ldp_panel_driver);
|
||||
}
|
||||
|
||||
module_init(ldp_panel_drv_init);
|
||||
module_exit(ldp_panel_drv_exit);
|
||||
|
|
@ -1,130 +0,0 @@
|
|||
/*
|
||||
* LCD panel support for the TI OMAP3 Beagle board
|
||||
*
|
||||
* Author: Koen Kooi <koen@openembedded.org>
|
||||
*
|
||||
* Derived from drivers/video/omap/lcd-omap3evm.c
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/i2c/twl.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include "omapfb.h"
|
||||
|
||||
#define LCD_PANEL_ENABLE_GPIO 170
|
||||
|
||||
static int omap3beagle_panel_init(struct lcd_panel *panel,
|
||||
struct omapfb_device *fbdev)
|
||||
{
|
||||
gpio_request(LCD_PANEL_ENABLE_GPIO, "LCD enable");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void omap3beagle_panel_cleanup(struct lcd_panel *panel)
|
||||
{
|
||||
gpio_free(LCD_PANEL_ENABLE_GPIO);
|
||||
}
|
||||
|
||||
static int omap3beagle_panel_enable(struct lcd_panel *panel)
|
||||
{
|
||||
gpio_set_value(LCD_PANEL_ENABLE_GPIO, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void omap3beagle_panel_disable(struct lcd_panel *panel)
|
||||
{
|
||||
gpio_set_value(LCD_PANEL_ENABLE_GPIO, 0);
|
||||
}
|
||||
|
||||
static unsigned long omap3beagle_panel_get_caps(struct lcd_panel *panel)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct lcd_panel omap3beagle_panel = {
|
||||
.name = "omap3beagle",
|
||||
.config = OMAP_LCDC_PANEL_TFT,
|
||||
|
||||
.bpp = 16,
|
||||
.data_lines = 24,
|
||||
.x_res = 1024,
|
||||
.y_res = 768,
|
||||
.hsw = 3, /* hsync_len (4) - 1 */
|
||||
.hfp = 3, /* right_margin (4) - 1 */
|
||||
.hbp = 39, /* left_margin (40) - 1 */
|
||||
.vsw = 1, /* vsync_len (2) - 1 */
|
||||
.vfp = 2, /* lower_margin */
|
||||
.vbp = 7, /* upper_margin (8) - 1 */
|
||||
|
||||
.pixel_clock = 64000,
|
||||
|
||||
.init = omap3beagle_panel_init,
|
||||
.cleanup = omap3beagle_panel_cleanup,
|
||||
.enable = omap3beagle_panel_enable,
|
||||
.disable = omap3beagle_panel_disable,
|
||||
.get_caps = omap3beagle_panel_get_caps,
|
||||
};
|
||||
|
||||
static int omap3beagle_panel_probe(struct platform_device *pdev)
|
||||
{
|
||||
omapfb_register_panel(&omap3beagle_panel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap3beagle_panel_remove(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap3beagle_panel_suspend(struct platform_device *pdev,
|
||||
pm_message_t mesg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap3beagle_panel_resume(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct platform_driver omap3beagle_panel_driver = {
|
||||
.probe = omap3beagle_panel_probe,
|
||||
.remove = omap3beagle_panel_remove,
|
||||
.suspend = omap3beagle_panel_suspend,
|
||||
.resume = omap3beagle_panel_resume,
|
||||
.driver = {
|
||||
.name = "omap3beagle_lcd",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init omap3beagle_panel_drv_init(void)
|
||||
{
|
||||
return platform_driver_register(&omap3beagle_panel_driver);
|
||||
}
|
||||
|
||||
static void __exit omap3beagle_panel_drv_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&omap3beagle_panel_driver);
|
||||
}
|
||||
|
||||
module_init(omap3beagle_panel_drv_init);
|
||||
module_exit(omap3beagle_panel_drv_exit);
|
||||
|
|
@ -1,193 +0,0 @@
|
|||
/*
|
||||
* LCD panel support for the TI OMAP3 EVM board
|
||||
*
|
||||
* Author: Steve Sakoman <steve@sakoman.com>
|
||||
*
|
||||
* Derived from drivers/video/omap/lcd-apollon.c
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/i2c/twl.h>
|
||||
|
||||
#include <plat/mux.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include "omapfb.h"
|
||||
|
||||
#define LCD_PANEL_ENABLE_GPIO 153
|
||||
#define LCD_PANEL_LR 2
|
||||
#define LCD_PANEL_UD 3
|
||||
#define LCD_PANEL_INI 152
|
||||
#define LCD_PANEL_QVGA 154
|
||||
#define LCD_PANEL_RESB 155
|
||||
|
||||
#define ENABLE_VDAC_DEDICATED 0x03
|
||||
#define ENABLE_VDAC_DEV_GRP 0x20
|
||||
#define ENABLE_VPLL2_DEDICATED 0x05
|
||||
#define ENABLE_VPLL2_DEV_GRP 0xE0
|
||||
|
||||
#define TWL_LED_LEDEN 0x00
|
||||
#define TWL_PWMA_PWMAON 0x00
|
||||
#define TWL_PWMA_PWMAOFF 0x01
|
||||
|
||||
static unsigned int bklight_level;
|
||||
|
||||
static int omap3evm_panel_init(struct lcd_panel *panel,
|
||||
struct omapfb_device *fbdev)
|
||||
{
|
||||
gpio_request(LCD_PANEL_LR, "LCD lr");
|
||||
gpio_request(LCD_PANEL_UD, "LCD ud");
|
||||
gpio_request(LCD_PANEL_INI, "LCD ini");
|
||||
gpio_request(LCD_PANEL_RESB, "LCD resb");
|
||||
gpio_request(LCD_PANEL_QVGA, "LCD qvga");
|
||||
|
||||
gpio_direction_output(LCD_PANEL_RESB, 1);
|
||||
gpio_direction_output(LCD_PANEL_INI, 1);
|
||||
gpio_direction_output(LCD_PANEL_QVGA, 0);
|
||||
gpio_direction_output(LCD_PANEL_LR, 1);
|
||||
gpio_direction_output(LCD_PANEL_UD, 1);
|
||||
|
||||
twl_i2c_write_u8(TWL4030_MODULE_LED, 0x11, TWL_LED_LEDEN);
|
||||
twl_i2c_write_u8(TWL4030_MODULE_PWMA, 0x01, TWL_PWMA_PWMAON);
|
||||
twl_i2c_write_u8(TWL4030_MODULE_PWMA, 0x02, TWL_PWMA_PWMAOFF);
|
||||
bklight_level = 100;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void omap3evm_panel_cleanup(struct lcd_panel *panel)
|
||||
{
|
||||
gpio_free(LCD_PANEL_QVGA);
|
||||
gpio_free(LCD_PANEL_RESB);
|
||||
gpio_free(LCD_PANEL_INI);
|
||||
gpio_free(LCD_PANEL_UD);
|
||||
gpio_free(LCD_PANEL_LR);
|
||||
}
|
||||
|
||||
static int omap3evm_panel_enable(struct lcd_panel *panel)
|
||||
{
|
||||
gpio_set_value(LCD_PANEL_ENABLE_GPIO, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void omap3evm_panel_disable(struct lcd_panel *panel)
|
||||
{
|
||||
gpio_set_value(LCD_PANEL_ENABLE_GPIO, 1);
|
||||
}
|
||||
|
||||
static unsigned long omap3evm_panel_get_caps(struct lcd_panel *panel)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap3evm_bklight_setlevel(struct lcd_panel *panel,
|
||||
unsigned int level)
|
||||
{
|
||||
u8 c;
|
||||
if ((level >= 0) && (level <= 100)) {
|
||||
c = (125 * (100 - level)) / 100 + 2;
|
||||
twl_i2c_write_u8(TWL4030_MODULE_PWMA, c, TWL_PWMA_PWMAOFF);
|
||||
bklight_level = level;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int omap3evm_bklight_getlevel(struct lcd_panel *panel)
|
||||
{
|
||||
return bklight_level;
|
||||
}
|
||||
|
||||
static unsigned int omap3evm_bklight_getmaxlevel(struct lcd_panel *panel)
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
|
||||
struct lcd_panel omap3evm_panel = {
|
||||
.name = "omap3evm",
|
||||
.config = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC |
|
||||
OMAP_LCDC_INV_HSYNC,
|
||||
|
||||
.bpp = 16,
|
||||
.data_lines = 18,
|
||||
.x_res = 480,
|
||||
.y_res = 640,
|
||||
.hsw = 3, /* hsync_len (4) - 1 */
|
||||
.hfp = 3, /* right_margin (4) - 1 */
|
||||
.hbp = 39, /* left_margin (40) - 1 */
|
||||
.vsw = 1, /* vsync_len (2) - 1 */
|
||||
.vfp = 2, /* lower_margin */
|
||||
.vbp = 7, /* upper_margin (8) - 1 */
|
||||
|
||||
.pixel_clock = 26000,
|
||||
|
||||
.init = omap3evm_panel_init,
|
||||
.cleanup = omap3evm_panel_cleanup,
|
||||
.enable = omap3evm_panel_enable,
|
||||
.disable = omap3evm_panel_disable,
|
||||
.get_caps = omap3evm_panel_get_caps,
|
||||
.set_bklight_level = omap3evm_bklight_setlevel,
|
||||
.get_bklight_level = omap3evm_bklight_getlevel,
|
||||
.get_bklight_max = omap3evm_bklight_getmaxlevel,
|
||||
};
|
||||
|
||||
static int omap3evm_panel_probe(struct platform_device *pdev)
|
||||
{
|
||||
omapfb_register_panel(&omap3evm_panel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap3evm_panel_remove(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap3evm_panel_suspend(struct platform_device *pdev,
|
||||
pm_message_t mesg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap3evm_panel_resume(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct platform_driver omap3evm_panel_driver = {
|
||||
.probe = omap3evm_panel_probe,
|
||||
.remove = omap3evm_panel_remove,
|
||||
.suspend = omap3evm_panel_suspend,
|
||||
.resume = omap3evm_panel_resume,
|
||||
.driver = {
|
||||
.name = "omap3evm_lcd",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init omap3evm_panel_drv_init(void)
|
||||
{
|
||||
return platform_driver_register(&omap3evm_panel_driver);
|
||||
}
|
||||
|
||||
static void __exit omap3evm_panel_drv_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&omap3evm_panel_driver);
|
||||
}
|
||||
|
||||
module_init(omap3evm_panel_drv_init);
|
||||
module_exit(omap3evm_panel_drv_exit);
|
||||
|
|
@ -1,180 +0,0 @@
|
|||
/*
|
||||
* LCD panel support for the Gumstix Overo
|
||||
*
|
||||
* Author: Steve Sakoman <steve@sakoman.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/i2c/twl.h>
|
||||
|
||||
#include <asm/gpio.h>
|
||||
#include <plat/mux.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include "omapfb.h"
|
||||
|
||||
#define LCD_ENABLE 144
|
||||
|
||||
static int overo_panel_init(struct lcd_panel *panel,
|
||||
struct omapfb_device *fbdev)
|
||||
{
|
||||
if ((gpio_request(LCD_ENABLE, "LCD_ENABLE") == 0) &&
|
||||
(gpio_direction_output(LCD_ENABLE, 1) == 0))
|
||||
gpio_export(LCD_ENABLE, 0);
|
||||
else
|
||||
printk(KERN_ERR "could not obtain gpio for LCD_ENABLE\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void overo_panel_cleanup(struct lcd_panel *panel)
|
||||
{
|
||||
gpio_free(LCD_ENABLE);
|
||||
}
|
||||
|
||||
static int overo_panel_enable(struct lcd_panel *panel)
|
||||
{
|
||||
gpio_set_value(LCD_ENABLE, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void overo_panel_disable(struct lcd_panel *panel)
|
||||
{
|
||||
gpio_set_value(LCD_ENABLE, 0);
|
||||
}
|
||||
|
||||
static unsigned long overo_panel_get_caps(struct lcd_panel *panel)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct lcd_panel overo_panel = {
|
||||
.name = "overo",
|
||||
.config = OMAP_LCDC_PANEL_TFT,
|
||||
.bpp = 16,
|
||||
.data_lines = 24,
|
||||
|
||||
#if defined CONFIG_FB_OMAP_031M3R
|
||||
|
||||
/* 640 x 480 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */
|
||||
.x_res = 640,
|
||||
.y_res = 480,
|
||||
.hfp = 48,
|
||||
.hsw = 32,
|
||||
.hbp = 80,
|
||||
.vfp = 3,
|
||||
.vsw = 4,
|
||||
.vbp = 7,
|
||||
.pixel_clock = 23500,
|
||||
|
||||
#elif defined CONFIG_FB_OMAP_048M3R
|
||||
|
||||
/* 800 x 600 @ 60 Hz Reduced blanking VESA CVT 0.48M3-R */
|
||||
.x_res = 800,
|
||||
.y_res = 600,
|
||||
.hfp = 48,
|
||||
.hsw = 32,
|
||||
.hbp = 80,
|
||||
.vfp = 3,
|
||||
.vsw = 4,
|
||||
.vbp = 11,
|
||||
.pixel_clock = 35500,
|
||||
|
||||
#elif defined CONFIG_FB_OMAP_079M3R
|
||||
|
||||
/* 1024 x 768 @ 60 Hz Reduced blanking VESA CVT 0.79M3-R */
|
||||
.x_res = 1024,
|
||||
.y_res = 768,
|
||||
.hfp = 48,
|
||||
.hsw = 32,
|
||||
.hbp = 80,
|
||||
.vfp = 3,
|
||||
.vsw = 4,
|
||||
.vbp = 15,
|
||||
.pixel_clock = 56000,
|
||||
|
||||
#elif defined CONFIG_FB_OMAP_092M9R
|
||||
|
||||
/* 1280 x 720 @ 60 Hz Reduced blanking VESA CVT 0.92M9-R */
|
||||
.x_res = 1280,
|
||||
.y_res = 720,
|
||||
.hfp = 48,
|
||||
.hsw = 32,
|
||||
.hbp = 80,
|
||||
.vfp = 3,
|
||||
.vsw = 5,
|
||||
.vbp = 13,
|
||||
.pixel_clock = 64000,
|
||||
|
||||
#else
|
||||
|
||||
/* use 640 x 480 if no config option */
|
||||
/* 640 x 480 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */
|
||||
.x_res = 640,
|
||||
.y_res = 480,
|
||||
.hfp = 48,
|
||||
.hsw = 32,
|
||||
.hbp = 80,
|
||||
.vfp = 3,
|
||||
.vsw = 4,
|
||||
.vbp = 7,
|
||||
.pixel_clock = 23500,
|
||||
|
||||
#endif
|
||||
|
||||
.init = overo_panel_init,
|
||||
.cleanup = overo_panel_cleanup,
|
||||
.enable = overo_panel_enable,
|
||||
.disable = overo_panel_disable,
|
||||
.get_caps = overo_panel_get_caps,
|
||||
};
|
||||
|
||||
static int overo_panel_probe(struct platform_device *pdev)
|
||||
{
|
||||
omapfb_register_panel(&overo_panel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int overo_panel_remove(struct platform_device *pdev)
|
||||
{
|
||||
/* omapfb does not have unregister_panel */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver overo_panel_driver = {
|
||||
.probe = overo_panel_probe,
|
||||
.remove = overo_panel_remove,
|
||||
.driver = {
|
||||
.name = "overo_lcd",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init overo_panel_drv_init(void)
|
||||
{
|
||||
return platform_driver_register(&overo_panel_driver);
|
||||
}
|
||||
|
||||
static void __exit overo_panel_drv_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&overo_panel_driver);
|
||||
}
|
||||
|
||||
module_init(overo_panel_drv_init);
|
||||
module_exit(overo_panel_drv_exit);
|
||||
|
|
@ -10,6 +10,13 @@ config PANEL_GENERIC_DPI
|
|||
Supports LCD Panel used in TI SDP3430 and EVM boards,
|
||||
OMAP3517 EVM boards and CM-T35.
|
||||
|
||||
config PANEL_DVI
|
||||
tristate "DVI output"
|
||||
depends on OMAP2_DSS_DPI
|
||||
help
|
||||
Driver for external monitors, connected via DVI. The driver uses i2c
|
||||
to read EDID information from the monitor.
|
||||
|
||||
config PANEL_LGPHILIPS_LB035Q02
|
||||
tristate "LG.Philips LB035Q02 LCD Panel"
|
||||
depends on OMAP2_DSS_DPI && SPI
|
||||
|
|
@ -19,20 +26,30 @@ config PANEL_LGPHILIPS_LB035Q02
|
|||
config PANEL_SHARP_LS037V7DW01
|
||||
tristate "Sharp LS037V7DW01 LCD Panel"
|
||||
depends on OMAP2_DSS_DPI
|
||||
select BACKLIGHT_CLASS_DEVICE
|
||||
depends on BACKLIGHT_CLASS_DEVICE
|
||||
help
|
||||
LCD Panel used in TI's SDP3430 and EVM boards
|
||||
|
||||
config PANEL_NEC_NL8048HL11_01B
|
||||
tristate "NEC NL8048HL11-01B Panel"
|
||||
depends on OMAP2_DSS_DPI
|
||||
depends on SPI
|
||||
depends on BACKLIGHT_CLASS_DEVICE
|
||||
help
|
||||
This NEC NL8048HL11-01B panel is TFT LCD
|
||||
used in the Zoom2/3/3630 sdp boards.
|
||||
|
||||
config PANEL_PICODLP
|
||||
tristate "TI PICO DLP mini-projector"
|
||||
depends on OMAP2_DSS && I2C
|
||||
help
|
||||
A mini-projector used in TI's SDP4430 and EVM boards
|
||||
For more info please visit http://www.dlp.com/projector/
|
||||
|
||||
config PANEL_TAAL
|
||||
tristate "Taal DSI Panel"
|
||||
depends on OMAP2_DSS_DSI
|
||||
depends on BACKLIGHT_CLASS_DEVICE
|
||||
help
|
||||
Taal DSI command mode panel from TPO.
|
||||
|
||||
|
|
@ -45,7 +62,14 @@ config PANEL_TPO_TD043MTEA1
|
|||
config PANEL_ACX565AKM
|
||||
tristate "ACX565AKM Panel"
|
||||
depends on OMAP2_DSS_SDI && SPI
|
||||
select BACKLIGHT_CLASS_DEVICE
|
||||
depends on BACKLIGHT_CLASS_DEVICE
|
||||
help
|
||||
This is the LCD panel used on Nokia N900
|
||||
|
||||
config PANEL_N8X0
|
||||
tristate "N8X0 Panel"
|
||||
depends on OMAP2_DSS_RFBI && SPI
|
||||
depends on BACKLIGHT_CLASS_DEVICE
|
||||
help
|
||||
This is the LCD panel used on Nokia N8x0
|
||||
endmenu
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
obj-$(CONFIG_PANEL_GENERIC_DPI) += panel-generic-dpi.o
|
||||
obj-$(CONFIG_PANEL_DVI) += panel-dvi.o
|
||||
obj-$(CONFIG_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o
|
||||
obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o
|
||||
obj-$(CONFIG_PANEL_NEC_NL8048HL11_01B) += panel-nec-nl8048hl11-01b.o
|
||||
|
||||
obj-$(CONFIG_PANEL_TAAL) += panel-taal.o
|
||||
obj-$(CONFIG_PANEL_PICODLP) += panel-picodlp.o
|
||||
obj-$(CONFIG_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o
|
||||
obj-$(CONFIG_PANEL_ACX565AKM) += panel-acx565akm.o
|
||||
obj-$(CONFIG_PANEL_N8X0) += panel-n8x0.o
|
||||
|
|
|
|||
363
drivers/video/omap2/displays/panel-dvi.c
Normal file
363
drivers/video/omap2/displays/panel-dvi.c
Normal file
|
|
@ -0,0 +1,363 @@
|
|||
/*
|
||||
* DVI output support
|
||||
*
|
||||
* Copyright (C) 2011 Texas Instruments Inc
|
||||
* Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <video/omapdss.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <drm/drm_edid.h>
|
||||
|
||||
#include <video/omap-panel-dvi.h>
|
||||
|
||||
static const struct omap_video_timings panel_dvi_default_timings = {
|
||||
.x_res = 640,
|
||||
.y_res = 480,
|
||||
|
||||
.pixel_clock = 23500,
|
||||
|
||||
.hfp = 48,
|
||||
.hsw = 32,
|
||||
.hbp = 80,
|
||||
|
||||
.vfp = 3,
|
||||
.vsw = 4,
|
||||
.vbp = 7,
|
||||
};
|
||||
|
||||
struct panel_drv_data {
|
||||
struct omap_dss_device *dssdev;
|
||||
|
||||
struct mutex lock;
|
||||
};
|
||||
|
||||
static inline struct panel_dvi_platform_data
|
||||
*get_pdata(const struct omap_dss_device *dssdev)
|
||||
{
|
||||
return dssdev->data;
|
||||
}
|
||||
|
||||
static int panel_dvi_power_on(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct panel_dvi_platform_data *pdata = get_pdata(dssdev);
|
||||
int r;
|
||||
|
||||
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
|
||||
return 0;
|
||||
|
||||
r = omapdss_dpi_display_enable(dssdev);
|
||||
if (r)
|
||||
goto err0;
|
||||
|
||||
if (pdata->platform_enable) {
|
||||
r = pdata->platform_enable(dssdev);
|
||||
if (r)
|
||||
goto err1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err1:
|
||||
omapdss_dpi_display_disable(dssdev);
|
||||
err0:
|
||||
return r;
|
||||
}
|
||||
|
||||
static void panel_dvi_power_off(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct panel_dvi_platform_data *pdata = get_pdata(dssdev);
|
||||
|
||||
if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
|
||||
return;
|
||||
|
||||
if (pdata->platform_disable)
|
||||
pdata->platform_disable(dssdev);
|
||||
|
||||
omapdss_dpi_display_disable(dssdev);
|
||||
}
|
||||
|
||||
static int panel_dvi_probe(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct panel_drv_data *ddata;
|
||||
|
||||
ddata = kzalloc(sizeof(*ddata), GFP_KERNEL);
|
||||
if (!ddata)
|
||||
return -ENOMEM;
|
||||
|
||||
dssdev->panel.timings = panel_dvi_default_timings;
|
||||
dssdev->panel.config = OMAP_DSS_LCD_TFT;
|
||||
|
||||
ddata->dssdev = dssdev;
|
||||
mutex_init(&ddata->lock);
|
||||
|
||||
dev_set_drvdata(&dssdev->dev, ddata);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit panel_dvi_remove(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
|
||||
|
||||
mutex_lock(&ddata->lock);
|
||||
|
||||
dev_set_drvdata(&dssdev->dev, NULL);
|
||||
|
||||
mutex_unlock(&ddata->lock);
|
||||
|
||||
kfree(ddata);
|
||||
}
|
||||
|
||||
static int panel_dvi_enable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
|
||||
int r;
|
||||
|
||||
mutex_lock(&ddata->lock);
|
||||
|
||||
r = panel_dvi_power_on(dssdev);
|
||||
if (r == 0)
|
||||
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
|
||||
|
||||
mutex_unlock(&ddata->lock);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void panel_dvi_disable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
|
||||
|
||||
mutex_lock(&ddata->lock);
|
||||
|
||||
panel_dvi_power_off(dssdev);
|
||||
|
||||
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
|
||||
|
||||
mutex_unlock(&ddata->lock);
|
||||
}
|
||||
|
||||
static int panel_dvi_suspend(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
|
||||
|
||||
mutex_lock(&ddata->lock);
|
||||
|
||||
panel_dvi_power_off(dssdev);
|
||||
|
||||
dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
|
||||
|
||||
mutex_unlock(&ddata->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int panel_dvi_resume(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
|
||||
int r;
|
||||
|
||||
mutex_lock(&ddata->lock);
|
||||
|
||||
r = panel_dvi_power_on(dssdev);
|
||||
if (r == 0)
|
||||
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
|
||||
|
||||
mutex_unlock(&ddata->lock);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void panel_dvi_set_timings(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings)
|
||||
{
|
||||
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
|
||||
|
||||
mutex_lock(&ddata->lock);
|
||||
dpi_set_timings(dssdev, timings);
|
||||
mutex_unlock(&ddata->lock);
|
||||
}
|
||||
|
||||
static void panel_dvi_get_timings(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings)
|
||||
{
|
||||
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
|
||||
|
||||
mutex_lock(&ddata->lock);
|
||||
*timings = dssdev->panel.timings;
|
||||
mutex_unlock(&ddata->lock);
|
||||
}
|
||||
|
||||
static int panel_dvi_check_timings(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings)
|
||||
{
|
||||
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
|
||||
int r;
|
||||
|
||||
mutex_lock(&ddata->lock);
|
||||
r = dpi_check_timings(dssdev, timings);
|
||||
mutex_unlock(&ddata->lock);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
static int panel_dvi_ddc_read(struct i2c_adapter *adapter,
|
||||
unsigned char *buf, u16 count, u8 offset)
|
||||
{
|
||||
int r, retries;
|
||||
|
||||
for (retries = 3; retries > 0; retries--) {
|
||||
struct i2c_msg msgs[] = {
|
||||
{
|
||||
.addr = DDC_ADDR,
|
||||
.flags = 0,
|
||||
.len = 1,
|
||||
.buf = &offset,
|
||||
}, {
|
||||
.addr = DDC_ADDR,
|
||||
.flags = I2C_M_RD,
|
||||
.len = count,
|
||||
.buf = buf,
|
||||
}
|
||||
};
|
||||
|
||||
r = i2c_transfer(adapter, msgs, 2);
|
||||
if (r == 2)
|
||||
return 0;
|
||||
|
||||
if (r != -EAGAIN)
|
||||
break;
|
||||
}
|
||||
|
||||
return r < 0 ? r : -EIO;
|
||||
}
|
||||
|
||||
static int panel_dvi_read_edid(struct omap_dss_device *dssdev,
|
||||
u8 *edid, int len)
|
||||
{
|
||||
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
|
||||
struct panel_dvi_platform_data *pdata = get_pdata(dssdev);
|
||||
struct i2c_adapter *adapter;
|
||||
int r, l, bytes_read;
|
||||
|
||||
mutex_lock(&ddata->lock);
|
||||
|
||||
if (pdata->i2c_bus_num == 0) {
|
||||
r = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
|
||||
adapter = i2c_get_adapter(pdata->i2c_bus_num);
|
||||
if (!adapter) {
|
||||
dev_err(&dssdev->dev, "Failed to get I2C adapter, bus %d\n",
|
||||
pdata->i2c_bus_num);
|
||||
r = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
l = min(EDID_LENGTH, len);
|
||||
r = panel_dvi_ddc_read(adapter, edid, l, 0);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
bytes_read = l;
|
||||
|
||||
/* if there are extensions, read second block */
|
||||
if (len > EDID_LENGTH && edid[0x7e] > 0) {
|
||||
l = min(EDID_LENGTH, len - EDID_LENGTH);
|
||||
|
||||
r = panel_dvi_ddc_read(adapter, edid + EDID_LENGTH,
|
||||
l, EDID_LENGTH);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
bytes_read += l;
|
||||
}
|
||||
|
||||
mutex_unlock(&ddata->lock);
|
||||
|
||||
return bytes_read;
|
||||
|
||||
err:
|
||||
mutex_unlock(&ddata->lock);
|
||||
return r;
|
||||
}
|
||||
|
||||
static bool panel_dvi_detect(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
|
||||
struct panel_dvi_platform_data *pdata = get_pdata(dssdev);
|
||||
struct i2c_adapter *adapter;
|
||||
unsigned char out;
|
||||
int r;
|
||||
|
||||
mutex_lock(&ddata->lock);
|
||||
|
||||
if (pdata->i2c_bus_num == 0)
|
||||
goto out;
|
||||
|
||||
adapter = i2c_get_adapter(pdata->i2c_bus_num);
|
||||
if (!adapter)
|
||||
goto out;
|
||||
|
||||
r = panel_dvi_ddc_read(adapter, &out, 1, 0);
|
||||
|
||||
mutex_unlock(&ddata->lock);
|
||||
|
||||
return r == 0;
|
||||
|
||||
out:
|
||||
mutex_unlock(&ddata->lock);
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct omap_dss_driver panel_dvi_driver = {
|
||||
.probe = panel_dvi_probe,
|
||||
.remove = __exit_p(panel_dvi_remove),
|
||||
|
||||
.enable = panel_dvi_enable,
|
||||
.disable = panel_dvi_disable,
|
||||
.suspend = panel_dvi_suspend,
|
||||
.resume = panel_dvi_resume,
|
||||
|
||||
.set_timings = panel_dvi_set_timings,
|
||||
.get_timings = panel_dvi_get_timings,
|
||||
.check_timings = panel_dvi_check_timings,
|
||||
|
||||
.read_edid = panel_dvi_read_edid,
|
||||
.detect = panel_dvi_detect,
|
||||
|
||||
.driver = {
|
||||
.name = "dvi",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init panel_dvi_init(void)
|
||||
{
|
||||
return omap_dss_register_driver(&panel_dvi_driver);
|
||||
}
|
||||
|
||||
static void __exit panel_dvi_exit(void)
|
||||
{
|
||||
omap_dss_unregister_driver(&panel_dvi_driver);
|
||||
}
|
||||
|
||||
module_init(panel_dvi_init);
|
||||
module_exit(panel_dvi_exit);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
@ -58,30 +58,6 @@ struct panel_config {
|
|||
|
||||
/* Panel configurations */
|
||||
static struct panel_config generic_dpi_panels[] = {
|
||||
/* Generic Panel */
|
||||
{
|
||||
{
|
||||
.x_res = 640,
|
||||
.y_res = 480,
|
||||
|
||||
.pixel_clock = 23500,
|
||||
|
||||
.hfp = 48,
|
||||
.hsw = 32,
|
||||
.hbp = 80,
|
||||
|
||||
.vfp = 3,
|
||||
.vsw = 4,
|
||||
.vbp = 7,
|
||||
},
|
||||
.acbi = 0x0,
|
||||
.acb = 0x0,
|
||||
.config = OMAP_DSS_LCD_TFT,
|
||||
.power_on_delay = 0,
|
||||
.power_off_delay = 0,
|
||||
.name = "generic",
|
||||
},
|
||||
|
||||
/* Sharp LQ043T1DG01 */
|
||||
{
|
||||
{
|
||||
|
|
@ -232,6 +208,95 @@ static struct panel_config generic_dpi_panels[] = {
|
|||
.power_off_delay = 0,
|
||||
.name = "powertip_ph480272t",
|
||||
},
|
||||
|
||||
/* Innolux AT070TN83 */
|
||||
{
|
||||
{
|
||||
.x_res = 800,
|
||||
.y_res = 480,
|
||||
|
||||
.pixel_clock = 40000,
|
||||
|
||||
.hsw = 48,
|
||||
.hfp = 1,
|
||||
.hbp = 1,
|
||||
|
||||
.vsw = 3,
|
||||
.vfp = 12,
|
||||
.vbp = 25,
|
||||
},
|
||||
.acbi = 0x0,
|
||||
.acb = 0x28,
|
||||
.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
|
||||
OMAP_DSS_LCD_IHS,
|
||||
.power_on_delay = 0,
|
||||
.power_off_delay = 0,
|
||||
.name = "innolux_at070tn83",
|
||||
},
|
||||
|
||||
/* NEC NL2432DR22-11B */
|
||||
{
|
||||
{
|
||||
.x_res = 240,
|
||||
.y_res = 320,
|
||||
|
||||
.pixel_clock = 5400,
|
||||
|
||||
.hsw = 3,
|
||||
.hfp = 3,
|
||||
.hbp = 39,
|
||||
|
||||
.vsw = 1,
|
||||
.vfp = 2,
|
||||
.vbp = 7,
|
||||
},
|
||||
.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
|
||||
OMAP_DSS_LCD_IHS,
|
||||
.name = "nec_nl2432dr22-11b",
|
||||
},
|
||||
|
||||
/* Unknown panel used in OMAP H4 */
|
||||
{
|
||||
{
|
||||
.x_res = 240,
|
||||
.y_res = 320,
|
||||
|
||||
.pixel_clock = 6250,
|
||||
|
||||
.hsw = 15,
|
||||
.hfp = 15,
|
||||
.hbp = 60,
|
||||
|
||||
.vsw = 1,
|
||||
.vfp = 1,
|
||||
.vbp = 1,
|
||||
},
|
||||
.config = OMAP_DSS_LCD_TFT,
|
||||
|
||||
.name = "h4",
|
||||
},
|
||||
|
||||
/* Unknown panel used in Samsung OMAP2 Apollon */
|
||||
{
|
||||
{
|
||||
.x_res = 480,
|
||||
.y_res = 272,
|
||||
|
||||
.pixel_clock = 6250,
|
||||
|
||||
.hsw = 41,
|
||||
.hfp = 2,
|
||||
.hbp = 2,
|
||||
|
||||
.vsw = 10,
|
||||
.vfp = 2,
|
||||
.vbp = 2,
|
||||
},
|
||||
.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
|
||||
OMAP_DSS_LCD_IHS,
|
||||
|
||||
.name = "apollon",
|
||||
},
|
||||
};
|
||||
|
||||
struct panel_drv_data {
|
||||
|
|
|
|||
747
drivers/video/omap2/displays/panel-n8x0.c
Normal file
747
drivers/video/omap2/displays/panel-n8x0.c
Normal file
|
|
@ -0,0 +1,747 @@
|
|||
/* #define DEBUG */
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/backlight.h>
|
||||
#include <linux/fb.h>
|
||||
|
||||
#include <video/omapdss.h>
|
||||
#include <video/omap-panel-n8x0.h>
|
||||
|
||||
#define BLIZZARD_REV_CODE 0x00
|
||||
#define BLIZZARD_CONFIG 0x02
|
||||
#define BLIZZARD_PLL_DIV 0x04
|
||||
#define BLIZZARD_PLL_LOCK_RANGE 0x06
|
||||
#define BLIZZARD_PLL_CLOCK_SYNTH_0 0x08
|
||||
#define BLIZZARD_PLL_CLOCK_SYNTH_1 0x0a
|
||||
#define BLIZZARD_PLL_MODE 0x0c
|
||||
#define BLIZZARD_CLK_SRC 0x0e
|
||||
#define BLIZZARD_MEM_BANK0_ACTIVATE 0x10
|
||||
#define BLIZZARD_MEM_BANK0_STATUS 0x14
|
||||
#define BLIZZARD_PANEL_CONFIGURATION 0x28
|
||||
#define BLIZZARD_HDISP 0x2a
|
||||
#define BLIZZARD_HNDP 0x2c
|
||||
#define BLIZZARD_VDISP0 0x2e
|
||||
#define BLIZZARD_VDISP1 0x30
|
||||
#define BLIZZARD_VNDP 0x32
|
||||
#define BLIZZARD_HSW 0x34
|
||||
#define BLIZZARD_VSW 0x38
|
||||
#define BLIZZARD_DISPLAY_MODE 0x68
|
||||
#define BLIZZARD_INPUT_WIN_X_START_0 0x6c
|
||||
#define BLIZZARD_DATA_SOURCE_SELECT 0x8e
|
||||
#define BLIZZARD_DISP_MEM_DATA_PORT 0x90
|
||||
#define BLIZZARD_DISP_MEM_READ_ADDR0 0x92
|
||||
#define BLIZZARD_POWER_SAVE 0xE6
|
||||
#define BLIZZARD_NDISP_CTRL_STATUS 0xE8
|
||||
|
||||
/* Data source select */
|
||||
/* For S1D13745 */
|
||||
#define BLIZZARD_SRC_WRITE_LCD_BACKGROUND 0x00
|
||||
#define BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE 0x01
|
||||
#define BLIZZARD_SRC_WRITE_OVERLAY_ENABLE 0x04
|
||||
#define BLIZZARD_SRC_DISABLE_OVERLAY 0x05
|
||||
/* For S1D13744 */
|
||||
#define BLIZZARD_SRC_WRITE_LCD 0x00
|
||||
#define BLIZZARD_SRC_BLT_LCD 0x06
|
||||
|
||||
#define BLIZZARD_COLOR_RGB565 0x01
|
||||
#define BLIZZARD_COLOR_YUV420 0x09
|
||||
|
||||
#define BLIZZARD_VERSION_S1D13745 0x01 /* Hailstorm */
|
||||
#define BLIZZARD_VERSION_S1D13744 0x02 /* Blizzard */
|
||||
|
||||
#define MIPID_CMD_READ_DISP_ID 0x04
|
||||
#define MIPID_CMD_READ_RED 0x06
|
||||
#define MIPID_CMD_READ_GREEN 0x07
|
||||
#define MIPID_CMD_READ_BLUE 0x08
|
||||
#define MIPID_CMD_READ_DISP_STATUS 0x09
|
||||
#define MIPID_CMD_RDDSDR 0x0F
|
||||
#define MIPID_CMD_SLEEP_IN 0x10
|
||||
#define MIPID_CMD_SLEEP_OUT 0x11
|
||||
#define MIPID_CMD_DISP_OFF 0x28
|
||||
#define MIPID_CMD_DISP_ON 0x29
|
||||
|
||||
static struct panel_drv_data {
|
||||
struct mutex lock;
|
||||
|
||||
struct omap_dss_device *dssdev;
|
||||
struct spi_device *spidev;
|
||||
struct backlight_device *bldev;
|
||||
|
||||
int blizzard_ver;
|
||||
} s_drv_data;
|
||||
|
||||
|
||||
static inline
|
||||
struct panel_n8x0_data *get_board_data(const struct omap_dss_device *dssdev)
|
||||
{
|
||||
return dssdev->data;
|
||||
}
|
||||
|
||||
static inline
|
||||
struct panel_drv_data *get_drv_data(const struct omap_dss_device *dssdev)
|
||||
{
|
||||
return &s_drv_data;
|
||||
}
|
||||
|
||||
|
||||
static inline void blizzard_cmd(u8 cmd)
|
||||
{
|
||||
omap_rfbi_write_command(&cmd, 1);
|
||||
}
|
||||
|
||||
static inline void blizzard_write(u8 cmd, const u8 *buf, int len)
|
||||
{
|
||||
omap_rfbi_write_command(&cmd, 1);
|
||||
omap_rfbi_write_data(buf, len);
|
||||
}
|
||||
|
||||
static inline void blizzard_read(u8 cmd, u8 *buf, int len)
|
||||
{
|
||||
omap_rfbi_write_command(&cmd, 1);
|
||||
omap_rfbi_read_data(buf, len);
|
||||
}
|
||||
|
||||
static u8 blizzard_read_reg(u8 cmd)
|
||||
{
|
||||
u8 data;
|
||||
blizzard_read(cmd, &data, 1);
|
||||
return data;
|
||||
}
|
||||
|
||||
static void blizzard_ctrl_setup_update(struct omap_dss_device *dssdev,
|
||||
int x, int y, int w, int h)
|
||||
{
|
||||
struct panel_drv_data *ddata = get_drv_data(dssdev);
|
||||
u8 tmp[18];
|
||||
int x_end, y_end;
|
||||
|
||||
x_end = x + w - 1;
|
||||
y_end = y + h - 1;
|
||||
|
||||
tmp[0] = x;
|
||||
tmp[1] = x >> 8;
|
||||
tmp[2] = y;
|
||||
tmp[3] = y >> 8;
|
||||
tmp[4] = x_end;
|
||||
tmp[5] = x_end >> 8;
|
||||
tmp[6] = y_end;
|
||||
tmp[7] = y_end >> 8;
|
||||
|
||||
/* scaling? */
|
||||
tmp[8] = x;
|
||||
tmp[9] = x >> 8;
|
||||
tmp[10] = y;
|
||||
tmp[11] = y >> 8;
|
||||
tmp[12] = x_end;
|
||||
tmp[13] = x_end >> 8;
|
||||
tmp[14] = y_end;
|
||||
tmp[15] = y_end >> 8;
|
||||
|
||||
tmp[16] = BLIZZARD_COLOR_RGB565;
|
||||
|
||||
if (ddata->blizzard_ver == BLIZZARD_VERSION_S1D13745)
|
||||
tmp[17] = BLIZZARD_SRC_WRITE_LCD_BACKGROUND;
|
||||
else
|
||||
tmp[17] = ddata->blizzard_ver == BLIZZARD_VERSION_S1D13744 ?
|
||||
BLIZZARD_SRC_WRITE_LCD :
|
||||
BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE;
|
||||
|
||||
omap_rfbi_configure(dssdev, 16, 8);
|
||||
|
||||
blizzard_write(BLIZZARD_INPUT_WIN_X_START_0, tmp, 18);
|
||||
|
||||
omap_rfbi_configure(dssdev, 16, 16);
|
||||
}
|
||||
|
||||
static void mipid_transfer(struct spi_device *spi, int cmd, const u8 *wbuf,
|
||||
int wlen, u8 *rbuf, int rlen)
|
||||
{
|
||||
struct spi_message m;
|
||||
struct spi_transfer *x, xfer[4];
|
||||
u16 w;
|
||||
int r;
|
||||
|
||||
spi_message_init(&m);
|
||||
|
||||
memset(xfer, 0, sizeof(xfer));
|
||||
x = &xfer[0];
|
||||
|
||||
cmd &= 0xff;
|
||||
x->tx_buf = &cmd;
|
||||
x->bits_per_word = 9;
|
||||
x->len = 2;
|
||||
spi_message_add_tail(x, &m);
|
||||
|
||||
if (wlen) {
|
||||
x++;
|
||||
x->tx_buf = wbuf;
|
||||
x->len = wlen;
|
||||
x->bits_per_word = 9;
|
||||
spi_message_add_tail(x, &m);
|
||||
}
|
||||
|
||||
if (rlen) {
|
||||
x++;
|
||||
x->rx_buf = &w;
|
||||
x->len = 1;
|
||||
spi_message_add_tail(x, &m);
|
||||
|
||||
if (rlen > 1) {
|
||||
/* Arrange for the extra clock before the first
|
||||
* data bit.
|
||||
*/
|
||||
x->bits_per_word = 9;
|
||||
x->len = 2;
|
||||
|
||||
x++;
|
||||
x->rx_buf = &rbuf[1];
|
||||
x->len = rlen - 1;
|
||||
spi_message_add_tail(x, &m);
|
||||
}
|
||||
}
|
||||
|
||||
r = spi_sync(spi, &m);
|
||||
if (r < 0)
|
||||
dev_dbg(&spi->dev, "spi_sync %d\n", r);
|
||||
|
||||
if (rlen)
|
||||
rbuf[0] = w & 0xff;
|
||||
}
|
||||
|
||||
static inline void mipid_cmd(struct spi_device *spi, int cmd)
|
||||
{
|
||||
mipid_transfer(spi, cmd, NULL, 0, NULL, 0);
|
||||
}
|
||||
|
||||
static inline void mipid_write(struct spi_device *spi,
|
||||
int reg, const u8 *buf, int len)
|
||||
{
|
||||
mipid_transfer(spi, reg, buf, len, NULL, 0);
|
||||
}
|
||||
|
||||
static inline void mipid_read(struct spi_device *spi,
|
||||
int reg, u8 *buf, int len)
|
||||
{
|
||||
mipid_transfer(spi, reg, NULL, 0, buf, len);
|
||||
}
|
||||
|
||||
static void set_data_lines(struct spi_device *spi, int data_lines)
|
||||
{
|
||||
u16 par;
|
||||
|
||||
switch (data_lines) {
|
||||
case 16:
|
||||
par = 0x150;
|
||||
break;
|
||||
case 18:
|
||||
par = 0x160;
|
||||
break;
|
||||
case 24:
|
||||
par = 0x170;
|
||||
break;
|
||||
}
|
||||
|
||||
mipid_write(spi, 0x3a, (u8 *)&par, 2);
|
||||
}
|
||||
|
||||
static void send_init_string(struct spi_device *spi)
|
||||
{
|
||||
u16 initpar[] = { 0x0102, 0x0100, 0x0100 };
|
||||
mipid_write(spi, 0xc2, (u8 *)initpar, sizeof(initpar));
|
||||
}
|
||||
|
||||
static void send_display_on(struct spi_device *spi)
|
||||
{
|
||||
mipid_cmd(spi, MIPID_CMD_DISP_ON);
|
||||
}
|
||||
|
||||
static void send_display_off(struct spi_device *spi)
|
||||
{
|
||||
mipid_cmd(spi, MIPID_CMD_DISP_OFF);
|
||||
}
|
||||
|
||||
static void send_sleep_out(struct spi_device *spi)
|
||||
{
|
||||
mipid_cmd(spi, MIPID_CMD_SLEEP_OUT);
|
||||
msleep(120);
|
||||
}
|
||||
|
||||
static void send_sleep_in(struct spi_device *spi)
|
||||
{
|
||||
mipid_cmd(spi, MIPID_CMD_SLEEP_IN);
|
||||
msleep(50);
|
||||
}
|
||||
|
||||
static int n8x0_panel_power_on(struct omap_dss_device *dssdev)
|
||||
{
|
||||
int r;
|
||||
struct panel_n8x0_data *bdata = get_board_data(dssdev);
|
||||
struct panel_drv_data *ddata = get_drv_data(dssdev);
|
||||
struct spi_device *spi = ddata->spidev;
|
||||
u8 rev, conf;
|
||||
u8 display_id[3];
|
||||
const char *panel_name;
|
||||
|
||||
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
|
||||
return 0;
|
||||
|
||||
gpio_direction_output(bdata->ctrl_pwrdown, 1);
|
||||
|
||||
if (bdata->platform_enable) {
|
||||
r = bdata->platform_enable(dssdev);
|
||||
if (r)
|
||||
goto err_plat_en;
|
||||
}
|
||||
|
||||
r = omapdss_rfbi_display_enable(dssdev);
|
||||
if (r)
|
||||
goto err_rfbi_en;
|
||||
|
||||
rev = blizzard_read_reg(BLIZZARD_REV_CODE);
|
||||
conf = blizzard_read_reg(BLIZZARD_CONFIG);
|
||||
|
||||
switch (rev & 0xfc) {
|
||||
case 0x9c:
|
||||
ddata->blizzard_ver = BLIZZARD_VERSION_S1D13744;
|
||||
dev_info(&dssdev->dev, "s1d13744 LCD controller rev %d "
|
||||
"initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07);
|
||||
break;
|
||||
case 0xa4:
|
||||
ddata->blizzard_ver = BLIZZARD_VERSION_S1D13745;
|
||||
dev_info(&dssdev->dev, "s1d13745 LCD controller rev %d "
|
||||
"initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07);
|
||||
break;
|
||||
default:
|
||||
dev_err(&dssdev->dev, "invalid s1d1374x revision %02x\n", rev);
|
||||
r = -ENODEV;
|
||||
goto err_inv_chip;
|
||||
}
|
||||
|
||||
/* panel */
|
||||
|
||||
gpio_direction_output(bdata->panel_reset, 1);
|
||||
|
||||
mipid_read(spi, MIPID_CMD_READ_DISP_ID, display_id, 3);
|
||||
dev_dbg(&spi->dev, "MIPI display ID: %02x%02x%02x\n",
|
||||
display_id[0], display_id[1], display_id[2]);
|
||||
|
||||
switch (display_id[0]) {
|
||||
case 0x45:
|
||||
panel_name = "lph8923";
|
||||
break;
|
||||
case 0x83:
|
||||
panel_name = "ls041y3";
|
||||
break;
|
||||
default:
|
||||
dev_err(&dssdev->dev, "invalid display ID 0x%x\n",
|
||||
display_id[0]);
|
||||
r = -ENODEV;
|
||||
goto err_inv_panel;
|
||||
}
|
||||
|
||||
dev_info(&dssdev->dev, "%s rev %02x LCD detected\n",
|
||||
panel_name, display_id[1]);
|
||||
|
||||
send_sleep_out(spi);
|
||||
send_init_string(spi);
|
||||
set_data_lines(spi, 24);
|
||||
send_display_on(spi);
|
||||
|
||||
return 0;
|
||||
|
||||
err_inv_panel:
|
||||
/*
|
||||
* HACK: we should turn off the panel here, but there is some problem
|
||||
* with the initialization sequence, and we fail to init the panel if we
|
||||
* have turned it off
|
||||
*/
|
||||
/* gpio_direction_output(bdata->panel_reset, 0); */
|
||||
err_inv_chip:
|
||||
omapdss_rfbi_display_disable(dssdev);
|
||||
err_rfbi_en:
|
||||
if (bdata->platform_disable)
|
||||
bdata->platform_disable(dssdev);
|
||||
err_plat_en:
|
||||
gpio_direction_output(bdata->ctrl_pwrdown, 0);
|
||||
return r;
|
||||
}
|
||||
|
||||
static void n8x0_panel_power_off(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct panel_n8x0_data *bdata = get_board_data(dssdev);
|
||||
struct panel_drv_data *ddata = get_drv_data(dssdev);
|
||||
struct spi_device *spi = ddata->spidev;
|
||||
|
||||
if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
|
||||
return;
|
||||
|
||||
send_display_off(spi);
|
||||
send_sleep_in(spi);
|
||||
|
||||
if (bdata->platform_disable)
|
||||
bdata->platform_disable(dssdev);
|
||||
|
||||
/*
|
||||
* HACK: we should turn off the panel here, but there is some problem
|
||||
* with the initialization sequence, and we fail to init the panel if we
|
||||
* have turned it off
|
||||
*/
|
||||
/* gpio_direction_output(bdata->panel_reset, 0); */
|
||||
gpio_direction_output(bdata->ctrl_pwrdown, 0);
|
||||
omapdss_rfbi_display_disable(dssdev);
|
||||
}
|
||||
|
||||
static const struct rfbi_timings n8x0_panel_timings = {
|
||||
.cs_on_time = 0,
|
||||
|
||||
.we_on_time = 9000,
|
||||
.we_off_time = 18000,
|
||||
.we_cycle_time = 36000,
|
||||
|
||||
.re_on_time = 9000,
|
||||
.re_off_time = 27000,
|
||||
.re_cycle_time = 36000,
|
||||
|
||||
.access_time = 27000,
|
||||
.cs_off_time = 36000,
|
||||
|
||||
.cs_pulse_width = 0,
|
||||
};
|
||||
|
||||
static int n8x0_bl_update_status(struct backlight_device *dev)
|
||||
{
|
||||
struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev);
|
||||
struct panel_n8x0_data *bdata = get_board_data(dssdev);
|
||||
struct panel_drv_data *ddata = get_drv_data(dssdev);
|
||||
int r;
|
||||
int level;
|
||||
|
||||
mutex_lock(&ddata->lock);
|
||||
|
||||
if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
|
||||
dev->props.power == FB_BLANK_UNBLANK)
|
||||
level = dev->props.brightness;
|
||||
else
|
||||
level = 0;
|
||||
|
||||
dev_dbg(&dssdev->dev, "update brightness to %d\n", level);
|
||||
|
||||
if (!bdata->set_backlight)
|
||||
r = -EINVAL;
|
||||
else
|
||||
r = bdata->set_backlight(dssdev, level);
|
||||
|
||||
mutex_unlock(&ddata->lock);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int n8x0_bl_get_intensity(struct backlight_device *dev)
|
||||
{
|
||||
if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
|
||||
dev->props.power == FB_BLANK_UNBLANK)
|
||||
return dev->props.brightness;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct backlight_ops n8x0_bl_ops = {
|
||||
.get_brightness = n8x0_bl_get_intensity,
|
||||
.update_status = n8x0_bl_update_status,
|
||||
};
|
||||
|
||||
static int n8x0_panel_probe(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct panel_n8x0_data *bdata = get_board_data(dssdev);
|
||||
struct panel_drv_data *ddata;
|
||||
struct backlight_device *bldev;
|
||||
struct backlight_properties props;
|
||||
int r;
|
||||
|
||||
dev_dbg(&dssdev->dev, "probe\n");
|
||||
|
||||
if (!bdata)
|
||||
return -EINVAL;
|
||||
|
||||
s_drv_data.dssdev = dssdev;
|
||||
|
||||
ddata = &s_drv_data;
|
||||
|
||||
mutex_init(&ddata->lock);
|
||||
|
||||
dssdev->panel.config = OMAP_DSS_LCD_TFT;
|
||||
dssdev->panel.timings.x_res = 800;
|
||||
dssdev->panel.timings.y_res = 480;
|
||||
dssdev->ctrl.pixel_size = 16;
|
||||
dssdev->ctrl.rfbi_timings = n8x0_panel_timings;
|
||||
|
||||
memset(&props, 0, sizeof(props));
|
||||
props.max_brightness = 127;
|
||||
props.type = BACKLIGHT_PLATFORM;
|
||||
bldev = backlight_device_register(dev_name(&dssdev->dev), &dssdev->dev,
|
||||
dssdev, &n8x0_bl_ops, &props);
|
||||
if (IS_ERR(bldev)) {
|
||||
r = PTR_ERR(bldev);
|
||||
dev_err(&dssdev->dev, "register backlight failed\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
ddata->bldev = bldev;
|
||||
|
||||
bldev->props.fb_blank = FB_BLANK_UNBLANK;
|
||||
bldev->props.power = FB_BLANK_UNBLANK;
|
||||
bldev->props.brightness = 127;
|
||||
|
||||
n8x0_bl_update_status(bldev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void n8x0_panel_remove(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct panel_drv_data *ddata = get_drv_data(dssdev);
|
||||
struct backlight_device *bldev;
|
||||
|
||||
dev_dbg(&dssdev->dev, "remove\n");
|
||||
|
||||
bldev = ddata->bldev;
|
||||
bldev->props.power = FB_BLANK_POWERDOWN;
|
||||
n8x0_bl_update_status(bldev);
|
||||
backlight_device_unregister(bldev);
|
||||
|
||||
dev_set_drvdata(&dssdev->dev, NULL);
|
||||
}
|
||||
|
||||
static int n8x0_panel_enable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct panel_drv_data *ddata = get_drv_data(dssdev);
|
||||
int r;
|
||||
|
||||
dev_dbg(&dssdev->dev, "enable\n");
|
||||
|
||||
mutex_lock(&ddata->lock);
|
||||
|
||||
rfbi_bus_lock();
|
||||
|
||||
r = n8x0_panel_power_on(dssdev);
|
||||
|
||||
rfbi_bus_unlock();
|
||||
|
||||
if (r) {
|
||||
mutex_unlock(&ddata->lock);
|
||||
return r;
|
||||
}
|
||||
|
||||
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
|
||||
|
||||
mutex_unlock(&ddata->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void n8x0_panel_disable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct panel_drv_data *ddata = get_drv_data(dssdev);
|
||||
|
||||
dev_dbg(&dssdev->dev, "disable\n");
|
||||
|
||||
mutex_lock(&ddata->lock);
|
||||
|
||||
rfbi_bus_lock();
|
||||
|
||||
n8x0_panel_power_off(dssdev);
|
||||
|
||||
rfbi_bus_unlock();
|
||||
|
||||
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
|
||||
|
||||
mutex_unlock(&ddata->lock);
|
||||
}
|
||||
|
||||
static int n8x0_panel_suspend(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct panel_drv_data *ddata = get_drv_data(dssdev);
|
||||
|
||||
dev_dbg(&dssdev->dev, "suspend\n");
|
||||
|
||||
mutex_lock(&ddata->lock);
|
||||
|
||||
rfbi_bus_lock();
|
||||
|
||||
n8x0_panel_power_off(dssdev);
|
||||
|
||||
rfbi_bus_unlock();
|
||||
|
||||
dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
|
||||
|
||||
mutex_unlock(&ddata->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int n8x0_panel_resume(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct panel_drv_data *ddata = get_drv_data(dssdev);
|
||||
int r;
|
||||
|
||||
dev_dbg(&dssdev->dev, "resume\n");
|
||||
|
||||
mutex_lock(&ddata->lock);
|
||||
|
||||
rfbi_bus_lock();
|
||||
|
||||
r = n8x0_panel_power_on(dssdev);
|
||||
|
||||
rfbi_bus_unlock();
|
||||
|
||||
if (r) {
|
||||
mutex_unlock(&ddata->lock);
|
||||
return r;
|
||||
}
|
||||
|
||||
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
|
||||
|
||||
mutex_unlock(&ddata->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void n8x0_panel_get_timings(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings)
|
||||
{
|
||||
*timings = dssdev->panel.timings;
|
||||
}
|
||||
|
||||
static void n8x0_panel_get_resolution(struct omap_dss_device *dssdev,
|
||||
u16 *xres, u16 *yres)
|
||||
{
|
||||
*xres = dssdev->panel.timings.x_res;
|
||||
*yres = dssdev->panel.timings.y_res;
|
||||
}
|
||||
|
||||
static void update_done(void *data)
|
||||
{
|
||||
rfbi_bus_unlock();
|
||||
}
|
||||
|
||||
static int n8x0_panel_update(struct omap_dss_device *dssdev,
|
||||
u16 x, u16 y, u16 w, u16 h)
|
||||
{
|
||||
struct panel_drv_data *ddata = get_drv_data(dssdev);
|
||||
|
||||
dev_dbg(&dssdev->dev, "update\n");
|
||||
|
||||
mutex_lock(&ddata->lock);
|
||||
rfbi_bus_lock();
|
||||
|
||||
omap_rfbi_prepare_update(dssdev, &x, &y, &w, &h);
|
||||
|
||||
blizzard_ctrl_setup_update(dssdev, x, y, w, h);
|
||||
|
||||
omap_rfbi_update(dssdev, x, y, w, h, update_done, NULL);
|
||||
|
||||
mutex_unlock(&ddata->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int n8x0_panel_sync(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct panel_drv_data *ddata = get_drv_data(dssdev);
|
||||
|
||||
dev_dbg(&dssdev->dev, "sync\n");
|
||||
|
||||
mutex_lock(&ddata->lock);
|
||||
rfbi_bus_lock();
|
||||
rfbi_bus_unlock();
|
||||
mutex_unlock(&ddata->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct omap_dss_driver n8x0_panel_driver = {
|
||||
.probe = n8x0_panel_probe,
|
||||
.remove = n8x0_panel_remove,
|
||||
|
||||
.enable = n8x0_panel_enable,
|
||||
.disable = n8x0_panel_disable,
|
||||
.suspend = n8x0_panel_suspend,
|
||||
.resume = n8x0_panel_resume,
|
||||
|
||||
.update = n8x0_panel_update,
|
||||
.sync = n8x0_panel_sync,
|
||||
|
||||
.get_resolution = n8x0_panel_get_resolution,
|
||||
.get_recommended_bpp = omapdss_default_get_recommended_bpp,
|
||||
|
||||
.get_timings = n8x0_panel_get_timings,
|
||||
|
||||
.driver = {
|
||||
.name = "n8x0_panel",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
/* PANEL */
|
||||
|
||||
static int mipid_spi_probe(struct spi_device *spi)
|
||||
{
|
||||
dev_dbg(&spi->dev, "mipid_spi_probe\n");
|
||||
|
||||
spi->mode = SPI_MODE_0;
|
||||
|
||||
s_drv_data.spidev = spi;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mipid_spi_remove(struct spi_device *spi)
|
||||
{
|
||||
dev_dbg(&spi->dev, "mipid_spi_remove\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct spi_driver mipid_spi_driver = {
|
||||
.driver = {
|
||||
.name = "lcd_mipid",
|
||||
.bus = &spi_bus_type,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = mipid_spi_probe,
|
||||
.remove = __devexit_p(mipid_spi_remove),
|
||||
};
|
||||
|
||||
static int __init n8x0_panel_drv_init(void)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = spi_register_driver(&mipid_spi_driver);
|
||||
if (r) {
|
||||
pr_err("n8x0_panel: spi driver registration failed\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
r = omap_dss_register_driver(&n8x0_panel_driver);
|
||||
if (r) {
|
||||
pr_err("n8x0_panel: dss driver registration failed\n");
|
||||
spi_unregister_driver(&mipid_spi_driver);
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit n8x0_panel_drv_exit(void)
|
||||
{
|
||||
spi_unregister_driver(&mipid_spi_driver);
|
||||
|
||||
omap_dss_unregister_driver(&n8x0_panel_driver);
|
||||
}
|
||||
|
||||
module_init(n8x0_panel_drv_init);
|
||||
module_exit(n8x0_panel_drv_exit);
|
||||
MODULE_LICENSE("GPL");
|
||||
594
drivers/video/omap2/displays/panel-picodlp.c
Normal file
594
drivers/video/omap2/displays/panel-picodlp.c
Normal file
|
|
@ -0,0 +1,594 @@
|
|||
/*
|
||||
* picodlp panel driver
|
||||
* picodlp_i2c_driver: i2c_client driver
|
||||
*
|
||||
* Copyright (C) 2009-2011 Texas Instruments
|
||||
* Author: Mythri P K <mythripk@ti.com>
|
||||
* Mayuresh Janorkar <mayur@ti.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#include <video/omapdss.h>
|
||||
#include <video/omap-panel-picodlp.h>
|
||||
|
||||
#include "panel-picodlp.h"
|
||||
|
||||
struct picodlp_data {
|
||||
struct mutex lock;
|
||||
struct i2c_client *picodlp_i2c_client;
|
||||
};
|
||||
|
||||
static struct i2c_board_info picodlp_i2c_board_info = {
|
||||
I2C_BOARD_INFO("picodlp_i2c_driver", 0x1b),
|
||||
};
|
||||
|
||||
struct picodlp_i2c_data {
|
||||
struct mutex xfer_lock;
|
||||
};
|
||||
|
||||
static struct i2c_device_id picodlp_i2c_id[] = {
|
||||
{ "picodlp_i2c_driver", 0 },
|
||||
};
|
||||
|
||||
struct picodlp_i2c_command {
|
||||
u8 reg;
|
||||
u32 value;
|
||||
};
|
||||
|
||||
static struct omap_video_timings pico_ls_timings = {
|
||||
.x_res = 864,
|
||||
.y_res = 480,
|
||||
.hsw = 7,
|
||||
.hfp = 11,
|
||||
.hbp = 7,
|
||||
|
||||
.pixel_clock = 19200,
|
||||
|
||||
.vsw = 2,
|
||||
.vfp = 3,
|
||||
.vbp = 14,
|
||||
};
|
||||
|
||||
static inline struct picodlp_panel_data
|
||||
*get_panel_data(const struct omap_dss_device *dssdev)
|
||||
{
|
||||
return (struct picodlp_panel_data *) dssdev->data;
|
||||
}
|
||||
|
||||
static u32 picodlp_i2c_read(struct i2c_client *client, u8 reg)
|
||||
{
|
||||
u8 read_cmd[] = {READ_REG_SELECT, reg}, data[4];
|
||||
struct picodlp_i2c_data *picodlp_i2c_data = i2c_get_clientdata(client);
|
||||
struct i2c_msg msg[2];
|
||||
|
||||
mutex_lock(&picodlp_i2c_data->xfer_lock);
|
||||
|
||||
msg[0].addr = client->addr;
|
||||
msg[0].flags = 0;
|
||||
msg[0].len = 2;
|
||||
msg[0].buf = read_cmd;
|
||||
|
||||
msg[1].addr = client->addr;
|
||||
msg[1].flags = I2C_M_RD;
|
||||
msg[1].len = 4;
|
||||
msg[1].buf = data;
|
||||
|
||||
i2c_transfer(client->adapter, msg, 2);
|
||||
mutex_unlock(&picodlp_i2c_data->xfer_lock);
|
||||
return (data[3] | (data[2] << 8) | (data[1] << 16) | (data[0] << 24));
|
||||
}
|
||||
|
||||
static int picodlp_i2c_write_block(struct i2c_client *client,
|
||||
u8 *data, int len)
|
||||
{
|
||||
struct i2c_msg msg;
|
||||
int i, r, msg_count = 1;
|
||||
|
||||
struct picodlp_i2c_data *picodlp_i2c_data = i2c_get_clientdata(client);
|
||||
|
||||
if (len < 1 || len > 32) {
|
||||
dev_err(&client->dev,
|
||||
"too long syn_write_block len %d\n", len);
|
||||
return -EIO;
|
||||
}
|
||||
mutex_lock(&picodlp_i2c_data->xfer_lock);
|
||||
|
||||
msg.addr = client->addr;
|
||||
msg.flags = 0;
|
||||
msg.len = len;
|
||||
msg.buf = data;
|
||||
r = i2c_transfer(client->adapter, &msg, msg_count);
|
||||
mutex_unlock(&picodlp_i2c_data->xfer_lock);
|
||||
|
||||
/*
|
||||
* i2c_transfer returns:
|
||||
* number of messages sent in case of success
|
||||
* a negative error number in case of failure
|
||||
*/
|
||||
if (r != msg_count)
|
||||
goto err;
|
||||
|
||||
/* In case of success */
|
||||
for (i = 0; i < len; i++)
|
||||
dev_dbg(&client->dev,
|
||||
"addr %x bw 0x%02x[%d]: 0x%02x\n",
|
||||
client->addr, data[0] + i, i, data[i]);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
dev_err(&client->dev, "picodlp_i2c_write error\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
static int picodlp_i2c_write(struct i2c_client *client, u8 reg, u32 value)
|
||||
{
|
||||
u8 data[5];
|
||||
int i;
|
||||
|
||||
data[0] = reg;
|
||||
for (i = 1; i < 5; i++)
|
||||
data[i] = (value >> (32 - (i) * 8)) & 0xFF;
|
||||
|
||||
return picodlp_i2c_write_block(client, data, 5);
|
||||
}
|
||||
|
||||
static int picodlp_i2c_write_array(struct i2c_client *client,
|
||||
const struct picodlp_i2c_command commands[],
|
||||
int count)
|
||||
{
|
||||
int i, r = 0;
|
||||
for (i = 0; i < count; i++) {
|
||||
r = picodlp_i2c_write(client, commands[i].reg,
|
||||
commands[i].value);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static int picodlp_wait_for_dma_done(struct i2c_client *client)
|
||||
{
|
||||
u8 trial = 100;
|
||||
|
||||
do {
|
||||
msleep(1);
|
||||
if (!trial--)
|
||||
return -ETIMEDOUT;
|
||||
} while (picodlp_i2c_read(client, MAIN_STATUS) & DMA_STATUS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* picodlp_i2c_init: i2c_initialization routine
|
||||
* client: i2c_client for communication
|
||||
*
|
||||
* return
|
||||
* 0 : Success, no error
|
||||
* error code : Failure
|
||||
*/
|
||||
static int picodlp_i2c_init(struct i2c_client *client)
|
||||
{
|
||||
int r;
|
||||
static const struct picodlp_i2c_command init_cmd_set1[] = {
|
||||
{SOFT_RESET, 1},
|
||||
{DMD_PARK_TRIGGER, 1},
|
||||
{MISC_REG, 5},
|
||||
{SEQ_CONTROL, 0},
|
||||
{SEQ_VECTOR, 0x100},
|
||||
{DMD_BLOCK_COUNT, 7},
|
||||
{DMD_VCC_CONTROL, 0x109},
|
||||
{DMD_PARK_PULSE_COUNT, 0xA},
|
||||
{DMD_PARK_PULSE_WIDTH, 0xB},
|
||||
{DMD_PARK_DELAY, 0x2ED},
|
||||
{DMD_SHADOW_ENABLE, 0},
|
||||
{FLASH_OPCODE, 0xB},
|
||||
{FLASH_DUMMY_BYTES, 1},
|
||||
{FLASH_ADDR_BYTES, 3},
|
||||
{PBC_CONTROL, 0},
|
||||
{FLASH_START_ADDR, CMT_LUT_0_START_ADDR},
|
||||
{FLASH_READ_BYTES, CMT_LUT_0_SIZE},
|
||||
{CMT_SPLASH_LUT_START_ADDR, 0},
|
||||
{CMT_SPLASH_LUT_DEST_SELECT, CMT_LUT_ALL},
|
||||
{PBC_CONTROL, 1},
|
||||
};
|
||||
|
||||
static const struct picodlp_i2c_command init_cmd_set2[] = {
|
||||
{PBC_CONTROL, 0},
|
||||
{CMT_SPLASH_LUT_DEST_SELECT, 0},
|
||||
{PBC_CONTROL, 0},
|
||||
{FLASH_START_ADDR, SEQUENCE_0_START_ADDR},
|
||||
{FLASH_READ_BYTES, SEQUENCE_0_SIZE},
|
||||
{SEQ_RESET_LUT_START_ADDR, 0},
|
||||
{SEQ_RESET_LUT_DEST_SELECT, SEQ_SEQ_LUT},
|
||||
{PBC_CONTROL, 1},
|
||||
};
|
||||
|
||||
static const struct picodlp_i2c_command init_cmd_set3[] = {
|
||||
{PBC_CONTROL, 0},
|
||||
{SEQ_RESET_LUT_DEST_SELECT, 0},
|
||||
{PBC_CONTROL, 0},
|
||||
{FLASH_START_ADDR, DRC_TABLE_0_START_ADDR},
|
||||
{FLASH_READ_BYTES, DRC_TABLE_0_SIZE},
|
||||
{SEQ_RESET_LUT_START_ADDR, 0},
|
||||
{SEQ_RESET_LUT_DEST_SELECT, SEQ_DRC_LUT_ALL},
|
||||
{PBC_CONTROL, 1},
|
||||
};
|
||||
|
||||
static const struct picodlp_i2c_command init_cmd_set4[] = {
|
||||
{PBC_CONTROL, 0},
|
||||
{SEQ_RESET_LUT_DEST_SELECT, 0},
|
||||
{SDC_ENABLE, 1},
|
||||
{AGC_CTRL, 7},
|
||||
{CCA_C1A, 0x100},
|
||||
{CCA_C1B, 0x0},
|
||||
{CCA_C1C, 0x0},
|
||||
{CCA_C2A, 0x0},
|
||||
{CCA_C2B, 0x100},
|
||||
{CCA_C2C, 0x0},
|
||||
{CCA_C3A, 0x0},
|
||||
{CCA_C3B, 0x0},
|
||||
{CCA_C3C, 0x100},
|
||||
{CCA_C7A, 0x100},
|
||||
{CCA_C7B, 0x100},
|
||||
{CCA_C7C, 0x100},
|
||||
{CCA_ENABLE, 1},
|
||||
{CPU_IF_MODE, 1},
|
||||
{SHORT_FLIP, 1},
|
||||
{CURTAIN_CONTROL, 0},
|
||||
{DMD_PARK_TRIGGER, 0},
|
||||
{R_DRIVE_CURRENT, 0x298},
|
||||
{G_DRIVE_CURRENT, 0x298},
|
||||
{B_DRIVE_CURRENT, 0x298},
|
||||
{RGB_DRIVER_ENABLE, 7},
|
||||
{SEQ_CONTROL, 0},
|
||||
{ACTGEN_CONTROL, 0x10},
|
||||
{SEQUENCE_MODE, SEQ_LOCK},
|
||||
{DATA_FORMAT, RGB888},
|
||||
{INPUT_RESOLUTION, WVGA_864_LANDSCAPE},
|
||||
{INPUT_SOURCE, PARALLEL_RGB},
|
||||
{CPU_IF_SYNC_METHOD, 1},
|
||||
{SEQ_CONTROL, 1}
|
||||
};
|
||||
|
||||
r = picodlp_i2c_write_array(client, init_cmd_set1,
|
||||
ARRAY_SIZE(init_cmd_set1));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = picodlp_wait_for_dma_done(client);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = picodlp_i2c_write_array(client, init_cmd_set2,
|
||||
ARRAY_SIZE(init_cmd_set2));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = picodlp_wait_for_dma_done(client);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = picodlp_i2c_write_array(client, init_cmd_set3,
|
||||
ARRAY_SIZE(init_cmd_set3));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = picodlp_wait_for_dma_done(client);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = picodlp_i2c_write_array(client, init_cmd_set4,
|
||||
ARRAY_SIZE(init_cmd_set4));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int picodlp_i2c_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct picodlp_i2c_data *picodlp_i2c_data;
|
||||
|
||||
picodlp_i2c_data = kzalloc(sizeof(struct picodlp_i2c_data), GFP_KERNEL);
|
||||
|
||||
if (!picodlp_i2c_data)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_init(&picodlp_i2c_data->xfer_lock);
|
||||
i2c_set_clientdata(client, picodlp_i2c_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int picodlp_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
struct picodlp_i2c_data *picodlp_i2c_data =
|
||||
i2c_get_clientdata(client);
|
||||
kfree(picodlp_i2c_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct i2c_driver picodlp_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "picodlp_i2c_driver",
|
||||
},
|
||||
.probe = picodlp_i2c_probe,
|
||||
.remove = picodlp_i2c_remove,
|
||||
.id_table = picodlp_i2c_id,
|
||||
};
|
||||
|
||||
static int picodlp_panel_power_on(struct omap_dss_device *dssdev)
|
||||
{
|
||||
int r, trial = 100;
|
||||
struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
|
||||
struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev);
|
||||
|
||||
if (dssdev->platform_enable) {
|
||||
r = dssdev->platform_enable(dssdev);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
gpio_set_value(picodlp_pdata->pwrgood_gpio, 0);
|
||||
msleep(1);
|
||||
gpio_set_value(picodlp_pdata->pwrgood_gpio, 1);
|
||||
|
||||
while (!gpio_get_value(picodlp_pdata->emu_done_gpio)) {
|
||||
if (!trial--) {
|
||||
dev_err(&dssdev->dev, "emu_done signal not"
|
||||
" going high\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
msleep(5);
|
||||
}
|
||||
/*
|
||||
* As per dpp2600 programming guide,
|
||||
* it is required to sleep for 1000ms after emu_done signal goes high
|
||||
* then only i2c commands can be successfully sent to dpp2600
|
||||
*/
|
||||
msleep(1000);
|
||||
r = omapdss_dpi_display_enable(dssdev);
|
||||
if (r) {
|
||||
dev_err(&dssdev->dev, "failed to enable DPI\n");
|
||||
goto err1;
|
||||
}
|
||||
|
||||
r = picodlp_i2c_init(picod->picodlp_i2c_client);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
|
||||
|
||||
return r;
|
||||
err:
|
||||
omapdss_dpi_display_disable(dssdev);
|
||||
err1:
|
||||
if (dssdev->platform_disable)
|
||||
dssdev->platform_disable(dssdev);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void picodlp_panel_power_off(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev);
|
||||
|
||||
omapdss_dpi_display_disable(dssdev);
|
||||
|
||||
gpio_set_value(picodlp_pdata->emu_done_gpio, 0);
|
||||
gpio_set_value(picodlp_pdata->pwrgood_gpio, 0);
|
||||
|
||||
if (dssdev->platform_disable)
|
||||
dssdev->platform_disable(dssdev);
|
||||
}
|
||||
|
||||
static int picodlp_panel_probe(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct picodlp_data *picod;
|
||||
struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev);
|
||||
struct i2c_adapter *adapter;
|
||||
struct i2c_client *picodlp_i2c_client;
|
||||
int r = 0, picodlp_adapter_id;
|
||||
|
||||
dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_ONOFF |
|
||||
OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IVS;
|
||||
dssdev->panel.acb = 0x0;
|
||||
dssdev->panel.timings = pico_ls_timings;
|
||||
|
||||
picod = kzalloc(sizeof(struct picodlp_data), GFP_KERNEL);
|
||||
if (!picod)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_init(&picod->lock);
|
||||
|
||||
picodlp_adapter_id = picodlp_pdata->picodlp_adapter_id;
|
||||
|
||||
adapter = i2c_get_adapter(picodlp_adapter_id);
|
||||
if (!adapter) {
|
||||
dev_err(&dssdev->dev, "can't get i2c adapter\n");
|
||||
r = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
|
||||
picodlp_i2c_client = i2c_new_device(adapter, &picodlp_i2c_board_info);
|
||||
if (!picodlp_i2c_client) {
|
||||
dev_err(&dssdev->dev, "can't add i2c device::"
|
||||
" picodlp_i2c_client is NULL\n");
|
||||
r = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
|
||||
picod->picodlp_i2c_client = picodlp_i2c_client;
|
||||
|
||||
dev_set_drvdata(&dssdev->dev, picod);
|
||||
return r;
|
||||
err:
|
||||
kfree(picod);
|
||||
return r;
|
||||
}
|
||||
|
||||
static void picodlp_panel_remove(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
|
||||
|
||||
i2c_unregister_device(picod->picodlp_i2c_client);
|
||||
dev_set_drvdata(&dssdev->dev, NULL);
|
||||
dev_dbg(&dssdev->dev, "removing picodlp panel\n");
|
||||
|
||||
kfree(picod);
|
||||
}
|
||||
|
||||
static int picodlp_panel_enable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
|
||||
int r;
|
||||
|
||||
dev_dbg(&dssdev->dev, "enabling picodlp panel\n");
|
||||
|
||||
mutex_lock(&picod->lock);
|
||||
if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
|
||||
mutex_unlock(&picod->lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = picodlp_panel_power_on(dssdev);
|
||||
mutex_unlock(&picod->lock);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void picodlp_panel_disable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
|
||||
|
||||
mutex_lock(&picod->lock);
|
||||
/* Turn off DLP Power */
|
||||
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
|
||||
picodlp_panel_power_off(dssdev);
|
||||
|
||||
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
|
||||
mutex_unlock(&picod->lock);
|
||||
|
||||
dev_dbg(&dssdev->dev, "disabling picodlp panel\n");
|
||||
}
|
||||
|
||||
static int picodlp_panel_suspend(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
|
||||
|
||||
mutex_lock(&picod->lock);
|
||||
/* Turn off DLP Power */
|
||||
if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
|
||||
mutex_unlock(&picod->lock);
|
||||
dev_err(&dssdev->dev, "unable to suspend picodlp panel,"
|
||||
" panel is not ACTIVE\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
picodlp_panel_power_off(dssdev);
|
||||
|
||||
dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
|
||||
mutex_unlock(&picod->lock);
|
||||
|
||||
dev_dbg(&dssdev->dev, "suspending picodlp panel\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int picodlp_panel_resume(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
|
||||
int r;
|
||||
|
||||
mutex_lock(&picod->lock);
|
||||
if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
|
||||
mutex_unlock(&picod->lock);
|
||||
dev_err(&dssdev->dev, "unable to resume picodlp panel,"
|
||||
" panel is not ACTIVE\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = picodlp_panel_power_on(dssdev);
|
||||
mutex_unlock(&picod->lock);
|
||||
dev_dbg(&dssdev->dev, "resuming picodlp panel\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
static void picodlp_get_resolution(struct omap_dss_device *dssdev,
|
||||
u16 *xres, u16 *yres)
|
||||
{
|
||||
*xres = dssdev->panel.timings.x_res;
|
||||
*yres = dssdev->panel.timings.y_res;
|
||||
}
|
||||
|
||||
static struct omap_dss_driver picodlp_driver = {
|
||||
.probe = picodlp_panel_probe,
|
||||
.remove = picodlp_panel_remove,
|
||||
|
||||
.enable = picodlp_panel_enable,
|
||||
.disable = picodlp_panel_disable,
|
||||
|
||||
.get_resolution = picodlp_get_resolution,
|
||||
|
||||
.suspend = picodlp_panel_suspend,
|
||||
.resume = picodlp_panel_resume,
|
||||
|
||||
.driver = {
|
||||
.name = "picodlp_panel",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init picodlp_init(void)
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
r = i2c_add_driver(&picodlp_i2c_driver);
|
||||
if (r) {
|
||||
printk(KERN_WARNING "picodlp_i2c_driver" \
|
||||
" registration failed\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
r = omap_dss_register_driver(&picodlp_driver);
|
||||
if (r)
|
||||
i2c_del_driver(&picodlp_i2c_driver);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void __exit picodlp_exit(void)
|
||||
{
|
||||
i2c_del_driver(&picodlp_i2c_driver);
|
||||
omap_dss_unregister_driver(&picodlp_driver);
|
||||
}
|
||||
|
||||
module_init(picodlp_init);
|
||||
module_exit(picodlp_exit);
|
||||
|
||||
MODULE_AUTHOR("Mythri P K <[email protected]>");
|
||||
MODULE_DESCRIPTION("picodlp driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
288
drivers/video/omap2/displays/panel-picodlp.h
Normal file
288
drivers/video/omap2/displays/panel-picodlp.h
Normal file
|
|
@ -0,0 +1,288 @@
|
|||
/*
|
||||
* Header file required by picodlp panel driver
|
||||
*
|
||||
* Copyright (C) 2009-2011 Texas Instruments
|
||||
* Author: Mythri P K <mythripk@ti.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __OMAP2_DISPLAY_PANEL_PICODLP_H
|
||||
#define __OMAP2_DISPLAY_PANEL_PICODLP_H
|
||||
|
||||
/* Commands used for configuring picodlp panel */
|
||||
|
||||
#define MAIN_STATUS 0x03
|
||||
#define PBC_CONTROL 0x08
|
||||
#define INPUT_SOURCE 0x0B
|
||||
#define INPUT_RESOLUTION 0x0C
|
||||
#define DATA_FORMAT 0x0D
|
||||
#define IMG_ROTATION 0x0E
|
||||
#define LONG_FLIP 0x0F
|
||||
#define SHORT_FLIP 0x10
|
||||
#define TEST_PAT_SELECT 0x11
|
||||
#define R_DRIVE_CURRENT 0x12
|
||||
#define G_DRIVE_CURRENT 0x13
|
||||
#define B_DRIVE_CURRENT 0x14
|
||||
#define READ_REG_SELECT 0x15
|
||||
#define RGB_DRIVER_ENABLE 0x16
|
||||
|
||||
#define CPU_IF_MODE 0x18
|
||||
#define FRAME_RATE 0x19
|
||||
#define CPU_IF_SYNC_METHOD 0x1A
|
||||
#define CPU_IF_SOF 0x1B
|
||||
#define CPU_IF_EOF 0x1C
|
||||
#define CPU_IF_SLEEP 0x1D
|
||||
|
||||
#define SEQUENCE_MODE 0x1E
|
||||
#define SOFT_RESET 0x1F
|
||||
#define FRONT_END_RESET 0x21
|
||||
#define AUTO_PWR_ENABLE 0x22
|
||||
|
||||
#define VSYNC_LINE_DELAY 0x23
|
||||
#define CPU_PI_HORIZ_START 0x24
|
||||
#define CPU_PI_VERT_START 0x25
|
||||
#define CPU_PI_HORIZ_WIDTH 0x26
|
||||
#define CPU_PI_VERT_HEIGHT 0x27
|
||||
|
||||
#define PIXEL_MASK_CROP 0x28
|
||||
#define CROP_FIRST_LINE 0x29
|
||||
#define CROP_LAST_LINE 0x2A
|
||||
#define CROP_FIRST_PIXEL 0x2B
|
||||
#define CROP_LAST_PIXEL 0x2C
|
||||
#define DMD_PARK_TRIGGER 0x2D
|
||||
|
||||
#define MISC_REG 0x30
|
||||
|
||||
/* AGC registers */
|
||||
#define AGC_CTRL 0x50
|
||||
#define AGC_CLIPPED_PIXS 0x55
|
||||
#define AGC_BRIGHT_PIXS 0x56
|
||||
#define AGC_BG_PIXS 0x57
|
||||
#define AGC_SAFETY_MARGIN 0x17
|
||||
|
||||
/* Color Coordinate Adjustment registers */
|
||||
#define CCA_ENABLE 0x5E
|
||||
#define CCA_C1A 0x5F
|
||||
#define CCA_C1B 0x60
|
||||
#define CCA_C1C 0x61
|
||||
#define CCA_C2A 0x62
|
||||
#define CCA_C2B 0x63
|
||||
#define CCA_C2C 0x64
|
||||
#define CCA_C3A 0x65
|
||||
#define CCA_C3B 0x66
|
||||
#define CCA_C3C 0x67
|
||||
#define CCA_C7A 0x71
|
||||
#define CCA_C7B 0x72
|
||||
#define CCA_C7C 0x73
|
||||
|
||||
/**
|
||||
* DLP Pico Processor 2600 comes with flash
|
||||
* We can do DMA operations from flash for accessing Look Up Tables
|
||||
*/
|
||||
#define DMA_STATUS 0x100
|
||||
#define FLASH_ADDR_BYTES 0x74
|
||||
#define FLASH_DUMMY_BYTES 0x75
|
||||
#define FLASH_WRITE_BYTES 0x76
|
||||
#define FLASH_READ_BYTES 0x77
|
||||
#define FLASH_OPCODE 0x78
|
||||
#define FLASH_START_ADDR 0x79
|
||||
#define FLASH_DUMMY2 0x7A
|
||||
#define FLASH_WRITE_DATA 0x7B
|
||||
|
||||
#define TEMPORAL_DITH_DISABLE 0x7E
|
||||
#define SEQ_CONTROL 0x82
|
||||
#define SEQ_VECTOR 0x83
|
||||
|
||||
/* DMD is Digital Micromirror Device */
|
||||
#define DMD_BLOCK_COUNT 0x84
|
||||
#define DMD_VCC_CONTROL 0x86
|
||||
#define DMD_PARK_PULSE_COUNT 0x87
|
||||
#define DMD_PARK_PULSE_WIDTH 0x88
|
||||
#define DMD_PARK_DELAY 0x89
|
||||
#define DMD_SHADOW_ENABLE 0x8E
|
||||
#define SEQ_STATUS 0x8F
|
||||
#define FLASH_CLOCK_CONTROL 0x98
|
||||
#define DMD_PARK 0x2D
|
||||
|
||||
#define SDRAM_BIST_ENABLE 0x46
|
||||
#define DDR_DRIVER_STRENGTH 0x9A
|
||||
#define SDC_ENABLE 0x9D
|
||||
#define SDC_BUFF_SWAP_DISABLE 0xA3
|
||||
#define CURTAIN_CONTROL 0xA6
|
||||
#define DDR_BUS_SWAP_ENABLE 0xA7
|
||||
#define DMD_TRC_ENABLE 0xA8
|
||||
#define DMD_BUS_SWAP_ENABLE 0xA9
|
||||
|
||||
#define ACTGEN_ENABLE 0xAE
|
||||
#define ACTGEN_CONTROL 0xAF
|
||||
#define ACTGEN_HORIZ_BP 0xB0
|
||||
#define ACTGEN_VERT_BP 0xB1
|
||||
|
||||
/* Look Up Table access */
|
||||
#define CMT_SPLASH_LUT_START_ADDR 0xFA
|
||||
#define CMT_SPLASH_LUT_DEST_SELECT 0xFB
|
||||
#define CMT_SPLASH_LUT_DATA 0xFC
|
||||
#define SEQ_RESET_LUT_START_ADDR 0xFD
|
||||
#define SEQ_RESET_LUT_DEST_SELECT 0xFE
|
||||
#define SEQ_RESET_LUT_DATA 0xFF
|
||||
|
||||
/* Input source definitions */
|
||||
#define PARALLEL_RGB 0
|
||||
#define INT_TEST_PATTERN 1
|
||||
#define SPLASH_SCREEN 2
|
||||
#define CPU_INTF 3
|
||||
#define BT656 4
|
||||
|
||||
/* Standard input resolution definitions */
|
||||
#define QWVGA_LANDSCAPE 3 /* (427h*240v) */
|
||||
#define WVGA_864_LANDSCAPE 21 /* (864h*480v) */
|
||||
#define WVGA_DMD_OPTICAL_TEST 35 /* (608h*684v) */
|
||||
|
||||
/* Standard data format definitions */
|
||||
#define RGB565 0
|
||||
#define RGB666 1
|
||||
#define RGB888 2
|
||||
|
||||
/* Test Pattern definitions */
|
||||
#define TPG_CHECKERBOARD 0
|
||||
#define TPG_BLACK 1
|
||||
#define TPG_WHITE 2
|
||||
#define TPG_RED 3
|
||||
#define TPG_BLUE 4
|
||||
#define TPG_GREEN 5
|
||||
#define TPG_VLINES_BLACK 6
|
||||
#define TPG_HLINES_BLACK 7
|
||||
#define TPG_VLINES_ALT 8
|
||||
#define TPG_HLINES_ALT 9
|
||||
#define TPG_DIAG_LINES 10
|
||||
#define TPG_GREYRAMP_VERT 11
|
||||
#define TPG_GREYRAMP_HORIZ 12
|
||||
#define TPG_ANSI_CHECKERBOARD 13
|
||||
|
||||
/* sequence mode definitions */
|
||||
#define SEQ_FREE_RUN 0
|
||||
#define SEQ_LOCK 1
|
||||
|
||||
/* curtain color definitions */
|
||||
#define CURTAIN_BLACK 0
|
||||
#define CURTAIN_RED 1
|
||||
#define CURTAIN_GREEN 2
|
||||
#define CURTAIN_BLUE 3
|
||||
#define CURTAIN_YELLOW 4
|
||||
#define CURTAIN_MAGENTA 5
|
||||
#define CURTAIN_CYAN 6
|
||||
#define CURTAIN_WHITE 7
|
||||
|
||||
/* LUT definitions */
|
||||
#define CMT_LUT_NONE 0
|
||||
#define CMT_LUT_GREEN 1
|
||||
#define CMT_LUT_RED 2
|
||||
#define CMT_LUT_BLUE 3
|
||||
#define CMT_LUT_ALL 4
|
||||
#define SPLASH_LUT 5
|
||||
|
||||
#define SEQ_LUT_NONE 0
|
||||
#define SEQ_DRC_LUT_0 1
|
||||
#define SEQ_DRC_LUT_1 2
|
||||
#define SEQ_DRC_LUT_2 3
|
||||
#define SEQ_DRC_LUT_3 4
|
||||
#define SEQ_SEQ_LUT 5
|
||||
#define SEQ_DRC_LUT_ALL 6
|
||||
#define WPC_PROGRAM_LUT 7
|
||||
|
||||
#define BITSTREAM_START_ADDR 0x00000000
|
||||
#define BITSTREAM_SIZE 0x00040000
|
||||
|
||||
#define WPC_FW_0_START_ADDR 0x00040000
|
||||
#define WPC_FW_0_SIZE 0x00000ce8
|
||||
|
||||
#define SEQUENCE_0_START_ADDR 0x00044000
|
||||
#define SEQUENCE_0_SIZE 0x00001000
|
||||
|
||||
#define SEQUENCE_1_START_ADDR 0x00045000
|
||||
#define SEQUENCE_1_SIZE 0x00000d10
|
||||
|
||||
#define SEQUENCE_2_START_ADDR 0x00046000
|
||||
#define SEQUENCE_2_SIZE 0x00000d10
|
||||
|
||||
#define SEQUENCE_3_START_ADDR 0x00047000
|
||||
#define SEQUENCE_3_SIZE 0x00000d10
|
||||
|
||||
#define SEQUENCE_4_START_ADDR 0x00048000
|
||||
#define SEQUENCE_4_SIZE 0x00000d10
|
||||
|
||||
#define SEQUENCE_5_START_ADDR 0x00049000
|
||||
#define SEQUENCE_5_SIZE 0x00000d10
|
||||
|
||||
#define SEQUENCE_6_START_ADDR 0x0004a000
|
||||
#define SEQUENCE_6_SIZE 0x00000d10
|
||||
|
||||
#define CMT_LUT_0_START_ADDR 0x0004b200
|
||||
#define CMT_LUT_0_SIZE 0x00000600
|
||||
|
||||
#define CMT_LUT_1_START_ADDR 0x0004b800
|
||||
#define CMT_LUT_1_SIZE 0x00000600
|
||||
|
||||
#define CMT_LUT_2_START_ADDR 0x0004be00
|
||||
#define CMT_LUT_2_SIZE 0x00000600
|
||||
|
||||
#define CMT_LUT_3_START_ADDR 0x0004c400
|
||||
#define CMT_LUT_3_SIZE 0x00000600
|
||||
|
||||
#define CMT_LUT_4_START_ADDR 0x0004ca00
|
||||
#define CMT_LUT_4_SIZE 0x00000600
|
||||
|
||||
#define CMT_LUT_5_START_ADDR 0x0004d000
|
||||
#define CMT_LUT_5_SIZE 0x00000600
|
||||
|
||||
#define CMT_LUT_6_START_ADDR 0x0004d600
|
||||
#define CMT_LUT_6_SIZE 0x00000600
|
||||
|
||||
#define DRC_TABLE_0_START_ADDR 0x0004dc00
|
||||
#define DRC_TABLE_0_SIZE 0x00000100
|
||||
|
||||
#define SPLASH_0_START_ADDR 0x0004dd00
|
||||
#define SPLASH_0_SIZE 0x00032280
|
||||
|
||||
#define SEQUENCE_7_START_ADDR 0x00080000
|
||||
#define SEQUENCE_7_SIZE 0x00000d10
|
||||
|
||||
#define SEQUENCE_8_START_ADDR 0x00081800
|
||||
#define SEQUENCE_8_SIZE 0x00000d10
|
||||
|
||||
#define SEQUENCE_9_START_ADDR 0x00083000
|
||||
#define SEQUENCE_9_SIZE 0x00000d10
|
||||
|
||||
#define CMT_LUT_7_START_ADDR 0x0008e000
|
||||
#define CMT_LUT_7_SIZE 0x00000600
|
||||
|
||||
#define CMT_LUT_8_START_ADDR 0x0008e800
|
||||
#define CMT_LUT_8_SIZE 0x00000600
|
||||
|
||||
#define CMT_LUT_9_START_ADDR 0x0008f000
|
||||
#define CMT_LUT_9_SIZE 0x00000600
|
||||
|
||||
#define SPLASH_1_START_ADDR 0x0009a000
|
||||
#define SPLASH_1_SIZE 0x00032280
|
||||
|
||||
#define SPLASH_2_START_ADDR 0x000cd000
|
||||
#define SPLASH_2_SIZE 0x00032280
|
||||
|
||||
#define SPLASH_3_START_ADDR 0x00100000
|
||||
#define SPLASH_3_SIZE 0x00032280
|
||||
|
||||
#define OPT_SPLASH_0_START_ADDR 0x00134000
|
||||
#define OPT_SPLASH_0_SIZE 0x000cb100
|
||||
|
||||
#endif
|
||||
|
|
@ -35,26 +35,12 @@
|
|||
|
||||
#include <video/omapdss.h>
|
||||
#include <video/omap-panel-nokia-dsi.h>
|
||||
#include <video/mipi_display.h>
|
||||
|
||||
/* DSI Virtual channel. Hardcoded for now. */
|
||||
#define TCH 0
|
||||
|
||||
#define DCS_READ_NUM_ERRORS 0x05
|
||||
#define DCS_READ_POWER_MODE 0x0a
|
||||
#define DCS_READ_MADCTL 0x0b
|
||||
#define DCS_READ_PIXEL_FORMAT 0x0c
|
||||
#define DCS_RDDSDR 0x0f
|
||||
#define DCS_SLEEP_IN 0x10
|
||||
#define DCS_SLEEP_OUT 0x11
|
||||
#define DCS_DISPLAY_OFF 0x28
|
||||
#define DCS_DISPLAY_ON 0x29
|
||||
#define DCS_COLUMN_ADDR 0x2a
|
||||
#define DCS_PAGE_ADDR 0x2b
|
||||
#define DCS_MEMORY_WRITE 0x2c
|
||||
#define DCS_TEAR_OFF 0x34
|
||||
#define DCS_TEAR_ON 0x35
|
||||
#define DCS_MEM_ACC_CTRL 0x36
|
||||
#define DCS_PIXEL_FORMAT 0x3a
|
||||
#define DCS_BRIGHTNESS 0x51
|
||||
#define DCS_CTRL_DISPLAY 0x53
|
||||
#define DCS_WRITE_CABC 0x55
|
||||
|
|
@ -222,8 +208,6 @@ struct taal_data {
|
|||
|
||||
struct delayed_work te_timeout_work;
|
||||
|
||||
bool use_dsi_bl;
|
||||
|
||||
bool cabc_broken;
|
||||
unsigned cabc_mode;
|
||||
|
||||
|
|
@ -302,7 +286,7 @@ static int taal_sleep_in(struct taal_data *td)
|
|||
|
||||
hw_guard_wait(td);
|
||||
|
||||
cmd = DCS_SLEEP_IN;
|
||||
cmd = MIPI_DCS_ENTER_SLEEP_MODE;
|
||||
r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, &cmd, 1);
|
||||
if (r)
|
||||
return r;
|
||||
|
|
@ -321,7 +305,7 @@ static int taal_sleep_out(struct taal_data *td)
|
|||
|
||||
hw_guard_wait(td);
|
||||
|
||||
r = taal_dcs_write_0(td, DCS_SLEEP_OUT);
|
||||
r = taal_dcs_write_0(td, MIPI_DCS_EXIT_SLEEP_MODE);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
|
@ -356,7 +340,7 @@ static int taal_set_addr_mode(struct taal_data *td, u8 rotate, bool mirror)
|
|||
u8 mode;
|
||||
int b5, b6, b7;
|
||||
|
||||
r = taal_dcs_read_1(td, DCS_READ_MADCTL, &mode);
|
||||
r = taal_dcs_read_1(td, MIPI_DCS_GET_ADDRESS_MODE, &mode);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
|
@ -390,7 +374,7 @@ static int taal_set_addr_mode(struct taal_data *td, u8 rotate, bool mirror)
|
|||
mode &= ~((1<<7) | (1<<6) | (1<<5));
|
||||
mode |= (b7 << 7) | (b6 << 6) | (b5 << 5);
|
||||
|
||||
return taal_dcs_write_1(td, DCS_MEM_ACC_CTRL, mode);
|
||||
return taal_dcs_write_1(td, MIPI_DCS_SET_ADDRESS_MODE, mode);
|
||||
}
|
||||
|
||||
static int taal_set_update_window(struct taal_data *td,
|
||||
|
|
@ -403,7 +387,7 @@ static int taal_set_update_window(struct taal_data *td,
|
|||
u16 y2 = y + h - 1;
|
||||
|
||||
u8 buf[5];
|
||||
buf[0] = DCS_COLUMN_ADDR;
|
||||
buf[0] = MIPI_DCS_SET_COLUMN_ADDRESS;
|
||||
buf[1] = (x1 >> 8) & 0xff;
|
||||
buf[2] = (x1 >> 0) & 0xff;
|
||||
buf[3] = (x2 >> 8) & 0xff;
|
||||
|
|
@ -413,7 +397,7 @@ static int taal_set_update_window(struct taal_data *td,
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
buf[0] = DCS_PAGE_ADDR;
|
||||
buf[0] = MIPI_DCS_SET_PAGE_ADDRESS;
|
||||
buf[1] = (y1 >> 8) & 0xff;
|
||||
buf[2] = (y1 >> 0) & 0xff;
|
||||
buf[3] = (y2 >> 8) & 0xff;
|
||||
|
|
@ -555,7 +539,6 @@ static int taal_bl_update_status(struct backlight_device *dev)
|
|||
{
|
||||
struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev);
|
||||
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
|
||||
struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
|
||||
int r;
|
||||
int level;
|
||||
|
||||
|
|
@ -569,23 +552,16 @@ static int taal_bl_update_status(struct backlight_device *dev)
|
|||
|
||||
mutex_lock(&td->lock);
|
||||
|
||||
if (td->use_dsi_bl) {
|
||||
if (td->enabled) {
|
||||
dsi_bus_lock(dssdev);
|
||||
if (td->enabled) {
|
||||
dsi_bus_lock(dssdev);
|
||||
|
||||
r = taal_wake_up(dssdev);
|
||||
if (!r)
|
||||
r = taal_dcs_write_1(td, DCS_BRIGHTNESS, level);
|
||||
r = taal_wake_up(dssdev);
|
||||
if (!r)
|
||||
r = taal_dcs_write_1(td, DCS_BRIGHTNESS, level);
|
||||
|
||||
dsi_bus_unlock(dssdev);
|
||||
} else {
|
||||
r = 0;
|
||||
}
|
||||
dsi_bus_unlock(dssdev);
|
||||
} else {
|
||||
if (!panel_data->set_backlight)
|
||||
r = -EINVAL;
|
||||
else
|
||||
r = panel_data->set_backlight(dssdev, level);
|
||||
r = 0;
|
||||
}
|
||||
|
||||
mutex_unlock(&td->lock);
|
||||
|
|
@ -964,7 +940,7 @@ static int taal_probe(struct omap_dss_device *dssdev)
|
|||
{
|
||||
struct backlight_properties props;
|
||||
struct taal_data *td;
|
||||
struct backlight_device *bldev;
|
||||
struct backlight_device *bldev = NULL;
|
||||
struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
|
||||
struct panel_config *panel_config = NULL;
|
||||
int r, i;
|
||||
|
|
@ -990,7 +966,7 @@ static int taal_probe(struct omap_dss_device *dssdev)
|
|||
|
||||
dssdev->panel.config = OMAP_DSS_LCD_TFT;
|
||||
dssdev->panel.timings = panel_config->timings;
|
||||
dssdev->ctrl.pixel_size = 24;
|
||||
dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888;
|
||||
|
||||
td = kzalloc(sizeof(*td), GFP_KERNEL);
|
||||
if (!td) {
|
||||
|
|
@ -1025,35 +1001,26 @@ static int taal_probe(struct omap_dss_device *dssdev)
|
|||
|
||||
taal_hw_reset(dssdev);
|
||||
|
||||
/* if no platform set_backlight() defined, presume DSI backlight
|
||||
* control */
|
||||
memset(&props, 0, sizeof(struct backlight_properties));
|
||||
if (!panel_data->set_backlight)
|
||||
td->use_dsi_bl = true;
|
||||
|
||||
if (td->use_dsi_bl)
|
||||
if (panel_data->use_dsi_backlight) {
|
||||
memset(&props, 0, sizeof(struct backlight_properties));
|
||||
props.max_brightness = 255;
|
||||
else
|
||||
props.max_brightness = 127;
|
||||
|
||||
props.type = BACKLIGHT_RAW;
|
||||
bldev = backlight_device_register(dev_name(&dssdev->dev), &dssdev->dev,
|
||||
dssdev, &taal_bl_ops, &props);
|
||||
if (IS_ERR(bldev)) {
|
||||
r = PTR_ERR(bldev);
|
||||
goto err_bl;
|
||||
}
|
||||
props.type = BACKLIGHT_RAW;
|
||||
bldev = backlight_device_register(dev_name(&dssdev->dev),
|
||||
&dssdev->dev, dssdev, &taal_bl_ops, &props);
|
||||
if (IS_ERR(bldev)) {
|
||||
r = PTR_ERR(bldev);
|
||||
goto err_bl;
|
||||
}
|
||||
|
||||
td->bldev = bldev;
|
||||
td->bldev = bldev;
|
||||
|
||||
bldev->props.fb_blank = FB_BLANK_UNBLANK;
|
||||
bldev->props.power = FB_BLANK_UNBLANK;
|
||||
if (td->use_dsi_bl)
|
||||
bldev->props.fb_blank = FB_BLANK_UNBLANK;
|
||||
bldev->props.power = FB_BLANK_UNBLANK;
|
||||
bldev->props.brightness = 255;
|
||||
else
|
||||
bldev->props.brightness = 127;
|
||||
|
||||
taal_bl_update_status(bldev);
|
||||
taal_bl_update_status(bldev);
|
||||
}
|
||||
|
||||
if (panel_data->use_ext_te) {
|
||||
int gpio = panel_data->ext_te_gpio;
|
||||
|
|
@ -1067,7 +1034,7 @@ static int taal_probe(struct omap_dss_device *dssdev)
|
|||
gpio_direction_input(gpio);
|
||||
|
||||
r = request_irq(gpio_to_irq(gpio), taal_te_isr,
|
||||
IRQF_DISABLED | IRQF_TRIGGER_RISING,
|
||||
IRQF_TRIGGER_RISING,
|
||||
"taal vsync", dssdev);
|
||||
|
||||
if (r) {
|
||||
|
|
@ -1111,7 +1078,8 @@ err_irq:
|
|||
if (panel_data->use_ext_te)
|
||||
gpio_free(panel_data->ext_te_gpio);
|
||||
err_gpio:
|
||||
backlight_device_unregister(bldev);
|
||||
if (bldev != NULL)
|
||||
backlight_device_unregister(bldev);
|
||||
err_bl:
|
||||
destroy_workqueue(td->workqueue);
|
||||
err_wq:
|
||||
|
|
@ -1140,9 +1108,11 @@ static void __exit taal_remove(struct omap_dss_device *dssdev)
|
|||
}
|
||||
|
||||
bldev = td->bldev;
|
||||
bldev->props.power = FB_BLANK_POWERDOWN;
|
||||
taal_bl_update_status(bldev);
|
||||
backlight_device_unregister(bldev);
|
||||
if (bldev != NULL) {
|
||||
bldev->props.power = FB_BLANK_POWERDOWN;
|
||||
taal_bl_update_status(bldev);
|
||||
backlight_device_unregister(bldev);
|
||||
}
|
||||
|
||||
taal_cancel_ulps_work(dssdev);
|
||||
taal_cancel_esd_work(dssdev);
|
||||
|
|
@ -1195,7 +1165,8 @@ static int taal_power_on(struct omap_dss_device *dssdev)
|
|||
if (r)
|
||||
goto err;
|
||||
|
||||
r = taal_dcs_write_1(td, DCS_PIXEL_FORMAT, 0x7); /* 24bit/pixel */
|
||||
r = taal_dcs_write_1(td, MIPI_DCS_SET_PIXEL_FORMAT,
|
||||
MIPI_DCS_PIXEL_FMT_24BIT);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
|
|
@ -1209,7 +1180,7 @@ static int taal_power_on(struct omap_dss_device *dssdev)
|
|||
goto err;
|
||||
}
|
||||
|
||||
r = taal_dcs_write_0(td, DCS_DISPLAY_ON);
|
||||
r = taal_dcs_write_0(td, MIPI_DCS_SET_DISPLAY_ON);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
|
|
@ -1246,7 +1217,7 @@ static void taal_power_off(struct omap_dss_device *dssdev)
|
|||
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
|
||||
int r;
|
||||
|
||||
r = taal_dcs_write_0(td, DCS_DISPLAY_OFF);
|
||||
r = taal_dcs_write_0(td, MIPI_DCS_SET_DISPLAY_OFF);
|
||||
if (!r)
|
||||
r = taal_sleep_in(td);
|
||||
|
||||
|
|
@ -1529,9 +1500,9 @@ static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
|
|||
int r;
|
||||
|
||||
if (enable)
|
||||
r = taal_dcs_write_1(td, DCS_TEAR_ON, 0);
|
||||
r = taal_dcs_write_1(td, MIPI_DCS_SET_TEAR_ON, 0);
|
||||
else
|
||||
r = taal_dcs_write_0(td, DCS_TEAR_OFF);
|
||||
r = taal_dcs_write_0(td, MIPI_DCS_SET_TEAR_OFF);
|
||||
|
||||
if (!panel_data->use_ext_te)
|
||||
omapdss_dsi_enable_te(dssdev, enable);
|
||||
|
|
@ -1851,7 +1822,7 @@ static void taal_esd_work(struct work_struct *work)
|
|||
goto err;
|
||||
}
|
||||
|
||||
r = taal_dcs_read_1(td, DCS_RDDSDR, &state1);
|
||||
r = taal_dcs_read_1(td, MIPI_DCS_GET_DIAGNOSTIC_RESULT, &state1);
|
||||
if (r) {
|
||||
dev_err(&dssdev->dev, "failed to read Taal status\n");
|
||||
goto err;
|
||||
|
|
@ -1864,7 +1835,7 @@ static void taal_esd_work(struct work_struct *work)
|
|||
goto err;
|
||||
}
|
||||
|
||||
r = taal_dcs_read_1(td, DCS_RDDSDR, &state2);
|
||||
r = taal_dcs_read_1(td, MIPI_DCS_GET_DIAGNOSTIC_RESULT, &state2);
|
||||
if (r) {
|
||||
dev_err(&dssdev->dev, "failed to read Taal status\n");
|
||||
goto err;
|
||||
|
|
@ -1880,7 +1851,7 @@ static void taal_esd_work(struct work_struct *work)
|
|||
/* Self-diagnostics result is also shown on TE GPIO line. We need
|
||||
* to re-enable TE after self diagnostics */
|
||||
if (td->te_enabled && panel_data->use_ext_te) {
|
||||
r = taal_dcs_write_1(td, DCS_TEAR_ON, 0);
|
||||
r = taal_dcs_write_1(td, MIPI_DCS_SET_TEAR_ON, 0);
|
||||
if (r)
|
||||
goto err;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
menuconfig OMAP2_DSS
|
||||
tristate "OMAP2+ Display Subsystem support (EXPERIMENTAL)"
|
||||
tristate "OMAP2+ Display Subsystem support"
|
||||
depends on ARCH_OMAP2PLUS
|
||||
help
|
||||
OMAP2+ Display Subsystem support.
|
||||
|
|
|
|||
|
|
@ -6,4 +6,4 @@ omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
|
|||
omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
|
||||
omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
|
||||
omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \
|
||||
hdmi_omap4_panel.o
|
||||
hdmi_panel.o ti_hdmi_4xxx_ip.o
|
||||
|
|
|
|||
|
|
@ -144,6 +144,10 @@ static int dss_initialize_debugfs(void)
|
|||
#ifdef CONFIG_OMAP2_DSS_VENC
|
||||
debugfs_create_file("venc", S_IRUGO, dss_debugfs_dir,
|
||||
&venc_dump_regs, &dss_debug_fops);
|
||||
#endif
|
||||
#ifdef CONFIG_OMAP4_DSS_HDMI
|
||||
debugfs_create_file("hdmi", S_IRUGO, dss_debugfs_dir,
|
||||
&hdmi_dump_regs, &dss_debug_fops);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -291,6 +291,8 @@ static inline u16 DISPC_OVL_BASE(enum omap_plane plane)
|
|||
return 0x00BC;
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x014C;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x0300;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
|
@ -304,6 +306,8 @@ static inline u16 DISPC_BA0_OFFSET(enum omap_plane plane)
|
|||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0000;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x0008;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
|
@ -316,6 +320,8 @@ static inline u16 DISPC_BA1_OFFSET(enum omap_plane plane)
|
|||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0004;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x000C;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
|
@ -330,6 +336,8 @@ static inline u16 DISPC_BA0_UV_OFFSET(enum omap_plane plane)
|
|||
return 0x0544;
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x04BC;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x0310;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
|
@ -344,6 +352,8 @@ static inline u16 DISPC_BA1_UV_OFFSET(enum omap_plane plane)
|
|||
return 0x0548;
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x04C0;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x0314;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
|
@ -356,6 +366,8 @@ static inline u16 DISPC_POS_OFFSET(enum omap_plane plane)
|
|||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0008;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x009C;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
|
@ -368,6 +380,8 @@ static inline u16 DISPC_SIZE_OFFSET(enum omap_plane plane)
|
|||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x000C;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x00A8;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
|
@ -381,6 +395,8 @@ static inline u16 DISPC_ATTR_OFFSET(enum omap_plane plane)
|
|||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0010;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x0070;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
|
@ -395,6 +411,8 @@ static inline u16 DISPC_ATTR2_OFFSET(enum omap_plane plane)
|
|||
return 0x0568;
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x04DC;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x032C;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
|
@ -408,6 +426,8 @@ static inline u16 DISPC_FIFO_THRESH_OFFSET(enum omap_plane plane)
|
|||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0014;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x008C;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
|
@ -421,6 +441,8 @@ static inline u16 DISPC_FIFO_SIZE_STATUS_OFFSET(enum omap_plane plane)
|
|||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0018;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x0088;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
|
@ -434,6 +456,8 @@ static inline u16 DISPC_ROW_INC_OFFSET(enum omap_plane plane)
|
|||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x001C;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x00A4;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
|
@ -447,6 +471,8 @@ static inline u16 DISPC_PIX_INC_OFFSET(enum omap_plane plane)
|
|||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0020;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x0098;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
|
@ -459,6 +485,7 @@ static inline u16 DISPC_WINDOW_SKIP_OFFSET(enum omap_plane plane)
|
|||
return 0x0034;
|
||||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
case OMAP_DSS_VIDEO3:
|
||||
BUG();
|
||||
default:
|
||||
BUG();
|
||||
|
|
@ -472,6 +499,7 @@ static inline u16 DISPC_TABLE_BA_OFFSET(enum omap_plane plane)
|
|||
return 0x0038;
|
||||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
case OMAP_DSS_VIDEO3:
|
||||
BUG();
|
||||
default:
|
||||
BUG();
|
||||
|
|
@ -486,6 +514,8 @@ static inline u16 DISPC_FIR_OFFSET(enum omap_plane plane)
|
|||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0024;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x0090;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
|
@ -500,6 +530,8 @@ static inline u16 DISPC_FIR2_OFFSET(enum omap_plane plane)
|
|||
return 0x0580;
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x055C;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x0424;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
|
@ -513,6 +545,8 @@ static inline u16 DISPC_PIC_SIZE_OFFSET(enum omap_plane plane)
|
|||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0028;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x0094;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
|
@ -527,6 +561,8 @@ static inline u16 DISPC_ACCU0_OFFSET(enum omap_plane plane)
|
|||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x002C;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x0000;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
|
@ -541,6 +577,8 @@ static inline u16 DISPC_ACCU2_0_OFFSET(enum omap_plane plane)
|
|||
return 0x0584;
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0560;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x0428;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
|
@ -554,6 +592,8 @@ static inline u16 DISPC_ACCU1_OFFSET(enum omap_plane plane)
|
|||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0030;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x0004;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
|
@ -568,6 +608,8 @@ static inline u16 DISPC_ACCU2_1_OFFSET(enum omap_plane plane)
|
|||
return 0x0588;
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0564;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x042C;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
|
@ -582,6 +624,8 @@ static inline u16 DISPC_FIR_COEF_H_OFFSET(enum omap_plane plane, u16 i)
|
|||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0034 + i * 0x8;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x0010 + i * 0x8;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
|
@ -597,6 +641,8 @@ static inline u16 DISPC_FIR_COEF_H2_OFFSET(enum omap_plane plane, u16 i)
|
|||
return 0x058C + i * 0x8;
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0568 + i * 0x8;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x0430 + i * 0x8;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
|
@ -611,6 +657,8 @@ static inline u16 DISPC_FIR_COEF_HV_OFFSET(enum omap_plane plane, u16 i)
|
|||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0038 + i * 0x8;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x0014 + i * 0x8;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
|
@ -626,6 +674,8 @@ static inline u16 DISPC_FIR_COEF_HV2_OFFSET(enum omap_plane plane, u16 i)
|
|||
return 0x0590 + i * 8;
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x056C + i * 0x8;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x0434 + i * 0x8;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
|
@ -639,6 +689,7 @@ static inline u16 DISPC_CONV_COEF_OFFSET(enum omap_plane plane, u16 i)
|
|||
BUG();
|
||||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x0074 + i * 0x4;
|
||||
default:
|
||||
BUG();
|
||||
|
|
@ -655,6 +706,8 @@ static inline u16 DISPC_FIR_COEF_V_OFFSET(enum omap_plane plane, u16 i)
|
|||
return 0x0124 + i * 0x4;
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x00B4 + i * 0x4;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x0050 + i * 0x4;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
|
@ -670,6 +723,8 @@ static inline u16 DISPC_FIR_COEF_V2_OFFSET(enum omap_plane plane, u16 i)
|
|||
return 0x05CC + i * 0x4;
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x05A8 + i * 0x4;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x0470 + i * 0x4;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
|
@ -684,6 +739,8 @@ static inline u16 DISPC_PRELOAD_OFFSET(enum omap_plane plane)
|
|||
return 0x0174;
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x00E8;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x00A0;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,14 +45,13 @@ static ssize_t display_enabled_store(struct device *dev,
|
|||
const char *buf, size_t size)
|
||||
{
|
||||
struct omap_dss_device *dssdev = to_dss_device(dev);
|
||||
int r, enabled;
|
||||
int r;
|
||||
bool enabled;
|
||||
|
||||
r = kstrtoint(buf, 0, &enabled);
|
||||
r = strtobool(buf, &enabled);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
enabled = !!enabled;
|
||||
|
||||
if (enabled != (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)) {
|
||||
if (enabled) {
|
||||
r = dssdev->driver->enable(dssdev);
|
||||
|
|
@ -79,17 +78,16 @@ static ssize_t display_tear_store(struct device *dev,
|
|||
struct device_attribute *attr, const char *buf, size_t size)
|
||||
{
|
||||
struct omap_dss_device *dssdev = to_dss_device(dev);
|
||||
int te, r;
|
||||
int r;
|
||||
bool te;
|
||||
|
||||
if (!dssdev->driver->enable_te || !dssdev->driver->get_te)
|
||||
return -ENOENT;
|
||||
|
||||
r = kstrtoint(buf, 0, &te);
|
||||
r = strtobool(buf, &te);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
te = !!te;
|
||||
|
||||
r = dssdev->driver->enable_te(dssdev, te);
|
||||
if (r)
|
||||
return r;
|
||||
|
|
@ -195,17 +193,16 @@ static ssize_t display_mirror_store(struct device *dev,
|
|||
struct device_attribute *attr, const char *buf, size_t size)
|
||||
{
|
||||
struct omap_dss_device *dssdev = to_dss_device(dev);
|
||||
int mirror, r;
|
||||
int r;
|
||||
bool mirror;
|
||||
|
||||
if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror)
|
||||
return -ENOENT;
|
||||
|
||||
r = kstrtoint(buf, 0, &mirror);
|
||||
r = strtobool(buf, &mirror);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
mirror = !!mirror;
|
||||
|
||||
r = dssdev->driver->set_mirror(dssdev, mirror);
|
||||
if (r)
|
||||
return r;
|
||||
|
|
@ -302,11 +299,15 @@ int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev)
|
|||
return 16;
|
||||
|
||||
case OMAP_DISPLAY_TYPE_DBI:
|
||||
case OMAP_DISPLAY_TYPE_DSI:
|
||||
if (dssdev->ctrl.pixel_size == 24)
|
||||
return 24;
|
||||
else
|
||||
return 16;
|
||||
case OMAP_DISPLAY_TYPE_DSI:
|
||||
if (dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt) > 16)
|
||||
return 24;
|
||||
else
|
||||
return 16;
|
||||
case OMAP_DISPLAY_TYPE_VENC:
|
||||
case OMAP_DISPLAY_TYPE_SDI:
|
||||
case OMAP_DISPLAY_TYPE_HDMI:
|
||||
|
|
@ -342,9 +343,11 @@ bool dss_use_replication(struct omap_dss_device *dssdev,
|
|||
bpp = 24;
|
||||
break;
|
||||
case OMAP_DISPLAY_TYPE_DBI:
|
||||
case OMAP_DISPLAY_TYPE_DSI:
|
||||
bpp = dssdev->ctrl.pixel_size;
|
||||
break;
|
||||
case OMAP_DISPLAY_TYPE_DSI:
|
||||
bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,9 +82,11 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, bool is_tft,
|
|||
|
||||
dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
|
||||
|
||||
r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo);
|
||||
if (r)
|
||||
r = dispc_mgr_set_clock_div(dssdev->manager->id, &dispc_cinfo);
|
||||
if (r) {
|
||||
dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
|
||||
return r;
|
||||
}
|
||||
|
||||
*fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
|
||||
*lck_div = dispc_cinfo.lck_div;
|
||||
|
|
@ -109,7 +111,7 @@ static int dpi_set_dispc_clk(struct omap_dss_device *dssdev, bool is_tft,
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo);
|
||||
r = dispc_mgr_set_clock_div(dssdev->manager->id, &dispc_cinfo);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
|
@ -129,7 +131,7 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
|
|||
bool is_tft;
|
||||
int r = 0;
|
||||
|
||||
dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config,
|
||||
dispc_mgr_set_pol_freq(dssdev->manager->id, dssdev->panel.config,
|
||||
dssdev->panel.acbi, dssdev->panel.acb);
|
||||
|
||||
is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0;
|
||||
|
|
@ -153,7 +155,7 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
|
|||
t->pixel_clock = pck;
|
||||
}
|
||||
|
||||
dispc_set_lcd_timings(dssdev->manager->id, t);
|
||||
dispc_mgr_set_lcd_timings(dssdev->manager->id, t);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -164,11 +166,12 @@ static void dpi_basic_init(struct omap_dss_device *dssdev)
|
|||
|
||||
is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0;
|
||||
|
||||
dispc_set_parallel_interface_mode(dssdev->manager->id,
|
||||
OMAP_DSS_PARALLELMODE_BYPASS);
|
||||
dispc_set_lcd_display_type(dssdev->manager->id, is_tft ?
|
||||
dispc_mgr_set_io_pad_mode(DSS_IO_PAD_MODE_BYPASS);
|
||||
dispc_mgr_enable_stallmode(dssdev->manager->id, false);
|
||||
|
||||
dispc_mgr_set_lcd_display_type(dssdev->manager->id, is_tft ?
|
||||
OMAP_DSS_LCD_DISPLAY_TFT : OMAP_DSS_LCD_DISPLAY_STN);
|
||||
dispc_set_tft_data_lines(dssdev->manager->id,
|
||||
dispc_mgr_set_tft_data_lines(dssdev->manager->id,
|
||||
dssdev->phy.dpi.data_lines);
|
||||
}
|
||||
|
||||
|
|
@ -176,6 +179,11 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
|
|||
{
|
||||
int r;
|
||||
|
||||
if (dssdev->manager == NULL) {
|
||||
DSSERR("failed to enable display: no manager\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
r = omap_dss_start_device(dssdev);
|
||||
if (r) {
|
||||
DSSERR("failed to start device\n");
|
||||
|
|
@ -277,7 +285,7 @@ void dpi_set_timings(struct omap_dss_device *dssdev,
|
|||
}
|
||||
|
||||
dpi_set_mode(dssdev);
|
||||
dispc_go(dssdev->manager->id);
|
||||
dispc_mgr_go(dssdev->manager->id);
|
||||
|
||||
dispc_runtime_put();
|
||||
dss_runtime_put();
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -639,6 +639,17 @@ void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select hdmi)
|
|||
REG_FLD_MOD(DSS_CONTROL, hdmi, 15, 15); /* VENC_HDMI_SWITCH */
|
||||
}
|
||||
|
||||
enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void)
|
||||
{
|
||||
enum omap_display_type displays;
|
||||
|
||||
displays = dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_DIGIT);
|
||||
if ((displays & OMAP_DISPLAY_TYPE_HDMI) == 0)
|
||||
return DSS_VENC_TV_CLK;
|
||||
|
||||
return REG_GET(DSS_CONTROL, 15, 15);
|
||||
}
|
||||
|
||||
static int dss_get_clocks(void)
|
||||
{
|
||||
struct clk *clk;
|
||||
|
|
@ -691,11 +702,6 @@ static void dss_put_clocks(void)
|
|||
clk_put(dss.dss_clk);
|
||||
}
|
||||
|
||||
struct clk *dss_get_ick(void)
|
||||
{
|
||||
return clk_get(&dss.pdev->dev, "ick");
|
||||
}
|
||||
|
||||
int dss_runtime_get(void)
|
||||
{
|
||||
int r;
|
||||
|
|
@ -824,13 +830,11 @@ static int omap_dsshw_remove(struct platform_device *pdev)
|
|||
static int dss_runtime_suspend(struct device *dev)
|
||||
{
|
||||
dss_save_context();
|
||||
clk_disable(dss.dss_clk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dss_runtime_resume(struct device *dev)
|
||||
{
|
||||
clk_enable(dss.dss_clk);
|
||||
dss_restore_context();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,10 +97,10 @@ extern unsigned int dss_debug;
|
|||
#define FLD_MOD(orig, val, start, end) \
|
||||
(((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end))
|
||||
|
||||
enum omap_parallel_interface_mode {
|
||||
OMAP_DSS_PARALLELMODE_BYPASS, /* MIPI DPI */
|
||||
OMAP_DSS_PARALLELMODE_RFBI, /* MIPI DBI */
|
||||
OMAP_DSS_PARALLELMODE_DSI,
|
||||
enum dss_io_pad_mode {
|
||||
DSS_IO_PAD_MODE_RESET,
|
||||
DSS_IO_PAD_MODE_RFBI,
|
||||
DSS_IO_PAD_MODE_BYPASS,
|
||||
};
|
||||
|
||||
enum dss_hdmi_venc_clk_source_select {
|
||||
|
|
@ -108,6 +108,11 @@ enum dss_hdmi_venc_clk_source_select {
|
|||
DSS_HDMI_M_PCLK = 1,
|
||||
};
|
||||
|
||||
enum dss_dsi_content_type {
|
||||
DSS_DSI_CONTENT_DCS,
|
||||
DSS_DSI_CONTENT_GENERIC,
|
||||
};
|
||||
|
||||
struct dss_clock_info {
|
||||
/* rates that we get with dividers below */
|
||||
unsigned long fck;
|
||||
|
|
@ -150,16 +155,6 @@ struct dsi_clock_info {
|
|||
bool use_sys_clk;
|
||||
};
|
||||
|
||||
/* HDMI PLL structure */
|
||||
struct hdmi_pll_info {
|
||||
u16 regn;
|
||||
u16 regm;
|
||||
u32 regmf;
|
||||
u16 regm2;
|
||||
u16 regsd;
|
||||
u16 dcofreq;
|
||||
};
|
||||
|
||||
struct seq_file;
|
||||
struct platform_device;
|
||||
|
||||
|
|
@ -209,9 +204,8 @@ void dss_uninit_platform_driver(void);
|
|||
int dss_runtime_get(void);
|
||||
void dss_runtime_put(void);
|
||||
|
||||
struct clk *dss_get_ick(void);
|
||||
|
||||
void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
|
||||
enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void);
|
||||
const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src);
|
||||
void dss_dump_clocks(struct seq_file *s);
|
||||
|
||||
|
|
@ -279,6 +273,8 @@ void dsi_create_debugfs_files_reg(struct dentry *debugfs_dir,
|
|||
|
||||
int dsi_init_display(struct omap_dss_device *display);
|
||||
void dsi_irq_handler(void);
|
||||
u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt);
|
||||
|
||||
unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev);
|
||||
int dsi_pll_set_clock_div(struct platform_device *dsidev,
|
||||
struct dsi_clock_info *cinfo);
|
||||
|
|
@ -309,6 +305,11 @@ static inline int dsi_runtime_get(struct platform_device *dsidev)
|
|||
static inline void dsi_runtime_put(struct platform_device *dsidev)
|
||||
{
|
||||
}
|
||||
static inline u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt)
|
||||
{
|
||||
WARN("%s: DSI not compiled in, returning pixel_size as 0\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
static inline unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev)
|
||||
{
|
||||
WARN("%s: DSI not compiled in, returning rate as 0\n", __func__);
|
||||
|
|
@ -385,90 +386,71 @@ void dispc_disable_sidle(void);
|
|||
void dispc_lcd_enable_signal_polarity(bool act_high);
|
||||
void dispc_lcd_enable_signal(bool enable);
|
||||
void dispc_pck_free_enable(bool enable);
|
||||
void dispc_enable_fifohandcheck(enum omap_channel channel, bool enable);
|
||||
|
||||
void dispc_set_lcd_size(enum omap_channel channel, u16 width, u16 height);
|
||||
void dispc_set_digit_size(u16 width, u16 height);
|
||||
u32 dispc_get_plane_fifo_size(enum omap_plane plane);
|
||||
void dispc_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high);
|
||||
void dispc_enable_fifomerge(bool enable);
|
||||
u32 dispc_get_burst_size(enum omap_plane plane);
|
||||
void dispc_enable_cpr(enum omap_channel channel, bool enable);
|
||||
void dispc_set_cpr_coef(enum omap_channel channel,
|
||||
struct omap_dss_cpr_coefs *coefs);
|
||||
|
||||
void dispc_set_plane_ba0(enum omap_plane plane, u32 paddr);
|
||||
void dispc_set_plane_ba1(enum omap_plane plane, u32 paddr);
|
||||
void dispc_set_plane_pos(enum omap_plane plane, u16 x, u16 y);
|
||||
void dispc_set_plane_size(enum omap_plane plane, u16 width, u16 height);
|
||||
void dispc_set_channel_out(enum omap_plane plane,
|
||||
enum omap_channel channel_out);
|
||||
|
||||
void dispc_enable_gamma_table(bool enable);
|
||||
int dispc_setup_plane(enum omap_plane plane,
|
||||
u32 paddr, u16 screen_width,
|
||||
u16 pos_x, u16 pos_y,
|
||||
u16 width, u16 height,
|
||||
u16 out_width, u16 out_height,
|
||||
enum omap_color_mode color_mode,
|
||||
bool ilace,
|
||||
enum omap_dss_rotation_type rotation_type,
|
||||
u8 rotation, bool mirror,
|
||||
u8 global_alpha, u8 pre_mult_alpha,
|
||||
enum omap_channel channel,
|
||||
u32 puv_addr);
|
||||
|
||||
bool dispc_go_busy(enum omap_channel channel);
|
||||
void dispc_go(enum omap_channel channel);
|
||||
void dispc_enable_channel(enum omap_channel channel, bool enable);
|
||||
bool dispc_is_channel_enabled(enum omap_channel channel);
|
||||
int dispc_enable_plane(enum omap_plane plane, bool enable);
|
||||
void dispc_enable_replication(enum omap_plane plane, bool enable);
|
||||
|
||||
void dispc_set_parallel_interface_mode(enum omap_channel channel,
|
||||
enum omap_parallel_interface_mode mode);
|
||||
void dispc_set_tft_data_lines(enum omap_channel channel, u8 data_lines);
|
||||
void dispc_set_lcd_display_type(enum omap_channel channel,
|
||||
enum omap_lcd_display_type type);
|
||||
void dispc_set_loadmode(enum omap_dss_load_mode mode);
|
||||
|
||||
void dispc_set_default_color(enum omap_channel channel, u32 color);
|
||||
u32 dispc_get_default_color(enum omap_channel channel);
|
||||
void dispc_set_trans_key(enum omap_channel ch,
|
||||
enum omap_dss_trans_key_type type,
|
||||
u32 trans_key);
|
||||
void dispc_get_trans_key(enum omap_channel ch,
|
||||
enum omap_dss_trans_key_type *type,
|
||||
u32 *trans_key);
|
||||
void dispc_enable_trans_key(enum omap_channel ch, bool enable);
|
||||
void dispc_enable_alpha_blending(enum omap_channel ch, bool enable);
|
||||
bool dispc_trans_key_enabled(enum omap_channel ch);
|
||||
bool dispc_alpha_blending_enabled(enum omap_channel ch);
|
||||
|
||||
bool dispc_lcd_timings_ok(struct omap_video_timings *timings);
|
||||
void dispc_set_lcd_timings(enum omap_channel channel,
|
||||
struct omap_video_timings *timings);
|
||||
unsigned long dispc_fclk_rate(void);
|
||||
unsigned long dispc_lclk_rate(enum omap_channel channel);
|
||||
unsigned long dispc_pclk_rate(enum omap_channel channel);
|
||||
void dispc_set_pol_freq(enum omap_channel channel,
|
||||
enum omap_panel_config config, u8 acbi, u8 acb);
|
||||
void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck,
|
||||
struct dispc_clock_info *cinfo);
|
||||
int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
|
||||
struct dispc_clock_info *cinfo);
|
||||
int dispc_set_clock_div(enum omap_channel channel,
|
||||
struct dispc_clock_info *cinfo);
|
||||
int dispc_get_clock_div(enum omap_channel channel,
|
||||
struct dispc_clock_info *cinfo);
|
||||
|
||||
|
||||
u32 dispc_ovl_get_fifo_size(enum omap_plane plane);
|
||||
u32 dispc_ovl_get_burst_size(enum omap_plane plane);
|
||||
int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
|
||||
bool ilace, enum omap_channel channel, bool replication,
|
||||
u32 fifo_low, u32 fifo_high);
|
||||
int dispc_ovl_enable(enum omap_plane plane, bool enable);
|
||||
|
||||
|
||||
void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable);
|
||||
void dispc_mgr_set_lcd_size(enum omap_channel channel, u16 width, u16 height);
|
||||
void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable);
|
||||
void dispc_mgr_set_cpr_coef(enum omap_channel channel,
|
||||
struct omap_dss_cpr_coefs *coefs);
|
||||
bool dispc_mgr_go_busy(enum omap_channel channel);
|
||||
void dispc_mgr_go(enum omap_channel channel);
|
||||
void dispc_mgr_enable(enum omap_channel channel, bool enable);
|
||||
bool dispc_mgr_is_channel_enabled(enum omap_channel channel);
|
||||
void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode);
|
||||
void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable);
|
||||
void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines);
|
||||
void dispc_mgr_set_lcd_display_type(enum omap_channel channel,
|
||||
enum omap_lcd_display_type type);
|
||||
void dispc_mgr_set_default_color(enum omap_channel channel, u32 color);
|
||||
u32 dispc_mgr_get_default_color(enum omap_channel channel);
|
||||
void dispc_mgr_set_trans_key(enum omap_channel ch,
|
||||
enum omap_dss_trans_key_type type,
|
||||
u32 trans_key);
|
||||
void dispc_mgr_get_trans_key(enum omap_channel ch,
|
||||
enum omap_dss_trans_key_type *type,
|
||||
u32 *trans_key);
|
||||
void dispc_mgr_enable_trans_key(enum omap_channel ch, bool enable);
|
||||
void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch, bool enable);
|
||||
bool dispc_mgr_trans_key_enabled(enum omap_channel ch);
|
||||
bool dispc_mgr_alpha_fixed_zorder_enabled(enum omap_channel ch);
|
||||
void dispc_mgr_set_lcd_timings(enum omap_channel channel,
|
||||
struct omap_video_timings *timings);
|
||||
void dispc_mgr_set_pol_freq(enum omap_channel channel,
|
||||
enum omap_panel_config config, u8 acbi, u8 acb);
|
||||
unsigned long dispc_mgr_lclk_rate(enum omap_channel channel);
|
||||
unsigned long dispc_mgr_pclk_rate(enum omap_channel channel);
|
||||
int dispc_mgr_set_clock_div(enum omap_channel channel,
|
||||
struct dispc_clock_info *cinfo);
|
||||
int dispc_mgr_get_clock_div(enum omap_channel channel,
|
||||
struct dispc_clock_info *cinfo);
|
||||
|
||||
/* VENC */
|
||||
#ifdef CONFIG_OMAP2_DSS_VENC
|
||||
int venc_init_platform_driver(void);
|
||||
void venc_uninit_platform_driver(void);
|
||||
void venc_dump_regs(struct seq_file *s);
|
||||
int venc_init_display(struct omap_dss_device *display);
|
||||
unsigned long venc_get_pixel_clock(void);
|
||||
#else
|
||||
static inline int venc_init_platform_driver(void)
|
||||
{
|
||||
|
|
@ -477,6 +459,11 @@ static inline int venc_init_platform_driver(void)
|
|||
static inline void venc_uninit_platform_driver(void)
|
||||
{
|
||||
}
|
||||
static inline unsigned long venc_get_pixel_clock(void)
|
||||
{
|
||||
WARN("%s: VENC not compiled in, returning pclk as 0\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* HDMI */
|
||||
|
|
@ -484,6 +471,8 @@ static inline void venc_uninit_platform_driver(void)
|
|||
int hdmi_init_platform_driver(void);
|
||||
void hdmi_uninit_platform_driver(void);
|
||||
int hdmi_init_display(struct omap_dss_device *dssdev);
|
||||
unsigned long hdmi_get_pixel_clock(void);
|
||||
void hdmi_dump_regs(struct seq_file *s);
|
||||
#else
|
||||
static inline int hdmi_init_display(struct omap_dss_device *dssdev)
|
||||
{
|
||||
|
|
@ -496,12 +485,19 @@ static inline int hdmi_init_platform_driver(void)
|
|||
static inline void hdmi_uninit_platform_driver(void)
|
||||
{
|
||||
}
|
||||
static inline unsigned long hdmi_get_pixel_clock(void)
|
||||
{
|
||||
WARN("%s: HDMI not compiled in, returning pclk as 0\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev);
|
||||
void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev);
|
||||
void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev);
|
||||
int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings);
|
||||
int omapdss_hdmi_read_edid(u8 *buf, int len);
|
||||
bool omapdss_hdmi_detect(void);
|
||||
int hdmi_panel_init(void);
|
||||
void hdmi_panel_exit(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ struct omap_dss_features {
|
|||
const int num_ovls;
|
||||
const enum omap_display_type *supported_displays;
|
||||
const enum omap_color_mode *supported_color_modes;
|
||||
const enum omap_overlay_caps *overlay_caps;
|
||||
const char * const *clksrc_names;
|
||||
const struct dss_param_range *dss_params;
|
||||
|
||||
|
|
@ -209,6 +210,68 @@ static const enum omap_color_mode omap4_dss_supported_color_modes[] = {
|
|||
OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 |
|
||||
OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 |
|
||||
OMAP_DSS_COLOR_RGBX32,
|
||||
|
||||
/* OMAP_DSS_VIDEO3 */
|
||||
OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB12U |
|
||||
OMAP_DSS_COLOR_YUV2 | OMAP_DSS_COLOR_ARGB16_1555 |
|
||||
OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_NV12 |
|
||||
OMAP_DSS_COLOR_RGBA16 | OMAP_DSS_COLOR_RGB24U |
|
||||
OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_UYVY |
|
||||
OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 |
|
||||
OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 |
|
||||
OMAP_DSS_COLOR_RGBX32,
|
||||
};
|
||||
|
||||
static const enum omap_overlay_caps omap2_dss_overlay_caps[] = {
|
||||
/* OMAP_DSS_GFX */
|
||||
0,
|
||||
|
||||
/* OMAP_DSS_VIDEO1 */
|
||||
OMAP_DSS_OVL_CAP_SCALE,
|
||||
|
||||
/* OMAP_DSS_VIDEO2 */
|
||||
OMAP_DSS_OVL_CAP_SCALE,
|
||||
};
|
||||
|
||||
static const enum omap_overlay_caps omap3430_dss_overlay_caps[] = {
|
||||
/* OMAP_DSS_GFX */
|
||||
OMAP_DSS_OVL_CAP_GLOBAL_ALPHA,
|
||||
|
||||
/* OMAP_DSS_VIDEO1 */
|
||||
OMAP_DSS_OVL_CAP_SCALE,
|
||||
|
||||
/* OMAP_DSS_VIDEO2 */
|
||||
OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA,
|
||||
};
|
||||
|
||||
static const enum omap_overlay_caps omap3630_dss_overlay_caps[] = {
|
||||
/* OMAP_DSS_GFX */
|
||||
OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA,
|
||||
|
||||
/* OMAP_DSS_VIDEO1 */
|
||||
OMAP_DSS_OVL_CAP_SCALE,
|
||||
|
||||
/* OMAP_DSS_VIDEO2 */
|
||||
OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
|
||||
OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA,
|
||||
};
|
||||
|
||||
static const enum omap_overlay_caps omap4_dss_overlay_caps[] = {
|
||||
/* OMAP_DSS_GFX */
|
||||
OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA |
|
||||
OMAP_DSS_OVL_CAP_ZORDER,
|
||||
|
||||
/* OMAP_DSS_VIDEO1 */
|
||||
OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
|
||||
OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER,
|
||||
|
||||
/* OMAP_DSS_VIDEO2 */
|
||||
OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
|
||||
OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER,
|
||||
|
||||
/* OMAP_DSS_VIDEO3 */
|
||||
OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
|
||||
OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER,
|
||||
};
|
||||
|
||||
static const char * const omap2_dss_clk_source_names[] = {
|
||||
|
|
@ -233,32 +296,38 @@ static const char * const omap4_dss_clk_source_names[] = {
|
|||
|
||||
static const struct dss_param_range omap2_dss_param_range[] = {
|
||||
[FEAT_PARAM_DSS_FCK] = { 0, 173000000 },
|
||||
[FEAT_PARAM_DSS_PCD] = { 2, 255 },
|
||||
[FEAT_PARAM_DSIPLL_REGN] = { 0, 0 },
|
||||
[FEAT_PARAM_DSIPLL_REGM] = { 0, 0 },
|
||||
[FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, 0 },
|
||||
[FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, 0 },
|
||||
[FEAT_PARAM_DSIPLL_FINT] = { 0, 0 },
|
||||
[FEAT_PARAM_DSIPLL_LPDIV] = { 0, 0 },
|
||||
[FEAT_PARAM_DOWNSCALE] = { 1, 2 },
|
||||
};
|
||||
|
||||
static const struct dss_param_range omap3_dss_param_range[] = {
|
||||
[FEAT_PARAM_DSS_FCK] = { 0, 173000000 },
|
||||
[FEAT_PARAM_DSS_PCD] = { 1, 255 },
|
||||
[FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 7) - 1 },
|
||||
[FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 11) - 1 },
|
||||
[FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 4) - 1 },
|
||||
[FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 4) - 1 },
|
||||
[FEAT_PARAM_DSIPLL_FINT] = { 750000, 2100000 },
|
||||
[FEAT_PARAM_DSIPLL_LPDIV] = { 1, (1 << 13) - 1},
|
||||
[FEAT_PARAM_DOWNSCALE] = { 1, 4 },
|
||||
};
|
||||
|
||||
static const struct dss_param_range omap4_dss_param_range[] = {
|
||||
[FEAT_PARAM_DSS_FCK] = { 0, 186000000 },
|
||||
[FEAT_PARAM_DSS_PCD] = { 1, 255 },
|
||||
[FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 8) - 1 },
|
||||
[FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 12) - 1 },
|
||||
[FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 5) - 1 },
|
||||
[FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 5) - 1 },
|
||||
[FEAT_PARAM_DSIPLL_FINT] = { 500000, 2500000 },
|
||||
[FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 },
|
||||
[FEAT_PARAM_DOWNSCALE] = { 1, 4 },
|
||||
};
|
||||
|
||||
/* OMAP2 DSS Features */
|
||||
|
|
@ -275,6 +344,7 @@ static const struct omap_dss_features omap2_dss_features = {
|
|||
.num_ovls = 3,
|
||||
.supported_displays = omap2_dss_supported_displays,
|
||||
.supported_color_modes = omap2_dss_supported_color_modes,
|
||||
.overlay_caps = omap2_dss_overlay_caps,
|
||||
.clksrc_names = omap2_dss_clk_source_names,
|
||||
.dss_params = omap2_dss_param_range,
|
||||
.buffer_size_unit = 1,
|
||||
|
|
@ -287,18 +357,19 @@ static const struct omap_dss_features omap3430_dss_features = {
|
|||
.num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields),
|
||||
|
||||
.has_feature =
|
||||
FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL |
|
||||
FEAT_LCDENABLEPOL |
|
||||
FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE |
|
||||
FEAT_FUNCGATED | FEAT_ROWREPEATENABLE |
|
||||
FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF |
|
||||
FEAT_DSI_PLL_FREQSEL | FEAT_DSI_REVERSE_TXCLKESC |
|
||||
FEAT_VENC_REQUIRES_TV_DAC_CLK | FEAT_CPR | FEAT_PRELOAD |
|
||||
FEAT_FIR_COEF_V,
|
||||
FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER,
|
||||
|
||||
.num_mgrs = 2,
|
||||
.num_ovls = 3,
|
||||
.supported_displays = omap3430_dss_supported_displays,
|
||||
.supported_color_modes = omap3_dss_supported_color_modes,
|
||||
.overlay_caps = omap3430_dss_overlay_caps,
|
||||
.clksrc_names = omap3_dss_clk_source_names,
|
||||
.dss_params = omap3_dss_param_range,
|
||||
.buffer_size_unit = 1,
|
||||
|
|
@ -310,18 +381,19 @@ static const struct omap_dss_features omap3630_dss_features = {
|
|||
.num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields),
|
||||
|
||||
.has_feature =
|
||||
FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL |
|
||||
FEAT_LCDENABLEPOL |
|
||||
FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE |
|
||||
FEAT_PRE_MULT_ALPHA | FEAT_FUNCGATED |
|
||||
FEAT_FUNCGATED |
|
||||
FEAT_ROWREPEATENABLE | FEAT_LINEBUFFERSPLIT |
|
||||
FEAT_RESIZECONF | FEAT_DSI_PLL_PWR_BUG |
|
||||
FEAT_DSI_PLL_FREQSEL | FEAT_CPR | FEAT_PRELOAD |
|
||||
FEAT_FIR_COEF_V,
|
||||
FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER,
|
||||
|
||||
.num_mgrs = 2,
|
||||
.num_ovls = 3,
|
||||
.supported_displays = omap3630_dss_supported_displays,
|
||||
.supported_color_modes = omap3_dss_supported_color_modes,
|
||||
.overlay_caps = omap3630_dss_overlay_caps,
|
||||
.clksrc_names = omap3_dss_clk_source_names,
|
||||
.dss_params = omap3_dss_param_range,
|
||||
.buffer_size_unit = 1,
|
||||
|
|
@ -335,17 +407,18 @@ static const struct omap_dss_features omap4430_es1_0_dss_features = {
|
|||
.num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
|
||||
|
||||
.has_feature =
|
||||
FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA |
|
||||
FEAT_MGR_LCD2 | FEAT_GLOBAL_ALPHA_VID1 |
|
||||
FEAT_MGR_LCD2 |
|
||||
FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC |
|
||||
FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH |
|
||||
FEAT_DSI_GNQ | FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2 |
|
||||
FEAT_CPR | FEAT_PRELOAD | FEAT_FIR_COEF_V,
|
||||
FEAT_CPR | FEAT_PRELOAD | FEAT_FIR_COEF_V |
|
||||
FEAT_ALPHA_FREE_ZORDER,
|
||||
|
||||
.num_mgrs = 3,
|
||||
.num_ovls = 3,
|
||||
.num_ovls = 4,
|
||||
.supported_displays = omap4_dss_supported_displays,
|
||||
.supported_color_modes = omap4_dss_supported_color_modes,
|
||||
.overlay_caps = omap4_dss_overlay_caps,
|
||||
.clksrc_names = omap4_dss_clk_source_names,
|
||||
.dss_params = omap4_dss_param_range,
|
||||
.buffer_size_unit = 16,
|
||||
|
|
@ -358,24 +431,50 @@ static const struct omap_dss_features omap4_dss_features = {
|
|||
.num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
|
||||
|
||||
.has_feature =
|
||||
FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA |
|
||||
FEAT_MGR_LCD2 | FEAT_GLOBAL_ALPHA_VID1 |
|
||||
FEAT_MGR_LCD2 |
|
||||
FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC |
|
||||
FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH |
|
||||
FEAT_DSI_GNQ | FEAT_HDMI_CTS_SWMODE |
|
||||
FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2 | FEAT_CPR |
|
||||
FEAT_PRELOAD | FEAT_FIR_COEF_V,
|
||||
FEAT_PRELOAD | FEAT_FIR_COEF_V | FEAT_ALPHA_FREE_ZORDER,
|
||||
|
||||
.num_mgrs = 3,
|
||||
.num_ovls = 3,
|
||||
.num_ovls = 4,
|
||||
.supported_displays = omap4_dss_supported_displays,
|
||||
.supported_color_modes = omap4_dss_supported_color_modes,
|
||||
.overlay_caps = omap4_dss_overlay_caps,
|
||||
.clksrc_names = omap4_dss_clk_source_names,
|
||||
.dss_params = omap4_dss_param_range,
|
||||
.buffer_size_unit = 16,
|
||||
.burst_size_unit = 16,
|
||||
};
|
||||
|
||||
#if defined(CONFIG_OMAP4_DSS_HDMI)
|
||||
/* HDMI OMAP4 Functions*/
|
||||
static const struct ti_hdmi_ip_ops omap4_hdmi_functions = {
|
||||
|
||||
.video_configure = ti_hdmi_4xxx_basic_configure,
|
||||
.phy_enable = ti_hdmi_4xxx_phy_enable,
|
||||
.phy_disable = ti_hdmi_4xxx_phy_disable,
|
||||
.read_edid = ti_hdmi_4xxx_read_edid,
|
||||
.detect = ti_hdmi_4xxx_detect,
|
||||
.pll_enable = ti_hdmi_4xxx_pll_enable,
|
||||
.pll_disable = ti_hdmi_4xxx_pll_disable,
|
||||
.video_enable = ti_hdmi_4xxx_wp_video_start,
|
||||
.dump_wrapper = ti_hdmi_4xxx_wp_dump,
|
||||
.dump_core = ti_hdmi_4xxx_core_dump,
|
||||
.dump_pll = ti_hdmi_4xxx_pll_dump,
|
||||
.dump_phy = ti_hdmi_4xxx_phy_dump,
|
||||
|
||||
};
|
||||
|
||||
void dss_init_hdmi_ip_ops(struct hdmi_ip_data *ip_data)
|
||||
{
|
||||
if (cpu_is_omap44xx())
|
||||
ip_data->ops = &omap4_hdmi_functions;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Functions returning values related to a DSS feature */
|
||||
int dss_feat_get_num_mgrs(void)
|
||||
{
|
||||
|
|
@ -407,6 +506,11 @@ enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane)
|
|||
return omap_current_dss_features->supported_color_modes[plane];
|
||||
}
|
||||
|
||||
enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane)
|
||||
{
|
||||
return omap_current_dss_features->overlay_caps[plane];
|
||||
}
|
||||
|
||||
bool dss_feat_color_mode_supported(enum omap_plane plane,
|
||||
enum omap_color_mode color_mode)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -20,16 +20,17 @@
|
|||
#ifndef __OMAP2_DSS_FEATURES_H
|
||||
#define __OMAP2_DSS_FEATURES_H
|
||||
|
||||
#if defined(CONFIG_OMAP4_DSS_HDMI)
|
||||
#include "ti_hdmi.h"
|
||||
#endif
|
||||
|
||||
#define MAX_DSS_MANAGERS 3
|
||||
#define MAX_DSS_OVERLAYS 3
|
||||
#define MAX_DSS_OVERLAYS 4
|
||||
#define MAX_DSS_LCD_MANAGERS 2
|
||||
#define MAX_NUM_DSI 2
|
||||
|
||||
/* DSS has feature id */
|
||||
enum dss_feat_id {
|
||||
FEAT_GLOBAL_ALPHA = 1 << 0,
|
||||
FEAT_GLOBAL_ALPHA_VID1 = 1 << 1,
|
||||
FEAT_PRE_MULT_ALPHA = 1 << 2,
|
||||
FEAT_LCDENABLEPOL = 1 << 3,
|
||||
FEAT_LCDENABLESIGNAL = 1 << 4,
|
||||
FEAT_PCKFREEENABLE = 1 << 5,
|
||||
|
|
@ -55,6 +56,8 @@ enum dss_feat_id {
|
|||
FEAT_CPR = 1 << 23,
|
||||
FEAT_PRELOAD = 1 << 24,
|
||||
FEAT_FIR_COEF_V = 1 << 25,
|
||||
FEAT_ALPHA_FIXED_ZORDER = 1 << 26,
|
||||
FEAT_ALPHA_FREE_ZORDER = 1 << 27,
|
||||
};
|
||||
|
||||
/* DSS register field id */
|
||||
|
|
@ -75,12 +78,14 @@ enum dss_feat_reg_field {
|
|||
|
||||
enum dss_range_param {
|
||||
FEAT_PARAM_DSS_FCK,
|
||||
FEAT_PARAM_DSS_PCD,
|
||||
FEAT_PARAM_DSIPLL_REGN,
|
||||
FEAT_PARAM_DSIPLL_REGM,
|
||||
FEAT_PARAM_DSIPLL_REGM_DISPC,
|
||||
FEAT_PARAM_DSIPLL_REGM_DSI,
|
||||
FEAT_PARAM_DSIPLL_FINT,
|
||||
FEAT_PARAM_DSIPLL_LPDIV,
|
||||
FEAT_PARAM_DOWNSCALE,
|
||||
};
|
||||
|
||||
/* DSS Feature Functions */
|
||||
|
|
@ -90,6 +95,7 @@ unsigned long dss_feat_get_param_min(enum dss_range_param param);
|
|||
unsigned long dss_feat_get_param_max(enum dss_range_param param);
|
||||
enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel);
|
||||
enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane);
|
||||
enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane);
|
||||
bool dss_feat_color_mode_supported(enum omap_plane plane,
|
||||
enum omap_color_mode color_mode);
|
||||
const char *dss_feat_get_clk_source_name(enum omap_dss_clk_source id);
|
||||
|
|
@ -100,4 +106,7 @@ u32 dss_feat_get_burst_size_unit(void); /* in bytes */
|
|||
bool dss_has_feature(enum dss_feat_id id);
|
||||
void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end);
|
||||
void dss_features_init(void);
|
||||
#if defined(CONFIG_OMAP4_DSS_HDMI)
|
||||
void dss_init_hdmi_ip_ops(struct hdmi_ip_data *ip_data);
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* hdmi_omap4_panel.c
|
||||
* hdmi_panel.c
|
||||
*
|
||||
* HDMI library support functions for TI OMAP4 processors.
|
||||
*
|
||||
|
|
@ -25,6 +25,7 @@
|
|||
#include <linux/mutex.h>
|
||||
#include <linux/module.h>
|
||||
#include <video/omapdss.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "dss.h"
|
||||
|
||||
|
|
@ -40,13 +41,7 @@ static int hdmi_panel_probe(struct omap_dss_device *dssdev)
|
|||
dssdev->panel.config = OMAP_DSS_LCD_TFT |
|
||||
OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS;
|
||||
|
||||
/*
|
||||
* Initialize the timings to 640 * 480
|
||||
* This is only for framebuffer update not for TV timing setting
|
||||
* Setting TV timing will be done only on enable
|
||||
*/
|
||||
dssdev->panel.timings.x_res = 640;
|
||||
dssdev->panel.timings.y_res = 480;
|
||||
dssdev->panel.timings = (struct omap_video_timings){640, 480, 25175, 96, 16, 48, 2 , 11, 31};
|
||||
|
||||
DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n",
|
||||
dssdev->panel.timings.x_res,
|
||||
|
|
@ -161,12 +156,7 @@ static void hdmi_set_timings(struct omap_dss_device *dssdev,
|
|||
mutex_lock(&hdmi.hdmi_lock);
|
||||
|
||||
dssdev->panel.timings = *timings;
|
||||
|
||||
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
|
||||
/* turn the hdmi off and on to get new timings to use */
|
||||
omapdss_hdmi_display_disable(dssdev);
|
||||
omapdss_hdmi_display_set_timing(dssdev);
|
||||
}
|
||||
omapdss_hdmi_display_set_timing(dssdev);
|
||||
|
||||
mutex_unlock(&hdmi.hdmi_lock);
|
||||
}
|
||||
|
|
@ -181,12 +171,54 @@ static int hdmi_check_timings(struct omap_dss_device *dssdev,
|
|||
mutex_lock(&hdmi.hdmi_lock);
|
||||
|
||||
r = omapdss_hdmi_display_check_timing(dssdev, timings);
|
||||
if (r) {
|
||||
DSSERR("Timing cannot be applied\n");
|
||||
goto err;
|
||||
|
||||
mutex_unlock(&hdmi.hdmi_lock);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int hdmi_read_edid(struct omap_dss_device *dssdev, u8 *buf, int len)
|
||||
{
|
||||
int r;
|
||||
|
||||
mutex_lock(&hdmi.hdmi_lock);
|
||||
|
||||
if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
|
||||
r = omapdss_hdmi_display_enable(dssdev);
|
||||
if (r)
|
||||
goto err;
|
||||
}
|
||||
|
||||
r = omapdss_hdmi_read_edid(buf, len);
|
||||
|
||||
if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED ||
|
||||
dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
|
||||
omapdss_hdmi_display_disable(dssdev);
|
||||
err:
|
||||
mutex_unlock(&hdmi.hdmi_lock);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static bool hdmi_detect(struct omap_dss_device *dssdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
mutex_lock(&hdmi.hdmi_lock);
|
||||
|
||||
if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
|
||||
r = omapdss_hdmi_display_enable(dssdev);
|
||||
if (r)
|
||||
goto err;
|
||||
}
|
||||
|
||||
r = omapdss_hdmi_detect();
|
||||
|
||||
if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED ||
|
||||
dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
|
||||
omapdss_hdmi_display_disable(dssdev);
|
||||
err:
|
||||
mutex_unlock(&hdmi.hdmi_lock);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
@ -200,6 +232,8 @@ static struct omap_dss_driver hdmi_driver = {
|
|||
.get_timings = hdmi_get_timings,
|
||||
.set_timings = hdmi_set_timings,
|
||||
.check_timings = hdmi_check_timings,
|
||||
.read_edid = hdmi_read_edid,
|
||||
.detect = hdmi_detect,
|
||||
.driver = {
|
||||
.name = "hdmi_panel",
|
||||
.owner = THIS_MODULE,
|
||||
|
|
@ -106,7 +106,7 @@ put_device:
|
|||
static ssize_t manager_default_color_show(struct omap_overlay_manager *mgr,
|
||||
char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", mgr->info.default_color);
|
||||
return snprintf(buf, PAGE_SIZE, "%#x\n", mgr->info.default_color);
|
||||
}
|
||||
|
||||
static ssize_t manager_default_color_store(struct omap_overlay_manager *mgr,
|
||||
|
|
@ -116,8 +116,9 @@ static ssize_t manager_default_color_store(struct omap_overlay_manager *mgr,
|
|||
u32 color;
|
||||
int r;
|
||||
|
||||
if (sscanf(buf, "%d", &color) != 1)
|
||||
return -EINVAL;
|
||||
r = kstrtouint(buf, 0, &color);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
mgr->get_manager_info(mgr, &info);
|
||||
|
||||
|
|
@ -184,7 +185,7 @@ static ssize_t manager_trans_key_type_store(struct omap_overlay_manager *mgr,
|
|||
static ssize_t manager_trans_key_value_show(struct omap_overlay_manager *mgr,
|
||||
char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", mgr->info.trans_key);
|
||||
return snprintf(buf, PAGE_SIZE, "%#x\n", mgr->info.trans_key);
|
||||
}
|
||||
|
||||
static ssize_t manager_trans_key_value_store(struct omap_overlay_manager *mgr,
|
||||
|
|
@ -194,8 +195,9 @@ static ssize_t manager_trans_key_value_store(struct omap_overlay_manager *mgr,
|
|||
u32 key_value;
|
||||
int r;
|
||||
|
||||
if (sscanf(buf, "%d", &key_value) != 1)
|
||||
return -EINVAL;
|
||||
r = kstrtouint(buf, 0, &key_value);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
mgr->get_manager_info(mgr, &info);
|
||||
|
||||
|
|
@ -222,15 +224,16 @@ static ssize_t manager_trans_key_enabled_store(struct omap_overlay_manager *mgr,
|
|||
const char *buf, size_t size)
|
||||
{
|
||||
struct omap_overlay_manager_info info;
|
||||
int enable;
|
||||
bool enable;
|
||||
int r;
|
||||
|
||||
if (sscanf(buf, "%d", &enable) != 1)
|
||||
return -EINVAL;
|
||||
r = strtobool(buf, &enable);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
mgr->get_manager_info(mgr, &info);
|
||||
|
||||
info.trans_enabled = enable ? true : false;
|
||||
info.trans_enabled = enable;
|
||||
|
||||
r = mgr->set_manager_info(mgr, &info);
|
||||
if (r)
|
||||
|
|
@ -246,7 +249,10 @@ static ssize_t manager_trans_key_enabled_store(struct omap_overlay_manager *mgr,
|
|||
static ssize_t manager_alpha_blending_enabled_show(
|
||||
struct omap_overlay_manager *mgr, char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", mgr->info.alpha_enabled);
|
||||
WARN_ON(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER));
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n",
|
||||
mgr->info.partial_alpha_enabled);
|
||||
}
|
||||
|
||||
static ssize_t manager_alpha_blending_enabled_store(
|
||||
|
|
@ -254,15 +260,18 @@ static ssize_t manager_alpha_blending_enabled_store(
|
|||
const char *buf, size_t size)
|
||||
{
|
||||
struct omap_overlay_manager_info info;
|
||||
int enable;
|
||||
bool enable;
|
||||
int r;
|
||||
|
||||
if (sscanf(buf, "%d", &enable) != 1)
|
||||
return -EINVAL;
|
||||
WARN_ON(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER));
|
||||
|
||||
r = strtobool(buf, &enable);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
mgr->get_manager_info(mgr, &info);
|
||||
|
||||
info.alpha_enabled = enable ? true : false;
|
||||
info.partial_alpha_enabled = enable;
|
||||
|
||||
r = mgr->set_manager_info(mgr, &info);
|
||||
if (r)
|
||||
|
|
@ -285,19 +294,16 @@ static ssize_t manager_cpr_enable_store(struct omap_overlay_manager *mgr,
|
|||
const char *buf, size_t size)
|
||||
{
|
||||
struct omap_overlay_manager_info info;
|
||||
int v;
|
||||
int r;
|
||||
bool enable;
|
||||
|
||||
if (!dss_has_feature(FEAT_CPR))
|
||||
return -ENODEV;
|
||||
|
||||
r = kstrtoint(buf, 0, &v);
|
||||
r = strtobool(buf, &enable);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
enable = !!v;
|
||||
|
||||
mgr->get_manager_info(mgr, &info);
|
||||
|
||||
if (info.cpr_enable == enable)
|
||||
|
|
@ -586,6 +592,13 @@ static int omap_dss_unset_device(struct omap_overlay_manager *mgr)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't allow currently enabled displays to have the overlay manager
|
||||
* pulled out from underneath them
|
||||
*/
|
||||
if (mgr->device->state != OMAP_DSS_DISPLAY_DISABLED)
|
||||
return -EINVAL;
|
||||
|
||||
mgr->device->manager = NULL;
|
||||
mgr->device = NULL;
|
||||
mgr->device_changed = true;
|
||||
|
|
@ -801,7 +814,7 @@ static int configure_overlay(enum omap_plane plane)
|
|||
{
|
||||
struct overlay_cache_data *c;
|
||||
struct manager_cache_data *mc;
|
||||
struct omap_overlay_info *oi;
|
||||
struct omap_overlay_info *oi, new_oi;
|
||||
struct omap_overlay_manager_info *mi;
|
||||
u16 outw, outh;
|
||||
u16 x, y, w, h;
|
||||
|
|
@ -815,7 +828,7 @@ static int configure_overlay(enum omap_plane plane)
|
|||
oi = &c->info;
|
||||
|
||||
if (!c->enabled) {
|
||||
dispc_enable_plane(plane, 0);
|
||||
dispc_ovl_enable(plane, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -843,7 +856,7 @@ static int configure_overlay(enum omap_plane plane)
|
|||
/* If the overlay is outside the update region, disable it */
|
||||
if (!rectangle_intersects(mc->x, mc->y, mc->w, mc->h,
|
||||
x, y, outw, outh)) {
|
||||
dispc_enable_plane(plane, 0);
|
||||
dispc_ovl_enable(plane, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -921,34 +934,27 @@ static int configure_overlay(enum omap_plane plane)
|
|||
}
|
||||
}
|
||||
|
||||
r = dispc_setup_plane(plane,
|
||||
paddr,
|
||||
oi->screen_width,
|
||||
x, y,
|
||||
w, h,
|
||||
outw, outh,
|
||||
oi->color_mode,
|
||||
c->ilace,
|
||||
oi->rotation_type,
|
||||
oi->rotation,
|
||||
oi->mirror,
|
||||
oi->global_alpha,
|
||||
oi->pre_mult_alpha,
|
||||
c->channel,
|
||||
oi->p_uv_addr);
|
||||
new_oi = *oi;
|
||||
|
||||
/* update new_oi members which could have been possibly updated */
|
||||
new_oi.pos_x = x;
|
||||
new_oi.pos_y = y;
|
||||
new_oi.width = w;
|
||||
new_oi.height = h;
|
||||
new_oi.out_width = outw;
|
||||
new_oi.out_height = outh;
|
||||
new_oi.paddr = paddr;
|
||||
|
||||
r = dispc_ovl_setup(plane, &new_oi, c->ilace, c->channel,
|
||||
c->replication, c->fifo_low, c->fifo_high);
|
||||
if (r) {
|
||||
/* this shouldn't happen */
|
||||
DSSERR("dispc_setup_plane failed for ovl %d\n", plane);
|
||||
dispc_enable_plane(plane, 0);
|
||||
DSSERR("dispc_ovl_setup failed for ovl %d\n", plane);
|
||||
dispc_ovl_enable(plane, 0);
|
||||
return r;
|
||||
}
|
||||
|
||||
dispc_enable_replication(plane, c->replication);
|
||||
|
||||
dispc_set_fifo_threshold(plane, c->fifo_low, c->fifo_high);
|
||||
|
||||
dispc_enable_plane(plane, 1);
|
||||
dispc_ovl_enable(plane, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -962,13 +968,13 @@ static void configure_manager(enum omap_channel channel)
|
|||
/* picking info from the cache */
|
||||
mi = &dss_cache.manager_cache[channel].info;
|
||||
|
||||
dispc_set_default_color(channel, mi->default_color);
|
||||
dispc_set_trans_key(channel, mi->trans_key_type, mi->trans_key);
|
||||
dispc_enable_trans_key(channel, mi->trans_enabled);
|
||||
dispc_enable_alpha_blending(channel, mi->alpha_enabled);
|
||||
dispc_mgr_set_default_color(channel, mi->default_color);
|
||||
dispc_mgr_set_trans_key(channel, mi->trans_key_type, mi->trans_key);
|
||||
dispc_mgr_enable_trans_key(channel, mi->trans_enabled);
|
||||
dispc_mgr_enable_alpha_fixed_zorder(channel, mi->partial_alpha_enabled);
|
||||
if (dss_has_feature(FEAT_CPR)) {
|
||||
dispc_enable_cpr(channel, mi->cpr_enable);
|
||||
dispc_set_cpr_coef(channel, &mi->cpr_coefs);
|
||||
dispc_mgr_enable_cpr(channel, mi->cpr_enable);
|
||||
dispc_mgr_set_cpr_coef(channel, &mi->cpr_coefs);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -992,7 +998,7 @@ static int configure_dispc(void)
|
|||
busy = false;
|
||||
|
||||
for (i = 0; i < num_mgrs; i++) {
|
||||
mgr_busy[i] = dispc_go_busy(i);
|
||||
mgr_busy[i] = dispc_mgr_go_busy(i);
|
||||
mgr_go[i] = false;
|
||||
}
|
||||
|
||||
|
|
@ -1053,7 +1059,7 @@ static int configure_dispc(void)
|
|||
* always be turned off after frame, and new settings will be
|
||||
* taken in to use at next update */
|
||||
if (!mc->manual_update)
|
||||
dispc_go(i);
|
||||
dispc_mgr_go(i);
|
||||
}
|
||||
|
||||
if (busy)
|
||||
|
|
@ -1258,7 +1264,7 @@ static void dss_apply_irq_handler(void *data, u32 mask)
|
|||
u32 irq_mask;
|
||||
|
||||
for (i = 0; i < num_mgrs; i++)
|
||||
mgr_busy[i] = dispc_go_busy(i);
|
||||
mgr_busy[i] = dispc_mgr_go_busy(i);
|
||||
|
||||
spin_lock(&dss_cache.lock);
|
||||
|
||||
|
|
@ -1280,7 +1286,7 @@ static void dss_apply_irq_handler(void *data, u32 mask)
|
|||
|
||||
/* re-read busy flags */
|
||||
for (i = 0; i < num_mgrs; i++)
|
||||
mgr_busy[i] = dispc_go_busy(i);
|
||||
mgr_busy[i] = dispc_mgr_go_busy(i);
|
||||
|
||||
/* keep running as long as there are busy managers, so that
|
||||
* we can collect overlay-applied information */
|
||||
|
|
@ -1326,11 +1332,13 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
|
|||
|
||||
ovl = omap_dss_get_overlay(i);
|
||||
|
||||
if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC))
|
||||
continue;
|
||||
|
||||
oc = &dss_cache.overlay_cache[ovl->id];
|
||||
|
||||
if (ovl->manager_changed) {
|
||||
ovl->manager_changed = false;
|
||||
ovl->info_dirty = true;
|
||||
}
|
||||
|
||||
if (!overlay_enabled(ovl)) {
|
||||
if (oc->enabled) {
|
||||
oc->enabled = false;
|
||||
|
|
@ -1375,9 +1383,6 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
|
|||
list_for_each_entry(mgr, &manager_list, list) {
|
||||
struct omap_dss_device *dssdev;
|
||||
|
||||
if (!(mgr->caps & OMAP_DSS_OVL_MGR_CAP_DISPC))
|
||||
continue;
|
||||
|
||||
mc = &dss_cache.manager_cache[mgr->id];
|
||||
|
||||
if (mgr->device_changed) {
|
||||
|
|
@ -1423,9 +1428,6 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
|
|||
|
||||
ovl = omap_dss_get_overlay(i);
|
||||
|
||||
if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC))
|
||||
continue;
|
||||
|
||||
oc = &dss_cache.overlay_cache[ovl->id];
|
||||
|
||||
if (!oc->enabled)
|
||||
|
|
@ -1433,11 +1435,11 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
|
|||
|
||||
dssdev = ovl->manager->device;
|
||||
|
||||
size = dispc_get_plane_fifo_size(ovl->id);
|
||||
size = dispc_ovl_get_fifo_size(ovl->id);
|
||||
if (use_fifomerge)
|
||||
size *= 3;
|
||||
|
||||
burst_size = dispc_get_burst_size(ovl->id);
|
||||
burst_size = dispc_ovl_get_burst_size(ovl->id);
|
||||
|
||||
switch (dssdev->type) {
|
||||
case OMAP_DISPLAY_TYPE_DPI:
|
||||
|
|
@ -1484,12 +1486,17 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
|
|||
|
||||
static int dss_check_manager(struct omap_overlay_manager *mgr)
|
||||
{
|
||||
/* OMAP supports only graphics source transparency color key and alpha
|
||||
* blending simultaneously. See TRM 15.4.2.4.2.2 Alpha Mode */
|
||||
|
||||
if (mgr->info.alpha_enabled && mgr->info.trans_enabled &&
|
||||
mgr->info.trans_key_type != OMAP_DSS_COLOR_KEY_GFX_DST)
|
||||
return -EINVAL;
|
||||
if (dss_has_feature(FEAT_ALPHA_FIXED_ZORDER)) {
|
||||
/*
|
||||
* OMAP3 supports only graphics source transparency color key
|
||||
* and alpha blending simultaneously. See TRM 15.4.2.4.2.2
|
||||
* Alpha Mode
|
||||
*/
|
||||
if (mgr->info.partial_alpha_enabled && mgr->info.trans_enabled
|
||||
&& mgr->info.trans_key_type !=
|
||||
OMAP_DSS_COLOR_KEY_GFX_DST)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1522,13 +1529,13 @@ static void omap_dss_mgr_get_info(struct omap_overlay_manager *mgr,
|
|||
|
||||
static int dss_mgr_enable(struct omap_overlay_manager *mgr)
|
||||
{
|
||||
dispc_enable_channel(mgr->id, 1);
|
||||
dispc_mgr_enable(mgr->id, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dss_mgr_disable(struct omap_overlay_manager *mgr)
|
||||
{
|
||||
dispc_enable_channel(mgr->id, 0);
|
||||
dispc_mgr_enable(mgr->id, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1580,7 +1587,7 @@ int dss_init_overlay_managers(struct platform_device *pdev)
|
|||
mgr->enable = &dss_mgr_enable;
|
||||
mgr->disable = &dss_mgr_disable;
|
||||
|
||||
mgr->caps = OMAP_DSS_OVL_MGR_CAP_DISPC;
|
||||
mgr->caps = 0;
|
||||
mgr->supported_displays =
|
||||
dss_feat_get_supported_displays(mgr->id);
|
||||
|
||||
|
|
@ -1597,42 +1604,6 @@ int dss_init_overlay_managers(struct platform_device *pdev)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef L4_EXAMPLE
|
||||
{
|
||||
int omap_dss_mgr_apply_l4(struct omap_overlay_manager *mgr)
|
||||
{
|
||||
DSSDBG("omap_dss_mgr_apply_l4(%s)\n", mgr->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct omap_overlay_manager *mgr;
|
||||
mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
|
||||
|
||||
BUG_ON(mgr == NULL);
|
||||
|
||||
mgr->name = "l4";
|
||||
mgr->supported_displays =
|
||||
OMAP_DISPLAY_TYPE_DBI | OMAP_DISPLAY_TYPE_DSI;
|
||||
|
||||
mgr->set_device = &omap_dss_set_device;
|
||||
mgr->unset_device = &omap_dss_unset_device;
|
||||
mgr->apply = &omap_dss_mgr_apply_l4;
|
||||
mgr->set_manager_info = &omap_dss_mgr_set_info;
|
||||
mgr->get_manager_info = &omap_dss_mgr_get_info;
|
||||
|
||||
dss_overlay_setup_l4_manager(mgr);
|
||||
|
||||
omap_dss_add_overlay_manager(mgr);
|
||||
|
||||
r = kobject_init_and_add(&mgr->kobj, &manager_ktype,
|
||||
&pdev->dev.kobj, "managerl4");
|
||||
|
||||
if (r)
|
||||
DSSERR("failed to create sysfs file\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -211,16 +211,17 @@ static ssize_t overlay_enabled_show(struct omap_overlay *ovl, char *buf)
|
|||
static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf,
|
||||
size_t size)
|
||||
{
|
||||
int r, enable;
|
||||
int r;
|
||||
bool enable;
|
||||
struct omap_overlay_info info;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
r = kstrtoint(buf, 0, &enable);
|
||||
r = strtobool(buf, &enable);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
info.enabled = !!enable;
|
||||
info.enabled = enable;
|
||||
|
||||
r = ovl->set_overlay_info(ovl, &info);
|
||||
if (r)
|
||||
|
|
@ -248,7 +249,7 @@ static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl,
|
|||
u8 alpha;
|
||||
struct omap_overlay_info info;
|
||||
|
||||
if (!dss_has_feature(FEAT_GLOBAL_ALPHA))
|
||||
if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
|
||||
return -ENODEV;
|
||||
|
||||
r = kstrtou8(buf, 0, &alpha);
|
||||
|
|
@ -257,14 +258,7 @@ static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl,
|
|||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
/* Video1 plane does not support global alpha
|
||||
* to always make it 255 completely opaque
|
||||
*/
|
||||
if (!dss_has_feature(FEAT_GLOBAL_ALPHA_VID1) &&
|
||||
ovl->id == OMAP_DSS_VIDEO1)
|
||||
info.global_alpha = 255;
|
||||
else
|
||||
info.global_alpha = alpha;
|
||||
info.global_alpha = alpha;
|
||||
|
||||
r = ovl->set_overlay_info(ovl, &info);
|
||||
if (r)
|
||||
|
|
@ -293,20 +287,52 @@ static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl,
|
|||
u8 alpha;
|
||||
struct omap_overlay_info info;
|
||||
|
||||
if ((ovl->caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0)
|
||||
return -ENODEV;
|
||||
|
||||
r = kstrtou8(buf, 0, &alpha);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
/* only GFX and Video2 plane support pre alpha multiplied
|
||||
* set zero for Video1 plane
|
||||
*/
|
||||
if (!dss_has_feature(FEAT_GLOBAL_ALPHA_VID1) &&
|
||||
ovl->id == OMAP_DSS_VIDEO1)
|
||||
info.pre_mult_alpha = 0;
|
||||
else
|
||||
info.pre_mult_alpha = alpha;
|
||||
info.pre_mult_alpha = alpha;
|
||||
|
||||
r = ovl->set_overlay_info(ovl, &info);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (ovl->manager) {
|
||||
r = ovl->manager->apply(ovl->manager);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t overlay_zorder_show(struct omap_overlay *ovl, char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", ovl->info.zorder);
|
||||
}
|
||||
|
||||
static ssize_t overlay_zorder_store(struct omap_overlay *ovl,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
int r;
|
||||
u8 zorder;
|
||||
struct omap_overlay_info info;
|
||||
|
||||
if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0)
|
||||
return -ENODEV;
|
||||
|
||||
r = kstrtou8(buf, 0, &zorder);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
info.zorder = zorder;
|
||||
|
||||
r = ovl->set_overlay_info(ovl, &info);
|
||||
if (r)
|
||||
|
|
@ -347,6 +373,8 @@ static OVERLAY_ATTR(global_alpha, S_IRUGO|S_IWUSR,
|
|||
static OVERLAY_ATTR(pre_mult_alpha, S_IRUGO|S_IWUSR,
|
||||
overlay_pre_mult_alpha_show,
|
||||
overlay_pre_mult_alpha_store);
|
||||
static OVERLAY_ATTR(zorder, S_IRUGO|S_IWUSR,
|
||||
overlay_zorder_show, overlay_zorder_store);
|
||||
|
||||
static struct attribute *overlay_sysfs_attrs[] = {
|
||||
&overlay_attr_name.attr,
|
||||
|
|
@ -358,6 +386,7 @@ static struct attribute *overlay_sysfs_attrs[] = {
|
|||
&overlay_attr_enabled.attr,
|
||||
&overlay_attr_global_alpha.attr,
|
||||
&overlay_attr_pre_mult_alpha.attr,
|
||||
&overlay_attr_zorder.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
@ -407,6 +436,7 @@ int dss_check_overlay(struct omap_overlay *ovl, struct omap_dss_device *dssdev)
|
|||
struct omap_overlay_info *info;
|
||||
u16 outw, outh;
|
||||
u16 dw, dh;
|
||||
int i;
|
||||
|
||||
if (!dssdev)
|
||||
return 0;
|
||||
|
|
@ -462,6 +492,31 @@ int dss_check_overlay(struct omap_overlay *ovl, struct omap_dss_device *dssdev)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) {
|
||||
if (info->zorder < 0 || info->zorder > 3) {
|
||||
DSSERR("zorder out of range: %d\n",
|
||||
info->zorder);
|
||||
return -EINVAL;
|
||||
}
|
||||
/*
|
||||
* Check that zorder doesn't match with zorder of any other
|
||||
* overlay which is enabled and is also connected to the same
|
||||
* manager
|
||||
*/
|
||||
for (i = 0; i < omap_dss_get_num_overlays(); i++) {
|
||||
struct omap_overlay *tmp_ovl = omap_dss_get_overlay(i);
|
||||
|
||||
if (tmp_ovl->id != ovl->id &&
|
||||
tmp_ovl->manager == ovl->manager &&
|
||||
tmp_ovl->info.enabled == true &&
|
||||
tmp_ovl->info.zorder == info->zorder) {
|
||||
DSSERR("%s and %s have same zorder: %d\n",
|
||||
ovl->name, tmp_ovl->name, info->zorder);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -516,6 +571,7 @@ static int omap_dss_set_manager(struct omap_overlay *ovl,
|
|||
}
|
||||
|
||||
ovl->manager = mgr;
|
||||
ovl->manager_changed = true;
|
||||
|
||||
/* XXX: When there is an overlay on a DSI manual update display, and
|
||||
* the overlay is first disabled, then moved to tv, and enabled, we
|
||||
|
|
@ -529,15 +585,12 @@ static int omap_dss_set_manager(struct omap_overlay *ovl,
|
|||
* Userspace workaround for this is to update the LCD after disabling
|
||||
* the overlay, but before moving the overlay to TV.
|
||||
*/
|
||||
dispc_set_channel_out(ovl->id, mgr->id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap_dss_unset_manager(struct omap_overlay *ovl)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (!ovl->manager) {
|
||||
DSSERR("failed to detach overlay: manager not set\n");
|
||||
return -EINVAL;
|
||||
|
|
@ -548,11 +601,8 @@ static int omap_dss_unset_manager(struct omap_overlay *ovl)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = ovl->wait_for_go(ovl);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
ovl->manager = NULL;
|
||||
ovl->manager_changed = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -618,22 +668,29 @@ void dss_init_overlays(struct platform_device *pdev)
|
|||
case 0:
|
||||
ovl->name = "gfx";
|
||||
ovl->id = OMAP_DSS_GFX;
|
||||
ovl->caps = OMAP_DSS_OVL_CAP_DISPC;
|
||||
ovl->info.global_alpha = 255;
|
||||
ovl->info.zorder = 0;
|
||||
break;
|
||||
case 1:
|
||||
ovl->name = "vid1";
|
||||
ovl->id = OMAP_DSS_VIDEO1;
|
||||
ovl->caps = OMAP_DSS_OVL_CAP_SCALE |
|
||||
OMAP_DSS_OVL_CAP_DISPC;
|
||||
ovl->info.global_alpha = 255;
|
||||
ovl->info.zorder =
|
||||
dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 3 : 0;
|
||||
break;
|
||||
case 2:
|
||||
ovl->name = "vid2";
|
||||
ovl->id = OMAP_DSS_VIDEO2;
|
||||
ovl->caps = OMAP_DSS_OVL_CAP_SCALE |
|
||||
OMAP_DSS_OVL_CAP_DISPC;
|
||||
ovl->info.global_alpha = 255;
|
||||
ovl->info.zorder =
|
||||
dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 2 : 0;
|
||||
break;
|
||||
case 3:
|
||||
ovl->name = "vid3";
|
||||
ovl->id = OMAP_DSS_VIDEO3;
|
||||
ovl->info.global_alpha = 255;
|
||||
ovl->info.zorder =
|
||||
dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 1 : 0;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -643,6 +700,7 @@ void dss_init_overlays(struct platform_device *pdev)
|
|||
ovl->get_overlay_info = &dss_ovl_get_overlay_info;
|
||||
ovl->wait_for_go = &dss_ovl_wait_for_go;
|
||||
|
||||
ovl->caps = dss_feat_get_overlay_caps(ovl->id);
|
||||
ovl->supported_modes =
|
||||
dss_feat_get_supported_color_modes(ovl->id);
|
||||
|
||||
|
|
|
|||
|
|
@ -309,9 +309,9 @@ static void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width,
|
|||
|
||||
DSSDBG("rfbi_transfer_area %dx%d\n", width, height);
|
||||
|
||||
dispc_set_lcd_size(dssdev->manager->id, width, height);
|
||||
dispc_mgr_set_lcd_size(dssdev->manager->id, width, height);
|
||||
|
||||
dispc_enable_channel(dssdev->manager->id, true);
|
||||
dispc_mgr_enable(dssdev->manager->id, true);
|
||||
|
||||
rfbi.framedone_callback = callback;
|
||||
rfbi.framedone_callback_data = data;
|
||||
|
|
@ -783,10 +783,8 @@ int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
|
|||
if (*w == 0 || *h == 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
|
||||
dss_setup_partial_planes(dssdev, x, y, w, h, true);
|
||||
dispc_set_lcd_size(dssdev->manager->id, *w, *h);
|
||||
}
|
||||
dss_setup_partial_planes(dssdev, x, y, w, h, true);
|
||||
dispc_mgr_set_lcd_size(dssdev->manager->id, *w, *h);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -796,22 +794,7 @@ int omap_rfbi_update(struct omap_dss_device *dssdev,
|
|||
u16 x, u16 y, u16 w, u16 h,
|
||||
void (*callback)(void *), void *data)
|
||||
{
|
||||
if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
|
||||
rfbi_transfer_area(dssdev, w, h, callback, data);
|
||||
} else {
|
||||
struct omap_overlay *ovl;
|
||||
void __iomem *addr;
|
||||
int scr_width;
|
||||
|
||||
ovl = dssdev->manager->overlays[0];
|
||||
scr_width = ovl->info.screen_width;
|
||||
addr = ovl->info.vaddr;
|
||||
|
||||
omap_rfbi_write_pixels(addr, scr_width, x, y, w, h);
|
||||
|
||||
callback(data);
|
||||
}
|
||||
|
||||
rfbi_transfer_area(dssdev, w, h, callback, data);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(omap_rfbi_update);
|
||||
|
|
@ -860,6 +843,11 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
|
|||
{
|
||||
int r;
|
||||
|
||||
if (dssdev->manager == NULL) {
|
||||
DSSERR("failed to enable display: no manager\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
r = rfbi_runtime_get();
|
||||
if (r)
|
||||
return r;
|
||||
|
|
@ -877,13 +865,13 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
|
|||
goto err1;
|
||||
}
|
||||
|
||||
dispc_set_lcd_display_type(dssdev->manager->id,
|
||||
dispc_mgr_set_lcd_display_type(dssdev->manager->id,
|
||||
OMAP_DSS_LCD_DISPLAY_TFT);
|
||||
|
||||
dispc_set_parallel_interface_mode(dssdev->manager->id,
|
||||
OMAP_DSS_PARALLELMODE_RFBI);
|
||||
dispc_mgr_set_io_pad_mode(DSS_IO_PAD_MODE_RFBI);
|
||||
dispc_mgr_enable_stallmode(dssdev->manager->id, true);
|
||||
|
||||
dispc_set_tft_data_lines(dssdev->manager->id, dssdev->ctrl.pixel_size);
|
||||
dispc_mgr_set_tft_data_lines(dssdev->manager->id, dssdev->ctrl.pixel_size);
|
||||
|
||||
rfbi_configure(dssdev->phy.rfbi.channel,
|
||||
dssdev->ctrl.pixel_size,
|
||||
|
|
@ -952,10 +940,7 @@ static int omap_rfbihw_probe(struct platform_device *pdev)
|
|||
|
||||
msleep(10);
|
||||
|
||||
if (cpu_is_omap24xx() || cpu_is_omap34xx() || cpu_is_omap3630())
|
||||
clk = dss_get_ick();
|
||||
else
|
||||
clk = clk_get(&pdev->dev, "ick");
|
||||
clk = clk_get(&pdev->dev, "ick");
|
||||
if (IS_ERR(clk)) {
|
||||
DSSERR("can't get ick\n");
|
||||
r = PTR_ERR(clk);
|
||||
|
|
|
|||
|
|
@ -35,13 +35,13 @@ static struct {
|
|||
static void sdi_basic_init(struct omap_dss_device *dssdev)
|
||||
|
||||
{
|
||||
dispc_set_parallel_interface_mode(dssdev->manager->id,
|
||||
OMAP_DSS_PARALLELMODE_BYPASS);
|
||||
dispc_mgr_set_io_pad_mode(DSS_IO_PAD_MODE_BYPASS);
|
||||
dispc_mgr_enable_stallmode(dssdev->manager->id, false);
|
||||
|
||||
dispc_set_lcd_display_type(dssdev->manager->id,
|
||||
dispc_mgr_set_lcd_display_type(dssdev->manager->id,
|
||||
OMAP_DSS_LCD_DISPLAY_TFT);
|
||||
|
||||
dispc_set_tft_data_lines(dssdev->manager->id, 24);
|
||||
dispc_mgr_set_tft_data_lines(dssdev->manager->id, 24);
|
||||
dispc_lcd_enable_signal_polarity(1);
|
||||
}
|
||||
|
||||
|
|
@ -55,6 +55,11 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
|
|||
unsigned long pck;
|
||||
int r;
|
||||
|
||||
if (dssdev->manager == NULL) {
|
||||
DSSERR("failed to enable display: no manager\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
r = omap_dss_start_device(dssdev);
|
||||
if (r) {
|
||||
DSSERR("failed to start device\n");
|
||||
|
|
@ -78,7 +83,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
|
|||
/* 15.5.9.1.2 */
|
||||
dssdev->panel.config |= OMAP_DSS_LCD_RF | OMAP_DSS_LCD_ONOFF;
|
||||
|
||||
dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config,
|
||||
dispc_mgr_set_pol_freq(dssdev->manager->id, dssdev->panel.config,
|
||||
dssdev->panel.acbi, dssdev->panel.acb);
|
||||
|
||||
r = dss_calc_clock_div(1, t->pixel_clock * 1000,
|
||||
|
|
@ -101,13 +106,13 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
|
|||
}
|
||||
|
||||
|
||||
dispc_set_lcd_timings(dssdev->manager->id, t);
|
||||
dispc_mgr_set_lcd_timings(dssdev->manager->id, t);
|
||||
|
||||
r = dss_set_clock_div(&dss_cinfo);
|
||||
if (r)
|
||||
goto err_set_dss_clock_div;
|
||||
|
||||
r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo);
|
||||
r = dispc_mgr_set_clock_div(dssdev->manager->id, &dispc_cinfo);
|
||||
if (r)
|
||||
goto err_set_dispc_clock_div;
|
||||
|
||||
|
|
|
|||
138
drivers/video/omap2/dss/ti_hdmi.h
Normal file
138
drivers/video/omap2/dss/ti_hdmi.h
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* ti_hdmi.h
|
||||
*
|
||||
* HDMI driver definition for TI OMAP4, DM81xx, DM38xx Processor.
|
||||
*
|
||||
* Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _TI_HDMI_H
|
||||
#define _TI_HDMI_H
|
||||
|
||||
struct hdmi_ip_data;
|
||||
|
||||
enum hdmi_pll_pwr {
|
||||
HDMI_PLLPWRCMD_ALLOFF = 0,
|
||||
HDMI_PLLPWRCMD_PLLONLY = 1,
|
||||
HDMI_PLLPWRCMD_BOTHON_ALLCLKS = 2,
|
||||
HDMI_PLLPWRCMD_BOTHON_NOPHYCLK = 3
|
||||
};
|
||||
|
||||
enum hdmi_core_hdmi_dvi {
|
||||
HDMI_DVI = 0,
|
||||
HDMI_HDMI = 1
|
||||
};
|
||||
|
||||
enum hdmi_clk_refsel {
|
||||
HDMI_REFSEL_PCLK = 0,
|
||||
HDMI_REFSEL_REF1 = 1,
|
||||
HDMI_REFSEL_REF2 = 2,
|
||||
HDMI_REFSEL_SYSCLK = 3
|
||||
};
|
||||
|
||||
struct hdmi_video_timings {
|
||||
u16 x_res;
|
||||
u16 y_res;
|
||||
/* Unit: KHz */
|
||||
u32 pixel_clock;
|
||||
u16 hsw;
|
||||
u16 hfp;
|
||||
u16 hbp;
|
||||
u16 vsw;
|
||||
u16 vfp;
|
||||
u16 vbp;
|
||||
};
|
||||
|
||||
/* HDMI timing structure */
|
||||
struct hdmi_timings {
|
||||
struct hdmi_video_timings timings;
|
||||
int vsync_pol;
|
||||
int hsync_pol;
|
||||
};
|
||||
|
||||
struct hdmi_cm {
|
||||
int code;
|
||||
int mode;
|
||||
};
|
||||
|
||||
struct hdmi_config {
|
||||
struct hdmi_timings timings;
|
||||
u16 interlace;
|
||||
struct hdmi_cm cm;
|
||||
};
|
||||
|
||||
/* HDMI PLL structure */
|
||||
struct hdmi_pll_info {
|
||||
u16 regn;
|
||||
u16 regm;
|
||||
u32 regmf;
|
||||
u16 regm2;
|
||||
u16 regsd;
|
||||
u16 dcofreq;
|
||||
enum hdmi_clk_refsel refsel;
|
||||
};
|
||||
|
||||
struct ti_hdmi_ip_ops {
|
||||
|
||||
void (*video_configure)(struct hdmi_ip_data *ip_data);
|
||||
|
||||
int (*phy_enable)(struct hdmi_ip_data *ip_data);
|
||||
|
||||
void (*phy_disable)(struct hdmi_ip_data *ip_data);
|
||||
|
||||
int (*read_edid)(struct hdmi_ip_data *ip_data, u8 *edid, int len);
|
||||
|
||||
bool (*detect)(struct hdmi_ip_data *ip_data);
|
||||
|
||||
int (*pll_enable)(struct hdmi_ip_data *ip_data);
|
||||
|
||||
void (*pll_disable)(struct hdmi_ip_data *ip_data);
|
||||
|
||||
void (*video_enable)(struct hdmi_ip_data *ip_data, bool start);
|
||||
|
||||
void (*dump_wrapper)(struct hdmi_ip_data *ip_data, struct seq_file *s);
|
||||
|
||||
void (*dump_core)(struct hdmi_ip_data *ip_data, struct seq_file *s);
|
||||
|
||||
void (*dump_pll)(struct hdmi_ip_data *ip_data, struct seq_file *s);
|
||||
|
||||
void (*dump_phy)(struct hdmi_ip_data *ip_data, struct seq_file *s);
|
||||
|
||||
};
|
||||
|
||||
struct hdmi_ip_data {
|
||||
void __iomem *base_wp; /* HDMI wrapper */
|
||||
unsigned long core_sys_offset;
|
||||
unsigned long core_av_offset;
|
||||
unsigned long pll_offset;
|
||||
unsigned long phy_offset;
|
||||
const struct ti_hdmi_ip_ops *ops;
|
||||
struct hdmi_config cfg;
|
||||
struct hdmi_pll_info pll_data;
|
||||
};
|
||||
int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data);
|
||||
void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data);
|
||||
int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data, u8 *edid, int len);
|
||||
bool ti_hdmi_4xxx_detect(struct hdmi_ip_data *ip_data);
|
||||
void ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data, bool start);
|
||||
int ti_hdmi_4xxx_pll_enable(struct hdmi_ip_data *ip_data);
|
||||
void ti_hdmi_4xxx_pll_disable(struct hdmi_ip_data *ip_data);
|
||||
void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data);
|
||||
void ti_hdmi_4xxx_wp_dump(struct hdmi_ip_data *ip_data, struct seq_file *s);
|
||||
void ti_hdmi_4xxx_pll_dump(struct hdmi_ip_data *ip_data, struct seq_file *s);
|
||||
void ti_hdmi_4xxx_core_dump(struct hdmi_ip_data *ip_data, struct seq_file *s);
|
||||
void ti_hdmi_4xxx_phy_dump(struct hdmi_ip_data *ip_data, struct seq_file *s);
|
||||
|
||||
#endif
|
||||
1239
drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
Normal file
1239
drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* hdmi.h
|
||||
* ti_hdmi_4xxx_ip.h
|
||||
*
|
||||
* HDMI driver definition for TI OMAP4 processors.
|
||||
* HDMI header definition for DM81xx, DM38xx, TI OMAP4 etc processors.
|
||||
*
|
||||
* Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
|
|
@ -18,202 +18,177 @@
|
|||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _OMAP4_DSS_HDMI_H_
|
||||
#define _OMAP4_DSS_HDMI_H_
|
||||
#ifndef _HDMI_TI_4xxx_H_
|
||||
#define _HDMI_TI_4xxx_H_
|
||||
|
||||
#include <linux/string.h>
|
||||
#include <video/omapdss.h>
|
||||
|
||||
#define HDMI_WP 0x0
|
||||
#define HDMI_CORE_SYS 0x400
|
||||
#define HDMI_CORE_AV 0x900
|
||||
#define HDMI_PLLCTRL 0x200
|
||||
#define HDMI_PHY 0x300
|
||||
|
||||
struct hdmi_reg { u16 idx; };
|
||||
|
||||
#define HDMI_REG(idx) ((const struct hdmi_reg) { idx })
|
||||
#include "ti_hdmi.h"
|
||||
#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
|
||||
defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
|
||||
#include <sound/soc.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#endif
|
||||
|
||||
/* HDMI Wrapper */
|
||||
#define HDMI_WP_REG(idx) HDMI_REG(HDMI_WP + idx)
|
||||
|
||||
#define HDMI_WP_REVISION HDMI_WP_REG(0x0)
|
||||
#define HDMI_WP_SYSCONFIG HDMI_WP_REG(0x10)
|
||||
#define HDMI_WP_IRQSTATUS_RAW HDMI_WP_REG(0x24)
|
||||
#define HDMI_WP_IRQSTATUS HDMI_WP_REG(0x28)
|
||||
#define HDMI_WP_PWR_CTRL HDMI_WP_REG(0x40)
|
||||
#define HDMI_WP_IRQENABLE_SET HDMI_WP_REG(0x2C)
|
||||
#define HDMI_WP_VIDEO_CFG HDMI_WP_REG(0x50)
|
||||
#define HDMI_WP_VIDEO_SIZE HDMI_WP_REG(0x60)
|
||||
#define HDMI_WP_VIDEO_TIMING_H HDMI_WP_REG(0x68)
|
||||
#define HDMI_WP_VIDEO_TIMING_V HDMI_WP_REG(0x6C)
|
||||
#define HDMI_WP_WP_CLK HDMI_WP_REG(0x70)
|
||||
#define HDMI_WP_AUDIO_CFG HDMI_WP_REG(0x80)
|
||||
#define HDMI_WP_AUDIO_CFG2 HDMI_WP_REG(0x84)
|
||||
#define HDMI_WP_AUDIO_CTRL HDMI_WP_REG(0x88)
|
||||
#define HDMI_WP_AUDIO_DATA HDMI_WP_REG(0x8C)
|
||||
#define HDMI_WP_REVISION 0x0
|
||||
#define HDMI_WP_SYSCONFIG 0x10
|
||||
#define HDMI_WP_IRQSTATUS_RAW 0x24
|
||||
#define HDMI_WP_IRQSTATUS 0x28
|
||||
#define HDMI_WP_PWR_CTRL 0x40
|
||||
#define HDMI_WP_IRQENABLE_SET 0x2C
|
||||
#define HDMI_WP_VIDEO_CFG 0x50
|
||||
#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_AUDIO_CFG 0x80
|
||||
#define HDMI_WP_AUDIO_CFG2 0x84
|
||||
#define HDMI_WP_AUDIO_CTRL 0x88
|
||||
#define HDMI_WP_AUDIO_DATA 0x8C
|
||||
|
||||
/* HDMI IP Core System */
|
||||
#define HDMI_CORE_SYS_REG(idx) HDMI_REG(HDMI_CORE_SYS + idx)
|
||||
|
||||
#define HDMI_CORE_SYS_VND_IDL HDMI_CORE_SYS_REG(0x0)
|
||||
#define HDMI_CORE_SYS_DEV_IDL HDMI_CORE_SYS_REG(0x8)
|
||||
#define HDMI_CORE_SYS_DEV_IDH HDMI_CORE_SYS_REG(0xC)
|
||||
#define HDMI_CORE_SYS_DEV_REV HDMI_CORE_SYS_REG(0x10)
|
||||
#define HDMI_CORE_SYS_SRST HDMI_CORE_SYS_REG(0x14)
|
||||
#define HDMI_CORE_CTRL1 HDMI_CORE_SYS_REG(0x20)
|
||||
#define HDMI_CORE_SYS_SYS_STAT HDMI_CORE_SYS_REG(0x24)
|
||||
#define HDMI_CORE_SYS_VID_ACEN HDMI_CORE_SYS_REG(0x124)
|
||||
#define HDMI_CORE_SYS_VID_MODE HDMI_CORE_SYS_REG(0x128)
|
||||
#define HDMI_CORE_SYS_INTR_STATE HDMI_CORE_SYS_REG(0x1C0)
|
||||
#define HDMI_CORE_SYS_INTR1 HDMI_CORE_SYS_REG(0x1C4)
|
||||
#define HDMI_CORE_SYS_INTR2 HDMI_CORE_SYS_REG(0x1C8)
|
||||
#define HDMI_CORE_SYS_INTR3 HDMI_CORE_SYS_REG(0x1CC)
|
||||
#define HDMI_CORE_SYS_INTR4 HDMI_CORE_SYS_REG(0x1D0)
|
||||
#define HDMI_CORE_SYS_UMASK1 HDMI_CORE_SYS_REG(0x1D4)
|
||||
#define HDMI_CORE_SYS_TMDS_CTRL HDMI_CORE_SYS_REG(0x208)
|
||||
#define HDMI_CORE_SYS_DE_DLY HDMI_CORE_SYS_REG(0xC8)
|
||||
#define HDMI_CORE_SYS_DE_CTRL HDMI_CORE_SYS_REG(0xCC)
|
||||
#define HDMI_CORE_SYS_DE_TOP HDMI_CORE_SYS_REG(0xD0)
|
||||
#define HDMI_CORE_SYS_DE_CNTL HDMI_CORE_SYS_REG(0xD8)
|
||||
#define HDMI_CORE_SYS_DE_CNTH HDMI_CORE_SYS_REG(0xDC)
|
||||
#define HDMI_CORE_SYS_DE_LINL HDMI_CORE_SYS_REG(0xE0)
|
||||
#define HDMI_CORE_SYS_DE_LINH_1 HDMI_CORE_SYS_REG(0xE4)
|
||||
#define HDMI_CORE_SYS_VND_IDL 0x0
|
||||
#define HDMI_CORE_SYS_DEV_IDL 0x8
|
||||
#define HDMI_CORE_SYS_DEV_IDH 0xC
|
||||
#define HDMI_CORE_SYS_DEV_REV 0x10
|
||||
#define HDMI_CORE_SYS_SRST 0x14
|
||||
#define HDMI_CORE_CTRL1 0x20
|
||||
#define HDMI_CORE_SYS_SYS_STAT 0x24
|
||||
#define HDMI_CORE_SYS_VID_ACEN 0x124
|
||||
#define HDMI_CORE_SYS_VID_MODE 0x128
|
||||
#define HDMI_CORE_SYS_INTR_STATE 0x1C0
|
||||
#define HDMI_CORE_SYS_INTR1 0x1C4
|
||||
#define HDMI_CORE_SYS_INTR2 0x1C8
|
||||
#define HDMI_CORE_SYS_INTR3 0x1CC
|
||||
#define HDMI_CORE_SYS_INTR4 0x1D0
|
||||
#define HDMI_CORE_SYS_UMASK1 0x1D4
|
||||
#define HDMI_CORE_SYS_TMDS_CTRL 0x208
|
||||
#define HDMI_CORE_SYS_DE_DLY 0xC8
|
||||
#define HDMI_CORE_SYS_DE_CTRL 0xCC
|
||||
#define HDMI_CORE_SYS_DE_TOP 0xD0
|
||||
#define HDMI_CORE_SYS_DE_CNTL 0xD8
|
||||
#define HDMI_CORE_SYS_DE_CNTH 0xDC
|
||||
#define HDMI_CORE_SYS_DE_LINL 0xE0
|
||||
#define HDMI_CORE_SYS_DE_LINH_1 0xE4
|
||||
#define HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC 0x1
|
||||
#define HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC 0x1
|
||||
#define HDMI_CORE_CTRL1_BSEL_24BITBUS 0x1
|
||||
#define HDMI_CORE_CTRL1_EDGE_RISINGEDGE 0x1
|
||||
|
||||
/* HDMI DDC E-DID */
|
||||
#define HDMI_CORE_DDC_CMD HDMI_CORE_SYS_REG(0x3CC)
|
||||
#define HDMI_CORE_DDC_STATUS HDMI_CORE_SYS_REG(0x3C8)
|
||||
#define HDMI_CORE_DDC_ADDR HDMI_CORE_SYS_REG(0x3B4)
|
||||
#define HDMI_CORE_DDC_OFFSET HDMI_CORE_SYS_REG(0x3BC)
|
||||
#define HDMI_CORE_DDC_COUNT1 HDMI_CORE_SYS_REG(0x3C0)
|
||||
#define HDMI_CORE_DDC_COUNT2 HDMI_CORE_SYS_REG(0x3C4)
|
||||
#define HDMI_CORE_DDC_DATA HDMI_CORE_SYS_REG(0x3D0)
|
||||
#define HDMI_CORE_DDC_SEGM HDMI_CORE_SYS_REG(0x3B8)
|
||||
#define HDMI_CORE_DDC_CMD 0x3CC
|
||||
#define HDMI_CORE_DDC_STATUS 0x3C8
|
||||
#define HDMI_CORE_DDC_ADDR 0x3B4
|
||||
#define HDMI_CORE_DDC_OFFSET 0x3BC
|
||||
#define HDMI_CORE_DDC_COUNT1 0x3C0
|
||||
#define HDMI_CORE_DDC_COUNT2 0x3C4
|
||||
#define HDMI_CORE_DDC_DATA 0x3D0
|
||||
#define HDMI_CORE_DDC_SEGM 0x3B8
|
||||
|
||||
/* HDMI IP Core Audio Video */
|
||||
#define HDMI_CORE_AV_REG(idx) HDMI_REG(HDMI_CORE_AV + idx)
|
||||
|
||||
#define HDMI_CORE_AV_HDMI_CTRL HDMI_CORE_AV_REG(0xBC)
|
||||
#define HDMI_CORE_AV_DPD HDMI_CORE_AV_REG(0xF4)
|
||||
#define HDMI_CORE_AV_PB_CTRL1 HDMI_CORE_AV_REG(0xF8)
|
||||
#define HDMI_CORE_AV_PB_CTRL2 HDMI_CORE_AV_REG(0xFC)
|
||||
#define HDMI_CORE_AV_AVI_TYPE HDMI_CORE_AV_REG(0x100)
|
||||
#define HDMI_CORE_AV_AVI_VERS HDMI_CORE_AV_REG(0x104)
|
||||
#define HDMI_CORE_AV_AVI_LEN HDMI_CORE_AV_REG(0x108)
|
||||
#define HDMI_CORE_AV_AVI_CHSUM HDMI_CORE_AV_REG(0x10C)
|
||||
#define HDMI_CORE_AV_AVI_DBYTE(n) HDMI_CORE_AV_REG(n * 4 + 0x110)
|
||||
#define HDMI_CORE_AV_AVI_DBYTE_NELEMS HDMI_CORE_AV_REG(15)
|
||||
#define HDMI_CORE_AV_SPD_DBYTE HDMI_CORE_AV_REG(0x190)
|
||||
#define HDMI_CORE_AV_SPD_DBYTE_NELEMS HDMI_CORE_AV_REG(27)
|
||||
#define HDMI_CORE_AV_AUD_DBYTE(n) HDMI_CORE_AV_REG(n * 4 + 0x210)
|
||||
#define HDMI_CORE_AV_AUD_DBYTE_NELEMS HDMI_CORE_AV_REG(10)
|
||||
#define HDMI_CORE_AV_MPEG_DBYTE HDMI_CORE_AV_REG(0x290)
|
||||
#define HDMI_CORE_AV_MPEG_DBYTE_NELEMS HDMI_CORE_AV_REG(27)
|
||||
#define HDMI_CORE_AV_GEN_DBYTE HDMI_CORE_AV_REG(0x300)
|
||||
#define HDMI_CORE_AV_GEN_DBYTE_NELEMS HDMI_CORE_AV_REG(31)
|
||||
#define HDMI_CORE_AV_GEN2_DBYTE HDMI_CORE_AV_REG(0x380)
|
||||
#define HDMI_CORE_AV_GEN2_DBYTE_NELEMS HDMI_CORE_AV_REG(31)
|
||||
#define HDMI_CORE_AV_ACR_CTRL HDMI_CORE_AV_REG(0x4)
|
||||
#define HDMI_CORE_AV_FREQ_SVAL HDMI_CORE_AV_REG(0x8)
|
||||
#define HDMI_CORE_AV_N_SVAL1 HDMI_CORE_AV_REG(0xC)
|
||||
#define HDMI_CORE_AV_N_SVAL2 HDMI_CORE_AV_REG(0x10)
|
||||
#define HDMI_CORE_AV_N_SVAL3 HDMI_CORE_AV_REG(0x14)
|
||||
#define HDMI_CORE_AV_CTS_SVAL1 HDMI_CORE_AV_REG(0x18)
|
||||
#define HDMI_CORE_AV_CTS_SVAL2 HDMI_CORE_AV_REG(0x1C)
|
||||
#define HDMI_CORE_AV_CTS_SVAL3 HDMI_CORE_AV_REG(0x20)
|
||||
#define HDMI_CORE_AV_CTS_HVAL1 HDMI_CORE_AV_REG(0x24)
|
||||
#define HDMI_CORE_AV_CTS_HVAL2 HDMI_CORE_AV_REG(0x28)
|
||||
#define HDMI_CORE_AV_CTS_HVAL3 HDMI_CORE_AV_REG(0x2C)
|
||||
#define HDMI_CORE_AV_AUD_MODE HDMI_CORE_AV_REG(0x50)
|
||||
#define HDMI_CORE_AV_SPDIF_CTRL HDMI_CORE_AV_REG(0x54)
|
||||
#define HDMI_CORE_AV_HW_SPDIF_FS HDMI_CORE_AV_REG(0x60)
|
||||
#define HDMI_CORE_AV_SWAP_I2S HDMI_CORE_AV_REG(0x64)
|
||||
#define HDMI_CORE_AV_SPDIF_ERTH HDMI_CORE_AV_REG(0x6C)
|
||||
#define HDMI_CORE_AV_I2S_IN_MAP HDMI_CORE_AV_REG(0x70)
|
||||
#define HDMI_CORE_AV_I2S_IN_CTRL HDMI_CORE_AV_REG(0x74)
|
||||
#define HDMI_CORE_AV_I2S_CHST0 HDMI_CORE_AV_REG(0x78)
|
||||
#define HDMI_CORE_AV_I2S_CHST1 HDMI_CORE_AV_REG(0x7C)
|
||||
#define HDMI_CORE_AV_I2S_CHST2 HDMI_CORE_AV_REG(0x80)
|
||||
#define HDMI_CORE_AV_I2S_CHST4 HDMI_CORE_AV_REG(0x84)
|
||||
#define HDMI_CORE_AV_I2S_CHST5 HDMI_CORE_AV_REG(0x88)
|
||||
#define HDMI_CORE_AV_ASRC HDMI_CORE_AV_REG(0x8C)
|
||||
#define HDMI_CORE_AV_I2S_IN_LEN HDMI_CORE_AV_REG(0x90)
|
||||
#define HDMI_CORE_AV_HDMI_CTRL HDMI_CORE_AV_REG(0xBC)
|
||||
#define HDMI_CORE_AV_AUDO_TXSTAT HDMI_CORE_AV_REG(0xC0)
|
||||
#define HDMI_CORE_AV_AUD_PAR_BUSCLK_1 HDMI_CORE_AV_REG(0xCC)
|
||||
#define HDMI_CORE_AV_AUD_PAR_BUSCLK_2 HDMI_CORE_AV_REG(0xD0)
|
||||
#define HDMI_CORE_AV_AUD_PAR_BUSCLK_3 HDMI_CORE_AV_REG(0xD4)
|
||||
#define HDMI_CORE_AV_TEST_TXCTRL HDMI_CORE_AV_REG(0xF0)
|
||||
#define HDMI_CORE_AV_DPD HDMI_CORE_AV_REG(0xF4)
|
||||
#define HDMI_CORE_AV_PB_CTRL1 HDMI_CORE_AV_REG(0xF8)
|
||||
#define HDMI_CORE_AV_PB_CTRL2 HDMI_CORE_AV_REG(0xFC)
|
||||
#define HDMI_CORE_AV_AVI_TYPE HDMI_CORE_AV_REG(0x100)
|
||||
#define HDMI_CORE_AV_AVI_VERS HDMI_CORE_AV_REG(0x104)
|
||||
#define HDMI_CORE_AV_AVI_LEN HDMI_CORE_AV_REG(0x108)
|
||||
#define HDMI_CORE_AV_AVI_CHSUM HDMI_CORE_AV_REG(0x10C)
|
||||
#define HDMI_CORE_AV_SPD_TYPE HDMI_CORE_AV_REG(0x180)
|
||||
#define HDMI_CORE_AV_SPD_VERS HDMI_CORE_AV_REG(0x184)
|
||||
#define HDMI_CORE_AV_SPD_LEN HDMI_CORE_AV_REG(0x188)
|
||||
#define HDMI_CORE_AV_SPD_CHSUM HDMI_CORE_AV_REG(0x18C)
|
||||
#define HDMI_CORE_AV_AUDIO_TYPE HDMI_CORE_AV_REG(0x200)
|
||||
#define HDMI_CORE_AV_AUDIO_VERS HDMI_CORE_AV_REG(0x204)
|
||||
#define HDMI_CORE_AV_AUDIO_LEN HDMI_CORE_AV_REG(0x208)
|
||||
#define HDMI_CORE_AV_AUDIO_CHSUM HDMI_CORE_AV_REG(0x20C)
|
||||
#define HDMI_CORE_AV_MPEG_TYPE HDMI_CORE_AV_REG(0x280)
|
||||
#define HDMI_CORE_AV_MPEG_VERS HDMI_CORE_AV_REG(0x284)
|
||||
#define HDMI_CORE_AV_MPEG_LEN HDMI_CORE_AV_REG(0x288)
|
||||
#define HDMI_CORE_AV_MPEG_CHSUM HDMI_CORE_AV_REG(0x28C)
|
||||
#define HDMI_CORE_AV_CP_BYTE1 HDMI_CORE_AV_REG(0x37C)
|
||||
#define HDMI_CORE_AV_CEC_ADDR_ID HDMI_CORE_AV_REG(0x3FC)
|
||||
#define HDMI_CORE_AV_HDMI_CTRL 0xBC
|
||||
#define HDMI_CORE_AV_DPD 0xF4
|
||||
#define HDMI_CORE_AV_PB_CTRL1 0xF8
|
||||
#define HDMI_CORE_AV_PB_CTRL2 0xFC
|
||||
#define HDMI_CORE_AV_AVI_TYPE 0x100
|
||||
#define HDMI_CORE_AV_AVI_VERS 0x104
|
||||
#define HDMI_CORE_AV_AVI_LEN 0x108
|
||||
#define HDMI_CORE_AV_AVI_CHSUM 0x10C
|
||||
#define HDMI_CORE_AV_AVI_DBYTE(n) (n * 4 + 0x110)
|
||||
#define HDMI_CORE_AV_AVI_DBYTE_NELEMS 15
|
||||
#define HDMI_CORE_AV_SPD_DBYTE(n) (n * 4 + 0x190)
|
||||
#define HDMI_CORE_AV_SPD_DBYTE_NELEMS 27
|
||||
#define HDMI_CORE_AV_AUD_DBYTE(n) (n * 4 + 0x210)
|
||||
#define HDMI_CORE_AV_AUD_DBYTE_NELEMS 10
|
||||
#define HDMI_CORE_AV_MPEG_DBYTE(n) (n * 4 + 0x290)
|
||||
#define HDMI_CORE_AV_MPEG_DBYTE_NELEMS 27
|
||||
#define HDMI_CORE_AV_GEN_DBYTE(n) (n * 4 + 0x300)
|
||||
#define HDMI_CORE_AV_GEN_DBYTE_NELEMS 31
|
||||
#define HDMI_CORE_AV_GEN2_DBYTE(n) (n * 4 + 0x380)
|
||||
#define HDMI_CORE_AV_GEN2_DBYTE_NELEMS 31
|
||||
#define HDMI_CORE_AV_ACR_CTRL 0x4
|
||||
#define HDMI_CORE_AV_FREQ_SVAL 0x8
|
||||
#define HDMI_CORE_AV_N_SVAL1 0xC
|
||||
#define HDMI_CORE_AV_N_SVAL2 0x10
|
||||
#define HDMI_CORE_AV_N_SVAL3 0x14
|
||||
#define HDMI_CORE_AV_CTS_SVAL1 0x18
|
||||
#define HDMI_CORE_AV_CTS_SVAL2 0x1C
|
||||
#define HDMI_CORE_AV_CTS_SVAL3 0x20
|
||||
#define HDMI_CORE_AV_CTS_HVAL1 0x24
|
||||
#define HDMI_CORE_AV_CTS_HVAL2 0x28
|
||||
#define HDMI_CORE_AV_CTS_HVAL3 0x2C
|
||||
#define HDMI_CORE_AV_AUD_MODE 0x50
|
||||
#define HDMI_CORE_AV_SPDIF_CTRL 0x54
|
||||
#define HDMI_CORE_AV_HW_SPDIF_FS 0x60
|
||||
#define HDMI_CORE_AV_SWAP_I2S 0x64
|
||||
#define HDMI_CORE_AV_SPDIF_ERTH 0x6C
|
||||
#define HDMI_CORE_AV_I2S_IN_MAP 0x70
|
||||
#define HDMI_CORE_AV_I2S_IN_CTRL 0x74
|
||||
#define HDMI_CORE_AV_I2S_CHST0 0x78
|
||||
#define HDMI_CORE_AV_I2S_CHST1 0x7C
|
||||
#define HDMI_CORE_AV_I2S_CHST2 0x80
|
||||
#define HDMI_CORE_AV_I2S_CHST4 0x84
|
||||
#define HDMI_CORE_AV_I2S_CHST5 0x88
|
||||
#define HDMI_CORE_AV_ASRC 0x8C
|
||||
#define HDMI_CORE_AV_I2S_IN_LEN 0x90
|
||||
#define HDMI_CORE_AV_HDMI_CTRL 0xBC
|
||||
#define HDMI_CORE_AV_AUDO_TXSTAT 0xC0
|
||||
#define HDMI_CORE_AV_AUD_PAR_BUSCLK_1 0xCC
|
||||
#define HDMI_CORE_AV_AUD_PAR_BUSCLK_2 0xD0
|
||||
#define HDMI_CORE_AV_AUD_PAR_BUSCLK_3 0xD4
|
||||
#define HDMI_CORE_AV_TEST_TXCTRL 0xF0
|
||||
#define HDMI_CORE_AV_DPD 0xF4
|
||||
#define HDMI_CORE_AV_PB_CTRL1 0xF8
|
||||
#define HDMI_CORE_AV_PB_CTRL2 0xFC
|
||||
#define HDMI_CORE_AV_AVI_TYPE 0x100
|
||||
#define HDMI_CORE_AV_AVI_VERS 0x104
|
||||
#define HDMI_CORE_AV_AVI_LEN 0x108
|
||||
#define HDMI_CORE_AV_AVI_CHSUM 0x10C
|
||||
#define HDMI_CORE_AV_SPD_TYPE 0x180
|
||||
#define HDMI_CORE_AV_SPD_VERS 0x184
|
||||
#define HDMI_CORE_AV_SPD_LEN 0x188
|
||||
#define HDMI_CORE_AV_SPD_CHSUM 0x18C
|
||||
#define HDMI_CORE_AV_AUDIO_TYPE 0x200
|
||||
#define HDMI_CORE_AV_AUDIO_VERS 0x204
|
||||
#define HDMI_CORE_AV_AUDIO_LEN 0x208
|
||||
#define HDMI_CORE_AV_AUDIO_CHSUM 0x20C
|
||||
#define HDMI_CORE_AV_MPEG_TYPE 0x280
|
||||
#define HDMI_CORE_AV_MPEG_VERS 0x284
|
||||
#define HDMI_CORE_AV_MPEG_LEN 0x288
|
||||
#define HDMI_CORE_AV_MPEG_CHSUM 0x28C
|
||||
#define HDMI_CORE_AV_CP_BYTE1 0x37C
|
||||
#define HDMI_CORE_AV_CEC_ADDR_ID 0x3FC
|
||||
#define HDMI_CORE_AV_SPD_DBYTE_ELSIZE 0x4
|
||||
#define HDMI_CORE_AV_GEN2_DBYTE_ELSIZE 0x4
|
||||
#define HDMI_CORE_AV_MPEG_DBYTE_ELSIZE 0x4
|
||||
#define HDMI_CORE_AV_GEN_DBYTE_ELSIZE 0x4
|
||||
|
||||
/* PLL */
|
||||
#define HDMI_PLL_REG(idx) HDMI_REG(HDMI_PLLCTRL + idx)
|
||||
|
||||
#define PLLCTRL_PLL_CONTROL HDMI_PLL_REG(0x0)
|
||||
#define PLLCTRL_PLL_STATUS HDMI_PLL_REG(0x4)
|
||||
#define PLLCTRL_PLL_GO HDMI_PLL_REG(0x8)
|
||||
#define PLLCTRL_CFG1 HDMI_PLL_REG(0xC)
|
||||
#define PLLCTRL_CFG2 HDMI_PLL_REG(0x10)
|
||||
#define PLLCTRL_CFG3 HDMI_PLL_REG(0x14)
|
||||
#define PLLCTRL_CFG4 HDMI_PLL_REG(0x20)
|
||||
#define PLLCTRL_PLL_CONTROL 0x0
|
||||
#define PLLCTRL_PLL_STATUS 0x4
|
||||
#define PLLCTRL_PLL_GO 0x8
|
||||
#define PLLCTRL_CFG1 0xC
|
||||
#define PLLCTRL_CFG2 0x10
|
||||
#define PLLCTRL_CFG3 0x14
|
||||
#define PLLCTRL_CFG4 0x20
|
||||
|
||||
/* HDMI PHY */
|
||||
#define HDMI_PHY_REG(idx) HDMI_REG(HDMI_PHY + idx)
|
||||
|
||||
#define HDMI_TXPHY_TX_CTRL HDMI_PHY_REG(0x0)
|
||||
#define HDMI_TXPHY_DIGITAL_CTRL HDMI_PHY_REG(0x4)
|
||||
#define HDMI_TXPHY_POWER_CTRL HDMI_PHY_REG(0x8)
|
||||
#define HDMI_TXPHY_PAD_CFG_CTRL HDMI_PHY_REG(0xC)
|
||||
#define HDMI_TXPHY_TX_CTRL 0x0
|
||||
#define HDMI_TXPHY_DIGITAL_CTRL 0x4
|
||||
#define HDMI_TXPHY_POWER_CTRL 0x8
|
||||
#define HDMI_TXPHY_PAD_CFG_CTRL 0xC
|
||||
|
||||
/* HDMI EDID Length */
|
||||
#define HDMI_EDID_MAX_LENGTH 256
|
||||
#define EDID_TIMING_DESCRIPTOR_SIZE 0x12
|
||||
#define EDID_DESCRIPTOR_BLOCK0_ADDRESS 0x36
|
||||
#define EDID_DESCRIPTOR_BLOCK1_ADDRESS 0x80
|
||||
#define EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR 4
|
||||
#define EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR 4
|
||||
|
||||
#define OMAP_HDMI_TIMINGS_NB 34
|
||||
|
||||
#define REG_FLD_MOD(idx, val, start, end) \
|
||||
hdmi_write_reg(idx, FLD_MOD(hdmi_read_reg(idx), val, start, end))
|
||||
#define REG_GET(idx, start, end) \
|
||||
FLD_GET(hdmi_read_reg(idx), start, end)
|
||||
|
||||
/* HDMI timing structure */
|
||||
struct hdmi_timings {
|
||||
struct omap_video_timings timings;
|
||||
int vsync_pol;
|
||||
int hsync_pol;
|
||||
};
|
||||
#define REG_FLD_MOD(base, idx, val, start, end) \
|
||||
hdmi_write_reg(base, idx, FLD_MOD(hdmi_read_reg(base, idx),\
|
||||
val, start, end))
|
||||
#define REG_GET(base, idx, start, end) \
|
||||
FLD_GET(hdmi_read_reg(base, idx), start, end)
|
||||
|
||||
enum hdmi_phy_pwr {
|
||||
HDMI_PHYPWRCMD_OFF = 0,
|
||||
|
|
@ -221,20 +196,6 @@ enum hdmi_phy_pwr {
|
|||
HDMI_PHYPWRCMD_TXON = 2
|
||||
};
|
||||
|
||||
enum hdmi_pll_pwr {
|
||||
HDMI_PLLPWRCMD_ALLOFF = 0,
|
||||
HDMI_PLLPWRCMD_PLLONLY = 1,
|
||||
HDMI_PLLPWRCMD_BOTHON_ALLCLKS = 2,
|
||||
HDMI_PLLPWRCMD_BOTHON_NOPHYCLK = 3
|
||||
};
|
||||
|
||||
enum hdmi_clk_refsel {
|
||||
HDMI_REFSEL_PCLK = 0,
|
||||
HDMI_REFSEL_REF1 = 1,
|
||||
HDMI_REFSEL_REF2 = 2,
|
||||
HDMI_REFSEL_SYSCLK = 3
|
||||
};
|
||||
|
||||
enum hdmi_core_inputbus_width {
|
||||
HDMI_INPUT_8BIT = 0,
|
||||
HDMI_INPUT_10BIT = 1,
|
||||
|
|
@ -263,11 +224,6 @@ enum hdmi_core_packet_mode {
|
|||
HDMI_PACKETMODE48BITPERPIXEL = 7
|
||||
};
|
||||
|
||||
enum hdmi_core_hdmi_dvi {
|
||||
HDMI_DVI = 0,
|
||||
HDMI_HDMI = 1
|
||||
};
|
||||
|
||||
enum hdmi_core_tclkselclkmult {
|
||||
HDMI_FPLL05IDCK = 0,
|
||||
HDMI_FPLL10IDCK = 1,
|
||||
|
|
@ -495,40 +451,40 @@ struct hdmi_core_video_config {
|
|||
* details about infoframe databytes
|
||||
*/
|
||||
struct hdmi_core_infoframe_avi {
|
||||
/* Y0, Y1 rgb,yCbCr */
|
||||
u8 db1_format;
|
||||
/* Y0, Y1 rgb,yCbCr */
|
||||
/* A0 Active information Present */
|
||||
u8 db1_active_info;
|
||||
/* A0 Active information Present */
|
||||
/* B0, B1 Bar info data valid */
|
||||
u8 db1_bar_info_dv;
|
||||
/* B0, B1 Bar info data valid */
|
||||
/* S0, S1 scan information */
|
||||
u8 db1_scan_info;
|
||||
/* S0, S1 scan information */
|
||||
/* C0, C1 colorimetry */
|
||||
u8 db2_colorimetry;
|
||||
/* C0, C1 colorimetry */
|
||||
/* M0, M1 Aspect ratio (4:3, 16:9) */
|
||||
u8 db2_aspect_ratio;
|
||||
/* M0, M1 Aspect ratio (4:3, 16:9) */
|
||||
/* R0...R3 Active format aspect ratio */
|
||||
u8 db2_active_fmt_ar;
|
||||
/* R0...R3 Active format aspect ratio */
|
||||
/* ITC IT content. */
|
||||
u8 db3_itc;
|
||||
/* ITC IT content. */
|
||||
/* EC0, EC1, EC2 Extended colorimetry */
|
||||
u8 db3_ec;
|
||||
/* EC0, EC1, EC2 Extended colorimetry */
|
||||
/* Q1, Q0 Quantization range */
|
||||
u8 db3_q_range;
|
||||
/* Q1, Q0 Quantization range */
|
||||
/* SC1, SC0 Non-uniform picture scaling */
|
||||
u8 db3_nup_scaling;
|
||||
/* SC1, SC0 Non-uniform picture scaling */
|
||||
/* VIC0..6 Video format identification */
|
||||
u8 db4_videocode;
|
||||
/* VIC0..6 Video format identification */
|
||||
/* PR0..PR3 Pixel repetition factor */
|
||||
u8 db5_pixel_repeat;
|
||||
/* PR0..PR3 Pixel repetition factor */
|
||||
/* Line number end of top bar */
|
||||
u16 db6_7_line_eoftop;
|
||||
/* Line number end of top bar */
|
||||
/* Line number start of bottom bar */
|
||||
u16 db8_9_line_sofbottom;
|
||||
/* Line number start of bottom bar */
|
||||
/* Pixel number end of left bar */
|
||||
u16 db10_11_pixel_eofleft;
|
||||
/* Pixel number end of left bar */
|
||||
/* Pixel number start of right bar */
|
||||
u16 db12_13_pixel_sofright;
|
||||
/* Pixel number start of right bar */
|
||||
};
|
||||
/*
|
||||
* Refer to section 8.2 in HDMI 1.3 specification for
|
||||
|
|
@ -568,17 +524,6 @@ struct hdmi_video_interface {
|
|||
int tm; /* Timing mode */
|
||||
};
|
||||
|
||||
struct hdmi_cm {
|
||||
int code;
|
||||
int mode;
|
||||
};
|
||||
|
||||
struct hdmi_config {
|
||||
struct hdmi_timings timings;
|
||||
u16 interlace;
|
||||
struct hdmi_cm cm;
|
||||
};
|
||||
|
||||
struct hdmi_audio_format {
|
||||
enum hdmi_stereo_channels stereo_channels;
|
||||
u8 active_chnnls_msk;
|
||||
|
|
@ -628,4 +573,21 @@ struct hdmi_core_audio_config {
|
|||
bool en_parallel_aud_input;
|
||||
bool en_spdif;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
|
||||
defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
|
||||
int hdmi_audio_trigger(struct hdmi_ip_data *ip_data,
|
||||
struct snd_pcm_substream *substream, int cmd,
|
||||
struct snd_soc_dai *dai);
|
||||
int hdmi_config_audio_acr(struct hdmi_ip_data *ip_data,
|
||||
u32 sample_freq, u32 *n, u32 *cts);
|
||||
void hdmi_core_audio_infoframe_config(struct hdmi_ip_data *ip_data,
|
||||
struct hdmi_core_infoframe_audio *info_aud);
|
||||
void hdmi_core_audio_config(struct hdmi_ip_data *ip_data,
|
||||
struct hdmi_core_audio_config *cfg);
|
||||
void hdmi_wp_audio_config_dma(struct hdmi_ip_data *ip_data,
|
||||
struct hdmi_audio_dma *aud_dma);
|
||||
void hdmi_wp_audio_config_format(struct hdmi_ip_data *ip_data,
|
||||
struct hdmi_audio_format *aud_fmt);
|
||||
#endif
|
||||
#endif
|
||||
|
|
@ -295,7 +295,6 @@ static struct {
|
|||
u32 wss_data;
|
||||
struct regulator *vdda_dac_reg;
|
||||
|
||||
struct clk *tv_clk;
|
||||
struct clk *tv_dac_clk;
|
||||
} venc;
|
||||
|
||||
|
|
@ -464,9 +463,11 @@ static void venc_power_off(struct omap_dss_device *dssdev)
|
|||
regulator_disable(venc.vdda_dac_reg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
unsigned long venc_get_pixel_clock(void)
|
||||
{
|
||||
/* VENC Pixel Clock in Mhz */
|
||||
return 13500000;
|
||||
}
|
||||
|
||||
/* driver */
|
||||
static int venc_panel_probe(struct omap_dss_device *dssdev)
|
||||
|
|
@ -732,22 +733,10 @@ static int venc_get_clocks(struct platform_device *pdev)
|
|||
{
|
||||
struct clk *clk;
|
||||
|
||||
clk = clk_get(&pdev->dev, "fck");
|
||||
if (IS_ERR(clk)) {
|
||||
DSSERR("can't get fck\n");
|
||||
return PTR_ERR(clk);
|
||||
}
|
||||
|
||||
venc.tv_clk = clk;
|
||||
|
||||
if (dss_has_feature(FEAT_VENC_REQUIRES_TV_DAC_CLK)) {
|
||||
if (cpu_is_omap34xx() || cpu_is_omap3630())
|
||||
clk = clk_get(&pdev->dev, "dss_96m_fck");
|
||||
else
|
||||
clk = clk_get(&pdev->dev, "tv_dac_clk");
|
||||
clk = clk_get(&pdev->dev, "tv_dac_clk");
|
||||
if (IS_ERR(clk)) {
|
||||
DSSERR("can't get tv_dac_clk\n");
|
||||
clk_put(venc.tv_clk);
|
||||
return PTR_ERR(clk);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -761,8 +750,6 @@ static int venc_get_clocks(struct platform_device *pdev)
|
|||
|
||||
static void venc_put_clocks(void)
|
||||
{
|
||||
if (venc.tv_clk)
|
||||
clk_put(venc.tv_clk);
|
||||
if (venc.tv_dac_clk)
|
||||
clk_put(venc.tv_dac_clk);
|
||||
}
|
||||
|
|
@ -838,7 +825,6 @@ static int venc_runtime_suspend(struct device *dev)
|
|||
{
|
||||
if (venc.tv_dac_clk)
|
||||
clk_disable(venc.tv_dac_clk);
|
||||
clk_disable(venc.tv_clk);
|
||||
|
||||
dispc_runtime_put();
|
||||
dss_runtime_put();
|
||||
|
|
@ -858,7 +844,6 @@ static int venc_runtime_resume(struct device *dev)
|
|||
if (r < 0)
|
||||
goto err_get_dispc;
|
||||
|
||||
clk_enable(venc.tv_clk);
|
||||
if (venc.tv_dac_clk)
|
||||
clk_enable(venc.tv_dac_clk);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
menuconfig FB_OMAP2
|
||||
tristate "OMAP2+ frame buffer support (EXPERIMENTAL)"
|
||||
tristate "OMAP2+ frame buffer support"
|
||||
depends on FB && OMAP2_DSS
|
||||
|
||||
select OMAP2_VRAM
|
||||
|
|
|
|||
|
|
@ -808,19 +808,15 @@ static unsigned calc_rotation_offset_vrfb(const struct fb_var_screeninfo *var,
|
|||
static void omapfb_calc_addr(const struct omapfb_info *ofbi,
|
||||
const struct fb_var_screeninfo *var,
|
||||
const struct fb_fix_screeninfo *fix,
|
||||
int rotation, u32 *paddr, void __iomem **vaddr)
|
||||
int rotation, u32 *paddr)
|
||||
{
|
||||
u32 data_start_p;
|
||||
void __iomem *data_start_v;
|
||||
int offset;
|
||||
|
||||
if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
|
||||
if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
|
||||
data_start_p = omapfb_get_region_rot_paddr(ofbi, rotation);
|
||||
data_start_v = NULL;
|
||||
} else {
|
||||
else
|
||||
data_start_p = omapfb_get_region_paddr(ofbi);
|
||||
data_start_v = omapfb_get_region_vaddr(ofbi);
|
||||
}
|
||||
|
||||
if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
|
||||
offset = calc_rotation_offset_vrfb(var, fix, rotation);
|
||||
|
|
@ -828,16 +824,14 @@ static void omapfb_calc_addr(const struct omapfb_info *ofbi,
|
|||
offset = calc_rotation_offset_dma(var, fix, rotation);
|
||||
|
||||
data_start_p += offset;
|
||||
data_start_v += offset;
|
||||
|
||||
if (offset)
|
||||
DBG("offset %d, %d = %d\n",
|
||||
var->xoffset, var->yoffset, offset);
|
||||
|
||||
DBG("paddr %x, vaddr %p\n", data_start_p, data_start_v);
|
||||
DBG("paddr %x\n", data_start_p);
|
||||
|
||||
*paddr = data_start_p;
|
||||
*vaddr = data_start_v;
|
||||
}
|
||||
|
||||
/* setup overlay according to the fb */
|
||||
|
|
@ -850,7 +844,6 @@ int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
|
|||
struct fb_fix_screeninfo *fix = &fbi->fix;
|
||||
enum omap_color_mode mode = 0;
|
||||
u32 data_start_p = 0;
|
||||
void __iomem *data_start_v = NULL;
|
||||
struct omap_overlay_info info;
|
||||
int xres, yres;
|
||||
int screen_width;
|
||||
|
|
@ -880,8 +873,7 @@ int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
|
|||
}
|
||||
|
||||
if (ofbi->region->size)
|
||||
omapfb_calc_addr(ofbi, var, fix, rotation,
|
||||
&data_start_p, &data_start_v);
|
||||
omapfb_calc_addr(ofbi, var, fix, rotation, &data_start_p);
|
||||
|
||||
r = fb_mode_to_dss_mode(var, &mode);
|
||||
if (r) {
|
||||
|
|
@ -910,7 +902,6 @@ int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
|
|||
mirror = ofbi->mirror;
|
||||
|
||||
info.paddr = data_start_p;
|
||||
info.vaddr = data_start_v;
|
||||
info.screen_width = screen_width;
|
||||
info.width = xres;
|
||||
info.height = yres;
|
||||
|
|
@ -2276,6 +2267,87 @@ static int omapfb_parse_def_modes(struct omapfb2_device *fbdev)
|
|||
return r;
|
||||
}
|
||||
|
||||
static void fb_videomode_to_omap_timings(struct fb_videomode *m,
|
||||
struct omap_video_timings *t)
|
||||
{
|
||||
t->x_res = m->xres;
|
||||
t->y_res = m->yres;
|
||||
t->pixel_clock = PICOS2KHZ(m->pixclock);
|
||||
t->hsw = m->hsync_len;
|
||||
t->hfp = m->right_margin;
|
||||
t->hbp = m->left_margin;
|
||||
t->vsw = m->vsync_len;
|
||||
t->vfp = m->lower_margin;
|
||||
t->vbp = m->upper_margin;
|
||||
}
|
||||
|
||||
static int omapfb_find_best_mode(struct omap_dss_device *display,
|
||||
struct omap_video_timings *timings)
|
||||
{
|
||||
struct fb_monspecs *specs;
|
||||
u8 *edid;
|
||||
int r, i, best_xres, best_idx, len;
|
||||
|
||||
if (!display->driver->read_edid)
|
||||
return -ENODEV;
|
||||
|
||||
len = 0x80 * 2;
|
||||
edid = kmalloc(len, GFP_KERNEL);
|
||||
|
||||
r = display->driver->read_edid(display, edid, len);
|
||||
if (r < 0)
|
||||
goto err1;
|
||||
|
||||
specs = kzalloc(sizeof(*specs), GFP_KERNEL);
|
||||
|
||||
fb_edid_to_monspecs(edid, specs);
|
||||
|
||||
if (edid[126] > 0)
|
||||
fb_edid_add_monspecs(edid + 0x80, specs);
|
||||
|
||||
best_xres = 0;
|
||||
best_idx = -1;
|
||||
|
||||
for (i = 0; i < specs->modedb_len; ++i) {
|
||||
struct fb_videomode *m;
|
||||
struct omap_video_timings t;
|
||||
|
||||
m = &specs->modedb[i];
|
||||
|
||||
if (m->pixclock == 0)
|
||||
continue;
|
||||
|
||||
/* skip repeated pixel modes */
|
||||
if (m->xres == 2880 || m->xres == 1440)
|
||||
continue;
|
||||
|
||||
fb_videomode_to_omap_timings(m, &t);
|
||||
|
||||
r = display->driver->check_timings(display, &t);
|
||||
if (r == 0 && best_xres < m->xres) {
|
||||
best_xres = m->xres;
|
||||
best_idx = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (best_xres == 0) {
|
||||
r = -ENOENT;
|
||||
goto err2;
|
||||
}
|
||||
|
||||
fb_videomode_to_omap_timings(&specs->modedb[best_idx], timings);
|
||||
|
||||
r = 0;
|
||||
|
||||
err2:
|
||||
fb_destroy_modedb(specs->modedb);
|
||||
kfree(specs);
|
||||
err1:
|
||||
kfree(edid);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int omapfb_init_display(struct omapfb2_device *fbdev,
|
||||
struct omap_dss_device *dssdev)
|
||||
{
|
||||
|
|
@ -2373,8 +2445,10 @@ static int omapfb_probe(struct platform_device *pdev)
|
|||
omap_dss_get_device(dssdev);
|
||||
|
||||
if (!dssdev->driver) {
|
||||
dev_err(&pdev->dev, "no driver for display\n");
|
||||
r = -ENODEV;
|
||||
dev_warn(&pdev->dev, "no driver for display: %s\n",
|
||||
dssdev->name);
|
||||
omap_dss_put_device(dssdev);
|
||||
continue;
|
||||
}
|
||||
|
||||
d = &fbdev->displays[fbdev->num_displays++];
|
||||
|
|
@ -2402,9 +2476,27 @@ static int omapfb_probe(struct platform_device *pdev)
|
|||
for (i = 0; i < fbdev->num_managers; i++)
|
||||
fbdev->managers[i] = omap_dss_get_overlay_manager(i);
|
||||
|
||||
/* gfx overlay should be the default one. find a display
|
||||
* connected to that, and use it as default display */
|
||||
ovl = omap_dss_get_overlay(0);
|
||||
if (ovl->manager && ovl->manager->device) {
|
||||
def_display = ovl->manager->device;
|
||||
} else {
|
||||
dev_warn(&pdev->dev, "cannot find default display\n");
|
||||
def_display = NULL;
|
||||
}
|
||||
|
||||
if (def_mode && strlen(def_mode) > 0) {
|
||||
if (omapfb_parse_def_modes(fbdev))
|
||||
dev_warn(&pdev->dev, "cannot parse default modes\n");
|
||||
} else if (def_display && def_display->driver->set_timings &&
|
||||
def_display->driver->check_timings) {
|
||||
struct omap_video_timings t;
|
||||
|
||||
r = omapfb_find_best_mode(def_display, &t);
|
||||
|
||||
if (r == 0)
|
||||
def_display->driver->set_timings(def_display, &t);
|
||||
}
|
||||
|
||||
r = omapfb_create_framebuffers(fbdev);
|
||||
|
|
@ -2421,16 +2513,6 @@ static int omapfb_probe(struct platform_device *pdev)
|
|||
|
||||
DBG("mgr->apply'ed\n");
|
||||
|
||||
/* gfx overlay should be the default one. find a display
|
||||
* connected to that, and use it as default display */
|
||||
ovl = omap_dss_get_overlay(0);
|
||||
if (ovl->manager && ovl->manager->device) {
|
||||
def_display = ovl->manager->device;
|
||||
} else {
|
||||
dev_warn(&pdev->dev, "cannot find default display\n");
|
||||
def_display = NULL;
|
||||
}
|
||||
|
||||
if (def_display) {
|
||||
r = omapfb_init_display(fbdev, def_display);
|
||||
if (r) {
|
||||
|
|
|
|||
|
|
@ -104,16 +104,14 @@ static ssize_t store_mirror(struct device *dev,
|
|||
{
|
||||
struct fb_info *fbi = dev_get_drvdata(dev);
|
||||
struct omapfb_info *ofbi = FB2OFB(fbi);
|
||||
int mirror;
|
||||
bool mirror;
|
||||
int r;
|
||||
struct fb_var_screeninfo new_var;
|
||||
|
||||
r = kstrtoint(buf, 0, &mirror);
|
||||
r = strtobool(buf, &mirror);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
mirror = !!mirror;
|
||||
|
||||
if (!lock_fb_info(fbi))
|
||||
return -ENODEV;
|
||||
|
||||
|
|
|
|||
|
|
@ -490,7 +490,7 @@ static int platinum_var_to_par(struct fb_var_screeninfo *var,
|
|||
|
||||
|
||||
/*
|
||||
* Parse user speficied options (`video=platinumfb:')
|
||||
* Parse user specified options (`video=platinumfb:')
|
||||
*/
|
||||
static int __init platinumfb_setup(char *options)
|
||||
{
|
||||
|
|
@ -683,7 +683,7 @@ static struct platform_driver platinum_driver =
|
|||
.of_match_table = platinumfb_match,
|
||||
},
|
||||
.probe = platinumfb_probe,
|
||||
.remove = platinumfb_remove,
|
||||
.remove = __devexit_p(platinumfb_remove),
|
||||
};
|
||||
|
||||
static int __init platinumfb_init(void)
|
||||
|
|
|
|||
|
|
@ -973,8 +973,8 @@ static int pm2fb_pan_display(struct fb_var_screeninfo *var,
|
|||
{
|
||||
struct pm2fb_par *p = info->par;
|
||||
u32 base;
|
||||
u32 depth = (var->bits_per_pixel + 7) & ~7;
|
||||
u32 xres = (var->xres + 31) & ~31;
|
||||
u32 depth = (info->var.bits_per_pixel + 7) & ~7;
|
||||
u32 xres = (info->var.xres + 31) & ~31;
|
||||
|
||||
depth = (depth > 32) ? 32 : depth;
|
||||
base = to3264(var->yoffset * xres + var->xoffset, depth, 1);
|
||||
|
|
@ -1773,7 +1773,7 @@ MODULE_DEVICE_TABLE(pci, pm2fb_id_table);
|
|||
|
||||
#ifndef MODULE
|
||||
/**
|
||||
* Parse user speficied options.
|
||||
* Parse user specified options.
|
||||
*
|
||||
* This is, comma-separated options following `video=pm2fb:'.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1147,9 +1147,9 @@ static int pm3fb_pan_display(struct fb_var_screeninfo *var,
|
|||
struct fb_info *info)
|
||||
{
|
||||
struct pm3_par *par = info->par;
|
||||
const u32 xres = (var->xres + 31) & ~31;
|
||||
const u32 xres = (info->var.xres + 31) & ~31;
|
||||
|
||||
par->base = pm3fb_shift_bpp(var->bits_per_pixel,
|
||||
par->base = pm3fb_shift_bpp(info->var.bits_per_pixel,
|
||||
(var->yoffset * xres)
|
||||
+ var->xoffset);
|
||||
PM3_WAIT(par, 1);
|
||||
|
|
@ -1525,7 +1525,7 @@ static int __init pm3fb_setup(char *options)
|
|||
{
|
||||
char *this_opt;
|
||||
|
||||
/* Parse user speficied options (`video=pm3fb:') */
|
||||
/* Parse user specified options (`video=pm3fb:') */
|
||||
if (!options || !*options)
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -1082,7 +1082,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
|
|||
}
|
||||
|
||||
retval = request_irq(ps3fb.irq_no, ps3fb_vsync_interrupt,
|
||||
IRQF_DISABLED, DEVICE_NAME, &dev->core);
|
||||
0, DEVICE_NAME, &dev->core);
|
||||
if (retval) {
|
||||
dev_err(&dev->core, "%s: request_irq failed %d\n", __func__,
|
||||
retval);
|
||||
|
|
|
|||
|
|
@ -31,8 +31,6 @@
|
|||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/miscdevice.h>
|
||||
|
|
@ -678,7 +676,7 @@ pxa3xx_gcu_probe(struct platform_device *dev)
|
|||
}
|
||||
|
||||
ret = request_irq(irq, pxa3xx_gcu_handle_irq,
|
||||
IRQF_DISABLED, DRV_NAME, priv);
|
||||
0, DRV_NAME, priv);
|
||||
if (ret) {
|
||||
dev_err(&dev->dev, "request_irq failed\n");
|
||||
ret = -EBUSY;
|
||||
|
|
|
|||
|
|
@ -2191,7 +2191,7 @@ static int __devinit pxafb_probe(struct platform_device *dev)
|
|||
goto failed_free_mem;
|
||||
}
|
||||
|
||||
ret = request_irq(irq, pxafb_handle_irq, IRQF_DISABLED, "LCD", fbi);
|
||||
ret = request_irq(irq, pxafb_handle_irq, 0, "LCD", fbi);
|
||||
if (ret) {
|
||||
dev_err(&dev->dev, "request_irq failed: %d\n", ret);
|
||||
ret = -EBUSY;
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ struct s3c_fb;
|
|||
* @palette: Address of palette memory, or 0 if none.
|
||||
* @has_prtcon: Set if has PRTCON register.
|
||||
* @has_shadowcon: Set if has SHADOWCON register.
|
||||
* @has_clksel: Set if VIDCON0 register has CLKSEL bit.
|
||||
*/
|
||||
struct s3c_fb_variant {
|
||||
unsigned int is_2443:1;
|
||||
|
|
@ -98,6 +99,7 @@ struct s3c_fb_variant {
|
|||
|
||||
unsigned int has_prtcon:1;
|
||||
unsigned int has_shadowcon:1;
|
||||
unsigned int has_clksel:1;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -186,6 +188,7 @@ struct s3c_fb_vsync {
|
|||
* @dev: The device that we bound to, for printing, etc.
|
||||
* @regs_res: The resource we claimed for the IO registers.
|
||||
* @bus_clk: The clk (hclk) feeding our interface and possibly pixclk.
|
||||
* @lcd_clk: The clk (sclk) feeding pixclk.
|
||||
* @regs: The mapped hardware registers.
|
||||
* @variant: Variant information for this hardware.
|
||||
* @enabled: A bitmask of enabled hardware windows.
|
||||
|
|
@ -200,6 +203,7 @@ struct s3c_fb {
|
|||
struct device *dev;
|
||||
struct resource *regs_res;
|
||||
struct clk *bus_clk;
|
||||
struct clk *lcd_clk;
|
||||
void __iomem *regs;
|
||||
struct s3c_fb_variant variant;
|
||||
|
||||
|
|
@ -336,10 +340,15 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var,
|
|||
*/
|
||||
static int s3c_fb_calc_pixclk(struct s3c_fb *sfb, unsigned int pixclk)
|
||||
{
|
||||
unsigned long clk = clk_get_rate(sfb->bus_clk);
|
||||
unsigned long clk;
|
||||
unsigned long long tmp;
|
||||
unsigned int result;
|
||||
|
||||
if (sfb->variant.has_clksel)
|
||||
clk = clk_get_rate(sfb->bus_clk);
|
||||
else
|
||||
clk = clk_get_rate(sfb->lcd_clk);
|
||||
|
||||
tmp = (unsigned long long)clk;
|
||||
tmp *= pixclk;
|
||||
|
||||
|
|
@ -883,7 +892,7 @@ static int s3c_fb_pan_display(struct fb_var_screeninfo *var,
|
|||
}
|
||||
}
|
||||
/* Offset in bytes to the end of the displayed area */
|
||||
end_boff = start_boff + var->yres * info->fix.line_length;
|
||||
end_boff = start_boff + info->var.yres * info->fix.line_length;
|
||||
|
||||
/* Temporarily turn off per-vsync update from shadow registers until
|
||||
* both start and end addresses are updated to prevent corruption */
|
||||
|
|
@ -1354,13 +1363,24 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
|
|||
|
||||
clk_enable(sfb->bus_clk);
|
||||
|
||||
if (!sfb->variant.has_clksel) {
|
||||
sfb->lcd_clk = clk_get(dev, "sclk_fimd");
|
||||
if (IS_ERR(sfb->lcd_clk)) {
|
||||
dev_err(dev, "failed to get lcd clock\n");
|
||||
ret = PTR_ERR(sfb->lcd_clk);
|
||||
goto err_bus_clk;
|
||||
}
|
||||
|
||||
clk_enable(sfb->lcd_clk);
|
||||
}
|
||||
|
||||
pm_runtime_enable(sfb->dev);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
dev_err(dev, "failed to find registers\n");
|
||||
ret = -ENOENT;
|
||||
goto err_clk;
|
||||
goto err_lcd_clk;
|
||||
}
|
||||
|
||||
sfb->regs_res = request_mem_region(res->start, resource_size(res),
|
||||
|
|
@ -1368,7 +1388,7 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
|
|||
if (!sfb->regs_res) {
|
||||
dev_err(dev, "failed to claim register region\n");
|
||||
ret = -ENOENT;
|
||||
goto err_clk;
|
||||
goto err_lcd_clk;
|
||||
}
|
||||
|
||||
sfb->regs = ioremap(res->start, resource_size(res));
|
||||
|
|
@ -1450,7 +1470,13 @@ err_ioremap:
|
|||
err_req_region:
|
||||
release_mem_region(sfb->regs_res->start, resource_size(sfb->regs_res));
|
||||
|
||||
err_clk:
|
||||
err_lcd_clk:
|
||||
if (!sfb->variant.has_clksel) {
|
||||
clk_disable(sfb->lcd_clk);
|
||||
clk_put(sfb->lcd_clk);
|
||||
}
|
||||
|
||||
err_bus_clk:
|
||||
clk_disable(sfb->bus_clk);
|
||||
clk_put(sfb->bus_clk);
|
||||
|
||||
|
|
@ -1481,6 +1507,11 @@ static int __devexit s3c_fb_remove(struct platform_device *pdev)
|
|||
|
||||
iounmap(sfb->regs);
|
||||
|
||||
if (!sfb->variant.has_clksel) {
|
||||
clk_disable(sfb->lcd_clk);
|
||||
clk_put(sfb->lcd_clk);
|
||||
}
|
||||
|
||||
clk_disable(sfb->bus_clk);
|
||||
clk_put(sfb->bus_clk);
|
||||
|
||||
|
|
@ -1510,6 +1541,9 @@ static int s3c_fb_suspend(struct device *dev)
|
|||
s3c_fb_blank(FB_BLANK_POWERDOWN, win->fbinfo);
|
||||
}
|
||||
|
||||
if (!sfb->variant.has_clksel)
|
||||
clk_disable(sfb->lcd_clk);
|
||||
|
||||
clk_disable(sfb->bus_clk);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1524,6 +1558,9 @@ static int s3c_fb_resume(struct device *dev)
|
|||
|
||||
clk_enable(sfb->bus_clk);
|
||||
|
||||
if (!sfb->variant.has_clksel)
|
||||
clk_enable(sfb->lcd_clk);
|
||||
|
||||
/* setup gpio and output polarity controls */
|
||||
pd->setup_gpio();
|
||||
writel(pd->vidcon1, sfb->regs + VIDCON1);
|
||||
|
|
@ -1569,6 +1606,9 @@ static int s3c_fb_runtime_suspend(struct device *dev)
|
|||
s3c_fb_blank(FB_BLANK_POWERDOWN, win->fbinfo);
|
||||
}
|
||||
|
||||
if (!sfb->variant.has_clksel)
|
||||
clk_disable(sfb->lcd_clk);
|
||||
|
||||
clk_disable(sfb->bus_clk);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1583,6 +1623,9 @@ static int s3c_fb_runtime_resume(struct device *dev)
|
|||
|
||||
clk_enable(sfb->bus_clk);
|
||||
|
||||
if (!sfb->variant.has_clksel)
|
||||
clk_enable(sfb->lcd_clk);
|
||||
|
||||
/* setup gpio and output polarity controls */
|
||||
pd->setup_gpio();
|
||||
writel(pd->vidcon1, sfb->regs + VIDCON1);
|
||||
|
|
@ -1755,6 +1798,7 @@ static struct s3c_fb_driverdata s3c_fb_data_64xx = {
|
|||
},
|
||||
|
||||
.has_prtcon = 1,
|
||||
.has_clksel = 1,
|
||||
},
|
||||
.win[0] = &s3c_fb_data_64xx_wins[0],
|
||||
.win[1] = &s3c_fb_data_64xx_wins[1],
|
||||
|
|
@ -1785,6 +1829,7 @@ static struct s3c_fb_driverdata s3c_fb_data_s5pc100 = {
|
|||
},
|
||||
|
||||
.has_prtcon = 1,
|
||||
.has_clksel = 1,
|
||||
},
|
||||
.win[0] = &s3c_fb_data_s5p_wins[0],
|
||||
.win[1] = &s3c_fb_data_s5p_wins[1],
|
||||
|
|
@ -1794,6 +1839,37 @@ static struct s3c_fb_driverdata s3c_fb_data_s5pc100 = {
|
|||
};
|
||||
|
||||
static struct s3c_fb_driverdata s3c_fb_data_s5pv210 = {
|
||||
.variant = {
|
||||
.nr_windows = 5,
|
||||
.vidtcon = VIDTCON0,
|
||||
.wincon = WINCON(0),
|
||||
.winmap = WINxMAP(0),
|
||||
.keycon = WKEYCON,
|
||||
.osd = VIDOSD_BASE,
|
||||
.osd_stride = 16,
|
||||
.buf_start = VIDW_BUF_START(0),
|
||||
.buf_size = VIDW_BUF_SIZE(0),
|
||||
.buf_end = VIDW_BUF_END(0),
|
||||
|
||||
.palette = {
|
||||
[0] = 0x2400,
|
||||
[1] = 0x2800,
|
||||
[2] = 0x2c00,
|
||||
[3] = 0x3000,
|
||||
[4] = 0x3400,
|
||||
},
|
||||
|
||||
.has_shadowcon = 1,
|
||||
.has_clksel = 1,
|
||||
},
|
||||
.win[0] = &s3c_fb_data_s5p_wins[0],
|
||||
.win[1] = &s3c_fb_data_s5p_wins[1],
|
||||
.win[2] = &s3c_fb_data_s5p_wins[2],
|
||||
.win[3] = &s3c_fb_data_s5p_wins[3],
|
||||
.win[4] = &s3c_fb_data_s5p_wins[4],
|
||||
};
|
||||
|
||||
static struct s3c_fb_driverdata s3c_fb_data_exynos4 = {
|
||||
.variant = {
|
||||
.nr_windows = 5,
|
||||
.vidtcon = VIDTCON0,
|
||||
|
|
@ -1843,6 +1919,7 @@ static struct s3c_fb_driverdata s3c_fb_data_s3c2443 = {
|
|||
[0] = 0x400,
|
||||
[1] = 0x800,
|
||||
},
|
||||
.has_clksel = 1,
|
||||
},
|
||||
.win[0] = &(struct s3c_fb_win_variant) {
|
||||
.palette_sz = 256,
|
||||
|
|
@ -1859,6 +1936,30 @@ static struct s3c_fb_driverdata s3c_fb_data_s3c2443 = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct s3c_fb_driverdata s3c_fb_data_s5p64x0 = {
|
||||
.variant = {
|
||||
.nr_windows = 3,
|
||||
.vidtcon = VIDTCON0,
|
||||
.wincon = WINCON(0),
|
||||
.winmap = WINxMAP(0),
|
||||
.keycon = WKEYCON,
|
||||
.osd = VIDOSD_BASE,
|
||||
.osd_stride = 16,
|
||||
.buf_start = VIDW_BUF_START(0),
|
||||
.buf_size = VIDW_BUF_SIZE(0),
|
||||
.buf_end = VIDW_BUF_END(0),
|
||||
|
||||
.palette = {
|
||||
[0] = 0x2400,
|
||||
[1] = 0x2800,
|
||||
[2] = 0x2c00,
|
||||
},
|
||||
},
|
||||
.win[0] = &s3c_fb_data_s5p_wins[0],
|
||||
.win[1] = &s3c_fb_data_s5p_wins[1],
|
||||
.win[2] = &s3c_fb_data_s5p_wins[2],
|
||||
};
|
||||
|
||||
static struct platform_device_id s3c_fb_driver_ids[] = {
|
||||
{
|
||||
.name = "s3c-fb",
|
||||
|
|
@ -1869,9 +1970,15 @@ static struct platform_device_id s3c_fb_driver_ids[] = {
|
|||
}, {
|
||||
.name = "s5pv210-fb",
|
||||
.driver_data = (unsigned long)&s3c_fb_data_s5pv210,
|
||||
}, {
|
||||
.name = "exynos4-fb",
|
||||
.driver_data = (unsigned long)&s3c_fb_data_exynos4,
|
||||
}, {
|
||||
.name = "s3c2443-fb",
|
||||
.driver_data = (unsigned long)&s3c_fb_data_s3c2443,
|
||||
}, {
|
||||
.name = "s5p64x0-fb",
|
||||
.driver_data = (unsigned long)&s3c_fb_data_s5p64x0,
|
||||
},
|
||||
{},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -767,7 +767,6 @@ static irqreturn_t s3c2410fb_irq(int irq, void *dev_id)
|
|||
static int s3c2410fb_cpufreq_transition(struct notifier_block *nb,
|
||||
unsigned long val, void *data)
|
||||
{
|
||||
struct cpufreq_freqs *freqs = data;
|
||||
struct s3c2410fb_info *info;
|
||||
struct fb_info *fbinfo;
|
||||
long delta_f;
|
||||
|
|
@ -911,7 +910,7 @@ static int __devinit s3c24xxfb_probe(struct platform_device *pdev,
|
|||
for (i = 0; i < 256; i++)
|
||||
info->palette_buffer[i] = PALETTE_BUFF_CLEAR;
|
||||
|
||||
ret = request_irq(irq, s3c2410fb_irq, IRQF_DISABLED, pdev->name, info);
|
||||
ret = request_irq(irq, s3c2410fb_irq, 0, pdev->name, info);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "cannot get irq %d - err %d\n", irq, ret);
|
||||
ret = -EBUSY;
|
||||
|
|
|
|||
|
|
@ -1019,12 +1019,13 @@ static int s3fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
|
|||
unsigned int offset;
|
||||
|
||||
/* Calculate the offset */
|
||||
if (var->bits_per_pixel == 0) {
|
||||
offset = (var->yoffset / 16) * (var->xres_virtual / 2) + (var->xoffset / 2);
|
||||
if (info->var.bits_per_pixel == 0) {
|
||||
offset = (var->yoffset / 16) * (info->var.xres_virtual / 2)
|
||||
+ (var->xoffset / 2);
|
||||
offset = offset >> 2;
|
||||
} else {
|
||||
offset = (var->yoffset * info->fix.line_length) +
|
||||
(var->xoffset * var->bits_per_pixel / 8);
|
||||
(var->xoffset * info->var.bits_per_pixel / 8);
|
||||
offset = offset >> 2;
|
||||
}
|
||||
|
||||
|
|
@ -1504,7 +1505,7 @@ static struct pci_driver s3fb_pci_driver = {
|
|||
.resume = s3_pci_resume,
|
||||
};
|
||||
|
||||
/* Parse user speficied options */
|
||||
/* Parse user specified options */
|
||||
|
||||
#ifndef MODULE
|
||||
static int __init s3fb_setup(char *options)
|
||||
|
|
|
|||
|
|
@ -1457,8 +1457,7 @@ static int __devinit sa1100fb_probe(struct platform_device *pdev)
|
|||
if (ret)
|
||||
goto failed;
|
||||
|
||||
ret = request_irq(irq, sa1100fb_handle_irq, IRQF_DISABLED,
|
||||
"LCD", fbi);
|
||||
ret = request_irq(irq, sa1100fb_handle_irq, 0, "LCD", fbi);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "sa1100fb: request_irq failed: %d\n", ret);
|
||||
goto failed;
|
||||
|
|
|
|||
|
|
@ -1477,15 +1477,9 @@ static void savagefb_set_par_int(struct savagefb_par *par, struct savage_reg *r
|
|||
vgaHWProtect(par, 0);
|
||||
}
|
||||
|
||||
static void savagefb_update_start(struct savagefb_par *par,
|
||||
struct fb_var_screeninfo *var)
|
||||
static void savagefb_update_start(struct savagefb_par *par, int base)
|
||||
{
|
||||
int base;
|
||||
|
||||
base = ((var->yoffset * var->xres_virtual + (var->xoffset & ~1))
|
||||
* ((var->bits_per_pixel+7) / 8)) >> 2;
|
||||
|
||||
/* now program the start address registers */
|
||||
/* program the start address registers */
|
||||
vga_out16(0x3d4, (base & 0x00ff00) | 0x0c, par);
|
||||
vga_out16(0x3d4, ((base & 0x00ff) << 8) | 0x0d, par);
|
||||
vga_out8(0x3d4, 0x69, par);
|
||||
|
|
@ -1550,8 +1544,12 @@ static int savagefb_pan_display(struct fb_var_screeninfo *var,
|
|||
struct fb_info *info)
|
||||
{
|
||||
struct savagefb_par *par = info->par;
|
||||
int base;
|
||||
|
||||
savagefb_update_start(par, var);
|
||||
base = (var->yoffset * info->fix.line_length
|
||||
+ (var->xoffset & ~1) * ((info->var.bits_per_pixel+7) / 8)) >> 2;
|
||||
|
||||
savagefb_update_start(par, base);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1111,6 +1111,7 @@ static long sh_hdmi_clk_configure(struct sh_hdmi *hdmi, unsigned long hdmi_rate,
|
|||
static void sh_hdmi_edid_work_fn(struct work_struct *work)
|
||||
{
|
||||
struct sh_hdmi *hdmi = container_of(work, struct sh_hdmi, edid_work.work);
|
||||
struct fb_info *info;
|
||||
struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
|
||||
struct sh_mobile_lcdc_chan *ch;
|
||||
int ret;
|
||||
|
|
@ -1123,8 +1124,9 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work)
|
|||
|
||||
mutex_lock(&hdmi->mutex);
|
||||
|
||||
info = hdmi->info;
|
||||
|
||||
if (hdmi->hp_state == HDMI_HOTPLUG_CONNECTED) {
|
||||
struct fb_info *info = hdmi->info;
|
||||
unsigned long parent_rate = 0, hdmi_rate;
|
||||
|
||||
ret = sh_hdmi_read_edid(hdmi, &hdmi_rate, &parent_rate);
|
||||
|
|
@ -1148,42 +1150,45 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work)
|
|||
|
||||
ch = info->par;
|
||||
|
||||
console_lock();
|
||||
if (lock_fb_info(info)) {
|
||||
console_lock();
|
||||
|
||||
/* HDMI plug in */
|
||||
if (!sh_hdmi_must_reconfigure(hdmi) &&
|
||||
info->state == FBINFO_STATE_RUNNING) {
|
||||
/*
|
||||
* First activation with the default monitor - just turn
|
||||
* on, if we run a resume here, the logo disappears
|
||||
*/
|
||||
if (lock_fb_info(info)) {
|
||||
/* HDMI plug in */
|
||||
if (!sh_hdmi_must_reconfigure(hdmi) &&
|
||||
info->state == FBINFO_STATE_RUNNING) {
|
||||
/*
|
||||
* First activation with the default monitor - just turn
|
||||
* on, if we run a resume here, the logo disappears
|
||||
*/
|
||||
info->var.width = hdmi->var.width;
|
||||
info->var.height = hdmi->var.height;
|
||||
sh_hdmi_display_on(hdmi, info);
|
||||
unlock_fb_info(info);
|
||||
} else {
|
||||
/* New monitor or have to wake up */
|
||||
fb_set_suspend(info, 0);
|
||||
}
|
||||
} else {
|
||||
/* New monitor or have to wake up */
|
||||
fb_set_suspend(info, 0);
|
||||
}
|
||||
|
||||
console_unlock();
|
||||
console_unlock();
|
||||
unlock_fb_info(info);
|
||||
}
|
||||
} else {
|
||||
ret = 0;
|
||||
if (!hdmi->info)
|
||||
if (!info)
|
||||
goto out;
|
||||
|
||||
hdmi->monspec.modedb_len = 0;
|
||||
fb_destroy_modedb(hdmi->monspec.modedb);
|
||||
hdmi->monspec.modedb = NULL;
|
||||
|
||||
console_lock();
|
||||
if (lock_fb_info(info)) {
|
||||
console_lock();
|
||||
|
||||
/* HDMI disconnect */
|
||||
fb_set_suspend(hdmi->info, 1);
|
||||
/* HDMI disconnect */
|
||||
fb_set_suspend(info, 1);
|
||||
|
||||
console_unlock();
|
||||
console_unlock();
|
||||
unlock_fb_info(info);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -18,6 +18,13 @@ struct sh_mobile_lcdc_priv;
|
|||
struct fb_info;
|
||||
struct backlight_device;
|
||||
|
||||
/*
|
||||
* struct sh_mobile_lcdc_chan - LCDC display channel
|
||||
*
|
||||
* @base_addr_y: Frame buffer viewport base address (luma component)
|
||||
* @base_addr_c: Frame buffer viewport base address (chroma component)
|
||||
* @pitch: Frame buffer line pitch
|
||||
*/
|
||||
struct sh_mobile_lcdc_chan {
|
||||
struct sh_mobile_lcdc_priv *lcdc;
|
||||
unsigned long *reg_offs;
|
||||
|
|
@ -25,7 +32,6 @@ struct sh_mobile_lcdc_chan {
|
|||
unsigned long enabled; /* ME and SE in LDCNT2R */
|
||||
struct sh_mobile_lcdc_chan_cfg cfg;
|
||||
u32 pseudo_palette[PALETTE_NR];
|
||||
unsigned long saved_ch_regs[NR_CH_REGS];
|
||||
struct fb_info *info;
|
||||
struct backlight_device *bl;
|
||||
dma_addr_t dma_handle;
|
||||
|
|
@ -40,6 +46,10 @@ struct sh_mobile_lcdc_chan {
|
|||
int blank_status;
|
||||
struct mutex open_lock; /* protects the use counter */
|
||||
int meram_enabled;
|
||||
|
||||
unsigned long base_addr_y;
|
||||
unsigned long base_addr_c;
|
||||
unsigned int pitch;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -12,29 +12,103 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "sh_mobile_meram.h"
|
||||
#include <video/sh_mobile_meram.h>
|
||||
|
||||
/* meram registers */
|
||||
#define MExxCTL 0x0
|
||||
#define MExxBSIZE 0x4
|
||||
#define MExxMNCF 0x8
|
||||
#define MExxSARA 0x10
|
||||
#define MExxSARB 0x14
|
||||
#define MExxSBSIZE 0x18
|
||||
#define MEVCR1 0x4
|
||||
#define MEVCR1_RST (1 << 31)
|
||||
#define MEVCR1_WD (1 << 30)
|
||||
#define MEVCR1_AMD1 (1 << 29)
|
||||
#define MEVCR1_AMD0 (1 << 28)
|
||||
#define MEQSEL1 0x40
|
||||
#define MEQSEL2 0x44
|
||||
|
||||
#define MERAM_MExxCTL_VAL(ctl, next_icb, addr) \
|
||||
((ctl) | (((next_icb) & 0x1f) << 11) | (((addr) & 0x7ff) << 16))
|
||||
#define MERAM_MExxBSIZE_VAL(a, b, c) \
|
||||
(((a) << 28) | ((b) << 16) | (c))
|
||||
#define MExxCTL 0x400
|
||||
#define MExxCTL_BV (1 << 31)
|
||||
#define MExxCTL_BSZ_SHIFT 28
|
||||
#define MExxCTL_MSAR_MASK (0x7ff << MExxCTL_MSAR_SHIFT)
|
||||
#define MExxCTL_MSAR_SHIFT 16
|
||||
#define MExxCTL_NXT_MASK (0x1f << MExxCTL_NXT_SHIFT)
|
||||
#define MExxCTL_NXT_SHIFT 11
|
||||
#define MExxCTL_WD1 (1 << 10)
|
||||
#define MExxCTL_WD0 (1 << 9)
|
||||
#define MExxCTL_WS (1 << 8)
|
||||
#define MExxCTL_CB (1 << 7)
|
||||
#define MExxCTL_WBF (1 << 6)
|
||||
#define MExxCTL_WF (1 << 5)
|
||||
#define MExxCTL_RF (1 << 4)
|
||||
#define MExxCTL_CM (1 << 3)
|
||||
#define MExxCTL_MD_READ (1 << 0)
|
||||
#define MExxCTL_MD_WRITE (2 << 0)
|
||||
#define MExxCTL_MD_ICB_WB (3 << 0)
|
||||
#define MExxCTL_MD_ICB (4 << 0)
|
||||
#define MExxCTL_MD_FB (7 << 0)
|
||||
#define MExxCTL_MD_MASK (7 << 0)
|
||||
#define MExxBSIZE 0x404
|
||||
#define MExxBSIZE_RCNT_SHIFT 28
|
||||
#define MExxBSIZE_YSZM1_SHIFT 16
|
||||
#define MExxBSIZE_XSZM1_SHIFT 0
|
||||
#define MExxMNCF 0x408
|
||||
#define MExxMNCF_KWBNM_SHIFT 28
|
||||
#define MExxMNCF_KRBNM_SHIFT 24
|
||||
#define MExxMNCF_BNM_SHIFT 16
|
||||
#define MExxMNCF_XBV (1 << 15)
|
||||
#define MExxMNCF_CPL_YCBCR444 (1 << 12)
|
||||
#define MExxMNCF_CPL_YCBCR420 (2 << 12)
|
||||
#define MExxMNCF_CPL_YCBCR422 (3 << 12)
|
||||
#define MExxMNCF_CPL_MSK (3 << 12)
|
||||
#define MExxMNCF_BL (1 << 2)
|
||||
#define MExxMNCF_LNM_SHIFT 0
|
||||
#define MExxSARA 0x410
|
||||
#define MExxSARB 0x414
|
||||
#define MExxSBSIZE 0x418
|
||||
#define MExxSBSIZE_HDV (1 << 31)
|
||||
#define MExxSBSIZE_HSZ16 (0 << 28)
|
||||
#define MExxSBSIZE_HSZ32 (1 << 28)
|
||||
#define MExxSBSIZE_HSZ64 (2 << 28)
|
||||
#define MExxSBSIZE_HSZ128 (3 << 28)
|
||||
#define MExxSBSIZE_SBSIZZ_SHIFT 0
|
||||
|
||||
#define MEVCR1 0x4
|
||||
#define MEACTS 0x10
|
||||
#define MEQSEL1 0x40
|
||||
#define MEQSEL2 0x44
|
||||
#define MERAM_MExxCTL_VAL(next, addr) \
|
||||
((((next) << MExxCTL_NXT_SHIFT) & MExxCTL_NXT_MASK) | \
|
||||
(((addr) << MExxCTL_MSAR_SHIFT) & MExxCTL_MSAR_MASK))
|
||||
#define MERAM_MExxBSIZE_VAL(rcnt, yszm1, xszm1) \
|
||||
(((rcnt) << MExxBSIZE_RCNT_SHIFT) | \
|
||||
((yszm1) << MExxBSIZE_YSZM1_SHIFT) | \
|
||||
((xszm1) << MExxBSIZE_XSZM1_SHIFT))
|
||||
|
||||
#define SH_MOBILE_MERAM_ICB_NUM 32
|
||||
|
||||
static unsigned long common_regs[] = {
|
||||
MEVCR1,
|
||||
MEQSEL1,
|
||||
MEQSEL2,
|
||||
};
|
||||
#define CMN_REGS_SIZE ARRAY_SIZE(common_regs)
|
||||
|
||||
static unsigned long icb_regs[] = {
|
||||
MExxCTL,
|
||||
MExxBSIZE,
|
||||
MExxMNCF,
|
||||
MExxSARA,
|
||||
MExxSARB,
|
||||
MExxSBSIZE,
|
||||
};
|
||||
#define ICB_REGS_SIZE ARRAY_SIZE(icb_regs)
|
||||
|
||||
struct sh_mobile_meram_priv {
|
||||
void __iomem *base;
|
||||
struct mutex lock;
|
||||
unsigned long used_icb;
|
||||
int used_meram_cache_regions;
|
||||
unsigned long used_meram_cache[SH_MOBILE_MERAM_ICB_NUM];
|
||||
unsigned long cmn_saved_regs[CMN_REGS_SIZE];
|
||||
unsigned long icb_saved_regs[ICB_REGS_SIZE * SH_MOBILE_MERAM_ICB_NUM];
|
||||
};
|
||||
|
||||
/* settings */
|
||||
#define MERAM_SEC_LINE 15
|
||||
|
|
@ -44,8 +118,7 @@
|
|||
* MERAM/ICB access functions
|
||||
*/
|
||||
|
||||
#define MERAM_ICB_OFFSET(base, idx, off) \
|
||||
((base) + (0x400 + ((idx) * 0x20) + (off)))
|
||||
#define MERAM_ICB_OFFSET(base, idx, off) ((base) + (off) + (idx) * 0x20)
|
||||
|
||||
static inline void meram_write_icb(void __iomem *base, int idx, int off,
|
||||
unsigned long val)
|
||||
|
|
@ -280,17 +353,18 @@ static int meram_init(struct sh_mobile_meram_priv *priv,
|
|||
/*
|
||||
* Set MERAM for framebuffer
|
||||
*
|
||||
* 0x70f: WD = 0x3, WS=0x1, CM=0x1, MD=FB mode
|
||||
* we also chain the cache_icb and the marker_icb.
|
||||
* we also split the allocated MERAM buffer between two ICBs.
|
||||
*/
|
||||
meram_write_icb(priv->base, icb->cache_icb, MExxCTL,
|
||||
MERAM_MExxCTL_VAL(0x70f, icb->marker_icb,
|
||||
icb->meram_offset));
|
||||
MERAM_MExxCTL_VAL(icb->marker_icb, icb->meram_offset) |
|
||||
MExxCTL_WD1 | MExxCTL_WD0 | MExxCTL_WS | MExxCTL_CM |
|
||||
MExxCTL_MD_FB);
|
||||
meram_write_icb(priv->base, icb->marker_icb, MExxCTL,
|
||||
MERAM_MExxCTL_VAL(0x70f, icb->cache_icb,
|
||||
icb->meram_offset +
|
||||
icb->meram_size / 2));
|
||||
MERAM_MExxCTL_VAL(icb->cache_icb, icb->meram_offset +
|
||||
icb->meram_size / 2) |
|
||||
MExxCTL_WD1 | MExxCTL_WD0 | MExxCTL_WS | MExxCTL_CM |
|
||||
MExxCTL_MD_FB);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -299,8 +373,10 @@ static void meram_deinit(struct sh_mobile_meram_priv *priv,
|
|||
struct sh_mobile_meram_icb *icb)
|
||||
{
|
||||
/* disable ICB */
|
||||
meram_write_icb(priv->base, icb->cache_icb, MExxCTL, 0);
|
||||
meram_write_icb(priv->base, icb->marker_icb, MExxCTL, 0);
|
||||
meram_write_icb(priv->base, icb->cache_icb, MExxCTL,
|
||||
MExxCTL_WBF | MExxCTL_WF | MExxCTL_RF);
|
||||
meram_write_icb(priv->base, icb->marker_icb, MExxCTL,
|
||||
MExxCTL_WBF | MExxCTL_WF | MExxCTL_RF);
|
||||
icb->cache_unit = 0;
|
||||
}
|
||||
|
||||
|
|
@ -337,24 +413,22 @@ static int sh_mobile_meram_register(struct sh_mobile_meram_info *pdata,
|
|||
xres, yres, (!pixelformat) ? "yuv" : "rgb",
|
||||
base_addr_y, base_addr_c);
|
||||
|
||||
mutex_lock(&priv->lock);
|
||||
|
||||
/* we can't handle wider than 8192px */
|
||||
if (xres > 8192) {
|
||||
dev_err(&pdev->dev, "width exceeding the limit (> 8192).");
|
||||
error = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (priv->used_meram_cache_regions + 2 > SH_MOBILE_MERAM_ICB_NUM) {
|
||||
dev_err(&pdev->dev, "no more ICB available.");
|
||||
error = -EINVAL;
|
||||
goto err;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* do we have at least one ICB config? */
|
||||
if (cfg->icb[0].marker_icb < 0 || cfg->icb[0].cache_icb < 0) {
|
||||
dev_err(&pdev->dev, "at least one ICB is required.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&priv->lock);
|
||||
|
||||
if (priv->used_meram_cache_regions + 2 > SH_MOBILE_MERAM_ICB_NUM) {
|
||||
dev_err(&pdev->dev, "no more ICB available.");
|
||||
error = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
|
@ -460,6 +534,57 @@ static int sh_mobile_meram_update(struct sh_mobile_meram_info *pdata,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int sh_mobile_meram_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct sh_mobile_meram_priv *priv = platform_get_drvdata(pdev);
|
||||
int k, j;
|
||||
|
||||
for (k = 0; k < CMN_REGS_SIZE; k++)
|
||||
priv->cmn_saved_regs[k] = meram_read_reg(priv->base,
|
||||
common_regs[k]);
|
||||
|
||||
for (j = 0; j < 32; j++) {
|
||||
if (!test_bit(j, &priv->used_icb))
|
||||
continue;
|
||||
for (k = 0; k < ICB_REGS_SIZE; k++) {
|
||||
priv->icb_saved_regs[j * ICB_REGS_SIZE + k] =
|
||||
meram_read_icb(priv->base, j, icb_regs[k]);
|
||||
/* Reset ICB on resume */
|
||||
if (icb_regs[k] == MExxCTL)
|
||||
priv->icb_saved_regs[j * ICB_REGS_SIZE + k] |=
|
||||
MExxCTL_WBF | MExxCTL_WF | MExxCTL_RF;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sh_mobile_meram_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct sh_mobile_meram_priv *priv = platform_get_drvdata(pdev);
|
||||
int k, j;
|
||||
|
||||
for (j = 0; j < 32; j++) {
|
||||
if (!test_bit(j, &priv->used_icb))
|
||||
continue;
|
||||
for (k = 0; k < ICB_REGS_SIZE; k++) {
|
||||
meram_write_icb(priv->base, j, icb_regs[k],
|
||||
priv->icb_saved_regs[j * ICB_REGS_SIZE + k]);
|
||||
}
|
||||
}
|
||||
|
||||
for (k = 0; k < CMN_REGS_SIZE; k++)
|
||||
meram_write_reg(priv->base, common_regs[k],
|
||||
priv->cmn_saved_regs[k]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops sh_mobile_meram_dev_pm_ops = {
|
||||
.runtime_suspend = sh_mobile_meram_runtime_suspend,
|
||||
.runtime_resume = sh_mobile_meram_runtime_resume,
|
||||
};
|
||||
|
||||
static struct sh_mobile_meram_ops sh_mobile_meram_ops = {
|
||||
.module = THIS_MODULE,
|
||||
.meram_register = sh_mobile_meram_register,
|
||||
|
|
@ -513,7 +638,9 @@ static int __devinit sh_mobile_meram_probe(struct platform_device *pdev)
|
|||
|
||||
/* initialize ICB addressing mode */
|
||||
if (pdata->addr_mode == SH_MOBILE_MERAM_MODE1)
|
||||
meram_write_reg(priv->base, MEVCR1, 1 << 29);
|
||||
meram_write_reg(priv->base, MEVCR1, MEVCR1_AMD1);
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
dev_info(&pdev->dev, "sh_mobile_meram initialized.");
|
||||
|
||||
|
|
@ -530,6 +657,8 @@ static int sh_mobile_meram_remove(struct platform_device *pdev)
|
|||
{
|
||||
struct sh_mobile_meram_priv *priv = platform_get_drvdata(pdev);
|
||||
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
if (priv->base)
|
||||
iounmap(priv->base);
|
||||
|
||||
|
|
@ -544,6 +673,7 @@ static struct platform_driver sh_mobile_meram_driver = {
|
|||
.driver = {
|
||||
.name = "sh_mobile_meram",
|
||||
.owner = THIS_MODULE,
|
||||
.pm = &sh_mobile_meram_dev_pm_ops,
|
||||
},
|
||||
.probe = sh_mobile_meram_probe,
|
||||
.remove = sh_mobile_meram_remove,
|
||||
|
|
|
|||
|
|
@ -1,41 +0,0 @@
|
|||
#ifndef __sh_mobile_meram_h__
|
||||
#define __sh_mobile_meram_h__
|
||||
|
||||
#include <linux/mutex.h>
|
||||
#include <video/sh_mobile_meram.h>
|
||||
|
||||
/*
|
||||
* MERAM private
|
||||
*/
|
||||
|
||||
#define MERAM_ICB_Y 0x1
|
||||
#define MERAM_ICB_C 0x2
|
||||
|
||||
/* MERAM cache size */
|
||||
#define SH_MOBILE_MERAM_ICB_NUM 32
|
||||
|
||||
#define SH_MOBILE_MERAM_CACHE_OFFSET(p) ((p) >> 16)
|
||||
#define SH_MOBILE_MERAM_CACHE_SIZE(p) ((p) & 0xffff)
|
||||
|
||||
struct sh_mobile_meram_priv {
|
||||
void __iomem *base;
|
||||
struct mutex lock;
|
||||
unsigned long used_icb;
|
||||
int used_meram_cache_regions;
|
||||
unsigned long used_meram_cache[SH_MOBILE_MERAM_ICB_NUM];
|
||||
};
|
||||
|
||||
int sh_mobile_meram_alloc_icb(const struct sh_mobile_meram_cfg *cfg,
|
||||
int xres,
|
||||
int yres,
|
||||
unsigned int base_addr,
|
||||
int yuv_mode,
|
||||
int *marker_icb,
|
||||
int *out_pitch);
|
||||
|
||||
void sh_mobile_meram_free_icb(int marker_icb);
|
||||
|
||||
#define SH_MOBILE_MERAM_START(ind, ab) \
|
||||
(0xC0000000 | ((ab & 0x1) << 23) | ((ind & 0x1F) << 24))
|
||||
|
||||
#endif /* !__sh_mobile_meram_h__ */
|
||||
|
|
@ -1333,19 +1333,14 @@ sisfb_set_base_CRT2(struct sis_video_info *ivideo, unsigned int base)
|
|||
}
|
||||
|
||||
static int
|
||||
sisfb_pan_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
|
||||
sisfb_pan_var(struct sis_video_info *ivideo, struct fb_info *info,
|
||||
struct fb_var_screeninfo *var)
|
||||
{
|
||||
if(var->xoffset > (var->xres_virtual - var->xres)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
if(var->yoffset > (var->yres_virtual - var->yres)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ivideo->current_base = (var->yoffset * var->xres_virtual) + var->xoffset;
|
||||
ivideo->current_base = var->yoffset * info->var.xres_virtual
|
||||
+ var->xoffset;
|
||||
|
||||
/* calculate base bpp dep. */
|
||||
switch(var->bits_per_pixel) {
|
||||
switch (info->var.bits_per_pixel) {
|
||||
case 32:
|
||||
break;
|
||||
case 16:
|
||||
|
|
@ -1635,20 +1630,15 @@ sisfb_pan_display(struct fb_var_screeninfo *var, struct fb_info* info)
|
|||
struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
|
||||
int err;
|
||||
|
||||
if(var->xoffset > (var->xres_virtual - var->xres))
|
||||
if (var->vmode & FB_VMODE_YWRAP)
|
||||
return -EINVAL;
|
||||
|
||||
if(var->yoffset > (var->yres_virtual - var->yres))
|
||||
if (var->xoffset + info->var.xres > info->var.xres_virtual ||
|
||||
var->yoffset + info->var.yres > info->var.yres_virtual)
|
||||
return -EINVAL;
|
||||
|
||||
if(var->vmode & FB_VMODE_YWRAP)
|
||||
return -EINVAL;
|
||||
|
||||
if(var->xoffset + info->var.xres > info->var.xres_virtual ||
|
||||
var->yoffset + info->var.yres > info->var.yres_virtual)
|
||||
return -EINVAL;
|
||||
|
||||
if((err = sisfb_pan_var(ivideo, var)) < 0)
|
||||
err = sisfb_pan_var(ivideo, info, var);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
info->var.xoffset = var->xoffset;
|
||||
|
|
|
|||
|
|
@ -989,7 +989,7 @@ static struct platform_device *xxxfb_device;
|
|||
*/
|
||||
int __init xxxfb_setup(char *options)
|
||||
{
|
||||
/* Parse user speficied options (`video=xxxfb:') */
|
||||
/* Parse user specified options (`video=xxxfb:') */
|
||||
}
|
||||
#endif /* MODULE */
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue