mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 19:51:31 -04:00
fbdev changes for 3.13
Nothing particularly stands out in this pull request. The biggest part of the changes are cleanups. Maybe one fix to mention is the "fb: reorder the lock sequence to fix potential dead lock" which hopefully fixes the fb locking issues reported by multiple persons. There are also a few commits that have changes to arch/arm/mach-at91 and arch/avr32, which have been acked by the maintainers. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.14 (GNU/Linux) iQIcBAABAgAGBQJSg2oCAAoJEPo9qoy8lh71vXsP/2AjkzOlcKBPutMG/W30QMHT tkKfr/RL8C3oXcimkE6ch3ksbFj2t5corxa/DLTdESdTpeFAgxj72pcdhN3X4+Xs 7IokExM2W5s6p4pP66PTr2A5XhEyAHtEMp+2JbHPRzwZitblzBLZvuPUJljwJDpj Z9+sD00xv/MZrXDCsEN8k2xdJ3rFn6JgX267y1qajlsocZoseTF2ed94IN/YnIM7 B2hra1B4E21FPYLzRDOJRmZa0YGomLTymezPnPg33hLBhnJU/aG4HLDHKUZWhduz /6UwACH63ja7I2z/8AZHQ1ACdbGheRtHbjwV9LLYlbaAvPmUqNTZ4b6UeQOb/EZ0 3SPCYbwD6+RMhSx/j/XhySvw82RY0i1aTlTDyjgOggfrfdi4x1Wk54bUWp5l9O3D SX1vSpNLGSh4GKXRzJjf3jouG/LcOzlpDlVZXzgsPzkyirluUv6QdMTopJwFwIGx rFgtsbkvhEsFvaNhhVIqQXKfwZ69r42U5JC+fDM5u7VX0mqyJ1usUNGvNSeifcDg EwUAI6RGnOXCO6crj2BZYpRTdc61tnY9b4CGLHDCeQkEXokEsEJ7Mz+8YfSwFo7X wqh+dAPQaixeHtUFZ8GhHXeAsjoQRSBXygf3NSNmCeP3WsmuozbauuujSrrTHITp LOXFPhU9uxHu4mDd6wrq =59+j -----END PGP SIGNATURE----- Merge tag 'fbdev-3.13' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux Pull fbdev changes from Tomi Valkeinen: "Nothing particularly stands out in this pull request. The biggest part of the changes are cleanups. Maybe one fix to mention is the "fb: reorder the lock sequence to fix potential dead lock" which hopefully fixes the fb locking issues reported by multiple persons. There are also a few commits that have changes to arch/arm/mach-at91 and arch/avr32, which have been acked by the maintainers" * tag 'fbdev-3.13' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux: (143 commits) fb: reorder the lock sequence to fix potential dead lock fbdev: shmobile-lcdcfb: Convert to clk_prepare/unprepare fbdev: shmobile-hdmi: Convert to clk_prepare/unprepare omapdss: Add new panel driver for Topolly td028ttec1 LCD. video: exynos_mipi_dsi: Unlock the mutex before returning video: da8xx-fb: remove unwanted define video: Remove unnecessary semicolons simplefb: use write-combined remapping simplefb: fix unmapping fb during destruction OMAPDSS: connector-dvi: fix releasing i2c_adapter OMAPDSS: DSI: fix perf measuring ifdefs framebuffer: Use fb_<level> framebuffer: Add fb_<level> convenience logging macros efifb: prevent null-deref when iterating dmi_list fbdev: fix error return code in metronomefb_probe() video: xilinxfb: Fix for "Use standard variable name convention" OMAPDSS: Fix de_level in videomode_to_omap_video_timings() video: xilinxfb: Simplify error path video: xilinxfb: Use devm_kzalloc instead of kzalloc video: xilinxfb: Use standard variable name convention ...
This commit is contained in:
commit
f0d55cc1a6
176 changed files with 3948 additions and 3104 deletions
|
|
@ -478,11 +478,10 @@ int __init mc68x328fb_init(void)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
printk(KERN_INFO
|
||||
"fb%d: %s frame buffer device\n", fb_info.node, fb_info.fix.id);
|
||||
printk(KERN_INFO
|
||||
"fb%d: %dx%dx%d at 0x%08lx\n", fb_info.node,
|
||||
mc68x328fb_default.xres_virtual, mc68x328fb_default.yres_virtual,
|
||||
fb_info(&fb_info, "%s frame buffer device\n", fb_info.fix.id);
|
||||
fb_info(&fb_info, "%dx%dx%d at 0x%08lx\n",
|
||||
mc68x328fb_default.xres_virtual,
|
||||
mc68x328fb_default.yres_virtual,
|
||||
1 << mc68x328fb_default.bits_per_pixel, videomemory);
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -996,6 +996,8 @@ config FB_ATMEL
|
|||
select FB_CFB_FILLRECT
|
||||
select FB_CFB_COPYAREA
|
||||
select FB_CFB_IMAGEBLIT
|
||||
select FB_MODE_HELPERS
|
||||
select VIDEOMODE_HELPERS
|
||||
help
|
||||
This enables support for the AT91/AT32 LCD Controller.
|
||||
|
||||
|
|
|
|||
|
|
@ -545,7 +545,7 @@ static int clcdfb_register(struct clcd_fb *fb)
|
|||
|
||||
static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id)
|
||||
{
|
||||
struct clcd_board *board = dev->dev.platform_data;
|
||||
struct clcd_board *board = dev_get_platdata(&dev->dev);
|
||||
struct clcd_fb *fb;
|
||||
int ret;
|
||||
|
||||
|
|
@ -599,8 +599,6 @@ static int clcdfb_remove(struct amba_device *dev)
|
|||
{
|
||||
struct clcd_fb *fb = amba_get_drvdata(dev);
|
||||
|
||||
amba_set_drvdata(dev, NULL);
|
||||
|
||||
clcdfb_disable(fb);
|
||||
unregister_framebuffer(&fb->fb);
|
||||
if (fb->fb.cmap.len)
|
||||
|
|
|
|||
|
|
@ -3742,13 +3742,12 @@ default_chipset:
|
|||
if (err)
|
||||
goto unset_drvdata;
|
||||
|
||||
printk("fb%d: %s frame buffer device, using %dK of video memory\n",
|
||||
info->node, info->fix.id, info->fix.smem_len>>10);
|
||||
fb_info(info, "%s frame buffer device, using %dK of video memory\n",
|
||||
info->fix.id, info->fix.smem_len>>10);
|
||||
|
||||
return 0;
|
||||
|
||||
unset_drvdata:
|
||||
dev_set_drvdata(&pdev->dev, NULL);
|
||||
fb_dealloc_cmap(&info->cmap);
|
||||
free_irq:
|
||||
free_irq(IRQ_AMIGA_COPPER, info->par);
|
||||
|
|
@ -3768,7 +3767,6 @@ static int __exit amifb_remove(struct platform_device *pdev)
|
|||
struct fb_info *info = dev_get_drvdata(&pdev->dev);
|
||||
|
||||
unregister_framebuffer(info);
|
||||
dev_set_drvdata(&pdev->dev, NULL);
|
||||
fb_dealloc_cmap(&info->cmap);
|
||||
free_irq(IRQ_AMIGA_COPPER, info->par);
|
||||
custom.dmacon = DMAF_ALL | DMAF_MASTER;
|
||||
|
|
|
|||
|
|
@ -556,9 +556,8 @@ static int arcfb_probe(struct platform_device *dev)
|
|||
goto err1;
|
||||
}
|
||||
}
|
||||
printk(KERN_INFO
|
||||
"fb%d: Arc frame buffer device, using %dK of video memory\n",
|
||||
info->node, videomemorysize >> 10);
|
||||
fb_info(info, "Arc frame buffer device, using %dK of video memory\n",
|
||||
videomemorysize >> 10);
|
||||
|
||||
/* this inits the lcd but doesn't clear dirty pixels */
|
||||
for (i = 0; i < num_cols * num_rows; i++) {
|
||||
|
|
@ -572,8 +571,7 @@ static int arcfb_probe(struct platform_device *dev)
|
|||
/* if we were told to splash the screen, we just clear it */
|
||||
if (!nosplash) {
|
||||
for (i = 0; i < num_cols * num_rows; i++) {
|
||||
printk(KERN_INFO "fb%d: splashing lcd %d\n",
|
||||
info->node, i);
|
||||
fb_info(info, "splashing lcd %d\n", i);
|
||||
ks108_set_start_line(par, i, 0);
|
||||
ks108_clear_lcd(par, i);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -137,8 +137,7 @@ static void arkfb_settile(struct fb_info *info, struct fb_tilemap *map)
|
|||
|
||||
if ((map->width != 8) || (map->height != 16) ||
|
||||
(map->depth != 1) || (map->length != 256)) {
|
||||
printk(KERN_ERR "fb%d: unsupported font parameters: width %d, "
|
||||
"height %d, depth %d, length %d\n", info->node,
|
||||
fb_err(info, "unsupported font parameters: width %d, height %d, depth %d, length %d\n",
|
||||
map->width, map->height, map->depth, map->length);
|
||||
return;
|
||||
}
|
||||
|
|
@ -517,7 +516,7 @@ static void ark_set_pixclock(struct fb_info *info, u32 pixclock)
|
|||
|
||||
int rv = dac_set_freq(par->dac, 0, 1000000000 / pixclock);
|
||||
if (rv < 0) {
|
||||
printk(KERN_ERR "fb%d: cannot set requested pixclock, keeping old value\n", info->node);
|
||||
fb_err(info, "cannot set requested pixclock, keeping old value\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -584,7 +583,7 @@ static int arkfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
|
|||
rv = svga_match_format (arkfb_formats, var, NULL);
|
||||
if (rv < 0)
|
||||
{
|
||||
printk(KERN_ERR "fb%d: unsupported mode requested\n", info->node);
|
||||
fb_err(info, "unsupported mode requested\n");
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
@ -604,14 +603,15 @@ static int arkfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
|
|||
mem = ((var->bits_per_pixel * var->xres_virtual) >> 3) * var->yres_virtual;
|
||||
if (mem > info->screen_size)
|
||||
{
|
||||
printk(KERN_ERR "fb%d: not enough framebuffer memory (%d kB requested , %d kB available)\n", info->node, mem >> 10, (unsigned int) (info->screen_size >> 10));
|
||||
fb_err(info, "not enough framebuffer memory (%d kB requested, %d kB available)\n",
|
||||
mem >> 10, (unsigned int) (info->screen_size >> 10));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rv = svga_check_timings (&ark_timing_regs, var, info->node);
|
||||
if (rv < 0)
|
||||
{
|
||||
printk(KERN_ERR "fb%d: invalid timings requested\n", info->node);
|
||||
fb_err(info, "invalid timings requested\n");
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
@ -693,7 +693,7 @@ static int arkfb_set_par(struct fb_info *info)
|
|||
vga_wseq(par->state.vgabase, 0x18, regval);
|
||||
|
||||
/* Set the offset register */
|
||||
pr_debug("fb%d: offset register : %d\n", info->node, offset_value);
|
||||
fb_dbg(info, "offset register : %d\n", offset_value);
|
||||
svga_wcrt_multi(par->state.vgabase, ark_offset_regs, offset_value);
|
||||
|
||||
/* fix for hi-res textmode */
|
||||
|
|
@ -716,7 +716,7 @@ static int arkfb_set_par(struct fb_info *info)
|
|||
/* Set mode-specific register values */
|
||||
switch (mode) {
|
||||
case 0:
|
||||
pr_debug("fb%d: text mode\n", info->node);
|
||||
fb_dbg(info, "text mode\n");
|
||||
svga_set_textmode_vga_regs(par->state.vgabase);
|
||||
|
||||
vga_wseq(par->state.vgabase, 0x11, 0x10); /* basic VGA mode */
|
||||
|
|
@ -725,7 +725,7 @@ static int arkfb_set_par(struct fb_info *info)
|
|||
|
||||
break;
|
||||
case 1:
|
||||
pr_debug("fb%d: 4 bit pseudocolor\n", info->node);
|
||||
fb_dbg(info, "4 bit pseudocolor\n");
|
||||
vga_wgfx(par->state.vgabase, VGA_GFX_MODE, 0x40);
|
||||
|
||||
vga_wseq(par->state.vgabase, 0x11, 0x10); /* basic VGA mode */
|
||||
|
|
@ -733,44 +733,44 @@ static int arkfb_set_par(struct fb_info *info)
|
|||
dac_set_mode(par->dac, DAC_PSEUDO8_8);
|
||||
break;
|
||||
case 2:
|
||||
pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node);
|
||||
fb_dbg(info, "4 bit pseudocolor, planar\n");
|
||||
|
||||
vga_wseq(par->state.vgabase, 0x11, 0x10); /* basic VGA mode */
|
||||
svga_wcrt_mask(par->state.vgabase, 0x46, 0x00, 0x04); /* 8bit pixel path */
|
||||
dac_set_mode(par->dac, DAC_PSEUDO8_8);
|
||||
break;
|
||||
case 3:
|
||||
pr_debug("fb%d: 8 bit pseudocolor\n", info->node);
|
||||
fb_dbg(info, "8 bit pseudocolor\n");
|
||||
|
||||
vga_wseq(par->state.vgabase, 0x11, 0x16); /* 8bpp accel mode */
|
||||
|
||||
if (info->var.pixclock > 20000) {
|
||||
pr_debug("fb%d: not using multiplex\n", info->node);
|
||||
fb_dbg(info, "not using multiplex\n");
|
||||
svga_wcrt_mask(par->state.vgabase, 0x46, 0x00, 0x04); /* 8bit pixel path */
|
||||
dac_set_mode(par->dac, DAC_PSEUDO8_8);
|
||||
} else {
|
||||
pr_debug("fb%d: using multiplex\n", info->node);
|
||||
fb_dbg(info, "using multiplex\n");
|
||||
svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */
|
||||
dac_set_mode(par->dac, DAC_PSEUDO8_16);
|
||||
hdiv = 2;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
pr_debug("fb%d: 5/5/5 truecolor\n", info->node);
|
||||
fb_dbg(info, "5/5/5 truecolor\n");
|
||||
|
||||
vga_wseq(par->state.vgabase, 0x11, 0x1A); /* 16bpp accel mode */
|
||||
svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */
|
||||
dac_set_mode(par->dac, DAC_RGB1555_16);
|
||||
break;
|
||||
case 5:
|
||||
pr_debug("fb%d: 5/6/5 truecolor\n", info->node);
|
||||
fb_dbg(info, "5/6/5 truecolor\n");
|
||||
|
||||
vga_wseq(par->state.vgabase, 0x11, 0x1A); /* 16bpp accel mode */
|
||||
svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */
|
||||
dac_set_mode(par->dac, DAC_RGB0565_16);
|
||||
break;
|
||||
case 6:
|
||||
pr_debug("fb%d: 8/8/8 truecolor\n", info->node);
|
||||
fb_dbg(info, "8/8/8 truecolor\n");
|
||||
|
||||
vga_wseq(par->state.vgabase, 0x11, 0x16); /* 8bpp accel mode ??? */
|
||||
svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */
|
||||
|
|
@ -779,7 +779,7 @@ static int arkfb_set_par(struct fb_info *info)
|
|||
hdiv = 2;
|
||||
break;
|
||||
case 7:
|
||||
pr_debug("fb%d: 8/8/8/8 truecolor\n", info->node);
|
||||
fb_dbg(info, "8/8/8/8 truecolor\n");
|
||||
|
||||
vga_wseq(par->state.vgabase, 0x11, 0x1E); /* 32bpp accel mode */
|
||||
svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */
|
||||
|
|
@ -787,7 +787,7 @@ static int arkfb_set_par(struct fb_info *info)
|
|||
hmul = 2;
|
||||
break;
|
||||
default:
|
||||
printk(KERN_ERR "fb%d: unsupported mode - bug\n", info->node);
|
||||
fb_err(info, "unsupported mode - bug\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -879,19 +879,19 @@ static int arkfb_blank(int blank_mode, struct fb_info *info)
|
|||
|
||||
switch (blank_mode) {
|
||||
case FB_BLANK_UNBLANK:
|
||||
pr_debug("fb%d: unblank\n", info->node);
|
||||
fb_dbg(info, "unblank\n");
|
||||
svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
|
||||
break;
|
||||
case FB_BLANK_NORMAL:
|
||||
pr_debug("fb%d: blank\n", info->node);
|
||||
fb_dbg(info, "blank\n");
|
||||
svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
|
||||
break;
|
||||
case FB_BLANK_POWERDOWN:
|
||||
case FB_BLANK_HSYNC_SUSPEND:
|
||||
case FB_BLANK_VSYNC_SUSPEND:
|
||||
pr_debug("fb%d: sync down\n", info->node);
|
||||
fb_dbg(info, "sync down\n");
|
||||
svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x17, 0x00, 0x80);
|
||||
break;
|
||||
|
|
@ -1048,12 +1048,12 @@ static int ark_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
|
||||
rc = register_framebuffer(info);
|
||||
if (rc < 0) {
|
||||
dev_err(info->device, "cannot register framebugger\n");
|
||||
dev_err(info->device, "cannot register framebuffer\n");
|
||||
goto err_reg_fb;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "fb%d: %s on %s, %d MB RAM\n", info->node, info->fix.id,
|
||||
pci_name(dev), info->fix.smem_len >> 20);
|
||||
fb_info(info, "%s on %s, %d MB RAM\n",
|
||||
info->fix.id, pci_name(dev), info->fix.smem_len >> 20);
|
||||
|
||||
/* Record a reference to the driver data */
|
||||
pci_set_drvdata(dev, info);
|
||||
|
|
@ -1108,7 +1108,6 @@ static void ark_pci_remove(struct pci_dev *dev)
|
|||
pci_release_regions(dev);
|
||||
/* pci_disable_device(dev); */
|
||||
|
||||
pci_set_drvdata(dev, NULL);
|
||||
framebuffer_release(info);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -527,8 +527,8 @@ static int init_asiliant(struct fb_info *p, unsigned long addr)
|
|||
return err;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "fb%d: Asiliant 69000 frame buffer (%dK RAM detected)\n",
|
||||
p->node, p->fix.smem_len / 1024);
|
||||
fb_info(p, "Asiliant 69000 frame buffer (%dK RAM detected)\n",
|
||||
p->fix.smem_len / 1024);
|
||||
|
||||
writeb(0xff, mmio_base + 0x78c);
|
||||
chips_hw_init(p);
|
||||
|
|
|
|||
|
|
@ -3246,11 +3246,8 @@ int __init atafb_init(void)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
// FIXME: mode needs setting!
|
||||
//printk("fb%d: %s frame buffer device, using %dK of video memory\n",
|
||||
// fb_info.node, fb_info.mode->name, screen_len>>10);
|
||||
printk("fb%d: frame buffer device, using %dK of video memory\n",
|
||||
fb_info.node, screen_len >> 10);
|
||||
fb_info(&fb_info, "frame buffer device, using %dK of video memory\n",
|
||||
screen_len >> 10);
|
||||
|
||||
/* TODO: This driver cannot be unloaded yet */
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -20,12 +20,55 @@
|
|||
#include <linux/gfp.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_data/atmel.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <video/of_display_timing.h>
|
||||
#include <video/videomode.h>
|
||||
|
||||
#include <mach/cpu.h>
|
||||
#include <asm/gpio.h>
|
||||
|
||||
#include <video/atmel_lcdc.h>
|
||||
|
||||
struct atmel_lcdfb_config {
|
||||
bool have_alt_pixclock;
|
||||
bool have_hozval;
|
||||
bool have_intensity_bit;
|
||||
};
|
||||
|
||||
/* LCD Controller info data structure, stored in device platform_data */
|
||||
struct atmel_lcdfb_info {
|
||||
spinlock_t lock;
|
||||
struct fb_info *info;
|
||||
void __iomem *mmio;
|
||||
int irq_base;
|
||||
struct work_struct task;
|
||||
|
||||
unsigned int smem_len;
|
||||
struct platform_device *pdev;
|
||||
struct clk *bus_clk;
|
||||
struct clk *lcdc_clk;
|
||||
|
||||
struct backlight_device *backlight;
|
||||
u8 bl_power;
|
||||
u8 saved_lcdcon;
|
||||
|
||||
u32 pseudo_palette[16];
|
||||
bool have_intensity_bit;
|
||||
|
||||
struct atmel_lcdfb_pdata pdata;
|
||||
|
||||
struct atmel_lcdfb_config *config;
|
||||
};
|
||||
|
||||
struct atmel_lcdfb_power_ctrl_gpio {
|
||||
int gpio;
|
||||
int active_low;
|
||||
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
#define lcdc_readl(sinfo, reg) __raw_readl((sinfo)->mmio+(reg))
|
||||
#define lcdc_writel(sinfo, reg, val) __raw_writel((val), (sinfo)->mmio+(reg))
|
||||
|
||||
|
|
@ -34,12 +77,6 @@
|
|||
#define ATMEL_LCDC_DMA_BURST_LEN 8 /* words */
|
||||
#define ATMEL_LCDC_FIFO_SIZE 512 /* words */
|
||||
|
||||
struct atmel_lcdfb_config {
|
||||
bool have_alt_pixclock;
|
||||
bool have_hozval;
|
||||
bool have_intensity_bit;
|
||||
};
|
||||
|
||||
static struct atmel_lcdfb_config at91sam9261_config = {
|
||||
.have_hozval = true,
|
||||
.have_intensity_bit = true,
|
||||
|
|
@ -248,18 +285,27 @@ static void exit_backlight(struct atmel_lcdfb_info *sinfo)
|
|||
|
||||
static void init_contrast(struct atmel_lcdfb_info *sinfo)
|
||||
{
|
||||
struct atmel_lcdfb_pdata *pdata = &sinfo->pdata;
|
||||
|
||||
/* contrast pwm can be 'inverted' */
|
||||
if (sinfo->lcdcon_pol_negative)
|
||||
if (pdata->lcdcon_pol_negative)
|
||||
contrast_ctr &= ~(ATMEL_LCDC_POL_POSITIVE);
|
||||
|
||||
/* have some default contrast/backlight settings */
|
||||
lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, contrast_ctr);
|
||||
lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_VAL, ATMEL_LCDC_CVAL_DEFAULT);
|
||||
|
||||
if (sinfo->lcdcon_is_backlight)
|
||||
if (pdata->lcdcon_is_backlight)
|
||||
init_backlight(sinfo);
|
||||
}
|
||||
|
||||
static inline void atmel_lcdfb_power_control(struct atmel_lcdfb_info *sinfo, int on)
|
||||
{
|
||||
struct atmel_lcdfb_pdata *pdata = &sinfo->pdata;
|
||||
|
||||
if (pdata->atmel_lcdfb_power_control)
|
||||
pdata->atmel_lcdfb_power_control(pdata, on);
|
||||
}
|
||||
|
||||
static struct fb_fix_screeninfo atmel_lcdfb_fix __initdata = {
|
||||
.type = FB_TYPE_PACKED_PIXELS,
|
||||
|
|
@ -299,9 +345,11 @@ static unsigned long compute_hozval(struct atmel_lcdfb_info *sinfo,
|
|||
|
||||
static void atmel_lcdfb_stop_nowait(struct atmel_lcdfb_info *sinfo)
|
||||
{
|
||||
struct atmel_lcdfb_pdata *pdata = &sinfo->pdata;
|
||||
|
||||
/* Turn off the LCD controller and the DMA controller */
|
||||
lcdc_writel(sinfo, ATMEL_LCDC_PWRCON,
|
||||
sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET);
|
||||
pdata->guard_time << ATMEL_LCDC_GUARDT_OFFSET);
|
||||
|
||||
/* Wait for the LCDC core to become idle */
|
||||
while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY)
|
||||
|
|
@ -321,9 +369,11 @@ static void atmel_lcdfb_stop(struct atmel_lcdfb_info *sinfo)
|
|||
|
||||
static void atmel_lcdfb_start(struct atmel_lcdfb_info *sinfo)
|
||||
{
|
||||
lcdc_writel(sinfo, ATMEL_LCDC_DMACON, sinfo->default_dmacon);
|
||||
struct atmel_lcdfb_pdata *pdata = &sinfo->pdata;
|
||||
|
||||
lcdc_writel(sinfo, ATMEL_LCDC_DMACON, pdata->default_dmacon);
|
||||
lcdc_writel(sinfo, ATMEL_LCDC_PWRCON,
|
||||
(sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET)
|
||||
(pdata->guard_time << ATMEL_LCDC_GUARDT_OFFSET)
|
||||
| ATMEL_LCDC_PWR);
|
||||
}
|
||||
|
||||
|
|
@ -424,6 +474,7 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var,
|
|||
{
|
||||
struct device *dev = info->device;
|
||||
struct atmel_lcdfb_info *sinfo = info->par;
|
||||
struct atmel_lcdfb_pdata *pdata = &sinfo->pdata;
|
||||
unsigned long clk_value_khz;
|
||||
|
||||
clk_value_khz = clk_get_rate(sinfo->lcdc_clk) / 1000;
|
||||
|
|
@ -510,7 +561,7 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var,
|
|||
else
|
||||
var->green.length = 6;
|
||||
|
||||
if (sinfo->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB) {
|
||||
if (pdata->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB) {
|
||||
/* RGB:5X5 mode */
|
||||
var->red.offset = var->green.length + 5;
|
||||
var->blue.offset = 0;
|
||||
|
|
@ -527,7 +578,7 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var,
|
|||
var->transp.length = 8;
|
||||
/* fall through */
|
||||
case 24:
|
||||
if (sinfo->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB) {
|
||||
if (pdata->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB) {
|
||||
/* RGB:888 mode */
|
||||
var->red.offset = 16;
|
||||
var->blue.offset = 0;
|
||||
|
|
@ -576,6 +627,7 @@ static void atmel_lcdfb_reset(struct atmel_lcdfb_info *sinfo)
|
|||
static int atmel_lcdfb_set_par(struct fb_info *info)
|
||||
{
|
||||
struct atmel_lcdfb_info *sinfo = info->par;
|
||||
struct atmel_lcdfb_pdata *pdata = &sinfo->pdata;
|
||||
unsigned long hozval_linesz;
|
||||
unsigned long value;
|
||||
unsigned long clk_value_khz;
|
||||
|
|
@ -637,7 +689,7 @@ static int atmel_lcdfb_set_par(struct fb_info *info)
|
|||
|
||||
|
||||
/* Initialize control register 2 */
|
||||
value = sinfo->default_lcdcon2;
|
||||
value = pdata->default_lcdcon2;
|
||||
|
||||
if (!(info->var.sync & FB_SYNC_HOR_HIGH_ACT))
|
||||
value |= ATMEL_LCDC_INVLINE_INVERTED;
|
||||
|
|
@ -741,6 +793,7 @@ static int atmel_lcdfb_setcolreg(unsigned int regno, unsigned int red,
|
|||
unsigned int transp, struct fb_info *info)
|
||||
{
|
||||
struct atmel_lcdfb_info *sinfo = info->par;
|
||||
struct atmel_lcdfb_pdata *pdata = &sinfo->pdata;
|
||||
unsigned int val;
|
||||
u32 *pal;
|
||||
int ret = 1;
|
||||
|
|
@ -777,8 +830,7 @@ static int atmel_lcdfb_setcolreg(unsigned int regno, unsigned int red,
|
|||
*/
|
||||
} else {
|
||||
/* new style BGR:565 / RGB:565 */
|
||||
if (sinfo->lcd_wiring_mode ==
|
||||
ATMEL_LCDC_WIRING_RGB) {
|
||||
if (pdata->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB) {
|
||||
val = ((blue >> 11) & 0x001f);
|
||||
val |= ((red >> 0) & 0xf800);
|
||||
} else {
|
||||
|
|
@ -912,16 +964,187 @@ static void atmel_lcdfb_stop_clock(struct atmel_lcdfb_info *sinfo)
|
|||
clk_disable_unprepare(sinfo->lcdc_clk);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id atmel_lcdfb_dt_ids[] = {
|
||||
{ .compatible = "atmel,at91sam9261-lcdc" , .data = &at91sam9261_config, },
|
||||
{ .compatible = "atmel,at91sam9263-lcdc" , .data = &at91sam9263_config, },
|
||||
{ .compatible = "atmel,at91sam9g10-lcdc" , .data = &at91sam9g10_config, },
|
||||
{ .compatible = "atmel,at91sam9g45-lcdc" , .data = &at91sam9g45_config, },
|
||||
{ .compatible = "atmel,at91sam9g45es-lcdc" , .data = &at91sam9g45es_config, },
|
||||
{ .compatible = "atmel,at91sam9rl-lcdc" , .data = &at91sam9rl_config, },
|
||||
{ .compatible = "atmel,at32ap-lcdc" , .data = &at32ap_config, },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, atmel_lcdfb_dt_ids);
|
||||
|
||||
static const char *atmel_lcdfb_wiring_modes[] = {
|
||||
[ATMEL_LCDC_WIRING_BGR] = "BRG",
|
||||
[ATMEL_LCDC_WIRING_RGB] = "RGB",
|
||||
};
|
||||
|
||||
const int atmel_lcdfb_get_of_wiring_modes(struct device_node *np)
|
||||
{
|
||||
const char *mode;
|
||||
int err, i;
|
||||
|
||||
err = of_property_read_string(np, "atmel,lcd-wiring-mode", &mode);
|
||||
if (err < 0)
|
||||
return ATMEL_LCDC_WIRING_BGR;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(atmel_lcdfb_wiring_modes); i++)
|
||||
if (!strcasecmp(mode, atmel_lcdfb_wiring_modes[i]))
|
||||
return i;
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static void atmel_lcdfb_power_control_gpio(struct atmel_lcdfb_pdata *pdata, int on)
|
||||
{
|
||||
struct atmel_lcdfb_power_ctrl_gpio *og;
|
||||
|
||||
list_for_each_entry(og, &pdata->pwr_gpios, list)
|
||||
gpio_set_value(og->gpio, on);
|
||||
}
|
||||
|
||||
static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo)
|
||||
{
|
||||
struct fb_info *info = sinfo->info;
|
||||
struct atmel_lcdfb_pdata *pdata = &sinfo->pdata;
|
||||
struct fb_var_screeninfo *var = &info->var;
|
||||
struct device *dev = &sinfo->pdev->dev;
|
||||
struct device_node *np =dev->of_node;
|
||||
struct device_node *display_np;
|
||||
struct device_node *timings_np;
|
||||
struct display_timings *timings;
|
||||
enum of_gpio_flags flags;
|
||||
struct atmel_lcdfb_power_ctrl_gpio *og;
|
||||
bool is_gpio_power = false;
|
||||
int ret = -ENOENT;
|
||||
int i, gpio;
|
||||
|
||||
sinfo->config = (struct atmel_lcdfb_config*)
|
||||
of_match_device(atmel_lcdfb_dt_ids, dev)->data;
|
||||
|
||||
display_np = of_parse_phandle(np, "display", 0);
|
||||
if (!display_np) {
|
||||
dev_err(dev, "failed to find display phandle\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(display_np, "bits-per-pixel", &var->bits_per_pixel);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to get property bits-per-pixel\n");
|
||||
goto put_display_node;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(display_np, "atmel,guard-time", &pdata->guard_time);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to get property atmel,guard-time\n");
|
||||
goto put_display_node;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(display_np, "atmel,lcdcon2", &pdata->default_lcdcon2);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to get property atmel,lcdcon2\n");
|
||||
goto put_display_node;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(display_np, "atmel,dmacon", &pdata->default_dmacon);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to get property bits-per-pixel\n");
|
||||
goto put_display_node;
|
||||
}
|
||||
|
||||
ret = -ENOMEM;
|
||||
for (i = 0; i < of_gpio_named_count(display_np, "atmel,power-control-gpio"); i++) {
|
||||
gpio = of_get_named_gpio_flags(display_np, "atmel,power-control-gpio",
|
||||
i, &flags);
|
||||
if (gpio < 0)
|
||||
continue;
|
||||
|
||||
og = devm_kzalloc(dev, sizeof(*og), GFP_KERNEL);
|
||||
if (!og)
|
||||
goto put_display_node;
|
||||
|
||||
og->gpio = gpio;
|
||||
og->active_low = flags & OF_GPIO_ACTIVE_LOW;
|
||||
is_gpio_power = true;
|
||||
ret = devm_gpio_request(dev, gpio, "lcd-power-control-gpio");
|
||||
if (ret) {
|
||||
dev_err(dev, "request gpio %d failed\n", gpio);
|
||||
goto put_display_node;
|
||||
}
|
||||
|
||||
ret = gpio_direction_output(gpio, og->active_low);
|
||||
if (ret) {
|
||||
dev_err(dev, "set direction output gpio %d failed\n", gpio);
|
||||
goto put_display_node;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_gpio_power)
|
||||
pdata->atmel_lcdfb_power_control = atmel_lcdfb_power_control_gpio;
|
||||
|
||||
ret = atmel_lcdfb_get_of_wiring_modes(display_np);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "invalid atmel,lcd-wiring-mode\n");
|
||||
goto put_display_node;
|
||||
}
|
||||
pdata->lcd_wiring_mode = ret;
|
||||
|
||||
pdata->lcdcon_is_backlight = of_property_read_bool(display_np, "atmel,lcdcon-backlight");
|
||||
|
||||
timings = of_get_display_timings(display_np);
|
||||
if (!timings) {
|
||||
dev_err(dev, "failed to get display timings\n");
|
||||
goto put_display_node;
|
||||
}
|
||||
|
||||
timings_np = of_find_node_by_name(display_np, "display-timings");
|
||||
if (!timings_np) {
|
||||
dev_err(dev, "failed to find display-timings node\n");
|
||||
goto put_display_node;
|
||||
}
|
||||
|
||||
for (i = 0; i < of_get_child_count(timings_np); i++) {
|
||||
struct videomode vm;
|
||||
struct fb_videomode fb_vm;
|
||||
|
||||
ret = videomode_from_timings(timings, &vm, i);
|
||||
if (ret < 0)
|
||||
goto put_timings_node;
|
||||
ret = fb_videomode_from_videomode(&vm, &fb_vm);
|
||||
if (ret < 0)
|
||||
goto put_timings_node;
|
||||
|
||||
fb_add_videomode(&fb_vm, &info->modelist);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
put_timings_node:
|
||||
of_node_put(timings_np);
|
||||
put_display_node:
|
||||
of_node_put(display_np);
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int __init atmel_lcdfb_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct fb_info *info;
|
||||
struct atmel_lcdfb_info *sinfo;
|
||||
struct atmel_lcdfb_info *pdata_sinfo;
|
||||
struct fb_videomode fbmode;
|
||||
struct atmel_lcdfb_pdata *pdata = NULL;
|
||||
struct resource *regs = NULL;
|
||||
struct resource *map = NULL;
|
||||
struct fb_modelist *modelist;
|
||||
int ret;
|
||||
|
||||
dev_dbg(dev, "%s BEGIN\n", __func__);
|
||||
|
|
@ -934,26 +1157,35 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
sinfo = info->par;
|
||||
sinfo->pdev = pdev;
|
||||
sinfo->info = info;
|
||||
|
||||
if (dev->platform_data) {
|
||||
pdata_sinfo = (struct atmel_lcdfb_info *)dev->platform_data;
|
||||
sinfo->default_bpp = pdata_sinfo->default_bpp;
|
||||
sinfo->default_dmacon = pdata_sinfo->default_dmacon;
|
||||
sinfo->default_lcdcon2 = pdata_sinfo->default_lcdcon2;
|
||||
sinfo->default_monspecs = pdata_sinfo->default_monspecs;
|
||||
sinfo->atmel_lcdfb_power_control = pdata_sinfo->atmel_lcdfb_power_control;
|
||||
sinfo->guard_time = pdata_sinfo->guard_time;
|
||||
sinfo->smem_len = pdata_sinfo->smem_len;
|
||||
sinfo->lcdcon_is_backlight = pdata_sinfo->lcdcon_is_backlight;
|
||||
sinfo->lcdcon_pol_negative = pdata_sinfo->lcdcon_pol_negative;
|
||||
sinfo->lcd_wiring_mode = pdata_sinfo->lcd_wiring_mode;
|
||||
INIT_LIST_HEAD(&info->modelist);
|
||||
|
||||
if (pdev->dev.of_node) {
|
||||
ret = atmel_lcdfb_of_init(sinfo);
|
||||
if (ret)
|
||||
goto free_info;
|
||||
} else if (dev_get_platdata(dev)) {
|
||||
struct fb_monspecs *monspecs;
|
||||
int i;
|
||||
|
||||
pdata = dev_get_platdata(dev);
|
||||
monspecs = pdata->default_monspecs;
|
||||
sinfo->pdata = *pdata;
|
||||
|
||||
for (i = 0; i < monspecs->modedb_len; i++)
|
||||
fb_add_videomode(&monspecs->modedb[i], &info->modelist);
|
||||
|
||||
sinfo->config = atmel_lcdfb_get_config(pdev);
|
||||
|
||||
info->var.bits_per_pixel = pdata->default_bpp ? pdata->default_bpp : 16;
|
||||
memcpy(&info->monspecs, pdata->default_monspecs, sizeof(info->monspecs));
|
||||
} else {
|
||||
dev_err(dev, "cannot get default configuration\n");
|
||||
goto free_info;
|
||||
}
|
||||
sinfo->info = info;
|
||||
sinfo->pdev = pdev;
|
||||
sinfo->config = atmel_lcdfb_get_config(pdev);
|
||||
|
||||
if (!sinfo->config)
|
||||
goto free_info;
|
||||
|
||||
|
|
@ -962,7 +1194,6 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
|
|||
info->pseudo_palette = sinfo->pseudo_palette;
|
||||
info->fbops = &atmel_lcdfb_ops;
|
||||
|
||||
memcpy(&info->monspecs, sinfo->default_monspecs, sizeof(info->monspecs));
|
||||
info->fix = atmel_lcdfb_fix;
|
||||
|
||||
/* Enable LCDC Clocks */
|
||||
|
|
@ -978,14 +1209,11 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
|
|||
}
|
||||
atmel_lcdfb_start_clock(sinfo);
|
||||
|
||||
ret = fb_find_mode(&info->var, info, NULL, info->monspecs.modedb,
|
||||
info->monspecs.modedb_len, info->monspecs.modedb,
|
||||
sinfo->default_bpp);
|
||||
if (!ret) {
|
||||
dev_err(dev, "no suitable video mode found\n");
|
||||
goto stop_clk;
|
||||
}
|
||||
modelist = list_first_entry(&info->modelist,
|
||||
struct fb_modelist, list);
|
||||
fb_videomode_to_var(&info->var, &modelist->mode);
|
||||
|
||||
atmel_lcdfb_check_var(&info->var, info);
|
||||
|
||||
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!regs) {
|
||||
|
|
@ -1069,18 +1297,6 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
|
|||
goto unregister_irqs;
|
||||
}
|
||||
|
||||
/*
|
||||
* This makes sure that our colour bitfield
|
||||
* descriptors are correctly initialised.
|
||||
*/
|
||||
atmel_lcdfb_check_var(&info->var, info);
|
||||
|
||||
ret = fb_set_var(info, &info->var);
|
||||
if (ret) {
|
||||
dev_warn(dev, "unable to set display parameters\n");
|
||||
goto free_cmap;
|
||||
}
|
||||
|
||||
dev_set_drvdata(dev, info);
|
||||
|
||||
/*
|
||||
|
|
@ -1092,13 +1308,8 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
|
|||
goto reset_drvdata;
|
||||
}
|
||||
|
||||
/* add selected videomode to modelist */
|
||||
fb_var_to_videomode(&fbmode, &info->var);
|
||||
fb_add_videomode(&fbmode, &info->modelist);
|
||||
|
||||
/* Power up the LCDC screen */
|
||||
if (sinfo->atmel_lcdfb_power_control)
|
||||
sinfo->atmel_lcdfb_power_control(1);
|
||||
atmel_lcdfb_power_control(sinfo, 1);
|
||||
|
||||
dev_info(dev, "fb%d: Atmel LCDC at 0x%08lx (mapped at %p), irq %d\n",
|
||||
info->node, info->fix.mmio_start, sinfo->mmio, sinfo->irq_base);
|
||||
|
|
@ -1107,7 +1318,6 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
|
|||
|
||||
reset_drvdata:
|
||||
dev_set_drvdata(dev, NULL);
|
||||
free_cmap:
|
||||
fb_dealloc_cmap(&info->cmap);
|
||||
unregister_irqs:
|
||||
cancel_work_sync(&sinfo->task);
|
||||
|
|
@ -1143,15 +1353,16 @@ static int __exit atmel_lcdfb_remove(struct platform_device *pdev)
|
|||
struct device *dev = &pdev->dev;
|
||||
struct fb_info *info = dev_get_drvdata(dev);
|
||||
struct atmel_lcdfb_info *sinfo;
|
||||
struct atmel_lcdfb_pdata *pdata;
|
||||
|
||||
if (!info || !info->par)
|
||||
return 0;
|
||||
sinfo = info->par;
|
||||
pdata = &sinfo->pdata;
|
||||
|
||||
cancel_work_sync(&sinfo->task);
|
||||
exit_backlight(sinfo);
|
||||
if (sinfo->atmel_lcdfb_power_control)
|
||||
sinfo->atmel_lcdfb_power_control(0);
|
||||
atmel_lcdfb_power_control(sinfo, 0);
|
||||
unregister_framebuffer(info);
|
||||
atmel_lcdfb_stop_clock(sinfo);
|
||||
clk_put(sinfo->lcdc_clk);
|
||||
|
|
@ -1167,7 +1378,6 @@ static int __exit atmel_lcdfb_remove(struct platform_device *pdev)
|
|||
atmel_lcdfb_free_video_memory(sinfo);
|
||||
}
|
||||
|
||||
dev_set_drvdata(dev, NULL);
|
||||
framebuffer_release(info);
|
||||
|
||||
return 0;
|
||||
|
|
@ -1188,9 +1398,7 @@ static int atmel_lcdfb_suspend(struct platform_device *pdev, pm_message_t mesg)
|
|||
|
||||
sinfo->saved_lcdcon = lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_CTR);
|
||||
lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, 0);
|
||||
if (sinfo->atmel_lcdfb_power_control)
|
||||
sinfo->atmel_lcdfb_power_control(0);
|
||||
|
||||
atmel_lcdfb_power_control(sinfo, 0);
|
||||
atmel_lcdfb_stop(sinfo);
|
||||
atmel_lcdfb_stop_clock(sinfo);
|
||||
|
||||
|
|
@ -1204,8 +1412,7 @@ static int atmel_lcdfb_resume(struct platform_device *pdev)
|
|||
|
||||
atmel_lcdfb_start_clock(sinfo);
|
||||
atmel_lcdfb_start(sinfo);
|
||||
if (sinfo->atmel_lcdfb_power_control)
|
||||
sinfo->atmel_lcdfb_power_control(1);
|
||||
atmel_lcdfb_power_control(sinfo, 1);
|
||||
lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, sinfo->saved_lcdcon);
|
||||
|
||||
/* Enable FIFO & DMA errors */
|
||||
|
|
@ -1228,6 +1435,7 @@ static struct platform_driver atmel_lcdfb_driver = {
|
|||
.driver = {
|
||||
.name = "atmel_lcdfb",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = of_match_ptr(atmel_lcdfb_dt_ids),
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -413,7 +413,6 @@ struct aty128fb_par {
|
|||
int blitter_may_be_busy;
|
||||
int fifo_slots; /* free slots in FIFO (64 max) */
|
||||
|
||||
int pm_reg;
|
||||
int crt_on, lcd_on;
|
||||
struct pci_dev *pdev;
|
||||
struct fb_info *next;
|
||||
|
|
@ -2016,7 +2015,6 @@ static int aty128_init(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
|
||||
aty128_init_engine(par);
|
||||
|
||||
par->pm_reg = pdev->pm_cap;
|
||||
par->pdev = pdev;
|
||||
par->asleep = 0;
|
||||
par->lock_blank = 0;
|
||||
|
|
@ -2029,8 +2027,8 @@ static int aty128_init(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
if (register_framebuffer(info) < 0)
|
||||
return 0;
|
||||
|
||||
printk(KERN_INFO "fb%d: %s frame buffer device on %s\n",
|
||||
info->node, info->fix.id, video_card);
|
||||
fb_info(info, "%s frame buffer device on %s\n",
|
||||
info->fix.id, video_card);
|
||||
|
||||
return 1; /* success! */
|
||||
}
|
||||
|
|
@ -2397,7 +2395,7 @@ static void aty128_set_suspend(struct aty128fb_par *par, int suspend)
|
|||
u32 pmgt;
|
||||
struct pci_dev *pdev = par->pdev;
|
||||
|
||||
if (!par->pm_reg)
|
||||
if (!par->pdev->pm_cap)
|
||||
return;
|
||||
|
||||
/* Set the chip into the appropriate suspend mode (we use D2,
|
||||
|
|
|
|||
|
|
@ -1848,7 +1848,6 @@ static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
|
|||
|
||||
return aty_waitforvblank(par, crtc);
|
||||
}
|
||||
break;
|
||||
|
||||
#if defined(DEBUG) && defined(CONFIG_FB_ATY_CT)
|
||||
case ATYIO_CLKR:
|
||||
|
|
|
|||
|
|
@ -819,11 +819,6 @@ static int radeonfb_check_var (struct fb_var_screeninfo *var, struct fb_info *in
|
|||
if (v.xres_virtual < v.xres)
|
||||
v.xres = v.xres_virtual;
|
||||
|
||||
if (v.xoffset < 0)
|
||||
v.xoffset = 0;
|
||||
if (v.yoffset < 0)
|
||||
v.yoffset = 0;
|
||||
|
||||
if (v.xoffset > v.xres_virtual - v.xres)
|
||||
v.xoffset = v.xres_virtual - v.xres - 1;
|
||||
|
||||
|
|
|
|||
|
|
@ -1427,6 +1427,8 @@ static void radeon_pm_full_reset_sdram(struct radeonfb_info *rinfo)
|
|||
mdelay( 15);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_PM)
|
||||
#if defined(CONFIG_X86) || defined(CONFIG_PPC_PMAC)
|
||||
static void radeon_pm_reset_pad_ctlr_strength(struct radeonfb_info *rinfo)
|
||||
{
|
||||
u32 tmp, tmp2;
|
||||
|
|
@ -1939,9 +1941,10 @@ static void radeon_reinitialize_M10(struct radeonfb_info *rinfo)
|
|||
*/
|
||||
radeon_pm_m10_enable_lvds_spread_spectrum(rinfo);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PPC_OF
|
||||
|
||||
#ifdef CONFIG_PPC_PMAC
|
||||
static void radeon_pm_m9p_reconfigure_mc(struct radeonfb_info *rinfo)
|
||||
{
|
||||
OUTREG(MC_CNTL, rinfo->save_regs[46]);
|
||||
|
|
@ -2202,6 +2205,8 @@ static void radeon_reinitialize_M9P(struct radeonfb_info *rinfo)
|
|||
radeon_pm_restore_pixel_pll(rinfo);
|
||||
radeon_pm_m10_enable_lvds_spread_spectrum(rinfo);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if 0 /* Not ready yet */
|
||||
static void radeon_reinitialize_QW(struct radeonfb_info *rinfo)
|
||||
|
|
@ -2515,13 +2520,13 @@ static void radeonfb_whack_power_state(struct radeonfb_info *rinfo, pci_power_t
|
|||
|
||||
for (;;) {
|
||||
pci_read_config_word(rinfo->pdev,
|
||||
rinfo->pm_reg+PCI_PM_CTRL,
|
||||
rinfo->pdev->pm_cap + PCI_PM_CTRL,
|
||||
&pwr_cmd);
|
||||
if (pwr_cmd & 2)
|
||||
if (pwr_cmd & state)
|
||||
break;
|
||||
pwr_cmd = (pwr_cmd & ~PCI_PM_CTRL_STATE_MASK) | 2;
|
||||
pwr_cmd = (pwr_cmd & ~PCI_PM_CTRL_STATE_MASK) | state;
|
||||
pci_write_config_word(rinfo->pdev,
|
||||
rinfo->pm_reg+PCI_PM_CTRL,
|
||||
rinfo->pdev->pm_cap + PCI_PM_CTRL,
|
||||
pwr_cmd);
|
||||
msleep(500);
|
||||
}
|
||||
|
|
@ -2532,7 +2537,7 @@ static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend)
|
|||
{
|
||||
u32 tmp;
|
||||
|
||||
if (!rinfo->pm_reg)
|
||||
if (!rinfo->pdev->pm_cap)
|
||||
return;
|
||||
|
||||
/* Set the chip into appropriate suspend mode (we use D2,
|
||||
|
|
@ -2804,9 +2809,6 @@ static void radeonfb_early_resume(void *data)
|
|||
|
||||
void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk, int ignore_devlist, int force_sleep)
|
||||
{
|
||||
/* Find PM registers in config space if any*/
|
||||
rinfo->pm_reg = rinfo->pdev->pm_cap;
|
||||
|
||||
/* Enable/Disable dynamic clocks: TODO add sysfs access */
|
||||
if (rinfo->family == CHIP_FAMILY_RS480)
|
||||
rinfo->dynclk = -1;
|
||||
|
|
@ -2830,7 +2832,7 @@ void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk, int ignore_devlis
|
|||
* reason. --BenH
|
||||
*/
|
||||
if (machine_is(powermac) && rinfo->of_node) {
|
||||
if (rinfo->is_mobility && rinfo->pm_reg &&
|
||||
if (rinfo->is_mobility && rinfo->pdev->pm_cap &&
|
||||
rinfo->family <= CHIP_FAMILY_RV250)
|
||||
rinfo->pm_mode |= radeon_pm_d2;
|
||||
|
||||
|
|
|
|||
|
|
@ -342,7 +342,6 @@ struct radeonfb_info {
|
|||
|
||||
int mtrr_hdl;
|
||||
|
||||
int pm_reg;
|
||||
u32 save_regs[100];
|
||||
int asleep;
|
||||
int lock_blank;
|
||||
|
|
|
|||
|
|
@ -564,7 +564,7 @@ int au1100fb_drv_remove(struct platform_device *dev)
|
|||
if (!dev)
|
||||
return -ENODEV;
|
||||
|
||||
fbdev = (struct au1100fb_device *) platform_get_drvdata(dev);
|
||||
fbdev = platform_get_drvdata(dev);
|
||||
|
||||
#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
|
||||
au1100fb_fb_blank(VESA_POWERDOWN, &fbdev->info);
|
||||
|
|
@ -636,19 +636,7 @@ static struct platform_driver au1100fb_driver = {
|
|||
.suspend = au1100fb_drv_suspend,
|
||||
.resume = au1100fb_drv_resume,
|
||||
};
|
||||
|
||||
static int __init au1100fb_load(void)
|
||||
{
|
||||
return platform_driver_register(&au1100fb_driver);
|
||||
}
|
||||
|
||||
static void __exit au1100fb_unload(void)
|
||||
{
|
||||
platform_driver_unregister(&au1100fb_driver);
|
||||
}
|
||||
|
||||
module_init(au1100fb_load);
|
||||
module_exit(au1100fb_unload);
|
||||
module_platform_driver(au1100fb_driver);
|
||||
|
||||
MODULE_DESCRIPTION(DRIVER_DESC);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -1853,21 +1853,7 @@ static struct platform_driver au1200fb_driver = {
|
|||
.probe = au1200fb_drv_probe,
|
||||
.remove = au1200fb_drv_remove,
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static int __init au1200fb_init(void)
|
||||
{
|
||||
return platform_driver_register(&au1200fb_driver);
|
||||
}
|
||||
|
||||
static void __exit au1200fb_cleanup(void)
|
||||
{
|
||||
platform_driver_unregister(&au1200fb_driver);
|
||||
}
|
||||
|
||||
module_init(au1200fb_init);
|
||||
module_exit(au1200fb_cleanup);
|
||||
module_platform_driver(au1200fb_driver);
|
||||
|
||||
MODULE_DESCRIPTION(DRIVER_DESC);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -244,7 +244,6 @@ static int l4f00242t03_remove(struct spi_device *spi)
|
|||
|
||||
l4f00242t03_lcd_power_set(priv->ld, FB_BLANK_POWERDOWN);
|
||||
lcd_device_unregister(priv->ld);
|
||||
spi_set_drvdata(spi, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -198,7 +198,7 @@ static int tosa_lcd_probe(struct spi_device *spi)
|
|||
ret = devm_gpio_request_one(&spi->dev, TOSA_GPIO_TG_ON,
|
||||
GPIOF_OUT_INIT_LOW, "tg #pwr");
|
||||
if (ret < 0)
|
||||
goto err_gpio_tg;
|
||||
return ret;
|
||||
|
||||
mdelay(60);
|
||||
|
||||
|
|
@ -219,8 +219,6 @@ static int tosa_lcd_probe(struct spi_device *spi)
|
|||
|
||||
err_register:
|
||||
tosa_lcd_tg_off(data);
|
||||
err_gpio_tg:
|
||||
spi_set_drvdata(spi, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -235,8 +233,6 @@ static int tosa_lcd_remove(struct spi_device *spi)
|
|||
|
||||
tosa_lcd_tg_off(data);
|
||||
|
||||
spi_set_drvdata(spi, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -761,19 +761,7 @@ static struct platform_driver bfin_bf54x_driver = {
|
|||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init bfin_bf54x_driver_init(void)
|
||||
{
|
||||
return platform_driver_register(&bfin_bf54x_driver);
|
||||
}
|
||||
|
||||
static void __exit bfin_bf54x_driver_cleanup(void)
|
||||
{
|
||||
platform_driver_unregister(&bfin_bf54x_driver);
|
||||
}
|
||||
module_platform_driver(bfin_bf54x_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Blackfin BF54x TFT LCD Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
module_init(bfin_bf54x_driver_init);
|
||||
module_exit(bfin_bf54x_driver_cleanup);
|
||||
|
|
|
|||
|
|
@ -664,19 +664,7 @@ static struct platform_driver bfin_t350mcqb_driver = {
|
|||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init bfin_t350mcqb_driver_init(void)
|
||||
{
|
||||
return platform_driver_register(&bfin_t350mcqb_driver);
|
||||
}
|
||||
|
||||
static void __exit bfin_t350mcqb_driver_cleanup(void)
|
||||
{
|
||||
platform_driver_unregister(&bfin_t350mcqb_driver);
|
||||
}
|
||||
module_platform_driver(bfin_t350mcqb_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Blackfin TFT LCD Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
module_init(bfin_t350mcqb_driver_init);
|
||||
module_exit(bfin_t350mcqb_driver_cleanup);
|
||||
|
|
|
|||
|
|
@ -1167,9 +1167,8 @@ static int broadsheetfb_probe(struct platform_device *dev)
|
|||
if (retval < 0)
|
||||
goto err_unreg_fb;
|
||||
|
||||
printk(KERN_INFO
|
||||
"fb%d: Broadsheet frame buffer, using %dK of video memory\n",
|
||||
info->node, videomemorysize >> 10);
|
||||
fb_info(info, "Broadsheet frame buffer, using %dK of video memory\n",
|
||||
videomemorysize >> 10);
|
||||
|
||||
|
||||
return 0;
|
||||
|
|
@ -1217,19 +1216,7 @@ static struct platform_driver broadsheetfb_driver = {
|
|||
.name = "broadsheetfb",
|
||||
},
|
||||
};
|
||||
|
||||
static int __init broadsheetfb_init(void)
|
||||
{
|
||||
return platform_driver_register(&broadsheetfb_driver);
|
||||
}
|
||||
|
||||
static void __exit broadsheetfb_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&broadsheetfb_driver);
|
||||
}
|
||||
|
||||
module_init(broadsheetfb_init);
|
||||
module_exit(broadsheetfb_exit);
|
||||
module_platform_driver(broadsheetfb_driver);
|
||||
|
||||
MODULE_DESCRIPTION("fbdev driver for Broadsheet controller");
|
||||
MODULE_AUTHOR("Jaya Kumar");
|
||||
|
|
|
|||
|
|
@ -363,8 +363,6 @@ static int bw2_remove(struct platform_device *op)
|
|||
|
||||
framebuffer_release(info);
|
||||
|
||||
dev_set_drvdata(&op->dev, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -585,8 +585,7 @@ static int alloc_carmine_fb(void __iomem *regs, void __iomem *smem_base,
|
|||
if (ret < 0)
|
||||
goto err_dealloc_cmap;
|
||||
|
||||
printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
|
||||
info->fix.id);
|
||||
fb_info(info, "%s frame buffer device\n", info->fix.id);
|
||||
|
||||
*rinfo = info;
|
||||
return 0;
|
||||
|
|
@ -746,7 +745,6 @@ static void carminefb_remove(struct pci_dev *dev)
|
|||
iounmap(hw->v_regs);
|
||||
release_mem_region(fix.mmio_start, fix.mmio_len);
|
||||
|
||||
pci_set_drvdata(dev, NULL);
|
||||
pci_disable_device(dev);
|
||||
kfree(hw);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ static inline void slow_imageblit(const struct fb_image *image, struct fb_info *
|
|||
}
|
||||
shift += bpp;
|
||||
shift &= (32 - 1);
|
||||
if (!l) { l = 8; s++; };
|
||||
if (!l) { l = 8; s++; }
|
||||
}
|
||||
|
||||
/* write trailing bits */
|
||||
|
|
|
|||
|
|
@ -330,7 +330,7 @@ static int cg14_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
|
|||
default:
|
||||
ret = -ENOSYS;
|
||||
break;
|
||||
};
|
||||
}
|
||||
if (!ret) {
|
||||
sbus_writeb(cur_mode, ®s->mcr);
|
||||
par->mode = mode;
|
||||
|
|
@ -343,7 +343,7 @@ static int cg14_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
|
|||
FBTYPE_MDICOLOR, 8,
|
||||
info->fix.smem_len);
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -583,8 +583,6 @@ static int cg14_remove(struct platform_device *op)
|
|||
|
||||
framebuffer_release(info);
|
||||
|
||||
dev_set_drvdata(&op->dev, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -446,8 +446,6 @@ static int cg3_remove(struct platform_device *op)
|
|||
|
||||
framebuffer_release(info);
|
||||
|
||||
dev_set_drvdata(&op->dev, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -624,7 +624,7 @@ static void cg6_init_fix(struct fb_info *info, int linebytes)
|
|||
default:
|
||||
cg6_cpu_name = "i386";
|
||||
break;
|
||||
};
|
||||
}
|
||||
if (((conf >> CG6_FHC_REV_SHIFT) & CG6_FHC_REV_MASK) >= 11) {
|
||||
if (info->fix.smem_len <= 0x100000)
|
||||
cg6_card_name = "TGX";
|
||||
|
|
@ -839,8 +839,6 @@ static int cg6_remove(struct platform_device *op)
|
|||
|
||||
framebuffer_release(info);
|
||||
|
||||
dev_set_drvdata(&op->dev, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -595,11 +595,6 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (var->xoffset < 0)
|
||||
var->xoffset = 0;
|
||||
if (var->yoffset < 0)
|
||||
var->yoffset = 0;
|
||||
|
||||
/* truncate xoffset and yoffset to maximum if too high */
|
||||
if (var->xoffset > var->xres_virtual - var->xres)
|
||||
var->xoffset = var->xres_virtual - var->xres - 1;
|
||||
|
|
@ -2159,7 +2154,6 @@ static int cirrusfb_pci_register(struct pci_dev *pdev,
|
|||
if (!ret)
|
||||
return 0;
|
||||
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
iounmap(info->screen_base);
|
||||
err_release_legacy:
|
||||
if (release_io_ports)
|
||||
|
|
|
|||
|
|
@ -368,8 +368,7 @@ static int cobalt_lcdfb_probe(struct platform_device *dev)
|
|||
|
||||
lcd_clear(info);
|
||||
|
||||
printk(KERN_INFO "fb%d: Cobalt server LCD frame buffer device\n",
|
||||
info->node);
|
||||
fb_info(info, "Cobalt server LCD frame buffer device\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -395,19 +394,7 @@ static struct platform_driver cobalt_lcdfb_driver = {
|
|||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init cobalt_lcdfb_init(void)
|
||||
{
|
||||
return platform_driver_register(&cobalt_lcdfb_driver);
|
||||
}
|
||||
|
||||
static void __exit cobalt_lcdfb_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&cobalt_lcdfb_driver);
|
||||
}
|
||||
|
||||
module_init(cobalt_lcdfb_init);
|
||||
module_exit(cobalt_lcdfb_exit);
|
||||
module_platform_driver(cobalt_lcdfb_driver);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_AUTHOR("Yoichi Yuasa");
|
||||
|
|
|
|||
|
|
@ -471,8 +471,8 @@ try_again:
|
|||
/* Register with fbdev layer */
|
||||
if (register_framebuffer(&p->info) < 0)
|
||||
return -ENXIO;
|
||||
|
||||
printk(KERN_INFO "fb%d: control display adapter\n", p->info.node);
|
||||
|
||||
fb_info(&p->info, "control display adapter\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1810,11 +1810,6 @@ static void cyberpro_pci_remove(struct pci_dev *dev)
|
|||
iounmap(cfb->region);
|
||||
cyberpro_free_fb_info(cfb);
|
||||
|
||||
/*
|
||||
* Ensure that the driver data is no longer
|
||||
* valid.
|
||||
*/
|
||||
pci_set_drvdata(dev, NULL);
|
||||
if (cfb == int_cfb_info)
|
||||
int_cfb_info = NULL;
|
||||
|
||||
|
|
|
|||
|
|
@ -129,7 +129,6 @@
|
|||
|
||||
#define LCD_NUM_BUFFERS 2
|
||||
|
||||
#define WSI_TIMEOUT 50
|
||||
#define PALETTE_SIZE 256
|
||||
|
||||
#define CLK_MIN_DIV 2
|
||||
|
|
@ -1314,7 +1313,7 @@ static struct fb_ops da8xx_fb_ops = {
|
|||
|
||||
static struct fb_videomode *da8xx_fb_get_videomode(struct platform_device *dev)
|
||||
{
|
||||
struct da8xx_lcdc_platform_data *fb_pdata = dev->dev.platform_data;
|
||||
struct da8xx_lcdc_platform_data *fb_pdata = dev_get_platdata(&dev->dev);
|
||||
struct fb_videomode *lcdc_info;
|
||||
int i;
|
||||
|
||||
|
|
@ -1336,7 +1335,7 @@ static struct fb_videomode *da8xx_fb_get_videomode(struct platform_device *dev)
|
|||
static int fb_probe(struct platform_device *device)
|
||||
{
|
||||
struct da8xx_lcdc_platform_data *fb_pdata =
|
||||
device->dev.platform_data;
|
||||
dev_get_platdata(&device->dev);
|
||||
static struct resource *lcdc_regs;
|
||||
struct lcd_ctrl_config *lcd_cfg;
|
||||
struct fb_videomode *lcdc_info;
|
||||
|
|
@ -1548,7 +1547,7 @@ err_pm_runtime_disable:
|
|||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
struct lcdc_context {
|
||||
static struct lcdc_context {
|
||||
u32 clk_enable;
|
||||
u32 ctrl;
|
||||
u32 dma_ctrl;
|
||||
|
|
@ -1663,19 +1662,7 @@ static struct platform_driver da8xx_fb_driver = {
|
|||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init da8xx_fb_init(void)
|
||||
{
|
||||
return platform_driver_register(&da8xx_fb_driver);
|
||||
}
|
||||
|
||||
static void __exit da8xx_fb_cleanup(void)
|
||||
{
|
||||
platform_driver_unregister(&da8xx_fb_driver);
|
||||
}
|
||||
|
||||
module_init(da8xx_fb_init);
|
||||
module_exit(da8xx_fb_cleanup);
|
||||
module_platform_driver(da8xx_fb_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Framebuffer driver for TI da8xx/omap-l1xx");
|
||||
MODULE_AUTHOR("Texas Instruments");
|
||||
|
|
|
|||
|
|
@ -108,8 +108,8 @@ static int efifb_setup(char *options)
|
|||
if (!*this_opt) continue;
|
||||
|
||||
for (i = 0; i < M_UNKNOWN; i++) {
|
||||
if (!strcmp(this_opt, efifb_dmi_list[i].optname) &&
|
||||
efifb_dmi_list[i].base != 0) {
|
||||
if (efifb_dmi_list[i].base != 0 &&
|
||||
!strcmp(this_opt, efifb_dmi_list[i].optname)) {
|
||||
screen_info.lfb_base = efifb_dmi_list[i].base;
|
||||
screen_info.lfb_linelength = efifb_dmi_list[i].stride;
|
||||
screen_info.lfb_width = efifb_dmi_list[i].width;
|
||||
|
|
@ -322,8 +322,7 @@ static int efifb_probe(struct platform_device *dev)
|
|||
printk(KERN_ERR "efifb: cannot register framebuffer\n");
|
||||
goto err_fb_dealoc;
|
||||
}
|
||||
printk(KERN_INFO "fb%d: %s frame buffer device\n",
|
||||
info->node, info->fix.id);
|
||||
fb_info(info, "%s frame buffer device\n", info->fix.id);
|
||||
return 0;
|
||||
|
||||
err_fb_dealoc:
|
||||
|
|
|
|||
|
|
@ -487,7 +487,7 @@ static void ep93xxfb_dealloc_videomem(struct fb_info *info)
|
|||
|
||||
static int ep93xxfb_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct ep93xxfb_mach_info *mach_info = pdev->dev.platform_data;
|
||||
struct ep93xxfb_mach_info *mach_info = dev_get_platdata(&pdev->dev);
|
||||
struct fb_info *info;
|
||||
struct ep93xx_fbi *fbi;
|
||||
struct resource *res;
|
||||
|
|
|
|||
|
|
@ -376,6 +376,7 @@ int exynos_mipi_dsi_rd_data(struct mipi_dsim_device *dsim, unsigned int data_id,
|
|||
"data id %x is not supported current DSI spec.\n",
|
||||
data_id);
|
||||
|
||||
mutex_unlock(&dsim->lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -667,7 +668,7 @@ int exynos_mipi_dsi_init_dsim(struct mipi_dsim_device *dsim)
|
|||
default:
|
||||
dev_info(dsim->dev, "data lane is invalid.\n");
|
||||
return -EINVAL;
|
||||
};
|
||||
}
|
||||
|
||||
exynos_mipi_dsi_sw_reset(dsim);
|
||||
exynos_mipi_dsi_func_reset(dsim);
|
||||
|
|
|
|||
|
|
@ -713,9 +713,8 @@ static int unifb_probe(struct platform_device *dev)
|
|||
platform_set_drvdata(dev, info);
|
||||
platform_device_add_data(dev, unifb_regs, sizeof(u32) * UNIFB_REGS_NUM);
|
||||
|
||||
printk(KERN_INFO
|
||||
"fb%d: Virtual frame buffer device, using %dM of video memory\n",
|
||||
info->node, UNIFB_MEMSIZE >> 20);
|
||||
fb_info(info, "Virtual frame buffer device, using %dM of video memory\n",
|
||||
UNIFB_MEMSIZE >> 20);
|
||||
return 0;
|
||||
err2:
|
||||
fb_dealloc_cmap(&info->cmap);
|
||||
|
|
|
|||
|
|
@ -1108,14 +1108,16 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
|
|||
case FBIOPUT_VSCREENINFO:
|
||||
if (copy_from_user(&var, argp, sizeof(var)))
|
||||
return -EFAULT;
|
||||
if (!lock_fb_info(info))
|
||||
return -ENODEV;
|
||||
console_lock();
|
||||
if (!lock_fb_info(info)) {
|
||||
console_unlock();
|
||||
return -ENODEV;
|
||||
}
|
||||
info->flags |= FBINFO_MISC_USEREVENT;
|
||||
ret = fb_set_var(info, &var);
|
||||
info->flags &= ~FBINFO_MISC_USEREVENT;
|
||||
console_unlock();
|
||||
unlock_fb_info(info);
|
||||
console_unlock();
|
||||
if (!ret && copy_to_user(argp, &var, sizeof(var)))
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
|
|
@ -1144,12 +1146,14 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
|
|||
case FBIOPAN_DISPLAY:
|
||||
if (copy_from_user(&var, argp, sizeof(var)))
|
||||
return -EFAULT;
|
||||
if (!lock_fb_info(info))
|
||||
return -ENODEV;
|
||||
console_lock();
|
||||
if (!lock_fb_info(info)) {
|
||||
console_unlock();
|
||||
return -ENODEV;
|
||||
}
|
||||
ret = fb_pan_display(info, &var);
|
||||
console_unlock();
|
||||
unlock_fb_info(info);
|
||||
console_unlock();
|
||||
if (ret == 0 && copy_to_user(argp, &var, sizeof(var)))
|
||||
return -EFAULT;
|
||||
break;
|
||||
|
|
@ -1184,23 +1188,27 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
|
|||
break;
|
||||
}
|
||||
event.data = &con2fb;
|
||||
if (!lock_fb_info(info))
|
||||
return -ENODEV;
|
||||
console_lock();
|
||||
if (!lock_fb_info(info)) {
|
||||
console_unlock();
|
||||
return -ENODEV;
|
||||
}
|
||||
event.info = info;
|
||||
ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, &event);
|
||||
console_unlock();
|
||||
unlock_fb_info(info);
|
||||
console_unlock();
|
||||
break;
|
||||
case FBIOBLANK:
|
||||
if (!lock_fb_info(info))
|
||||
return -ENODEV;
|
||||
console_lock();
|
||||
if (!lock_fb_info(info)) {
|
||||
console_unlock();
|
||||
return -ENODEV;
|
||||
}
|
||||
info->flags |= FBINFO_MISC_USEREVENT;
|
||||
ret = fb_blank(info, arg);
|
||||
info->flags &= ~FBINFO_MISC_USEREVENT;
|
||||
console_unlock();
|
||||
unlock_fb_info(info);
|
||||
console_unlock();
|
||||
break;
|
||||
default:
|
||||
if (!lock_fb_info(info))
|
||||
|
|
@ -1660,12 +1668,15 @@ static int do_register_framebuffer(struct fb_info *fb_info)
|
|||
registered_fb[i] = fb_info;
|
||||
|
||||
event.info = fb_info;
|
||||
if (!lock_fb_info(fb_info))
|
||||
return -ENODEV;
|
||||
console_lock();
|
||||
if (!lock_fb_info(fb_info)) {
|
||||
console_unlock();
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event);
|
||||
console_unlock();
|
||||
unlock_fb_info(fb_info);
|
||||
console_unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1678,13 +1689,16 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
|
|||
if (i < 0 || i >= FB_MAX || registered_fb[i] != fb_info)
|
||||
return -EINVAL;
|
||||
|
||||
if (!lock_fb_info(fb_info))
|
||||
return -ENODEV;
|
||||
console_lock();
|
||||
if (!lock_fb_info(fb_info)) {
|
||||
console_unlock();
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
event.info = fb_info;
|
||||
ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event);
|
||||
console_unlock();
|
||||
unlock_fb_info(fb_info);
|
||||
console_unlock();
|
||||
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
|
|
|
|||
|
|
@ -177,9 +177,12 @@ static ssize_t store_modes(struct device *device,
|
|||
if (i * sizeof(struct fb_videomode) != count)
|
||||
return -EINVAL;
|
||||
|
||||
if (!lock_fb_info(fb_info))
|
||||
return -ENODEV;
|
||||
console_lock();
|
||||
if (!lock_fb_info(fb_info)) {
|
||||
console_unlock();
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
list_splice(&fb_info->modelist, &old_list);
|
||||
fb_videomode_to_modelist((const struct fb_videomode *)buf, i,
|
||||
&fb_info->modelist);
|
||||
|
|
@ -189,8 +192,8 @@ static ssize_t store_modes(struct device *device,
|
|||
} else
|
||||
fb_destroy_modelist(&old_list);
|
||||
|
||||
console_unlock();
|
||||
unlock_fb_info(fb_info);
|
||||
console_unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -404,12 +407,16 @@ static ssize_t store_fbstate(struct device *device,
|
|||
|
||||
state = simple_strtoul(buf, &last, 0);
|
||||
|
||||
if (!lock_fb_info(fb_info))
|
||||
return -ENODEV;
|
||||
console_lock();
|
||||
if (!lock_fb_info(fb_info)) {
|
||||
console_unlock();
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
fb_set_suspend(fb_info, (int)state);
|
||||
console_unlock();
|
||||
|
||||
unlock_fb_info(fb_info);
|
||||
console_unlock();
|
||||
|
||||
return count;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1035,8 +1035,6 @@ static int ffb_remove(struct platform_device *op)
|
|||
|
||||
framebuffer_release(info);
|
||||
|
||||
dev_set_drvdata(&op->dev, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -289,7 +289,7 @@ static int fm2fb_probe(struct zorro_dev *z, const struct zorro_device_id *id)
|
|||
zorro_release_device(z);
|
||||
return -EINVAL;
|
||||
}
|
||||
printk("fb%d: %s frame buffer device\n", info->node, fb_fix.id);
|
||||
fb_info(info, "%s frame buffer device\n", fb_fix.id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1104,7 +1104,7 @@ static int fsl_diu_cursor(struct fb_info *info, struct fb_cursor *cursor)
|
|||
|
||||
fsl_diu_load_cursor_image(info, image, bg, fg,
|
||||
cursor->image.width, cursor->image.height);
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* Show or hide the cursor. The cursor data is always stored in the
|
||||
|
|
|
|||
|
|
@ -1236,9 +1236,9 @@ static int gbefb_probe(struct platform_device *p_dev)
|
|||
platform_set_drvdata(p_dev, info);
|
||||
gbefb_create_sysfs(&p_dev->dev);
|
||||
|
||||
printk(KERN_INFO "fb%d: %s rev %d @ 0x%08x using %dkB memory\n",
|
||||
info->node, info->fix.id, gbe_revision, (unsigned) GBE_BASE,
|
||||
gbe_mem_size >> 10);
|
||||
fb_info(info, "%s rev %d @ 0x%08x using %dkB memory\n",
|
||||
info->fix.id, gbe_revision, (unsigned)GBE_BASE,
|
||||
gbe_mem_size >> 10);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -357,7 +357,7 @@ static int gx1fb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
goto err;
|
||||
}
|
||||
pci_set_drvdata(pdev, info);
|
||||
printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id);
|
||||
fb_info(info, "%s frame buffer device\n", info->fix.id);
|
||||
return 0;
|
||||
|
||||
err:
|
||||
|
|
@ -399,7 +399,6 @@ static void gx1fb_remove(struct pci_dev *pdev)
|
|||
release_mem_region(gx1_gx_base() + 0x8300, 0x100);
|
||||
|
||||
fb_dealloc_cmap(&info->cmap);
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
|
||||
framebuffer_release(info);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -423,7 +423,7 @@ static int gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
goto err;
|
||||
}
|
||||
pci_set_drvdata(pdev, info);
|
||||
printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id);
|
||||
fb_info(info, "%s frame buffer device\n", info->fix.id);
|
||||
return 0;
|
||||
|
||||
err:
|
||||
|
|
@ -471,7 +471,6 @@ static void gxfb_remove(struct pci_dev *pdev)
|
|||
pci_release_region(pdev, 1);
|
||||
|
||||
fb_dealloc_cmap(&info->cmap);
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
|
||||
framebuffer_release(info);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -555,8 +555,7 @@ static int lxfb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
goto err;
|
||||
}
|
||||
pci_set_drvdata(pdev, info);
|
||||
printk(KERN_INFO "fb%d: %s frame buffer device\n",
|
||||
info->node, info->fix.id);
|
||||
fb_info(info, "%s frame buffer device\n", info->fix.id);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
@ -606,7 +605,6 @@ static void lxfb_remove(struct pci_dev *pdev)
|
|||
pci_release_region(pdev, 3);
|
||||
|
||||
fb_dealloc_cmap(&info->cmap);
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
framebuffer_release(info);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -496,7 +496,6 @@ static int grvga_probe(struct platform_device *dev)
|
|||
return 0;
|
||||
|
||||
free_mem:
|
||||
dev_set_drvdata(&dev->dev, NULL);
|
||||
if (grvga_fix_addr)
|
||||
iounmap((void *)virtual_start);
|
||||
else
|
||||
|
|
@ -530,7 +529,6 @@ static int grvga_remove(struct platform_device *device)
|
|||
kfree((void *)info->screen_base);
|
||||
|
||||
framebuffer_release(info);
|
||||
dev_set_drvdata(&device->dev, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -557,19 +555,7 @@ static struct platform_driver grvga_driver = {
|
|||
.remove = 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_platform_driver(grvga_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Aeroflex Gaisler");
|
||||
|
|
|
|||
|
|
@ -698,8 +698,7 @@ static int gxt4500_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
dev_err(&pdev->dev, "gxt4500: cannot register framebuffer\n");
|
||||
goto err_free_cmap;
|
||||
}
|
||||
printk(KERN_INFO "fb%d: %s frame buffer device\n",
|
||||
info->node, info->fix.id);
|
||||
fb_info(info, "%s frame buffer device\n", info->fix.id);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -261,9 +261,8 @@ static int hecubafb_probe(struct platform_device *dev)
|
|||
goto err_fbreg;
|
||||
platform_set_drvdata(dev, info);
|
||||
|
||||
printk(KERN_INFO
|
||||
"fb%d: Hecuba frame buffer device, using %dK of video memory\n",
|
||||
info->node, videomemorysize >> 10);
|
||||
fb_info(info, "Hecuba frame buffer device, using %dK of video memory\n",
|
||||
videomemorysize >> 10);
|
||||
|
||||
/* this inits the dpy */
|
||||
retval = par->board->init(par);
|
||||
|
|
@ -305,19 +304,7 @@ static struct platform_driver hecubafb_driver = {
|
|||
.name = "hecubafb",
|
||||
},
|
||||
};
|
||||
|
||||
static int __init hecubafb_init(void)
|
||||
{
|
||||
return platform_driver_register(&hecubafb_driver);
|
||||
}
|
||||
|
||||
static void __exit hecubafb_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&hecubafb_driver);
|
||||
}
|
||||
|
||||
module_init(hecubafb_init);
|
||||
module_exit(hecubafb_exit);
|
||||
module_platform_driver(hecubafb_driver);
|
||||
|
||||
MODULE_DESCRIPTION("fbdev driver for Hecuba/Apollo controller");
|
||||
MODULE_AUTHOR("Jaya Kumar");
|
||||
|
|
|
|||
|
|
@ -586,8 +586,7 @@ static int hgafb_probe(struct platform_device *pdev)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "fb%d: %s frame buffer device\n",
|
||||
info->node, info->fix.id);
|
||||
fb_info(info, "%s frame buffer device\n", info->fix.id);
|
||||
platform_set_drvdata(pdev, info);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -405,8 +405,7 @@ static int hitfb_probe(struct platform_device *dev)
|
|||
|
||||
platform_set_drvdata(dev, info);
|
||||
|
||||
printk(KERN_INFO "fb%d: %s frame buffer device\n",
|
||||
info->node, info->fix.id);
|
||||
fb_info(info, "%s frame buffer device\n", info->fix.id);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -298,8 +298,7 @@ static int hpfb_init_one(unsigned long phys_base, unsigned long virt_base)
|
|||
if (ret < 0)
|
||||
goto dealloc_cmap;
|
||||
|
||||
printk(KERN_INFO "fb%d: %s frame buffer device\n",
|
||||
fb_info.node, fb_info.fix.id);
|
||||
fb_info(&fb_info, "%s frame buffer device\n", fb_info.fix.id);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -575,6 +575,10 @@ static int hvfb_setcolreg(unsigned regno, unsigned red, unsigned green,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int hvfb_blank(int blank, struct fb_info *info)
|
||||
{
|
||||
return 1; /* get fb_blank to set the colormap to all black */
|
||||
}
|
||||
|
||||
static struct fb_ops hvfb_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
|
|
@ -584,6 +588,7 @@ static struct fb_ops hvfb_ops = {
|
|||
.fb_fillrect = cfb_fillrect,
|
||||
.fb_copyarea = cfb_copyarea,
|
||||
.fb_imageblit = cfb_imageblit,
|
||||
.fb_blank = hvfb_blank,
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -795,12 +800,21 @@ static int hvfb_remove(struct hv_device *hdev)
|
|||
}
|
||||
|
||||
|
||||
static DEFINE_PCI_DEVICE_TABLE(pci_stub_id_table) = {
|
||||
{
|
||||
.vendor = PCI_VENDOR_ID_MICROSOFT,
|
||||
.device = PCI_DEVICE_ID_HYPERV_VIDEO,
|
||||
},
|
||||
{ /* end of list */ }
|
||||
};
|
||||
|
||||
static const struct hv_vmbus_device_id id_table[] = {
|
||||
/* Synthetic Video Device GUID */
|
||||
{HV_SYNTHVID_GUID},
|
||||
{}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, pci_stub_id_table);
|
||||
MODULE_DEVICE_TABLE(vmbus, id_table);
|
||||
|
||||
static struct hv_driver hvfb_drv = {
|
||||
|
|
@ -810,14 +824,43 @@ static struct hv_driver hvfb_drv = {
|
|||
.remove = hvfb_remove,
|
||||
};
|
||||
|
||||
static int hvfb_pci_stub_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hvfb_pci_stub_remove(struct pci_dev *pdev)
|
||||
{
|
||||
}
|
||||
|
||||
static struct pci_driver hvfb_pci_stub_driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = pci_stub_id_table,
|
||||
.probe = hvfb_pci_stub_probe,
|
||||
.remove = hvfb_pci_stub_remove,
|
||||
};
|
||||
|
||||
static int __init hvfb_drv_init(void)
|
||||
{
|
||||
return vmbus_driver_register(&hvfb_drv);
|
||||
int ret;
|
||||
|
||||
ret = vmbus_driver_register(&hvfb_drv);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = pci_register_driver(&hvfb_pci_stub_driver);
|
||||
if (ret != 0) {
|
||||
vmbus_driver_unregister(&hvfb_drv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit hvfb_drv_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&hvfb_pci_stub_driver);
|
||||
vmbus_driver_unregister(&hvfb_drv);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -203,8 +203,7 @@ static int i740fb_release(struct fb_info *info, int user)
|
|||
|
||||
mutex_lock(&(par->open_lock));
|
||||
if (par->ref_count == 0) {
|
||||
printk(KERN_ERR "fb%d: release called with zero refcount\n",
|
||||
info->node);
|
||||
fb_err(info, "release called with zero refcount\n");
|
||||
mutex_unlock(&(par->open_lock));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -1067,7 +1066,7 @@ static int i740fb_probe(struct pci_dev *dev, const struct pci_device_id *ent)
|
|||
par->has_sgram = !((tmp & DRAM_RAS_TIMING) ||
|
||||
(tmp & DRAM_RAS_PRECHARGE));
|
||||
|
||||
printk(KERN_INFO "fb%d: Intel740 on %s, %ld KB %s\n", info->node,
|
||||
fb_info(info, "Intel740 on %s, %ld KB %s\n",
|
||||
pci_name(dev), info->screen_size >> 10,
|
||||
par->has_sgram ? "SGRAM" : "SDRAM");
|
||||
|
||||
|
|
@ -1143,8 +1142,7 @@ static int i740fb_probe(struct pci_dev *dev, const struct pci_device_id *ent)
|
|||
goto err_reg_framebuffer;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "fb%d: %s frame buffer device\n",
|
||||
info->node, info->fix.id);
|
||||
fb_info(info, "%s frame buffer device\n", info->fix.id);
|
||||
pci_set_drvdata(dev, info);
|
||||
#ifdef CONFIG_MTRR
|
||||
if (mtrr) {
|
||||
|
|
@ -1194,7 +1192,6 @@ static void i740fb_remove(struct pci_dev *dev)
|
|||
pci_iounmap(dev, info->screen_base);
|
||||
pci_release_regions(dev);
|
||||
/* pci_disable_device(dev); */
|
||||
pci_set_drvdata(dev, NULL);
|
||||
framebuffer_release(info);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2129,7 +2129,6 @@ static void __exit i810fb_remove_pci(struct pci_dev *dev)
|
|||
|
||||
unregister_framebuffer(info);
|
||||
i810fb_release_resource(info, par);
|
||||
pci_set_drvdata(dev, NULL);
|
||||
printk("cleanup_module: unloaded i810 framebuffer device\n");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -360,9 +360,8 @@ static int __init iga_init(struct fb_info *info, struct iga_par *par)
|
|||
if (register_framebuffer(info) < 0)
|
||||
return 0;
|
||||
|
||||
printk("fb%d: %s frame buffer device at 0x%08lx [%dMB VRAM]\n",
|
||||
info->node, info->fix.id,
|
||||
par->frame_buffer_phys, info->fix.smem_len >> 20);
|
||||
fb_info(info, "%s frame buffer device at 0x%08lx [%dMB VRAM]\n",
|
||||
info->fix.id, par->frame_buffer_phys, info->fix.smem_len >> 20);
|
||||
|
||||
iga_blank_border(par);
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -1461,8 +1461,8 @@ static void init_imstt(struct fb_info *info)
|
|||
}
|
||||
|
||||
tmp = (read_reg_le32(par->dc_regs, SSTATUS) & 0x0f00) >> 8;
|
||||
printk("fb%u: %s frame buffer; %uMB vram; chip version %u\n",
|
||||
info->node, info->fix.id, info->fix.smem_len >> 20, tmp);
|
||||
fb_info(info, "%s frame buffer; %uMB vram; chip version %u\n",
|
||||
info->fix.id, info->fix.smem_len >> 20, tmp);
|
||||
}
|
||||
|
||||
static int imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
|
|
|
|||
|
|
@ -755,7 +755,7 @@ static int imxfb_resume(struct platform_device *dev)
|
|||
|
||||
static int imxfb_init_fbinfo(struct platform_device *pdev)
|
||||
{
|
||||
struct imx_fb_platform_data *pdata = pdev->dev.platform_data;
|
||||
struct imx_fb_platform_data *pdata = dev_get_platdata(&pdev->dev);
|
||||
struct fb_info *info = dev_get_drvdata(&pdev->dev);
|
||||
struct imxfb_info *fbi = info->par;
|
||||
struct device_node *np;
|
||||
|
|
@ -877,7 +877,7 @@ static int imxfb_probe(struct platform_device *pdev)
|
|||
if (!res)
|
||||
return -ENODEV;
|
||||
|
||||
pdata = pdev->dev.platform_data;
|
||||
pdata = dev_get_platdata(&pdev->dev);
|
||||
|
||||
info = framebuffer_alloc(sizeof(struct imxfb_info), &pdev->dev);
|
||||
if (!info)
|
||||
|
|
@ -1066,7 +1066,7 @@ static int imxfb_remove(struct platform_device *pdev)
|
|||
#endif
|
||||
unregister_framebuffer(info);
|
||||
|
||||
pdata = pdev->dev.platform_data;
|
||||
pdata = dev_get_platdata(&pdev->dev);
|
||||
if (pdata && pdata->exit)
|
||||
pdata->exit(fbi->pdev);
|
||||
|
||||
|
|
|
|||
|
|
@ -931,8 +931,6 @@ static void intelfb_pci_unregister(struct pci_dev *pdev)
|
|||
return;
|
||||
|
||||
cleanup(dinfo);
|
||||
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
|
|
|
|||
|
|
@ -99,9 +99,9 @@
|
|||
#define JZ_LCD_CTRL_BPP_15_16 0x4
|
||||
#define JZ_LCD_CTRL_BPP_18_24 0x5
|
||||
|
||||
#define JZ_LCD_CMD_SOF_IRQ BIT(15)
|
||||
#define JZ_LCD_CMD_EOF_IRQ BIT(16)
|
||||
#define JZ_LCD_CMD_ENABLE_PAL BIT(12)
|
||||
#define JZ_LCD_CMD_SOF_IRQ BIT(31)
|
||||
#define JZ_LCD_CMD_EOF_IRQ BIT(30)
|
||||
#define JZ_LCD_CMD_ENABLE_PAL BIT(28)
|
||||
|
||||
#define JZ_LCD_SYNC_MASK 0x3ff
|
||||
|
||||
|
|
@ -471,7 +471,7 @@ static int jzfb_set_par(struct fb_info *info)
|
|||
writel(ctrl, jzfb->base + JZ_REG_LCD_CTRL);
|
||||
|
||||
if (!jzfb->is_enabled)
|
||||
clk_disable(jzfb->ldclk);
|
||||
clk_disable_unprepare(jzfb->ldclk);
|
||||
|
||||
mutex_unlock(&jzfb->lock);
|
||||
|
||||
|
|
@ -485,7 +485,7 @@ static void jzfb_enable(struct jzfb *jzfb)
|
|||
{
|
||||
uint32_t ctrl;
|
||||
|
||||
clk_enable(jzfb->ldclk);
|
||||
clk_prepare_enable(jzfb->ldclk);
|
||||
|
||||
jz_gpio_bulk_resume(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));
|
||||
jz_gpio_bulk_resume(jz_lcd_data_pins, jzfb_num_data_pins(jzfb));
|
||||
|
|
@ -514,7 +514,7 @@ static void jzfb_disable(struct jzfb *jzfb)
|
|||
jz_gpio_bulk_suspend(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));
|
||||
jz_gpio_bulk_suspend(jz_lcd_data_pins, jzfb_num_data_pins(jzfb));
|
||||
|
||||
clk_disable(jzfb->ldclk);
|
||||
clk_disable_unprepare(jzfb->ldclk);
|
||||
}
|
||||
|
||||
static int jzfb_blank(int blank_mode, struct fb_info *info)
|
||||
|
|
@ -693,7 +693,7 @@ static int jzfb_probe(struct platform_device *pdev)
|
|||
|
||||
fb_alloc_cmap(&fb->cmap, 256, 0);
|
||||
|
||||
clk_enable(jzfb->ldclk);
|
||||
clk_prepare_enable(jzfb->ldclk);
|
||||
jzfb->is_enabled = 1;
|
||||
|
||||
writel(jzfb->framedesc->next, jzfb->base + JZ_REG_LCD_DA0);
|
||||
|
|
@ -763,7 +763,7 @@ static int jzfb_suspend(struct device *dev)
|
|||
static int jzfb_resume(struct device *dev)
|
||||
{
|
||||
struct jzfb *jzfb = dev_get_drvdata(dev);
|
||||
clk_enable(jzfb->ldclk);
|
||||
clk_prepare_enable(jzfb->ldclk);
|
||||
|
||||
mutex_lock(&jzfb->lock);
|
||||
if (jzfb->is_enabled)
|
||||
|
|
@ -798,18 +798,7 @@ static struct platform_driver jzfb_driver = {
|
|||
.pm = JZFB_PM_OPS,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init jzfb_init(void)
|
||||
{
|
||||
return platform_driver_register(&jzfb_driver);
|
||||
}
|
||||
module_init(jzfb_init);
|
||||
|
||||
static void __exit jzfb_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&jzfb_driver);
|
||||
}
|
||||
module_exit(jzfb_exit);
|
||||
module_platform_driver(jzfb_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Lars-Peter Clausen <[email protected]>");
|
||||
|
|
|
|||
|
|
@ -623,7 +623,6 @@ static int kyrofb_ioctl(struct fb_info *info,
|
|||
"command instead.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
case KYRO_IOCTL_UVSTRIDE:
|
||||
if (copy_to_user(argp, &deviceInfo.ulOverlayUVStride, sizeof(unsigned long)))
|
||||
return -EFAULT;
|
||||
|
|
@ -736,10 +735,10 @@ static int kyrofb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
if (register_framebuffer(info) < 0)
|
||||
goto out_unmap;
|
||||
|
||||
printk("fb%d: %s frame buffer device, at %dx%d@%d using %ldk/%ldk of VRAM\n",
|
||||
info->node, info->fix.id, info->var.xres,
|
||||
info->var.yres, info->var.bits_per_pixel, size >> 10,
|
||||
(unsigned long)info->fix.smem_len >> 10);
|
||||
fb_info(info, "%s frame buffer device, at %dx%d@%d using %ldk/%ldk of VRAM\n",
|
||||
info->fix.id,
|
||||
info->var.xres, info->var.yres, info->var.bits_per_pixel,
|
||||
size >> 10, (unsigned long)info->fix.smem_len >> 10);
|
||||
|
||||
pci_set_drvdata(pdev, info);
|
||||
|
||||
|
|
@ -779,7 +778,6 @@ static void kyrofb_remove(struct pci_dev *pdev)
|
|||
#endif
|
||||
|
||||
unregister_framebuffer(info);
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
framebuffer_release(info);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -469,7 +469,7 @@ static void leo_wid_put(struct fb_info *info, struct fb_wid_list *wl)
|
|||
|
||||
default:
|
||||
continue;
|
||||
};
|
||||
}
|
||||
sbus_writel(0x5800 + j, &lx_krn->krn_type);
|
||||
sbus_writel(wi->wi_values[0], &lx_krn->krn_value);
|
||||
}
|
||||
|
|
@ -648,8 +648,6 @@ static int leo_remove(struct platform_device *op)
|
|||
|
||||
framebuffer_release(info);
|
||||
|
||||
dev_set_drvdata(&op->dev, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -913,8 +913,7 @@ static int __init macfb_init(void)
|
|||
if (err)
|
||||
goto fail_dealloc;
|
||||
|
||||
pr_info("fb%d: %s frame buffer device\n",
|
||||
fb_info.node, fb_info.fix.id);
|
||||
fb_info(&fb_info, "%s frame buffer device\n", fb_info.fix.id);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -494,7 +494,7 @@ static int m1064_compute(void* out, struct my_timming* m) {
|
|||
if (inDAC1064(minfo, M1064_XPIXPLLSTAT) & 0x40)
|
||||
break;
|
||||
udelay(10);
|
||||
};
|
||||
}
|
||||
|
||||
CRITEND
|
||||
|
||||
|
|
@ -639,7 +639,7 @@ static void MGAG100_progPixClock(const struct matrox_fb_info *minfo, int flags,
|
|||
if (inDAC1064(minfo, M1064_XPIXPLLSTAT) & 0x40)
|
||||
break;
|
||||
udelay(10);
|
||||
};
|
||||
}
|
||||
if (!clk)
|
||||
printk(KERN_ERR "matroxfb: Pixel PLL%c not locked after usual time\n", (reg-M1064_XPIXPLLAM-2)/4 + 'A');
|
||||
selClk = inDAC1064(minfo, M1064_XPIXCLKCTRL) & ~M1064_XPIXCLKCTRL_SRC_MASK;
|
||||
|
|
|
|||
|
|
@ -473,7 +473,7 @@ static void ti3026_setMCLK(struct matrox_fb_info *minfo, int fout)
|
|||
if (inTi3026(minfo, TVP3026_XPIXPLLDATA) & 0x40)
|
||||
break;
|
||||
udelay(10);
|
||||
};
|
||||
}
|
||||
if (!tmout)
|
||||
printk(KERN_ERR "matroxfb: Temporary pixel PLL not locked after 5 secs\n");
|
||||
|
||||
|
|
|
|||
|
|
@ -1893,14 +1893,12 @@ static int initMatrox2(struct matrox_fb_info *minfo, struct board *b)
|
|||
if (register_framebuffer(&minfo->fbcon) < 0) {
|
||||
goto failVideoIO;
|
||||
}
|
||||
printk("fb%d: %s frame buffer device\n",
|
||||
minfo->fbcon.node, minfo->fbcon.fix.id);
|
||||
fb_info(&minfo->fbcon, "%s frame buffer device\n", minfo->fbcon.fix.id);
|
||||
|
||||
/* there is no console on this fb... but we have to initialize hardware
|
||||
* until someone tells me what is proper thing to do */
|
||||
if (!minfo->initialized) {
|
||||
printk(KERN_INFO "fb%d: initializing hardware\n",
|
||||
minfo->fbcon.node);
|
||||
fb_info(&minfo->fbcon, "initializing hardware\n");
|
||||
/* We have to use FB_ACTIVATE_FORCE, as we had to put vesafb_defined to the fbcon.var
|
||||
* already before, so register_framebuffer works correctly. */
|
||||
vesafb_defined.activate |= FB_ACTIVATE_FORCE;
|
||||
|
|
|
|||
|
|
@ -1295,19 +1295,7 @@ static struct i2c_driver maven_driver={
|
|||
.id_table = maven_id,
|
||||
};
|
||||
|
||||
static int __init matroxfb_maven_init(void)
|
||||
{
|
||||
return i2c_add_driver(&maven_driver);
|
||||
}
|
||||
|
||||
static void __exit matroxfb_maven_exit(void)
|
||||
{
|
||||
i2c_del_driver(&maven_driver);
|
||||
}
|
||||
|
||||
module_i2c_driver(maven_driver);
|
||||
MODULE_AUTHOR("(c) 1999-2002 Petr Vandrovec <[email protected]>");
|
||||
MODULE_DESCRIPTION("Matrox G200/G400 Matrox MGA-TVO driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
module_init(matroxfb_maven_init);
|
||||
module_exit(matroxfb_maven_exit);
|
||||
/* we do not have __setup() yet */
|
||||
|
|
|
|||
|
|
@ -781,7 +781,6 @@ rel_reg:
|
|||
irqdisp:
|
||||
irq_dispose_mapping(par->irq);
|
||||
fbrel:
|
||||
dev_set_drvdata(dev, NULL);
|
||||
framebuffer_release(info);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -814,7 +813,6 @@ static int of_platform_mb862xx_remove(struct platform_device *ofdev)
|
|||
iounmap(par->mmio_base);
|
||||
iounmap(par->fb_base);
|
||||
|
||||
dev_set_drvdata(&ofdev->dev, NULL);
|
||||
release_mem_region(par->res->start, res_size);
|
||||
framebuffer_release(fbi);
|
||||
return 0;
|
||||
|
|
@ -1157,7 +1155,6 @@ static void mb862xx_pci_remove(struct pci_dev *pdev)
|
|||
|
||||
device_remove_file(&pdev->dev, &dev_attr_dispregs);
|
||||
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
unregister_framebuffer(fbi);
|
||||
fb_dealloc_cmap(&fbi->cmap);
|
||||
|
||||
|
|
|
|||
|
|
@ -890,7 +890,7 @@ static int mbxfb_probe(struct platform_device *dev)
|
|||
|
||||
dev_dbg(&dev->dev, "mbxfb_probe\n");
|
||||
|
||||
pdata = dev->dev.platform_data;
|
||||
pdata = dev_get_platdata(&dev->dev);
|
||||
if (!pdata) {
|
||||
dev_err(&dev->dev, "platform data is required\n");
|
||||
return -EINVAL;
|
||||
|
|
@ -976,7 +976,7 @@ static int mbxfb_probe(struct platform_device *dev)
|
|||
|
||||
platform_set_drvdata(dev, fbi);
|
||||
|
||||
printk(KERN_INFO "fb%d: mbx frame buffer device\n", fbi->node);
|
||||
fb_info(fbi, "mbx frame buffer device\n");
|
||||
|
||||
if (mfbi->platform_probe)
|
||||
mfbi->platform_probe(fbi);
|
||||
|
|
|
|||
|
|
@ -690,7 +690,8 @@ static int metronomefb_probe(struct platform_device *dev)
|
|||
goto err_csum_table;
|
||||
}
|
||||
|
||||
if (board->setup_irq(info))
|
||||
retval = board->setup_irq(info);
|
||||
if (retval)
|
||||
goto err_csum_table;
|
||||
|
||||
retval = metronome_init_regs(par);
|
||||
|
|
@ -769,23 +770,11 @@ static struct platform_driver metronomefb_driver = {
|
|||
.name = "metronomefb",
|
||||
},
|
||||
};
|
||||
|
||||
static int __init metronomefb_init(void)
|
||||
{
|
||||
return platform_driver_register(&metronomefb_driver);
|
||||
}
|
||||
|
||||
static void __exit metronomefb_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&metronomefb_driver);
|
||||
}
|
||||
module_platform_driver(metronomefb_driver);
|
||||
|
||||
module_param(user_wfm_size, uint, 0);
|
||||
MODULE_PARM_DESC(user_wfm_size, "Set custom waveform size");
|
||||
|
||||
module_init(metronomefb_init);
|
||||
module_exit(metronomefb_exit);
|
||||
|
||||
MODULE_DESCRIPTION("fbdev driver for Metronome controller");
|
||||
MODULE_AUTHOR("Jaya Kumar");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -392,12 +392,29 @@ static int var_update(struct fb_info *info)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void mmpfb_set_win(struct fb_info *info)
|
||||
{
|
||||
struct mmpfb_info *fbi = info->par;
|
||||
struct fb_var_screeninfo *var = &info->var;
|
||||
struct mmp_win win;
|
||||
u32 stride;
|
||||
|
||||
memset(&win, 0, sizeof(win));
|
||||
win.xsrc = win.xdst = fbi->mode.xres;
|
||||
win.ysrc = win.ydst = fbi->mode.yres;
|
||||
win.pix_fmt = fbi->pix_fmt;
|
||||
stride = pixfmt_to_stride(win.pix_fmt);
|
||||
win.pitch[0] = var->xres_virtual * stride;
|
||||
win.pitch[1] = win.pitch[2] =
|
||||
(stride == 1) ? (var->xres_virtual >> 1) : 0;
|
||||
mmp_overlay_set_win(fbi->overlay, &win);
|
||||
}
|
||||
|
||||
static int mmpfb_set_par(struct fb_info *info)
|
||||
{
|
||||
struct mmpfb_info *fbi = info->par;
|
||||
struct fb_var_screeninfo *var = &info->var;
|
||||
struct mmp_addr addr;
|
||||
struct mmp_win win;
|
||||
struct mmp_mode mode;
|
||||
int ret;
|
||||
|
||||
|
|
@ -409,11 +426,8 @@ static int mmpfb_set_par(struct fb_info *info)
|
|||
fbmode_to_mmpmode(&mode, &fbi->mode, fbi->output_fmt);
|
||||
mmp_path_set_mode(fbi->path, &mode);
|
||||
|
||||
memset(&win, 0, sizeof(win));
|
||||
win.xsrc = win.xdst = fbi->mode.xres;
|
||||
win.ysrc = win.ydst = fbi->mode.yres;
|
||||
win.pix_fmt = fbi->pix_fmt;
|
||||
mmp_overlay_set_win(fbi->overlay, &win);
|
||||
/* set window related info */
|
||||
mmpfb_set_win(info);
|
||||
|
||||
/* set address always */
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
|
|
@ -427,16 +441,12 @@ static int mmpfb_set_par(struct fb_info *info)
|
|||
static void mmpfb_power(struct mmpfb_info *fbi, int power)
|
||||
{
|
||||
struct mmp_addr addr;
|
||||
struct mmp_win win;
|
||||
struct fb_var_screeninfo *var = &fbi->fb_info->var;
|
||||
|
||||
/* for power on, always set address/window again */
|
||||
if (power) {
|
||||
memset(&win, 0, sizeof(win));
|
||||
win.xsrc = win.xdst = fbi->mode.xres;
|
||||
win.ysrc = win.ydst = fbi->mode.yres;
|
||||
win.pix_fmt = fbi->pix_fmt;
|
||||
mmp_overlay_set_win(fbi->overlay, &win);
|
||||
/* set window related info */
|
||||
mmpfb_set_win(fbi->fb_info);
|
||||
|
||||
/* set address always */
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
|
|
|
|||
|
|
@ -53,15 +53,14 @@ static irqreturn_t ctrl_handle_irq(int irq, void *dev_id)
|
|||
tmp = readl_relaxed(ctrl->reg_base + SPU_IRQ_ISR);
|
||||
if (tmp & isr)
|
||||
writel_relaxed(~isr, ctrl->reg_base + SPU_IRQ_ISR);
|
||||
} while ((isr = readl(ctrl->reg_base + SPU_IRQ_ISR)) & imask);
|
||||
} while ((isr = readl_relaxed(ctrl->reg_base + SPU_IRQ_ISR)) & imask);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static u32 fmt_to_reg(struct mmp_overlay *overlay, int pix_fmt)
|
||||
{
|
||||
u32 link_config = path_to_path_plat(overlay->path)->link_config;
|
||||
u32 rbswap, uvswap = 0, yuvswap = 0,
|
||||
u32 rbswap = 0, uvswap = 0, yuvswap = 0,
|
||||
csc_en = 0, val = 0,
|
||||
vid = overlay_is_vid(overlay);
|
||||
|
||||
|
|
@ -71,27 +70,23 @@ static u32 fmt_to_reg(struct mmp_overlay *overlay, int pix_fmt)
|
|||
case PIXFMT_RGB888PACK:
|
||||
case PIXFMT_RGB888UNPACK:
|
||||
case PIXFMT_RGBA888:
|
||||
rbswap = !(link_config & 0x1);
|
||||
rbswap = 1;
|
||||
break;
|
||||
case PIXFMT_VYUY:
|
||||
case PIXFMT_YVU422P:
|
||||
case PIXFMT_YVU420P:
|
||||
rbswap = link_config & 0x1;
|
||||
uvswap = 1;
|
||||
break;
|
||||
case PIXFMT_YUYV:
|
||||
rbswap = link_config & 0x1;
|
||||
yuvswap = 1;
|
||||
break;
|
||||
default:
|
||||
rbswap = link_config & 0x1;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (pix_fmt) {
|
||||
case PIXFMT_RGB565:
|
||||
case PIXFMT_BGR565:
|
||||
val = 0;
|
||||
break;
|
||||
case PIXFMT_RGB1555:
|
||||
case PIXFMT_BGR1555:
|
||||
|
|
@ -147,17 +142,27 @@ static void dmafetch_set_fmt(struct mmp_overlay *overlay)
|
|||
static void overlay_set_win(struct mmp_overlay *overlay, struct mmp_win *win)
|
||||
{
|
||||
struct lcd_regs *regs = path_regs(overlay->path);
|
||||
u32 pitch;
|
||||
|
||||
/* assert win supported */
|
||||
memcpy(&overlay->win, win, sizeof(struct mmp_win));
|
||||
|
||||
mutex_lock(&overlay->access_ok);
|
||||
pitch = win->xsrc * pixfmt_to_stride(win->pix_fmt);
|
||||
writel_relaxed(pitch, ®s->g_pitch);
|
||||
writel_relaxed((win->ysrc << 16) | win->xsrc, ®s->g_size);
|
||||
writel_relaxed((win->ydst << 16) | win->xdst, ®s->g_size_z);
|
||||
writel_relaxed(0, ®s->g_start);
|
||||
|
||||
if (overlay_is_vid(overlay)) {
|
||||
writel_relaxed(win->pitch[0], ®s->v_pitch_yc);
|
||||
writel_relaxed(win->pitch[2] << 16 |
|
||||
win->pitch[1], ®s->v_pitch_uv);
|
||||
|
||||
writel_relaxed((win->ysrc << 16) | win->xsrc, ®s->v_size);
|
||||
writel_relaxed((win->ydst << 16) | win->xdst, ®s->v_size_z);
|
||||
writel_relaxed(win->ypos << 16 | win->xpos, ®s->v_start);
|
||||
} else {
|
||||
writel_relaxed(win->pitch[0], ®s->g_pitch);
|
||||
|
||||
writel_relaxed((win->ysrc << 16) | win->xsrc, ®s->g_size);
|
||||
writel_relaxed((win->ydst << 16) | win->xdst, ®s->g_size_z);
|
||||
writel_relaxed(win->ypos << 16 | win->xpos, ®s->g_start);
|
||||
}
|
||||
|
||||
dmafetch_set_fmt(overlay);
|
||||
mutex_unlock(&overlay->access_ok);
|
||||
|
|
@ -239,7 +244,13 @@ static int overlay_set_addr(struct mmp_overlay *overlay, struct mmp_addr *addr)
|
|||
|
||||
/* FIXME: assert addr supported */
|
||||
memcpy(&overlay->addr, addr, sizeof(struct mmp_addr));
|
||||
writel(addr->phys[0], ®s->g_0);
|
||||
|
||||
if (overlay_is_vid(overlay)) {
|
||||
writel_relaxed(addr->phys[0], ®s->v_y0);
|
||||
writel_relaxed(addr->phys[1], ®s->v_u0);
|
||||
writel_relaxed(addr->phys[2], ®s->v_v0);
|
||||
} else
|
||||
writel_relaxed(addr->phys[0], ®s->g_0);
|
||||
|
||||
return overlay->addr.phys[0];
|
||||
}
|
||||
|
|
@ -248,7 +259,8 @@ static void path_set_mode(struct mmp_path *path, struct mmp_mode *mode)
|
|||
{
|
||||
struct lcd_regs *regs = path_regs(path);
|
||||
u32 total_x, total_y, vsync_ctrl, tmp, sclk_src, sclk_div,
|
||||
link_config = path_to_path_plat(path)->link_config;
|
||||
link_config = path_to_path_plat(path)->link_config,
|
||||
dsi_rbswap = path_to_path_plat(path)->link_config;
|
||||
|
||||
/* FIXME: assert videomode supported */
|
||||
memcpy(&path->mode, mode, sizeof(struct mmp_mode));
|
||||
|
|
@ -263,6 +275,12 @@ static void path_set_mode(struct mmp_path *path, struct mmp_mode *mode)
|
|||
tmp |= CFG_DUMB_ENA(1);
|
||||
writel_relaxed(tmp, ctrl_regs(path) + intf_ctrl(path->id));
|
||||
|
||||
/* interface rb_swap setting */
|
||||
tmp = readl_relaxed(ctrl_regs(path) + intf_rbswap_ctrl(path->id)) &
|
||||
(~(CFG_INTFRBSWAP_MASK));
|
||||
tmp |= dsi_rbswap & CFG_INTFRBSWAP_MASK;
|
||||
writel_relaxed(tmp, ctrl_regs(path) + intf_rbswap_ctrl(path->id));
|
||||
|
||||
writel_relaxed((mode->yres << 16) | mode->xres, ®s->screen_active);
|
||||
writel_relaxed((mode->left_margin << 16) | mode->right_margin,
|
||||
®s->screen_h_porch);
|
||||
|
|
@ -370,20 +388,12 @@ static void path_set_default(struct mmp_path *path)
|
|||
* bus arbiter for faster read if not tv path;
|
||||
* 2.enable horizontal smooth filter;
|
||||
*/
|
||||
if (PATH_PN == path->id) {
|
||||
mask = CFG_GRA_HSMOOTH_MASK | CFG_DMA_HSMOOTH_MASK
|
||||
| CFG_ARBFAST_ENA(1);
|
||||
tmp = readl_relaxed(ctrl_regs(path) + dma_ctrl(0, path->id));
|
||||
tmp |= mask;
|
||||
writel_relaxed(tmp, ctrl_regs(path) + dma_ctrl(0, path->id));
|
||||
} else if (PATH_TV == path->id) {
|
||||
mask = CFG_GRA_HSMOOTH_MASK | CFG_DMA_HSMOOTH_MASK
|
||||
| CFG_ARBFAST_ENA(1);
|
||||
tmp = readl_relaxed(ctrl_regs(path) + dma_ctrl(0, path->id));
|
||||
tmp &= ~mask;
|
||||
tmp |= CFG_GRA_HSMOOTH_MASK | CFG_DMA_HSMOOTH_MASK;
|
||||
writel_relaxed(tmp, ctrl_regs(path) + dma_ctrl(0, path->id));
|
||||
}
|
||||
mask = CFG_GRA_HSMOOTH_MASK | CFG_DMA_HSMOOTH_MASK | CFG_ARBFAST_ENA(1);
|
||||
tmp = readl_relaxed(ctrl_regs(path) + dma_ctrl(0, path->id));
|
||||
tmp |= mask;
|
||||
if (PATH_TV == path->id)
|
||||
tmp &= ~CFG_ARBFAST_ENA(1);
|
||||
writel_relaxed(tmp, ctrl_regs(path) + dma_ctrl(0, path->id));
|
||||
}
|
||||
|
||||
static int path_init(struct mmphw_path_plat *path_plat,
|
||||
|
|
@ -419,6 +429,7 @@ static int path_init(struct mmphw_path_plat *path_plat,
|
|||
path_plat->path = path;
|
||||
path_plat->path_config = config->path_config;
|
||||
path_plat->link_config = config->link_config;
|
||||
path_plat->dsi_rbswap = config->dsi_rbswap;
|
||||
path_set_default(path);
|
||||
|
||||
kfree(path_info);
|
||||
|
|
|
|||
|
|
@ -163,6 +163,8 @@ struct lcd_regs {
|
|||
|
||||
#define LCD_SCLK(path) ((PATH_PN == path->id) ? LCD_CFG_SCLK_DIV :\
|
||||
((PATH_TV == path->id) ? LCD_TCLK_DIV : LCD_PN2_SCLK_DIV))
|
||||
#define intf_rbswap_ctrl(id) ((id) ? (((id) & 1) ? LCD_TVIF_CTRL : \
|
||||
PN2_IOPAD_CONTROL) : LCD_TOP_CTRL)
|
||||
|
||||
/* dither configure */
|
||||
#ifdef CONFIG_CPU_PXA988
|
||||
|
|
@ -615,6 +617,8 @@ struct lcd_regs {
|
|||
#define LCD_SPU_DUMB_CTRL 0x01B8
|
||||
#define CFG_DUMBMODE(mode) ((mode)<<28)
|
||||
#define CFG_DUMBMODE_MASK 0xF0000000
|
||||
#define CFG_INTFRBSWAP(mode) ((mode)<<24)
|
||||
#define CFG_INTFRBSWAP_MASK 0x0F000000
|
||||
#define CFG_LCDGPIO_O(data) ((data)<<20)
|
||||
#define CFG_LCDGPIO_O_MASK 0x0FF00000
|
||||
#define CFG_LCDGPIO_ENA(gpio) ((gpio)<<12)
|
||||
|
|
@ -1427,6 +1431,7 @@ struct mmphw_path_plat {
|
|||
struct mmp_path *path;
|
||||
u32 path_config;
|
||||
u32 link_config;
|
||||
u32 dsi_rbswap;
|
||||
};
|
||||
|
||||
/* mmp ctrl describes mmp controller related info */
|
||||
|
|
|
|||
|
|
@ -1354,7 +1354,7 @@ static struct fb_info *mx3fb_init_fbinfo(struct device *dev, struct fb_ops *ops)
|
|||
static int init_fb_chan(struct mx3fb_data *mx3fb, struct idmac_channel *ichan)
|
||||
{
|
||||
struct device *dev = mx3fb->dev;
|
||||
struct mx3fb_platform_data *mx3fb_pdata = dev->platform_data;
|
||||
struct mx3fb_platform_data *mx3fb_pdata = dev_get_platdata(dev);
|
||||
const char *name = mx3fb_pdata->name;
|
||||
unsigned int irq;
|
||||
struct fb_info *fbi;
|
||||
|
|
@ -1462,7 +1462,7 @@ static bool chan_filter(struct dma_chan *chan, void *arg)
|
|||
return false;
|
||||
|
||||
dev = rq->mx3fb->dev;
|
||||
mx3fb_pdata = dev->platform_data;
|
||||
mx3fb_pdata = dev_get_platdata(dev);
|
||||
|
||||
return rq->id == chan->chan_id &&
|
||||
mx3fb_pdata->dma_dev == chan->device->dev;
|
||||
|
|
|
|||
|
|
@ -2106,8 +2106,7 @@ static int neofb_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
if (err < 0)
|
||||
goto err_reg_fb;
|
||||
|
||||
printk(KERN_INFO "fb%d: %s frame buffer device\n",
|
||||
info->node, info->fix.id);
|
||||
fb_info(info, "%s frame buffer device\n", info->fix.id);
|
||||
|
||||
/*
|
||||
* Our driver data
|
||||
|
|
@ -2148,12 +2147,6 @@ static void neofb_remove(struct pci_dev *dev)
|
|||
fb_destroy_modedb(info->monspecs.modedb);
|
||||
neo_unmap_mmio(info);
|
||||
neo_free_fb_info(info);
|
||||
|
||||
/*
|
||||
* Ensure that the driver data is no longer
|
||||
* valid.
|
||||
*/
|
||||
pci_set_drvdata(dev, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ static int nuc900fb_check_var(struct fb_var_screeninfo *var,
|
|||
struct fb_info *info)
|
||||
{
|
||||
struct nuc900fb_info *fbi = info->par;
|
||||
struct nuc900fb_mach_info *mach_info = fbi->dev->platform_data;
|
||||
struct nuc900fb_mach_info *mach_info = dev_get_platdata(fbi->dev);
|
||||
struct nuc900fb_display *display = NULL;
|
||||
struct nuc900fb_display *default_display = mach_info->displays +
|
||||
mach_info->default_display;
|
||||
|
|
@ -358,7 +358,7 @@ static inline void modify_gpio(void __iomem *reg,
|
|||
static int nuc900fb_init_registers(struct fb_info *info)
|
||||
{
|
||||
struct nuc900fb_info *fbi = info->par;
|
||||
struct nuc900fb_mach_info *mach_info = fbi->dev->platform_data;
|
||||
struct nuc900fb_mach_info *mach_info = dev_get_platdata(fbi->dev);
|
||||
void __iomem *regs = fbi->io;
|
||||
|
||||
/*reset the display engine*/
|
||||
|
|
@ -512,7 +512,7 @@ static int nuc900fb_probe(struct platform_device *pdev)
|
|||
int size;
|
||||
|
||||
dev_dbg(&pdev->dev, "devinit\n");
|
||||
mach_info = pdev->dev.platform_data;
|
||||
mach_info = dev_get_platdata(&pdev->dev);
|
||||
if (mach_info == NULL) {
|
||||
dev_err(&pdev->dev,
|
||||
"no platform data for lcd, cannot attach\n");
|
||||
|
|
@ -647,8 +647,7 @@ static int nuc900fb_probe(struct platform_device *pdev)
|
|||
goto free_cpufreq;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "fb%d: %s frame buffer device\n",
|
||||
fbinfo->node, fbinfo->fix.id);
|
||||
fb_info(fbinfo, "%s frame buffer device\n", fbinfo->fix.id);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -1300,7 +1300,7 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state)
|
|||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
NV_WR32(par->PGRAPH, 0x0b38, 0x2ffff800);
|
||||
NV_WR32(par->PGRAPH, 0x0b3c, 0x00006000);
|
||||
|
|
|
|||
|
|
@ -515,8 +515,7 @@ static void __init offb_init_fb(const char *name, const char *full_name,
|
|||
if (register_framebuffer(info) < 0)
|
||||
goto out_err;
|
||||
|
||||
printk(KERN_INFO "fb%d: Open Firmware frame buffer device on %s\n",
|
||||
info->node, full_name);
|
||||
fb_info(info, "Open Firmware frame buffer device on %s\n", full_name);
|
||||
return;
|
||||
|
||||
out_err:
|
||||
|
|
|
|||
|
|
@ -947,7 +947,7 @@ static int hwa742_init(struct omapfb_device *fbdev, int ext_mode,
|
|||
hwa742.extif = fbdev->ext_if;
|
||||
hwa742.int_ctrl = fbdev->int_ctrl;
|
||||
|
||||
omapfb_conf = fbdev->dev->platform_data;
|
||||
omapfb_conf = dev_get_platdata(fbdev->dev);
|
||||
|
||||
hwa742.sys_ck = clk_get(NULL, "hwa_sys_ck");
|
||||
|
||||
|
|
|
|||
|
|
@ -1602,7 +1602,7 @@ static int omapfb_find_ctrl(struct omapfb_device *fbdev)
|
|||
char name[17];
|
||||
int i;
|
||||
|
||||
conf = fbdev->dev->platform_data;
|
||||
conf = dev_get_platdata(fbdev->dev);
|
||||
|
||||
fbdev->ctrl = NULL;
|
||||
|
||||
|
|
@ -1674,7 +1674,7 @@ static int omapfb_do_probe(struct platform_device *pdev,
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
if (pdev->dev.platform_data == NULL) {
|
||||
if (dev_get_platdata(&pdev->dev) == NULL) {
|
||||
dev_err(&pdev->dev, "missing platform data\n");
|
||||
r = -ENOENT;
|
||||
goto cleanup;
|
||||
|
|
|
|||
|
|
@ -57,6 +57,12 @@ config DISPLAY_PANEL_SHARP_LS037V7DW01
|
|||
help
|
||||
LCD Panel used in TI's SDP3430 and EVM boards
|
||||
|
||||
config DISPLAY_PANEL_TPO_TD028TTEC1
|
||||
tristate "TPO TD028TTEC1 LCD Panel"
|
||||
depends on SPI
|
||||
help
|
||||
LCD panel used in Openmoko.
|
||||
|
||||
config DISPLAY_PANEL_TPO_TD043MTEA1
|
||||
tristate "TPO TD043MTEA1 LCD Panel"
|
||||
depends on SPI
|
||||
|
|
|
|||
|
|
@ -8,5 +8,6 @@ obj-$(CONFIG_DISPLAY_PANEL_DSI_CM) += panel-dsi-cm.o
|
|||
obj-$(CONFIG_DISPLAY_PANEL_SONY_ACX565AKM) += panel-sony-acx565akm.o
|
||||
obj-$(CONFIG_DISPLAY_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o
|
||||
obj-$(CONFIG_DISPLAY_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o
|
||||
obj-$(CONFIG_DISPLAY_PANEL_TPO_TD028TTEC1) += panel-tpo-td028ttec1.o
|
||||
obj-$(CONFIG_DISPLAY_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o
|
||||
obj-$(CONFIG_DISPLAY_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o
|
||||
|
|
|
|||
|
|
@ -262,6 +262,9 @@ static int dvic_probe_pdata(struct platform_device *pdev)
|
|||
|
||||
in = omap_dss_find_output(pdata->source);
|
||||
if (in == NULL) {
|
||||
if (ddata->i2c_adapter)
|
||||
i2c_put_adapter(ddata->i2c_adapter);
|
||||
|
||||
dev_err(&pdev->dev, "Failed to find video source\n");
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
|
@ -313,6 +316,10 @@ static int dvic_probe(struct platform_device *pdev)
|
|||
|
||||
err_reg:
|
||||
omap_dss_put_device(ddata->in);
|
||||
|
||||
if (ddata->i2c_adapter)
|
||||
i2c_put_adapter(ddata->i2c_adapter);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -599,7 +599,7 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
|
|||
if (r) {
|
||||
dev_err(&ddata->pdev->dev, "failed to configure DSI pins\n");
|
||||
goto err0;
|
||||
};
|
||||
}
|
||||
|
||||
r = in->ops.dsi->set_config(in, &dsi_config);
|
||||
if (r) {
|
||||
|
|
|
|||
480
drivers/video/omap2/displays-new/panel-tpo-td028ttec1.c
Normal file
480
drivers/video/omap2/displays-new/panel-tpo-td028ttec1.c
Normal file
|
|
@ -0,0 +1,480 @@
|
|||
/*
|
||||
* Toppoly TD028TTEC1 panel support
|
||||
*
|
||||
* Copyright (C) 2008 Nokia Corporation
|
||||
* Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
|
||||
*
|
||||
* Neo 1973 code (jbt6k74.c):
|
||||
* Copyright (C) 2006-2007 by OpenMoko, Inc.
|
||||
* Author: Harald Welte <laforge@openmoko.org>
|
||||
*
|
||||
* Ported and adapted from Neo 1973 U-Boot by:
|
||||
* H. Nikolaus Schaller <hns@goldelico.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/delay.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <video/omapdss.h>
|
||||
#include <video/omap-panel-data.h>
|
||||
|
||||
struct panel_drv_data {
|
||||
struct omap_dss_device dssdev;
|
||||
struct omap_dss_device *in;
|
||||
|
||||
int data_lines;
|
||||
|
||||
struct omap_video_timings videomode;
|
||||
|
||||
struct spi_device *spi_dev;
|
||||
};
|
||||
|
||||
static struct omap_video_timings td028ttec1_panel_timings = {
|
||||
.x_res = 480,
|
||||
.y_res = 640,
|
||||
.pixel_clock = 22153,
|
||||
.hfp = 24,
|
||||
.hsw = 8,
|
||||
.hbp = 8,
|
||||
.vfp = 4,
|
||||
.vsw = 2,
|
||||
.vbp = 2,
|
||||
|
||||
.vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
|
||||
.hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
|
||||
|
||||
.data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
|
||||
.de_level = OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
|
||||
};
|
||||
|
||||
#define JBT_COMMAND 0x000
|
||||
#define JBT_DATA 0x100
|
||||
|
||||
static int jbt_ret_write_0(struct panel_drv_data *ddata, u8 reg)
|
||||
{
|
||||
int rc;
|
||||
u16 tx_buf = JBT_COMMAND | reg;
|
||||
|
||||
rc = spi_write(ddata->spi_dev, (u8 *)&tx_buf,
|
||||
1*sizeof(u16));
|
||||
if (rc != 0)
|
||||
dev_err(&ddata->spi_dev->dev,
|
||||
"jbt_ret_write_0 spi_write ret %d\n", rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int jbt_reg_write_1(struct panel_drv_data *ddata, u8 reg, u8 data)
|
||||
{
|
||||
int rc;
|
||||
u16 tx_buf[2];
|
||||
|
||||
tx_buf[0] = JBT_COMMAND | reg;
|
||||
tx_buf[1] = JBT_DATA | data;
|
||||
rc = spi_write(ddata->spi_dev, (u8 *)tx_buf,
|
||||
2*sizeof(u16));
|
||||
if (rc != 0)
|
||||
dev_err(&ddata->spi_dev->dev,
|
||||
"jbt_reg_write_1 spi_write ret %d\n", rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int jbt_reg_write_2(struct panel_drv_data *ddata, u8 reg, u16 data)
|
||||
{
|
||||
int rc;
|
||||
u16 tx_buf[3];
|
||||
|
||||
tx_buf[0] = JBT_COMMAND | reg;
|
||||
tx_buf[1] = JBT_DATA | (data >> 8);
|
||||
tx_buf[2] = JBT_DATA | (data & 0xff);
|
||||
|
||||
rc = spi_write(ddata->spi_dev, (u8 *)tx_buf,
|
||||
3*sizeof(u16));
|
||||
|
||||
if (rc != 0)
|
||||
dev_err(&ddata->spi_dev->dev,
|
||||
"jbt_reg_write_2 spi_write ret %d\n", rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
enum jbt_register {
|
||||
JBT_REG_SLEEP_IN = 0x10,
|
||||
JBT_REG_SLEEP_OUT = 0x11,
|
||||
|
||||
JBT_REG_DISPLAY_OFF = 0x28,
|
||||
JBT_REG_DISPLAY_ON = 0x29,
|
||||
|
||||
JBT_REG_RGB_FORMAT = 0x3a,
|
||||
JBT_REG_QUAD_RATE = 0x3b,
|
||||
|
||||
JBT_REG_POWER_ON_OFF = 0xb0,
|
||||
JBT_REG_BOOSTER_OP = 0xb1,
|
||||
JBT_REG_BOOSTER_MODE = 0xb2,
|
||||
JBT_REG_BOOSTER_FREQ = 0xb3,
|
||||
JBT_REG_OPAMP_SYSCLK = 0xb4,
|
||||
JBT_REG_VSC_VOLTAGE = 0xb5,
|
||||
JBT_REG_VCOM_VOLTAGE = 0xb6,
|
||||
JBT_REG_EXT_DISPL = 0xb7,
|
||||
JBT_REG_OUTPUT_CONTROL = 0xb8,
|
||||
JBT_REG_DCCLK_DCEV = 0xb9,
|
||||
JBT_REG_DISPLAY_MODE1 = 0xba,
|
||||
JBT_REG_DISPLAY_MODE2 = 0xbb,
|
||||
JBT_REG_DISPLAY_MODE = 0xbc,
|
||||
JBT_REG_ASW_SLEW = 0xbd,
|
||||
JBT_REG_DUMMY_DISPLAY = 0xbe,
|
||||
JBT_REG_DRIVE_SYSTEM = 0xbf,
|
||||
|
||||
JBT_REG_SLEEP_OUT_FR_A = 0xc0,
|
||||
JBT_REG_SLEEP_OUT_FR_B = 0xc1,
|
||||
JBT_REG_SLEEP_OUT_FR_C = 0xc2,
|
||||
JBT_REG_SLEEP_IN_LCCNT_D = 0xc3,
|
||||
JBT_REG_SLEEP_IN_LCCNT_E = 0xc4,
|
||||
JBT_REG_SLEEP_IN_LCCNT_F = 0xc5,
|
||||
JBT_REG_SLEEP_IN_LCCNT_G = 0xc6,
|
||||
|
||||
JBT_REG_GAMMA1_FINE_1 = 0xc7,
|
||||
JBT_REG_GAMMA1_FINE_2 = 0xc8,
|
||||
JBT_REG_GAMMA1_INCLINATION = 0xc9,
|
||||
JBT_REG_GAMMA1_BLUE_OFFSET = 0xca,
|
||||
|
||||
JBT_REG_BLANK_CONTROL = 0xcf,
|
||||
JBT_REG_BLANK_TH_TV = 0xd0,
|
||||
JBT_REG_CKV_ON_OFF = 0xd1,
|
||||
JBT_REG_CKV_1_2 = 0xd2,
|
||||
JBT_REG_OEV_TIMING = 0xd3,
|
||||
JBT_REG_ASW_TIMING_1 = 0xd4,
|
||||
JBT_REG_ASW_TIMING_2 = 0xd5,
|
||||
|
||||
JBT_REG_HCLOCK_VGA = 0xec,
|
||||
JBT_REG_HCLOCK_QVGA = 0xed,
|
||||
};
|
||||
|
||||
#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
|
||||
|
||||
static int td028ttec1_panel_connect(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct panel_drv_data *ddata = to_panel_data(dssdev);
|
||||
struct omap_dss_device *in = ddata->in;
|
||||
int r;
|
||||
|
||||
if (omapdss_device_is_connected(dssdev))
|
||||
return 0;
|
||||
|
||||
r = in->ops.dpi->connect(in, dssdev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void td028ttec1_panel_disconnect(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct panel_drv_data *ddata = to_panel_data(dssdev);
|
||||
struct omap_dss_device *in = ddata->in;
|
||||
|
||||
if (!omapdss_device_is_connected(dssdev))
|
||||
return;
|
||||
|
||||
in->ops.dpi->disconnect(in, dssdev);
|
||||
}
|
||||
|
||||
static int td028ttec1_panel_enable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct panel_drv_data *ddata = to_panel_data(dssdev);
|
||||
struct omap_dss_device *in = ddata->in;
|
||||
int r;
|
||||
|
||||
if (!omapdss_device_is_connected(dssdev))
|
||||
return -ENODEV;
|
||||
|
||||
if (omapdss_device_is_enabled(dssdev))
|
||||
return 0;
|
||||
|
||||
in->ops.dpi->set_data_lines(in, ddata->data_lines);
|
||||
in->ops.dpi->set_timings(in, &ddata->videomode);
|
||||
|
||||
r = in->ops.dpi->enable(in);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
dev_dbg(dssdev->dev, "td028ttec1_panel_enable() - state %d\n",
|
||||
dssdev->state);
|
||||
|
||||
/* three times command zero */
|
||||
r |= jbt_ret_write_0(ddata, 0x00);
|
||||
usleep_range(1000, 2000);
|
||||
r |= jbt_ret_write_0(ddata, 0x00);
|
||||
usleep_range(1000, 2000);
|
||||
r |= jbt_ret_write_0(ddata, 0x00);
|
||||
usleep_range(1000, 2000);
|
||||
|
||||
if (r) {
|
||||
dev_warn(dssdev->dev, "transfer error\n");
|
||||
goto transfer_err;
|
||||
}
|
||||
|
||||
/* deep standby out */
|
||||
r |= jbt_reg_write_1(ddata, JBT_REG_POWER_ON_OFF, 0x17);
|
||||
|
||||
/* RGB I/F on, RAM write off, QVGA through, SIGCON enable */
|
||||
r |= jbt_reg_write_1(ddata, JBT_REG_DISPLAY_MODE, 0x80);
|
||||
|
||||
/* Quad mode off */
|
||||
r |= jbt_reg_write_1(ddata, JBT_REG_QUAD_RATE, 0x00);
|
||||
|
||||
/* AVDD on, XVDD on */
|
||||
r |= jbt_reg_write_1(ddata, JBT_REG_POWER_ON_OFF, 0x16);
|
||||
|
||||
/* Output control */
|
||||
r |= jbt_reg_write_2(ddata, JBT_REG_OUTPUT_CONTROL, 0xfff9);
|
||||
|
||||
/* Sleep mode off */
|
||||
r |= jbt_ret_write_0(ddata, JBT_REG_SLEEP_OUT);
|
||||
|
||||
/* at this point we have like 50% grey */
|
||||
|
||||
/* initialize register set */
|
||||
r |= jbt_reg_write_1(ddata, JBT_REG_DISPLAY_MODE1, 0x01);
|
||||
r |= jbt_reg_write_1(ddata, JBT_REG_DISPLAY_MODE2, 0x00);
|
||||
r |= jbt_reg_write_1(ddata, JBT_REG_RGB_FORMAT, 0x60);
|
||||
r |= jbt_reg_write_1(ddata, JBT_REG_DRIVE_SYSTEM, 0x10);
|
||||
r |= jbt_reg_write_1(ddata, JBT_REG_BOOSTER_OP, 0x56);
|
||||
r |= jbt_reg_write_1(ddata, JBT_REG_BOOSTER_MODE, 0x33);
|
||||
r |= jbt_reg_write_1(ddata, JBT_REG_BOOSTER_FREQ, 0x11);
|
||||
r |= jbt_reg_write_1(ddata, JBT_REG_BOOSTER_FREQ, 0x11);
|
||||
r |= jbt_reg_write_1(ddata, JBT_REG_OPAMP_SYSCLK, 0x02);
|
||||
r |= jbt_reg_write_1(ddata, JBT_REG_VSC_VOLTAGE, 0x2b);
|
||||
r |= jbt_reg_write_1(ddata, JBT_REG_VCOM_VOLTAGE, 0x40);
|
||||
r |= jbt_reg_write_1(ddata, JBT_REG_EXT_DISPL, 0x03);
|
||||
r |= jbt_reg_write_1(ddata, JBT_REG_DCCLK_DCEV, 0x04);
|
||||
/*
|
||||
* default of 0x02 in JBT_REG_ASW_SLEW responsible for 72Hz requirement
|
||||
* to avoid red / blue flicker
|
||||
*/
|
||||
r |= jbt_reg_write_1(ddata, JBT_REG_ASW_SLEW, 0x04);
|
||||
r |= jbt_reg_write_1(ddata, JBT_REG_DUMMY_DISPLAY, 0x00);
|
||||
|
||||
r |= jbt_reg_write_1(ddata, JBT_REG_SLEEP_OUT_FR_A, 0x11);
|
||||
r |= jbt_reg_write_1(ddata, JBT_REG_SLEEP_OUT_FR_B, 0x11);
|
||||
r |= jbt_reg_write_1(ddata, JBT_REG_SLEEP_OUT_FR_C, 0x11);
|
||||
r |= jbt_reg_write_2(ddata, JBT_REG_SLEEP_IN_LCCNT_D, 0x2040);
|
||||
r |= jbt_reg_write_2(ddata, JBT_REG_SLEEP_IN_LCCNT_E, 0x60c0);
|
||||
r |= jbt_reg_write_2(ddata, JBT_REG_SLEEP_IN_LCCNT_F, 0x1020);
|
||||
r |= jbt_reg_write_2(ddata, JBT_REG_SLEEP_IN_LCCNT_G, 0x60c0);
|
||||
|
||||
r |= jbt_reg_write_2(ddata, JBT_REG_GAMMA1_FINE_1, 0x5533);
|
||||
r |= jbt_reg_write_1(ddata, JBT_REG_GAMMA1_FINE_2, 0x00);
|
||||
r |= jbt_reg_write_1(ddata, JBT_REG_GAMMA1_INCLINATION, 0x00);
|
||||
r |= jbt_reg_write_1(ddata, JBT_REG_GAMMA1_BLUE_OFFSET, 0x00);
|
||||
|
||||
r |= jbt_reg_write_2(ddata, JBT_REG_HCLOCK_VGA, 0x1f0);
|
||||
r |= jbt_reg_write_1(ddata, JBT_REG_BLANK_CONTROL, 0x02);
|
||||
r |= jbt_reg_write_2(ddata, JBT_REG_BLANK_TH_TV, 0x0804);
|
||||
|
||||
r |= jbt_reg_write_1(ddata, JBT_REG_CKV_ON_OFF, 0x01);
|
||||
r |= jbt_reg_write_2(ddata, JBT_REG_CKV_1_2, 0x0000);
|
||||
|
||||
r |= jbt_reg_write_2(ddata, JBT_REG_OEV_TIMING, 0x0d0e);
|
||||
r |= jbt_reg_write_2(ddata, JBT_REG_ASW_TIMING_1, 0x11a4);
|
||||
r |= jbt_reg_write_1(ddata, JBT_REG_ASW_TIMING_2, 0x0e);
|
||||
|
||||
r |= jbt_ret_write_0(ddata, JBT_REG_DISPLAY_ON);
|
||||
|
||||
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
|
||||
|
||||
transfer_err:
|
||||
|
||||
return r ? -EIO : 0;
|
||||
}
|
||||
|
||||
static void td028ttec1_panel_disable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct panel_drv_data *ddata = to_panel_data(dssdev);
|
||||
struct omap_dss_device *in = ddata->in;
|
||||
|
||||
if (!omapdss_device_is_enabled(dssdev))
|
||||
return;
|
||||
|
||||
dev_dbg(dssdev->dev, "td028ttec1_panel_disable()\n");
|
||||
|
||||
jbt_ret_write_0(ddata, JBT_REG_DISPLAY_OFF);
|
||||
jbt_reg_write_2(ddata, JBT_REG_OUTPUT_CONTROL, 0x8002);
|
||||
jbt_ret_write_0(ddata, JBT_REG_SLEEP_IN);
|
||||
jbt_reg_write_1(ddata, JBT_REG_POWER_ON_OFF, 0x00);
|
||||
|
||||
in->ops.dpi->disable(in);
|
||||
|
||||
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
|
||||
}
|
||||
|
||||
static void td028ttec1_panel_set_timings(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings)
|
||||
{
|
||||
struct panel_drv_data *ddata = to_panel_data(dssdev);
|
||||
struct omap_dss_device *in = ddata->in;
|
||||
|
||||
ddata->videomode = *timings;
|
||||
dssdev->panel.timings = *timings;
|
||||
|
||||
in->ops.dpi->set_timings(in, timings);
|
||||
}
|
||||
|
||||
static void td028ttec1_panel_get_timings(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings)
|
||||
{
|
||||
struct panel_drv_data *ddata = to_panel_data(dssdev);
|
||||
|
||||
*timings = ddata->videomode;
|
||||
}
|
||||
|
||||
static int td028ttec1_panel_check_timings(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings)
|
||||
{
|
||||
struct panel_drv_data *ddata = to_panel_data(dssdev);
|
||||
struct omap_dss_device *in = ddata->in;
|
||||
|
||||
return in->ops.dpi->check_timings(in, timings);
|
||||
}
|
||||
|
||||
static struct omap_dss_driver td028ttec1_ops = {
|
||||
.connect = td028ttec1_panel_connect,
|
||||
.disconnect = td028ttec1_panel_disconnect,
|
||||
|
||||
.enable = td028ttec1_panel_enable,
|
||||
.disable = td028ttec1_panel_disable,
|
||||
|
||||
.set_timings = td028ttec1_panel_set_timings,
|
||||
.get_timings = td028ttec1_panel_get_timings,
|
||||
.check_timings = td028ttec1_panel_check_timings,
|
||||
};
|
||||
|
||||
static int td028ttec1_panel_probe_pdata(struct spi_device *spi)
|
||||
{
|
||||
const struct panel_tpo_td028ttec1_platform_data *pdata;
|
||||
struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
|
||||
struct omap_dss_device *dssdev, *in;
|
||||
|
||||
pdata = dev_get_platdata(&spi->dev);
|
||||
|
||||
in = omap_dss_find_output(pdata->source);
|
||||
if (in == NULL) {
|
||||
dev_err(&spi->dev, "failed to find video source '%s'\n",
|
||||
pdata->source);
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
ddata->in = in;
|
||||
|
||||
ddata->data_lines = pdata->data_lines;
|
||||
|
||||
dssdev = &ddata->dssdev;
|
||||
dssdev->name = pdata->name;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int td028ttec1_panel_probe(struct spi_device *spi)
|
||||
{
|
||||
struct panel_drv_data *ddata;
|
||||
struct omap_dss_device *dssdev;
|
||||
int r;
|
||||
|
||||
dev_dbg(&spi->dev, "%s\n", __func__);
|
||||
|
||||
spi->bits_per_word = 9;
|
||||
spi->mode = SPI_MODE_3;
|
||||
|
||||
r = spi_setup(spi);
|
||||
if (r < 0) {
|
||||
dev_err(&spi->dev, "spi_setup failed: %d\n", r);
|
||||
return r;
|
||||
}
|
||||
|
||||
ddata = devm_kzalloc(&spi->dev, sizeof(*ddata), GFP_KERNEL);
|
||||
if (ddata == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
dev_set_drvdata(&spi->dev, ddata);
|
||||
|
||||
ddata->spi_dev = spi;
|
||||
|
||||
if (dev_get_platdata(&spi->dev)) {
|
||||
r = td028ttec1_panel_probe_pdata(spi);
|
||||
if (r)
|
||||
return r;
|
||||
} else {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ddata->videomode = td028ttec1_panel_timings;
|
||||
|
||||
dssdev = &ddata->dssdev;
|
||||
dssdev->dev = &spi->dev;
|
||||
dssdev->driver = &td028ttec1_ops;
|
||||
dssdev->type = OMAP_DISPLAY_TYPE_DPI;
|
||||
dssdev->owner = THIS_MODULE;
|
||||
dssdev->panel.timings = ddata->videomode;
|
||||
dssdev->phy.dpi.data_lines = ddata->data_lines;
|
||||
|
||||
r = omapdss_register_display(dssdev);
|
||||
if (r) {
|
||||
dev_err(&spi->dev, "Failed to register panel\n");
|
||||
goto err_reg;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_reg:
|
||||
omap_dss_put_device(ddata->in);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int td028ttec1_panel_remove(struct spi_device *spi)
|
||||
{
|
||||
struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
|
||||
struct omap_dss_device *dssdev = &ddata->dssdev;
|
||||
struct omap_dss_device *in = ddata->in;
|
||||
|
||||
dev_dbg(&ddata->spi_dev->dev, "%s\n", __func__);
|
||||
|
||||
omapdss_unregister_display(dssdev);
|
||||
|
||||
td028ttec1_panel_disable(dssdev);
|
||||
td028ttec1_panel_disconnect(dssdev);
|
||||
|
||||
omap_dss_put_device(in);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct spi_driver td028ttec1_spi_driver = {
|
||||
.probe = td028ttec1_panel_probe,
|
||||
.remove = td028ttec1_panel_remove,
|
||||
|
||||
.driver = {
|
||||
.name = "panel-tpo-td028ttec1",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
module_spi_driver(td028ttec1_spi_driver);
|
||||
|
||||
MODULE_AUTHOR("H. Nikolaus Schaller <[email protected]>");
|
||||
MODULE_DESCRIPTION("Toppoly TD028TTEC1 panel driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
@ -10,5 +10,6 @@ omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
|
|||
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 ti_hdmi_4xxx_ip.o
|
||||
omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi4.o hdmi_common.o hdmi_wp.o hdmi_pll.o \
|
||||
hdmi_phy.o hdmi4_core.o
|
||||
ccflags-$(CONFIG_OMAP2_DSS_DEBUG) += -DDEBUG
|
||||
|
|
|
|||
|
|
@ -266,7 +266,7 @@ static int (*dss_output_drv_reg_funcs[])(void) __initdata = {
|
|||
venc_init_platform_driver,
|
||||
#endif
|
||||
#ifdef CONFIG_OMAP4_DSS_HDMI
|
||||
hdmi_init_platform_driver,
|
||||
hdmi4_init_platform_driver,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
@ -287,7 +287,7 @@ static void (*dss_output_drv_unreg_funcs[])(void) __exitdata = {
|
|||
venc_uninit_platform_driver,
|
||||
#endif
|
||||
#ifdef CONFIG_OMAP4_DSS_HDMI
|
||||
hdmi_uninit_platform_driver,
|
||||
hdmi4_uninit_platform_driver,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2352,7 +2352,7 @@ int dispc_ovl_check(enum omap_plane plane, enum omap_channel channel,
|
|||
{
|
||||
enum omap_overlay_caps caps = dss_feat_get_overlay_caps(plane);
|
||||
bool five_taps = true;
|
||||
bool fieldmode = 0;
|
||||
bool fieldmode = false;
|
||||
u16 in_height = oi->height;
|
||||
u16 in_width = oi->width;
|
||||
bool ilace = timings->interlace;
|
||||
|
|
@ -2365,7 +2365,7 @@ int dispc_ovl_check(enum omap_plane plane, enum omap_channel channel,
|
|||
out_height = oi->out_height == 0 ? oi->height : oi->out_height;
|
||||
|
||||
if (ilace && oi->height == out_height)
|
||||
fieldmode = 1;
|
||||
fieldmode = true;
|
||||
|
||||
if (ilace) {
|
||||
if (fieldmode)
|
||||
|
|
@ -2396,7 +2396,7 @@ static int dispc_ovl_setup_common(enum omap_plane plane,
|
|||
bool mem_to_mem)
|
||||
{
|
||||
bool five_taps = true;
|
||||
bool fieldmode = 0;
|
||||
bool fieldmode = false;
|
||||
int r, cconv = 0;
|
||||
unsigned offset0, offset1;
|
||||
s32 row_inc;
|
||||
|
|
@ -2417,7 +2417,7 @@ static int dispc_ovl_setup_common(enum omap_plane plane,
|
|||
out_height = out_height == 0 ? height : out_height;
|
||||
|
||||
if (ilace && height == out_height)
|
||||
fieldmode = 1;
|
||||
fieldmode = true;
|
||||
|
||||
if (ilace) {
|
||||
if (fieldmode)
|
||||
|
|
@ -2918,7 +2918,7 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
|
|||
break;
|
||||
default:
|
||||
BUG();
|
||||
};
|
||||
}
|
||||
|
||||
l = dispc_read_reg(DISPC_POL_FREQ(channel));
|
||||
l |= FLD_VAL(onoff, 17, 17);
|
||||
|
|
|
|||
|
|
@ -266,7 +266,7 @@ void videomode_to_omap_video_timings(const struct videomode *vm,
|
|||
OMAPDSS_SIG_ACTIVE_LOW;
|
||||
ovt->de_level = vm->flags & DISPLAY_FLAGS_DE_HIGH ?
|
||||
OMAPDSS_SIG_ACTIVE_HIGH :
|
||||
OMAPDSS_SIG_ACTIVE_HIGH;
|
||||
OMAPDSS_SIG_ACTIVE_LOW;
|
||||
ovt->data_pclk_edge = vm->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE ?
|
||||
OMAPDSS_DRIVE_SIG_RISING_EDGE :
|
||||
OMAPDSS_DRIVE_SIG_FALLING_EDGE;
|
||||
|
|
|
|||
|
|
@ -312,7 +312,7 @@ struct dsi_data {
|
|||
struct dsi_isr_tables isr_tables_copy;
|
||||
|
||||
int update_channel;
|
||||
#ifdef DEBUG
|
||||
#ifdef DSI_PERF_MEASURE
|
||||
unsigned update_bytes;
|
||||
#endif
|
||||
|
||||
|
|
@ -334,7 +334,7 @@ struct dsi_data {
|
|||
|
||||
u32 errors;
|
||||
spinlock_t errors_lock;
|
||||
#ifdef DEBUG
|
||||
#ifdef DSI_PERF_MEASURE
|
||||
ktime_t perf_setup_time;
|
||||
ktime_t perf_start_time;
|
||||
#endif
|
||||
|
|
@ -373,7 +373,7 @@ struct dsi_packet_sent_handler_data {
|
|||
struct completion *completion;
|
||||
};
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef DSI_PERF_MEASURE
|
||||
static bool dsi_perf;
|
||||
module_param(dsi_perf, bool, 0644);
|
||||
#endif
|
||||
|
|
@ -497,7 +497,7 @@ u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef DSI_PERF_MEASURE
|
||||
static void dsi_perf_mark_setup(struct platform_device *dsidev)
|
||||
{
|
||||
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
||||
|
|
@ -4066,7 +4066,7 @@ static int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
|
|||
default:
|
||||
r = -EINVAL;
|
||||
goto err_pix_fmt;
|
||||
};
|
||||
}
|
||||
|
||||
dsi_if_enable(dsidev, false);
|
||||
dsi_vc_enable(dsidev, channel, false);
|
||||
|
|
@ -4277,7 +4277,7 @@ static int dsi_update(struct omap_dss_device *dssdev, int channel,
|
|||
dw = dsi->timings.x_res;
|
||||
dh = dsi->timings.y_res;
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef DSI_PERF_MEASURE
|
||||
dsi->update_bytes = dw * dh *
|
||||
dsi_get_pixel_size(dsi->pix_fmt) / 8;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -427,8 +427,8 @@ int venc_init_platform_driver(void) __init;
|
|||
void venc_uninit_platform_driver(void) __exit;
|
||||
|
||||
/* HDMI */
|
||||
int hdmi_init_platform_driver(void) __init;
|
||||
void hdmi_uninit_platform_driver(void) __exit;
|
||||
int hdmi4_init_platform_driver(void) __init;
|
||||
void hdmi4_uninit_platform_driver(void) __exit;
|
||||
|
||||
/* RFBI */
|
||||
int rfbi_init_platform_driver(void) __init;
|
||||
|
|
|
|||
|
|
@ -789,50 +789,6 @@ static const struct omap_dss_features omap5_dss_features = {
|
|||
.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,
|
||||
.pll_enable = ti_hdmi_4xxx_pll_enable,
|
||||
.pll_disable = ti_hdmi_4xxx_pll_disable,
|
||||
.video_enable = ti_hdmi_4xxx_wp_video_start,
|
||||
.video_disable = ti_hdmi_4xxx_wp_video_stop,
|
||||
.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,
|
||||
#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
|
||||
.audio_enable = ti_hdmi_4xxx_wp_audio_enable,
|
||||
.audio_disable = ti_hdmi_4xxx_wp_audio_disable,
|
||||
.audio_start = ti_hdmi_4xxx_audio_start,
|
||||
.audio_stop = ti_hdmi_4xxx_audio_stop,
|
||||
.audio_config = ti_hdmi_4xxx_audio_config,
|
||||
.audio_get_dma_port = ti_hdmi_4xxx_audio_get_dma_port,
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
void dss_init_hdmi_ip_ops(struct hdmi_ip_data *ip_data,
|
||||
enum omapdss_version version)
|
||||
{
|
||||
switch (version) {
|
||||
case OMAPDSS_VER_OMAP4430_ES1:
|
||||
case OMAPDSS_VER_OMAP4430_ES2:
|
||||
case OMAPDSS_VER_OMAP4:
|
||||
ip_data->ops = &omap4_hdmi_functions;
|
||||
break;
|
||||
default:
|
||||
ip_data->ops = NULL;
|
||||
}
|
||||
|
||||
WARN_ON(ip_data->ops == NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Functions returning values related to a DSS feature */
|
||||
int dss_feat_get_num_mgrs(void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -20,10 +20,6 @@
|
|||
#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 4
|
||||
#define MAX_DSS_OVERLAYS 4
|
||||
#define MAX_DSS_LCD_MANAGERS 3
|
||||
|
|
@ -117,8 +113,4 @@ bool dss_feat_rotation_type_supported(enum omap_dss_rotation_type rot_type);
|
|||
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(enum omapdss_version version);
|
||||
#if defined(CONFIG_OMAP4_DSS_HDMI)
|
||||
void dss_init_hdmi_ip_ops(struct hdmi_ip_data *ip_data,
|
||||
enum omapdss_version version);
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
444
drivers/video/omap2/dss/hdmi.h
Normal file
444
drivers/video/omap2/dss/hdmi.h
Normal file
|
|
@ -0,0 +1,444 @@
|
|||
/*
|
||||
* HDMI driver definition for TI OMAP4 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 _HDMI_H
|
||||
#define _HDMI_H
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <video/omapdss.h>
|
||||
|
||||
#include "dss.h"
|
||||
|
||||
/* HDMI Wrapper */
|
||||
|
||||
#define HDMI_WP_REVISION 0x0
|
||||
#define HDMI_WP_SYSCONFIG 0x10
|
||||
#define HDMI_WP_IRQSTATUS_RAW 0x24
|
||||
#define HDMI_WP_IRQSTATUS 0x28
|
||||
#define HDMI_WP_IRQENABLE_SET 0x2C
|
||||
#define HDMI_WP_IRQENABLE_CLR 0x30
|
||||
#define HDMI_WP_IRQWAKEEN 0x34
|
||||
#define HDMI_WP_PWR_CTRL 0x40
|
||||
#define HDMI_WP_DEBOUNCE 0x44
|
||||
#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 WP IRQ flags */
|
||||
|
||||
#define HDMI_IRQ_OCP_TIMEOUT (1 << 4)
|
||||
#define HDMI_IRQ_AUDIO_FIFO_UNDERFLOW (1 << 8)
|
||||
#define HDMI_IRQ_AUDIO_FIFO_OVERFLOW (1 << 9)
|
||||
#define HDMI_IRQ_AUDIO_FIFO_SAMPLE_REQ (1 << 10)
|
||||
#define HDMI_IRQ_VIDEO_VSYNC (1 << 16)
|
||||
#define HDMI_IRQ_VIDEO_FRAME_DONE (1 << 17)
|
||||
#define HDMI_IRQ_PHY_LINE5V_ASSERT (1 << 24)
|
||||
#define HDMI_IRQ_LINK_CONNECT (1 << 25)
|
||||
#define HDMI_IRQ_LINK_DISCONNECT (1 << 26)
|
||||
#define HDMI_IRQ_PLL_LOCK (1 << 29)
|
||||
#define HDMI_IRQ_PLL_UNLOCK (1 << 30)
|
||||
#define HDMI_IRQ_PLL_RECAL (1 << 31)
|
||||
|
||||
/* HDMI PLL */
|
||||
|
||||
#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_SSC_CFG1 0x18
|
||||
#define PLLCTRL_SSC_CFG2 0x1C
|
||||
#define PLLCTRL_CFG4 0x20
|
||||
|
||||
/* HDMI PHY */
|
||||
|
||||
#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
|
||||
|
||||
enum hdmi_pll_pwr {
|
||||
HDMI_PLLPWRCMD_ALLOFF = 0,
|
||||
HDMI_PLLPWRCMD_PLLONLY = 1,
|
||||
HDMI_PLLPWRCMD_BOTHON_ALLCLKS = 2,
|
||||
HDMI_PLLPWRCMD_BOTHON_NOPHYCLK = 3
|
||||
};
|
||||
|
||||
enum hdmi_phy_pwr {
|
||||
HDMI_PHYPWRCMD_OFF = 0,
|
||||
HDMI_PHYPWRCMD_LDOON = 1,
|
||||
HDMI_PHYPWRCMD_TXON = 2
|
||||
};
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
enum hdmi_packing_mode {
|
||||
HDMI_PACK_10b_RGB_YUV444 = 0,
|
||||
HDMI_PACK_24b_RGB_YUV444_YUV422 = 1,
|
||||
HDMI_PACK_20b_YUV422 = 2,
|
||||
HDMI_PACK_ALREADYPACKED = 7
|
||||
};
|
||||
|
||||
enum hdmi_stereo_channels {
|
||||
HDMI_AUDIO_STEREO_NOCHANNELS = 0,
|
||||
HDMI_AUDIO_STEREO_ONECHANNEL = 1,
|
||||
HDMI_AUDIO_STEREO_TWOCHANNELS = 2,
|
||||
HDMI_AUDIO_STEREO_THREECHANNELS = 3,
|
||||
HDMI_AUDIO_STEREO_FOURCHANNELS = 4
|
||||
};
|
||||
|
||||
enum hdmi_audio_type {
|
||||
HDMI_AUDIO_TYPE_LPCM = 0,
|
||||
HDMI_AUDIO_TYPE_IEC = 1
|
||||
};
|
||||
|
||||
enum hdmi_audio_justify {
|
||||
HDMI_AUDIO_JUSTIFY_LEFT = 0,
|
||||
HDMI_AUDIO_JUSTIFY_RIGHT = 1
|
||||
};
|
||||
|
||||
enum hdmi_audio_sample_order {
|
||||
HDMI_AUDIO_SAMPLE_RIGHT_FIRST = 0,
|
||||
HDMI_AUDIO_SAMPLE_LEFT_FIRST = 1
|
||||
};
|
||||
|
||||
enum hdmi_audio_samples_perword {
|
||||
HDMI_AUDIO_ONEWORD_ONESAMPLE = 0,
|
||||
HDMI_AUDIO_ONEWORD_TWOSAMPLES = 1
|
||||
};
|
||||
|
||||
enum hdmi_audio_sample_size {
|
||||
HDMI_AUDIO_SAMPLE_16BITS = 0,
|
||||
HDMI_AUDIO_SAMPLE_24BITS = 1
|
||||
};
|
||||
|
||||
enum hdmi_audio_transf_mode {
|
||||
HDMI_AUDIO_TRANSF_DMA = 0,
|
||||
HDMI_AUDIO_TRANSF_IRQ = 1
|
||||
};
|
||||
|
||||
enum hdmi_audio_blk_strt_end_sig {
|
||||
HDMI_AUDIO_BLOCK_SIG_STARTEND_ON = 0,
|
||||
HDMI_AUDIO_BLOCK_SIG_STARTEND_OFF = 1
|
||||
};
|
||||
|
||||
enum hdmi_core_audio_layout {
|
||||
HDMI_AUDIO_LAYOUT_2CH = 0,
|
||||
HDMI_AUDIO_LAYOUT_8CH = 1
|
||||
};
|
||||
|
||||
enum hdmi_core_cts_mode {
|
||||
HDMI_AUDIO_CTS_MODE_HW = 0,
|
||||
HDMI_AUDIO_CTS_MODE_SW = 1
|
||||
};
|
||||
|
||||
enum hdmi_audio_mclk_mode {
|
||||
HDMI_AUDIO_MCLK_128FS = 0,
|
||||
HDMI_AUDIO_MCLK_256FS = 1,
|
||||
HDMI_AUDIO_MCLK_384FS = 2,
|
||||
HDMI_AUDIO_MCLK_512FS = 3,
|
||||
HDMI_AUDIO_MCLK_768FS = 4,
|
||||
HDMI_AUDIO_MCLK_1024FS = 5,
|
||||
HDMI_AUDIO_MCLK_1152FS = 6,
|
||||
HDMI_AUDIO_MCLK_192FS = 7
|
||||
};
|
||||
|
||||
/* INFOFRAME_AVI_ and INFOFRAME_AUDIO_ definitions */
|
||||
enum hdmi_core_infoframe {
|
||||
HDMI_INFOFRAME_AVI_DB1Y_RGB = 0,
|
||||
HDMI_INFOFRAME_AVI_DB1Y_YUV422 = 1,
|
||||
HDMI_INFOFRAME_AVI_DB1Y_YUV444 = 2,
|
||||
HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF = 0,
|
||||
HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_ON = 1,
|
||||
HDMI_INFOFRAME_AVI_DB1B_NO = 0,
|
||||
HDMI_INFOFRAME_AVI_DB1B_VERT = 1,
|
||||
HDMI_INFOFRAME_AVI_DB1B_HORI = 2,
|
||||
HDMI_INFOFRAME_AVI_DB1B_VERTHORI = 3,
|
||||
HDMI_INFOFRAME_AVI_DB1S_0 = 0,
|
||||
HDMI_INFOFRAME_AVI_DB1S_1 = 1,
|
||||
HDMI_INFOFRAME_AVI_DB1S_2 = 2,
|
||||
HDMI_INFOFRAME_AVI_DB2C_NO = 0,
|
||||
HDMI_INFOFRAME_AVI_DB2C_ITU601 = 1,
|
||||
HDMI_INFOFRAME_AVI_DB2C_ITU709 = 2,
|
||||
HDMI_INFOFRAME_AVI_DB2C_EC_EXTENDED = 3,
|
||||
HDMI_INFOFRAME_AVI_DB2M_NO = 0,
|
||||
HDMI_INFOFRAME_AVI_DB2M_43 = 1,
|
||||
HDMI_INFOFRAME_AVI_DB2M_169 = 2,
|
||||
HDMI_INFOFRAME_AVI_DB2R_SAME = 8,
|
||||
HDMI_INFOFRAME_AVI_DB2R_43 = 9,
|
||||
HDMI_INFOFRAME_AVI_DB2R_169 = 10,
|
||||
HDMI_INFOFRAME_AVI_DB2R_149 = 11,
|
||||
HDMI_INFOFRAME_AVI_DB3ITC_NO = 0,
|
||||
HDMI_INFOFRAME_AVI_DB3ITC_YES = 1,
|
||||
HDMI_INFOFRAME_AVI_DB3EC_XVYUV601 = 0,
|
||||
HDMI_INFOFRAME_AVI_DB3EC_XVYUV709 = 1,
|
||||
HDMI_INFOFRAME_AVI_DB3Q_DEFAULT = 0,
|
||||
HDMI_INFOFRAME_AVI_DB3Q_LR = 1,
|
||||
HDMI_INFOFRAME_AVI_DB3Q_FR = 2,
|
||||
HDMI_INFOFRAME_AVI_DB3SC_NO = 0,
|
||||
HDMI_INFOFRAME_AVI_DB3SC_HORI = 1,
|
||||
HDMI_INFOFRAME_AVI_DB3SC_VERT = 2,
|
||||
HDMI_INFOFRAME_AVI_DB3SC_HORIVERT = 3,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_NO = 0,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_2 = 1,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_3 = 2,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_4 = 3,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_5 = 4,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_6 = 5,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_7 = 6,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_8 = 7,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_9 = 8,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_10 = 9,
|
||||
};
|
||||
|
||||
struct hdmi_cm {
|
||||
int code;
|
||||
int mode;
|
||||
};
|
||||
|
||||
struct hdmi_video_format {
|
||||
enum hdmi_packing_mode packing_mode;
|
||||
u32 y_res; /* Line per panel */
|
||||
u32 x_res; /* pixel per line */
|
||||
};
|
||||
|
||||
struct hdmi_config {
|
||||
struct omap_video_timings timings;
|
||||
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 hdmi_audio_format {
|
||||
enum hdmi_stereo_channels stereo_channels;
|
||||
u8 active_chnnls_msk;
|
||||
enum hdmi_audio_type type;
|
||||
enum hdmi_audio_justify justification;
|
||||
enum hdmi_audio_sample_order sample_order;
|
||||
enum hdmi_audio_samples_perword samples_per_word;
|
||||
enum hdmi_audio_sample_size sample_size;
|
||||
enum hdmi_audio_blk_strt_end_sig en_sig_blk_strt_end;
|
||||
};
|
||||
|
||||
struct hdmi_audio_dma {
|
||||
u8 transfer_size;
|
||||
u8 block_size;
|
||||
enum hdmi_audio_transf_mode mode;
|
||||
u16 fifo_threshold;
|
||||
};
|
||||
|
||||
struct hdmi_core_audio_i2s_config {
|
||||
u8 in_length_bits;
|
||||
u8 justification;
|
||||
u8 sck_edge_mode;
|
||||
u8 vbit;
|
||||
u8 direction;
|
||||
u8 shift;
|
||||
u8 active_sds;
|
||||
};
|
||||
|
||||
struct hdmi_core_audio_config {
|
||||
struct hdmi_core_audio_i2s_config i2s_cfg;
|
||||
struct snd_aes_iec958 *iec60958_cfg;
|
||||
bool fs_override;
|
||||
u32 n;
|
||||
u32 cts;
|
||||
u32 aud_par_busclk;
|
||||
enum hdmi_core_audio_layout layout;
|
||||
enum hdmi_core_cts_mode cts_mode;
|
||||
bool use_mclk;
|
||||
enum hdmi_audio_mclk_mode mclk_mode;
|
||||
bool en_acr_pkt;
|
||||
bool en_dsd_audio;
|
||||
bool en_parallel_aud_input;
|
||||
bool en_spdif;
|
||||
};
|
||||
|
||||
/*
|
||||
* Refer to section 8.2 in HDMI 1.3 specification for
|
||||
* details about infoframe databytes
|
||||
*/
|
||||
struct hdmi_core_infoframe_avi {
|
||||
/* Y0, Y1 rgb,yCbCr */
|
||||
u8 db1_format;
|
||||
/* A0 Active information Present */
|
||||
u8 db1_active_info;
|
||||
/* B0, B1 Bar info data valid */
|
||||
u8 db1_bar_info_dv;
|
||||
/* S0, S1 scan information */
|
||||
u8 db1_scan_info;
|
||||
/* C0, C1 colorimetry */
|
||||
u8 db2_colorimetry;
|
||||
/* M0, M1 Aspect ratio (4:3, 16:9) */
|
||||
u8 db2_aspect_ratio;
|
||||
/* R0...R3 Active format aspect ratio */
|
||||
u8 db2_active_fmt_ar;
|
||||
/* ITC IT content. */
|
||||
u8 db3_itc;
|
||||
/* EC0, EC1, EC2 Extended colorimetry */
|
||||
u8 db3_ec;
|
||||
/* Q1, Q0 Quantization range */
|
||||
u8 db3_q_range;
|
||||
/* SC1, SC0 Non-uniform picture scaling */
|
||||
u8 db3_nup_scaling;
|
||||
/* VIC0..6 Video format identification */
|
||||
u8 db4_videocode;
|
||||
/* PR0..PR3 Pixel repetition factor */
|
||||
u8 db5_pixel_repeat;
|
||||
/* Line number end of top bar */
|
||||
u16 db6_7_line_eoftop;
|
||||
/* Line number start of bottom bar */
|
||||
u16 db8_9_line_sofbottom;
|
||||
/* Pixel number end of left bar */
|
||||
u16 db10_11_pixel_eofleft;
|
||||
/* Pixel number start of right bar */
|
||||
u16 db12_13_pixel_sofright;
|
||||
};
|
||||
|
||||
struct hdmi_wp_data {
|
||||
void __iomem *base;
|
||||
};
|
||||
|
||||
struct hdmi_pll_data {
|
||||
void __iomem *base;
|
||||
|
||||
struct hdmi_pll_info info;
|
||||
};
|
||||
|
||||
struct hdmi_phy_data {
|
||||
void __iomem *base;
|
||||
|
||||
int irq;
|
||||
};
|
||||
|
||||
struct hdmi_core_data {
|
||||
void __iomem *base;
|
||||
|
||||
struct hdmi_core_infoframe_avi avi_cfg;
|
||||
};
|
||||
|
||||
static inline void hdmi_write_reg(void __iomem *base_addr, const u16 idx,
|
||||
u32 val)
|
||||
{
|
||||
__raw_writel(val, base_addr + idx);
|
||||
}
|
||||
|
||||
static inline u32 hdmi_read_reg(void __iomem *base_addr, const u16 idx)
|
||||
{
|
||||
return __raw_readl(base_addr + idx);
|
||||
}
|
||||
|
||||
#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)
|
||||
|
||||
static inline int hdmi_wait_for_bit_change(void __iomem *base_addr,
|
||||
const u16 idx, int b2, int b1, u32 val)
|
||||
{
|
||||
u32 t = 0;
|
||||
while (val != REG_GET(base_addr, idx, b2, b1)) {
|
||||
udelay(1);
|
||||
if (t++ > 10000)
|
||||
return !val;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/* HDMI wrapper funcs */
|
||||
int hdmi_wp_video_start(struct hdmi_wp_data *wp);
|
||||
void hdmi_wp_video_stop(struct hdmi_wp_data *wp);
|
||||
void hdmi_wp_dump(struct hdmi_wp_data *wp, struct seq_file *s);
|
||||
u32 hdmi_wp_get_irqstatus(struct hdmi_wp_data *wp);
|
||||
void hdmi_wp_set_irqstatus(struct hdmi_wp_data *wp, u32 irqstatus);
|
||||
void hdmi_wp_set_irqenable(struct hdmi_wp_data *wp, u32 mask);
|
||||
void hdmi_wp_clear_irqenable(struct hdmi_wp_data *wp, u32 mask);
|
||||
int hdmi_wp_set_phy_pwr(struct hdmi_wp_data *wp, enum hdmi_phy_pwr val);
|
||||
int hdmi_wp_set_pll_pwr(struct hdmi_wp_data *wp, enum hdmi_pll_pwr val);
|
||||
void hdmi_wp_video_config_format(struct hdmi_wp_data *wp,
|
||||
struct hdmi_video_format *video_fmt);
|
||||
void hdmi_wp_video_config_interface(struct hdmi_wp_data *wp,
|
||||
struct omap_video_timings *timings);
|
||||
void hdmi_wp_video_config_timing(struct hdmi_wp_data *wp,
|
||||
struct omap_video_timings *timings);
|
||||
void hdmi_wp_init_vid_fmt_timings(struct hdmi_video_format *video_fmt,
|
||||
struct omap_video_timings *timings, struct hdmi_config *param);
|
||||
int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp);
|
||||
|
||||
/* HDMI PLL funcs */
|
||||
int hdmi_pll_enable(struct hdmi_pll_data *pll, struct hdmi_wp_data *wp);
|
||||
void hdmi_pll_disable(struct hdmi_pll_data *pll, struct hdmi_wp_data *wp);
|
||||
void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s);
|
||||
void hdmi_pll_compute(struct hdmi_pll_data *pll, unsigned long clkin, int phy);
|
||||
int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll);
|
||||
|
||||
/* HDMI PHY funcs */
|
||||
int hdmi_phy_enable(struct hdmi_phy_data *phy, struct hdmi_wp_data *wp,
|
||||
struct hdmi_config *cfg);
|
||||
void hdmi_phy_disable(struct hdmi_phy_data *phy, struct hdmi_wp_data *wp);
|
||||
void hdmi_phy_dump(struct hdmi_phy_data *phy, struct seq_file *s);
|
||||
int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy);
|
||||
|
||||
/* HDMI common funcs */
|
||||
const struct hdmi_config *hdmi_default_timing(void);
|
||||
const struct hdmi_config *hdmi_get_timings(int mode, int code);
|
||||
struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing);
|
||||
|
||||
#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
|
||||
int hdmi_compute_acr(u32 pclk, u32 sample_freq, u32 *n, u32 *cts);
|
||||
int hdmi_wp_audio_enable(struct hdmi_wp_data *wp, bool enable);
|
||||
int hdmi_wp_audio_core_req_enable(struct hdmi_wp_data *wp, bool enable);
|
||||
void hdmi_wp_audio_config_format(struct hdmi_wp_data *wp,
|
||||
struct hdmi_audio_format *aud_fmt);
|
||||
void hdmi_wp_audio_config_dma(struct hdmi_wp_data *wp,
|
||||
struct hdmi_audio_dma *aud_dma);
|
||||
static inline bool hdmi_mode_has_audio(int mode)
|
||||
{
|
||||
return mode == HDMI_HDMI ? true : false;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
696
drivers/video/omap2/dss/hdmi4.c
Normal file
696
drivers/video/omap2/dss/hdmi4.c
Normal file
|
|
@ -0,0 +1,696 @@
|
|||
/*
|
||||
* HDMI interface DSS driver for TI's OMAP4 family of SoCs.
|
||||
* Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* Authors: Yong Zhi
|
||||
* Mythri pk <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/>.
|
||||
*/
|
||||
|
||||
#define DSS_SUBSYS_NAME "HDMI"
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <video/omapdss.h>
|
||||
|
||||
#include "hdmi4_core.h"
|
||||
#include "dss.h"
|
||||
#include "dss_features.h"
|
||||
|
||||
static struct {
|
||||
struct mutex lock;
|
||||
struct platform_device *pdev;
|
||||
|
||||
struct hdmi_wp_data wp;
|
||||
struct hdmi_pll_data pll;
|
||||
struct hdmi_phy_data phy;
|
||||
struct hdmi_core_data core;
|
||||
|
||||
struct hdmi_config cfg;
|
||||
|
||||
struct clk *sys_clk;
|
||||
struct regulator *vdda_hdmi_dac_reg;
|
||||
|
||||
bool core_enabled;
|
||||
|
||||
struct omap_dss_device output;
|
||||
} hdmi;
|
||||
|
||||
static int hdmi_runtime_get(void)
|
||||
{
|
||||
int r;
|
||||
|
||||
DSSDBG("hdmi_runtime_get\n");
|
||||
|
||||
r = pm_runtime_get_sync(&hdmi.pdev->dev);
|
||||
WARN_ON(r < 0);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hdmi_runtime_put(void)
|
||||
{
|
||||
int r;
|
||||
|
||||
DSSDBG("hdmi_runtime_put\n");
|
||||
|
||||
r = pm_runtime_put_sync(&hdmi.pdev->dev);
|
||||
WARN_ON(r < 0 && r != -ENOSYS);
|
||||
}
|
||||
|
||||
static int hdmi_init_regulator(void)
|
||||
{
|
||||
struct regulator *reg;
|
||||
|
||||
if (hdmi.vdda_hdmi_dac_reg != NULL)
|
||||
return 0;
|
||||
|
||||
reg = devm_regulator_get(&hdmi.pdev->dev, "vdda_hdmi_dac");
|
||||
|
||||
/* DT HACK: try VDAC to make omapdss work for o4 sdp/panda */
|
||||
if (IS_ERR(reg))
|
||||
reg = devm_regulator_get(&hdmi.pdev->dev, "VDAC");
|
||||
|
||||
if (IS_ERR(reg)) {
|
||||
DSSERR("can't get VDDA_HDMI_DAC regulator\n");
|
||||
return PTR_ERR(reg);
|
||||
}
|
||||
|
||||
hdmi.vdda_hdmi_dac_reg = reg;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdmi_power_on_core(struct omap_dss_device *dssdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = regulator_enable(hdmi.vdda_hdmi_dac_reg);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = hdmi_runtime_get();
|
||||
if (r)
|
||||
goto err_runtime_get;
|
||||
|
||||
/* Make selection of HDMI in DSS */
|
||||
dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
|
||||
|
||||
hdmi.core_enabled = true;
|
||||
|
||||
return 0;
|
||||
|
||||
err_runtime_get:
|
||||
regulator_disable(hdmi.vdda_hdmi_dac_reg);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void hdmi_power_off_core(struct omap_dss_device *dssdev)
|
||||
{
|
||||
hdmi.core_enabled = false;
|
||||
|
||||
hdmi_runtime_put();
|
||||
regulator_disable(hdmi.vdda_hdmi_dac_reg);
|
||||
}
|
||||
|
||||
static int hdmi_power_on_full(struct omap_dss_device *dssdev)
|
||||
{
|
||||
int r;
|
||||
struct omap_video_timings *p;
|
||||
struct omap_overlay_manager *mgr = hdmi.output.manager;
|
||||
unsigned long phy;
|
||||
|
||||
r = hdmi_power_on_core(dssdev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
dss_mgr_disable(mgr);
|
||||
|
||||
p = &hdmi.cfg.timings;
|
||||
|
||||
DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);
|
||||
|
||||
phy = p->pixel_clock;
|
||||
|
||||
hdmi_pll_compute(&hdmi.pll, clk_get_rate(hdmi.sys_clk), phy);
|
||||
|
||||
hdmi_wp_video_stop(&hdmi.wp);
|
||||
|
||||
/* config the PLL and PHY hdmi_set_pll_pwrfirst */
|
||||
r = hdmi_pll_enable(&hdmi.pll, &hdmi.wp);
|
||||
if (r) {
|
||||
DSSDBG("Failed to lock PLL\n");
|
||||
goto err_pll_enable;
|
||||
}
|
||||
|
||||
r = hdmi_phy_enable(&hdmi.phy, &hdmi.wp, &hdmi.cfg);
|
||||
if (r) {
|
||||
DSSDBG("Failed to start PHY\n");
|
||||
goto err_phy_enable;
|
||||
}
|
||||
|
||||
hdmi4_configure(&hdmi.core, &hdmi.wp, &hdmi.cfg);
|
||||
|
||||
/* bypass TV gamma table */
|
||||
dispc_enable_gamma_table(0);
|
||||
|
||||
/* tv size */
|
||||
dss_mgr_set_timings(mgr, p);
|
||||
|
||||
r = hdmi_wp_video_start(&hdmi.wp);
|
||||
if (r)
|
||||
goto err_vid_enable;
|
||||
|
||||
r = dss_mgr_enable(mgr);
|
||||
if (r)
|
||||
goto err_mgr_enable;
|
||||
|
||||
return 0;
|
||||
|
||||
err_mgr_enable:
|
||||
hdmi_wp_video_stop(&hdmi.wp);
|
||||
err_vid_enable:
|
||||
hdmi_phy_disable(&hdmi.phy, &hdmi.wp);
|
||||
err_phy_enable:
|
||||
hdmi_pll_disable(&hdmi.pll, &hdmi.wp);
|
||||
err_pll_enable:
|
||||
hdmi_power_off_core(dssdev);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static void hdmi_power_off_full(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct omap_overlay_manager *mgr = hdmi.output.manager;
|
||||
|
||||
dss_mgr_disable(mgr);
|
||||
|
||||
hdmi_wp_video_stop(&hdmi.wp);
|
||||
hdmi_phy_disable(&hdmi.phy, &hdmi.wp);
|
||||
hdmi_pll_disable(&hdmi.pll, &hdmi.wp);
|
||||
|
||||
hdmi_power_off_core(dssdev);
|
||||
}
|
||||
|
||||
static int hdmi_display_check_timing(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings)
|
||||
{
|
||||
struct hdmi_cm cm;
|
||||
|
||||
cm = hdmi_get_code(timings);
|
||||
if (cm.code == -1)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings)
|
||||
{
|
||||
struct hdmi_cm cm;
|
||||
const struct hdmi_config *t;
|
||||
|
||||
mutex_lock(&hdmi.lock);
|
||||
|
||||
cm = hdmi_get_code(timings);
|
||||
hdmi.cfg.cm = cm;
|
||||
|
||||
t = hdmi_get_timings(cm.mode, cm.code);
|
||||
if (t != NULL) {
|
||||
hdmi.cfg = *t;
|
||||
|
||||
dispc_set_tv_pclk(t->timings.pixel_clock * 1000);
|
||||
}
|
||||
|
||||
mutex_unlock(&hdmi.lock);
|
||||
}
|
||||
|
||||
static void hdmi_display_get_timings(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings)
|
||||
{
|
||||
const struct hdmi_config *cfg;
|
||||
struct hdmi_cm cm = hdmi.cfg.cm;
|
||||
|
||||
cfg = hdmi_get_timings(cm.mode, cm.code);
|
||||
if (cfg == NULL)
|
||||
cfg = hdmi_default_timing();
|
||||
|
||||
memcpy(timings, &cfg->timings, sizeof(cfg->timings));
|
||||
}
|
||||
|
||||
static void hdmi_dump_regs(struct seq_file *s)
|
||||
{
|
||||
mutex_lock(&hdmi.lock);
|
||||
|
||||
if (hdmi_runtime_get()) {
|
||||
mutex_unlock(&hdmi.lock);
|
||||
return;
|
||||
}
|
||||
|
||||
hdmi_wp_dump(&hdmi.wp, s);
|
||||
hdmi_pll_dump(&hdmi.pll, s);
|
||||
hdmi_phy_dump(&hdmi.phy, s);
|
||||
hdmi4_core_dump(&hdmi.core, s);
|
||||
|
||||
hdmi_runtime_put();
|
||||
mutex_unlock(&hdmi.lock);
|
||||
}
|
||||
|
||||
static int read_edid(u8 *buf, int len)
|
||||
{
|
||||
int r;
|
||||
|
||||
mutex_lock(&hdmi.lock);
|
||||
|
||||
r = hdmi_runtime_get();
|
||||
BUG_ON(r);
|
||||
|
||||
r = hdmi4_read_edid(&hdmi.core, buf, len);
|
||||
|
||||
hdmi_runtime_put();
|
||||
mutex_unlock(&hdmi.lock);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int hdmi_display_enable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct omap_dss_device *out = &hdmi.output;
|
||||
int r = 0;
|
||||
|
||||
DSSDBG("ENTER hdmi_display_enable\n");
|
||||
|
||||
mutex_lock(&hdmi.lock);
|
||||
|
||||
if (out == NULL || out->manager == NULL) {
|
||||
DSSERR("failed to enable display: no output/manager\n");
|
||||
r = -ENODEV;
|
||||
goto err0;
|
||||
}
|
||||
|
||||
r = hdmi_power_on_full(dssdev);
|
||||
if (r) {
|
||||
DSSERR("failed to power on device\n");
|
||||
goto err0;
|
||||
}
|
||||
|
||||
mutex_unlock(&hdmi.lock);
|
||||
return 0;
|
||||
|
||||
err0:
|
||||
mutex_unlock(&hdmi.lock);
|
||||
return r;
|
||||
}
|
||||
|
||||
static void hdmi_display_disable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
DSSDBG("Enter hdmi_display_disable\n");
|
||||
|
||||
mutex_lock(&hdmi.lock);
|
||||
|
||||
hdmi_power_off_full(dssdev);
|
||||
|
||||
mutex_unlock(&hdmi.lock);
|
||||
}
|
||||
|
||||
static int hdmi_core_enable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
DSSDBG("ENTER omapdss_hdmi_core_enable\n");
|
||||
|
||||
mutex_lock(&hdmi.lock);
|
||||
|
||||
r = hdmi_power_on_core(dssdev);
|
||||
if (r) {
|
||||
DSSERR("failed to power on device\n");
|
||||
goto err0;
|
||||
}
|
||||
|
||||
mutex_unlock(&hdmi.lock);
|
||||
return 0;
|
||||
|
||||
err0:
|
||||
mutex_unlock(&hdmi.lock);
|
||||
return r;
|
||||
}
|
||||
|
||||
static void hdmi_core_disable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
DSSDBG("Enter omapdss_hdmi_core_disable\n");
|
||||
|
||||
mutex_lock(&hdmi.lock);
|
||||
|
||||
hdmi_power_off_core(dssdev);
|
||||
|
||||
mutex_unlock(&hdmi.lock);
|
||||
}
|
||||
|
||||
static int hdmi_get_clocks(struct platform_device *pdev)
|
||||
{
|
||||
struct clk *clk;
|
||||
|
||||
clk = devm_clk_get(&pdev->dev, "sys_clk");
|
||||
if (IS_ERR(clk)) {
|
||||
DSSERR("can't get sys_clk\n");
|
||||
return PTR_ERR(clk);
|
||||
}
|
||||
|
||||
hdmi.sys_clk = clk;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdmi_connect(struct omap_dss_device *dssdev,
|
||||
struct omap_dss_device *dst)
|
||||
{
|
||||
struct omap_overlay_manager *mgr;
|
||||
int r;
|
||||
|
||||
r = hdmi_init_regulator();
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel);
|
||||
if (!mgr)
|
||||
return -ENODEV;
|
||||
|
||||
r = dss_mgr_connect(mgr, dssdev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = omapdss_output_set_device(dssdev, dst);
|
||||
if (r) {
|
||||
DSSERR("failed to connect output to new device: %s\n",
|
||||
dst->name);
|
||||
dss_mgr_disconnect(mgr, dssdev);
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hdmi_disconnect(struct omap_dss_device *dssdev,
|
||||
struct omap_dss_device *dst)
|
||||
{
|
||||
WARN_ON(dst != dssdev->dst);
|
||||
|
||||
if (dst != dssdev->dst)
|
||||
return;
|
||||
|
||||
omapdss_output_unset_device(dssdev);
|
||||
|
||||
if (dssdev->manager)
|
||||
dss_mgr_disconnect(dssdev->manager, dssdev);
|
||||
}
|
||||
|
||||
static int hdmi_read_edid(struct omap_dss_device *dssdev,
|
||||
u8 *edid, int len)
|
||||
{
|
||||
bool need_enable;
|
||||
int r;
|
||||
|
||||
need_enable = hdmi.core_enabled == false;
|
||||
|
||||
if (need_enable) {
|
||||
r = hdmi_core_enable(dssdev);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = read_edid(edid, len);
|
||||
|
||||
if (need_enable)
|
||||
hdmi_core_disable(dssdev);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
|
||||
static int hdmi_audio_enable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
mutex_lock(&hdmi.lock);
|
||||
|
||||
if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) {
|
||||
r = -EPERM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
r = hdmi_wp_audio_enable(&hdmi.wp, true);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
mutex_unlock(&hdmi.lock);
|
||||
return 0;
|
||||
|
||||
err:
|
||||
mutex_unlock(&hdmi.lock);
|
||||
return r;
|
||||
}
|
||||
|
||||
static void hdmi_audio_disable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
hdmi_wp_audio_enable(&hdmi.wp, false);
|
||||
}
|
||||
|
||||
static int hdmi_audio_start(struct omap_dss_device *dssdev)
|
||||
{
|
||||
return hdmi4_audio_start(&hdmi.core, &hdmi.wp);
|
||||
}
|
||||
|
||||
static void hdmi_audio_stop(struct omap_dss_device *dssdev)
|
||||
{
|
||||
hdmi4_audio_stop(&hdmi.core, &hdmi.wp);
|
||||
}
|
||||
|
||||
static bool hdmi_audio_supported(struct omap_dss_device *dssdev)
|
||||
{
|
||||
bool r;
|
||||
|
||||
mutex_lock(&hdmi.lock);
|
||||
|
||||
r = hdmi_mode_has_audio(hdmi.cfg.cm.mode);
|
||||
|
||||
mutex_unlock(&hdmi.lock);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int hdmi_audio_config(struct omap_dss_device *dssdev,
|
||||
struct omap_dss_audio *audio)
|
||||
{
|
||||
int r;
|
||||
u32 pclk = hdmi.cfg.timings.pixel_clock;
|
||||
|
||||
mutex_lock(&hdmi.lock);
|
||||
|
||||
if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) {
|
||||
r = -EPERM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
r = hdmi4_audio_config(&hdmi.core, &hdmi.wp, audio, pclk);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
mutex_unlock(&hdmi.lock);
|
||||
return 0;
|
||||
|
||||
err:
|
||||
mutex_unlock(&hdmi.lock);
|
||||
return r;
|
||||
}
|
||||
#else
|
||||
static int hdmi_audio_enable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
static void hdmi_audio_disable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
}
|
||||
|
||||
static int hdmi_audio_start(struct omap_dss_device *dssdev)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
static void hdmi_audio_stop(struct omap_dss_device *dssdev)
|
||||
{
|
||||
}
|
||||
|
||||
static bool hdmi_audio_supported(struct omap_dss_device *dssdev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static int hdmi_audio_config(struct omap_dss_device *dssdev,
|
||||
struct omap_dss_audio *audio)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct omapdss_hdmi_ops hdmi_ops = {
|
||||
.connect = hdmi_connect,
|
||||
.disconnect = hdmi_disconnect,
|
||||
|
||||
.enable = hdmi_display_enable,
|
||||
.disable = hdmi_display_disable,
|
||||
|
||||
.check_timings = hdmi_display_check_timing,
|
||||
.set_timings = hdmi_display_set_timing,
|
||||
.get_timings = hdmi_display_get_timings,
|
||||
|
||||
.read_edid = hdmi_read_edid,
|
||||
|
||||
.audio_enable = hdmi_audio_enable,
|
||||
.audio_disable = hdmi_audio_disable,
|
||||
.audio_start = hdmi_audio_start,
|
||||
.audio_stop = hdmi_audio_stop,
|
||||
.audio_supported = hdmi_audio_supported,
|
||||
.audio_config = hdmi_audio_config,
|
||||
};
|
||||
|
||||
static void hdmi_init_output(struct platform_device *pdev)
|
||||
{
|
||||
struct omap_dss_device *out = &hdmi.output;
|
||||
|
||||
out->dev = &pdev->dev;
|
||||
out->id = OMAP_DSS_OUTPUT_HDMI;
|
||||
out->output_type = OMAP_DISPLAY_TYPE_HDMI;
|
||||
out->name = "hdmi.0";
|
||||
out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT;
|
||||
out->ops.hdmi = &hdmi_ops;
|
||||
out->owner = THIS_MODULE;
|
||||
|
||||
omapdss_register_output(out);
|
||||
}
|
||||
|
||||
static void __exit hdmi_uninit_output(struct platform_device *pdev)
|
||||
{
|
||||
struct omap_dss_device *out = &hdmi.output;
|
||||
|
||||
omapdss_unregister_output(out);
|
||||
}
|
||||
|
||||
/* HDMI HW IP initialisation */
|
||||
static int omapdss_hdmihw_probe(struct platform_device *pdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
hdmi.pdev = pdev;
|
||||
|
||||
mutex_init(&hdmi.lock);
|
||||
|
||||
r = hdmi_wp_init(pdev, &hdmi.wp);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = hdmi_pll_init(pdev, &hdmi.pll);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = hdmi_phy_init(pdev, &hdmi.phy);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = hdmi4_core_init(pdev, &hdmi.core);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = hdmi_get_clocks(pdev);
|
||||
if (r) {
|
||||
DSSERR("can't get clocks\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
hdmi_init_output(pdev);
|
||||
|
||||
dss_debugfs_create_file("hdmi", hdmi_dump_regs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
|
||||
{
|
||||
hdmi_uninit_output(pdev);
|
||||
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdmi_runtime_suspend(struct device *dev)
|
||||
{
|
||||
clk_disable_unprepare(hdmi.sys_clk);
|
||||
|
||||
dispc_runtime_put();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdmi_runtime_resume(struct device *dev)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = dispc_runtime_get();
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
clk_prepare_enable(hdmi.sys_clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops hdmi_pm_ops = {
|
||||
.runtime_suspend = hdmi_runtime_suspend,
|
||||
.runtime_resume = hdmi_runtime_resume,
|
||||
};
|
||||
|
||||
static struct platform_driver omapdss_hdmihw_driver = {
|
||||
.probe = omapdss_hdmihw_probe,
|
||||
.remove = __exit_p(omapdss_hdmihw_remove),
|
||||
.driver = {
|
||||
.name = "omapdss_hdmi",
|
||||
.owner = THIS_MODULE,
|
||||
.pm = &hdmi_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
int __init hdmi4_init_platform_driver(void)
|
||||
{
|
||||
return platform_driver_register(&omapdss_hdmihw_driver);
|
||||
}
|
||||
|
||||
void __exit hdmi4_uninit_platform_driver(void)
|
||||
{
|
||||
platform_driver_unregister(&omapdss_hdmihw_driver);
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,7 +1,5 @@
|
|||
/*
|
||||
* ti_hdmi_4xxx_ip.h
|
||||
*
|
||||
* HDMI header definition for DM81xx, DM38xx, TI OMAP4 etc processors.
|
||||
* HDMI header definition for OMAP4 HDMI core IP
|
||||
*
|
||||
* Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
|
|
@ -18,41 +16,22 @@
|
|||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _HDMI_TI_4xxx_H_
|
||||
#define _HDMI_TI_4xxx_H_
|
||||
#ifndef _HDMI4_CORE_H_
|
||||
#define _HDMI4_CORE_H_
|
||||
|
||||
#include <linux/string.h>
|
||||
#include <video/omapdss.h>
|
||||
#include "ti_hdmi.h"
|
||||
#include "hdmi.h"
|
||||
|
||||
/* HDMI Wrapper */
|
||||
|
||||
#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_IRQENABLE_CLR 0x30
|
||||
#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 */
|
||||
/* OMAP4 HDMI IP Core System */
|
||||
|
||||
#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_CTRL1 0x20
|
||||
#define HDMI_CORE_SYS_SYS_STAT 0x24
|
||||
#define HDMI_CORE_SYS_SYS_CTRL3 0x28
|
||||
#define HDMI_CORE_SYS_DCTL 0x34
|
||||
#define HDMI_CORE_SYS_DE_DLY 0xC8
|
||||
#define HDMI_CORE_SYS_DE_CTRL 0xCC
|
||||
#define HDMI_CORE_SYS_DE_TOP 0xD0
|
||||
|
|
@ -60,20 +39,65 @@
|
|||
#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_SYS_HRES_L 0xE8
|
||||
#define HDMI_CORE_SYS_HRES_H 0xEC
|
||||
#define HDMI_CORE_SYS_VRES_L 0xF0
|
||||
#define HDMI_CORE_SYS_VRES_H 0xF4
|
||||
#define HDMI_CORE_SYS_IADJUST 0xF8
|
||||
#define HDMI_CORE_SYS_POLDETECT 0xFC
|
||||
#define HDMI_CORE_SYS_HWIDTH1 0x110
|
||||
#define HDMI_CORE_SYS_HWIDTH2 0x114
|
||||
#define HDMI_CORE_SYS_VWIDTH 0x11C
|
||||
#define HDMI_CORE_SYS_VID_CTRL 0x120
|
||||
#define HDMI_CORE_SYS_VID_ACEN 0x124
|
||||
#define HDMI_CORE_SYS_VID_MODE 0x128
|
||||
#define HDMI_CORE_SYS_VID_BLANK1 0x12C
|
||||
#define HDMI_CORE_SYS_VID_BLANK2 0x130
|
||||
#define HDMI_CORE_SYS_VID_BLANK3 0x134
|
||||
#define HDMI_CORE_SYS_DC_HEADER 0x138
|
||||
#define HDMI_CORE_SYS_VID_DITHER 0x13C
|
||||
#define HDMI_CORE_SYS_RGB2XVYCC_CT 0x140
|
||||
#define HDMI_CORE_SYS_R2Y_COEFF_LOW 0x144
|
||||
#define HDMI_CORE_SYS_R2Y_COEFF_UP 0x148
|
||||
#define HDMI_CORE_SYS_G2Y_COEFF_LOW 0x14C
|
||||
#define HDMI_CORE_SYS_G2Y_COEFF_UP 0x150
|
||||
#define HDMI_CORE_SYS_B2Y_COEFF_LOW 0x154
|
||||
#define HDMI_CORE_SYS_B2Y_COEFF_UP 0x158
|
||||
#define HDMI_CORE_SYS_R2CB_COEFF_LOW 0x15C
|
||||
#define HDMI_CORE_SYS_R2CB_COEFF_UP 0x160
|
||||
#define HDMI_CORE_SYS_G2CB_COEFF_LOW 0x164
|
||||
#define HDMI_CORE_SYS_G2CB_COEFF_UP 0x168
|
||||
#define HDMI_CORE_SYS_B2CB_COEFF_LOW 0x16C
|
||||
#define HDMI_CORE_SYS_B2CB_COEFF_UP 0x170
|
||||
#define HDMI_CORE_SYS_R2CR_COEFF_LOW 0x174
|
||||
#define HDMI_CORE_SYS_R2CR_COEFF_UP 0x178
|
||||
#define HDMI_CORE_SYS_G2CR_COEFF_LOW 0x17C
|
||||
#define HDMI_CORE_SYS_G2CR_COEFF_UP 0x180
|
||||
#define HDMI_CORE_SYS_B2CR_COEFF_LOW 0x184
|
||||
#define HDMI_CORE_SYS_B2CR_COEFF_UP 0x188
|
||||
#define HDMI_CORE_SYS_RGB_OFFSET_LOW 0x18C
|
||||
#define HDMI_CORE_SYS_RGB_OFFSET_UP 0x190
|
||||
#define HDMI_CORE_SYS_Y_OFFSET_LOW 0x194
|
||||
#define HDMI_CORE_SYS_Y_OFFSET_UP 0x198
|
||||
#define HDMI_CORE_SYS_CBCR_OFFSET_LOW 0x19C
|
||||
#define HDMI_CORE_SYS_CBCR_OFFSET_UP 0x1A0
|
||||
#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_INTR_UNMASK1 0x1D4
|
||||
#define HDMI_CORE_SYS_INTR_UNMASK2 0x1D8
|
||||
#define HDMI_CORE_SYS_INTR_UNMASK3 0x1DC
|
||||
#define HDMI_CORE_SYS_INTR_UNMASK4 0x1E0
|
||||
#define HDMI_CORE_SYS_INTR_CTRL 0x1E4
|
||||
#define HDMI_CORE_SYS_TMDS_CTRL 0x208
|
||||
|
||||
#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
|
||||
/* value definitions for HDMI_CORE_SYS_SYS_CTRL1 fields */
|
||||
#define HDMI_CORE_SYS_SYS_CTRL1_VEN_FOLLOWVSYNC 0x1
|
||||
#define HDMI_CORE_SYS_SYS_CTRL1_HEN_FOLLOWHSYNC 0x1
|
||||
#define HDMI_CORE_SYS_SYS_CTRL1_BSEL_24BITBUS 0x1
|
||||
#define HDMI_CORE_SYS_SYS_CTRL1_EDGE_RISINGEDGE 0x1
|
||||
|
||||
/* HDMI DDC E-DID */
|
||||
#define HDMI_CORE_DDC_ADDR 0x3B4
|
||||
|
|
@ -158,35 +182,6 @@
|
|||
#define HDMI_CORE_AV_GEN_DBYTE_NELEMS 31
|
||||
#define HDMI_CORE_AV_GEN2_DBYTE_NELEMS 31
|
||||
|
||||
/* PLL */
|
||||
|
||||
#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_TXPHY_TX_CTRL 0x0
|
||||
#define HDMI_TXPHY_DIGITAL_CTRL 0x4
|
||||
#define HDMI_TXPHY_POWER_CTRL 0x8
|
||||
#define HDMI_TXPHY_PAD_CFG_CTRL 0xC
|
||||
|
||||
#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,
|
||||
HDMI_PHYPWRCMD_LDOON = 1,
|
||||
HDMI_PHYPWRCMD_TXON = 2
|
||||
};
|
||||
|
||||
enum hdmi_core_inputbus_width {
|
||||
HDMI_INPUT_8BIT = 0,
|
||||
HDMI_INPUT_10BIT = 1,
|
||||
|
|
@ -229,114 +224,6 @@ enum hdmi_core_packet_ctrl {
|
|||
HDMI_PACKETREPEATOFF = 0
|
||||
};
|
||||
|
||||
/* INFOFRAME_AVI_ and INFOFRAME_AUDIO_ definitions */
|
||||
enum hdmi_core_infoframe {
|
||||
HDMI_INFOFRAME_AVI_DB1Y_RGB = 0,
|
||||
HDMI_INFOFRAME_AVI_DB1Y_YUV422 = 1,
|
||||
HDMI_INFOFRAME_AVI_DB1Y_YUV444 = 2,
|
||||
HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF = 0,
|
||||
HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_ON = 1,
|
||||
HDMI_INFOFRAME_AVI_DB1B_NO = 0,
|
||||
HDMI_INFOFRAME_AVI_DB1B_VERT = 1,
|
||||
HDMI_INFOFRAME_AVI_DB1B_HORI = 2,
|
||||
HDMI_INFOFRAME_AVI_DB1B_VERTHORI = 3,
|
||||
HDMI_INFOFRAME_AVI_DB1S_0 = 0,
|
||||
HDMI_INFOFRAME_AVI_DB1S_1 = 1,
|
||||
HDMI_INFOFRAME_AVI_DB1S_2 = 2,
|
||||
HDMI_INFOFRAME_AVI_DB2C_NO = 0,
|
||||
HDMI_INFOFRAME_AVI_DB2C_ITU601 = 1,
|
||||
HDMI_INFOFRAME_AVI_DB2C_ITU709 = 2,
|
||||
HDMI_INFOFRAME_AVI_DB2C_EC_EXTENDED = 3,
|
||||
HDMI_INFOFRAME_AVI_DB2M_NO = 0,
|
||||
HDMI_INFOFRAME_AVI_DB2M_43 = 1,
|
||||
HDMI_INFOFRAME_AVI_DB2M_169 = 2,
|
||||
HDMI_INFOFRAME_AVI_DB2R_SAME = 8,
|
||||
HDMI_INFOFRAME_AVI_DB2R_43 = 9,
|
||||
HDMI_INFOFRAME_AVI_DB2R_169 = 10,
|
||||
HDMI_INFOFRAME_AVI_DB2R_149 = 11,
|
||||
HDMI_INFOFRAME_AVI_DB3ITC_NO = 0,
|
||||
HDMI_INFOFRAME_AVI_DB3ITC_YES = 1,
|
||||
HDMI_INFOFRAME_AVI_DB3EC_XVYUV601 = 0,
|
||||
HDMI_INFOFRAME_AVI_DB3EC_XVYUV709 = 1,
|
||||
HDMI_INFOFRAME_AVI_DB3Q_DEFAULT = 0,
|
||||
HDMI_INFOFRAME_AVI_DB3Q_LR = 1,
|
||||
HDMI_INFOFRAME_AVI_DB3Q_FR = 2,
|
||||
HDMI_INFOFRAME_AVI_DB3SC_NO = 0,
|
||||
HDMI_INFOFRAME_AVI_DB3SC_HORI = 1,
|
||||
HDMI_INFOFRAME_AVI_DB3SC_VERT = 2,
|
||||
HDMI_INFOFRAME_AVI_DB3SC_HORIVERT = 3,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_NO = 0,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_2 = 1,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_3 = 2,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_4 = 3,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_5 = 4,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_6 = 5,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_7 = 6,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_8 = 7,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_9 = 8,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_10 = 9,
|
||||
};
|
||||
|
||||
enum hdmi_packing_mode {
|
||||
HDMI_PACK_10b_RGB_YUV444 = 0,
|
||||
HDMI_PACK_24b_RGB_YUV444_YUV422 = 1,
|
||||
HDMI_PACK_20b_YUV422 = 2,
|
||||
HDMI_PACK_ALREADYPACKED = 7
|
||||
};
|
||||
|
||||
enum hdmi_core_audio_layout {
|
||||
HDMI_AUDIO_LAYOUT_2CH = 0,
|
||||
HDMI_AUDIO_LAYOUT_8CH = 1
|
||||
};
|
||||
|
||||
enum hdmi_core_cts_mode {
|
||||
HDMI_AUDIO_CTS_MODE_HW = 0,
|
||||
HDMI_AUDIO_CTS_MODE_SW = 1
|
||||
};
|
||||
|
||||
enum hdmi_stereo_channels {
|
||||
HDMI_AUDIO_STEREO_NOCHANNELS = 0,
|
||||
HDMI_AUDIO_STEREO_ONECHANNEL = 1,
|
||||
HDMI_AUDIO_STEREO_TWOCHANNELS = 2,
|
||||
HDMI_AUDIO_STEREO_THREECHANNELS = 3,
|
||||
HDMI_AUDIO_STEREO_FOURCHANNELS = 4
|
||||
};
|
||||
|
||||
enum hdmi_audio_type {
|
||||
HDMI_AUDIO_TYPE_LPCM = 0,
|
||||
HDMI_AUDIO_TYPE_IEC = 1
|
||||
};
|
||||
|
||||
enum hdmi_audio_justify {
|
||||
HDMI_AUDIO_JUSTIFY_LEFT = 0,
|
||||
HDMI_AUDIO_JUSTIFY_RIGHT = 1
|
||||
};
|
||||
|
||||
enum hdmi_audio_sample_order {
|
||||
HDMI_AUDIO_SAMPLE_RIGHT_FIRST = 0,
|
||||
HDMI_AUDIO_SAMPLE_LEFT_FIRST = 1
|
||||
};
|
||||
|
||||
enum hdmi_audio_samples_perword {
|
||||
HDMI_AUDIO_ONEWORD_ONESAMPLE = 0,
|
||||
HDMI_AUDIO_ONEWORD_TWOSAMPLES = 1
|
||||
};
|
||||
|
||||
enum hdmi_audio_sample_size {
|
||||
HDMI_AUDIO_SAMPLE_16BITS = 0,
|
||||
HDMI_AUDIO_SAMPLE_24BITS = 1
|
||||
};
|
||||
|
||||
enum hdmi_audio_transf_mode {
|
||||
HDMI_AUDIO_TRANSF_DMA = 0,
|
||||
HDMI_AUDIO_TRANSF_IRQ = 1
|
||||
};
|
||||
|
||||
enum hdmi_audio_blk_strt_end_sig {
|
||||
HDMI_AUDIO_BLOCK_SIG_STARTEND_ON = 0,
|
||||
HDMI_AUDIO_BLOCK_SIG_STARTEND_OFF = 1
|
||||
};
|
||||
|
||||
enum hdmi_audio_i2s_config {
|
||||
HDMI_AUDIO_I2S_MSB_SHIFTED_FIRST = 0,
|
||||
HDMI_AUDIO_I2S_LSB_SHIFTED_FIRST = 1,
|
||||
|
|
@ -352,17 +239,6 @@ enum hdmi_audio_i2s_config {
|
|||
HDMI_AUDIO_I2S_SD3_EN = 1 << 3,
|
||||
};
|
||||
|
||||
enum hdmi_audio_mclk_mode {
|
||||
HDMI_AUDIO_MCLK_128FS = 0,
|
||||
HDMI_AUDIO_MCLK_256FS = 1,
|
||||
HDMI_AUDIO_MCLK_384FS = 2,
|
||||
HDMI_AUDIO_MCLK_512FS = 3,
|
||||
HDMI_AUDIO_MCLK_768FS = 4,
|
||||
HDMI_AUDIO_MCLK_1024FS = 5,
|
||||
HDMI_AUDIO_MCLK_1152FS = 6,
|
||||
HDMI_AUDIO_MCLK_192FS = 7
|
||||
};
|
||||
|
||||
struct hdmi_core_video_config {
|
||||
enum hdmi_core_inputbus_width ip_bus_width;
|
||||
enum hdmi_core_dither_trunc op_dither_truc;
|
||||
|
|
@ -383,55 +259,18 @@ struct hdmi_core_packet_enable_repeat {
|
|||
u32 generic_pkt_repeat;
|
||||
};
|
||||
|
||||
struct hdmi_video_format {
|
||||
enum hdmi_packing_mode packing_mode;
|
||||
u32 y_res; /* Line per panel */
|
||||
u32 x_res; /* pixel per line */
|
||||
};
|
||||
int hdmi4_read_edid(struct hdmi_core_data *core, u8 *edid, int len);
|
||||
void hdmi4_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
|
||||
struct hdmi_config *cfg);
|
||||
void hdmi4_core_dump(struct hdmi_core_data *core, struct seq_file *s);
|
||||
int hdmi4_core_init(struct platform_device *pdev, struct hdmi_core_data *core);
|
||||
|
||||
struct hdmi_audio_format {
|
||||
enum hdmi_stereo_channels stereo_channels;
|
||||
u8 active_chnnls_msk;
|
||||
enum hdmi_audio_type type;
|
||||
enum hdmi_audio_justify justification;
|
||||
enum hdmi_audio_sample_order sample_order;
|
||||
enum hdmi_audio_samples_perword samples_per_word;
|
||||
enum hdmi_audio_sample_size sample_size;
|
||||
enum hdmi_audio_blk_strt_end_sig en_sig_blk_strt_end;
|
||||
};
|
||||
|
||||
struct hdmi_audio_dma {
|
||||
u8 transfer_size;
|
||||
u8 block_size;
|
||||
enum hdmi_audio_transf_mode mode;
|
||||
u16 fifo_threshold;
|
||||
};
|
||||
|
||||
struct hdmi_core_audio_i2s_config {
|
||||
u8 in_length_bits;
|
||||
u8 justification;
|
||||
u8 sck_edge_mode;
|
||||
u8 vbit;
|
||||
u8 direction;
|
||||
u8 shift;
|
||||
u8 active_sds;
|
||||
};
|
||||
|
||||
struct hdmi_core_audio_config {
|
||||
struct hdmi_core_audio_i2s_config i2s_cfg;
|
||||
struct snd_aes_iec958 *iec60958_cfg;
|
||||
bool fs_override;
|
||||
u32 n;
|
||||
u32 cts;
|
||||
u32 aud_par_busclk;
|
||||
enum hdmi_core_audio_layout layout;
|
||||
enum hdmi_core_cts_mode cts_mode;
|
||||
bool use_mclk;
|
||||
enum hdmi_audio_mclk_mode mclk_mode;
|
||||
bool en_acr_pkt;
|
||||
bool en_dsd_audio;
|
||||
bool en_parallel_aud_input;
|
||||
bool en_spdif;
|
||||
};
|
||||
#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
|
||||
int hdmi4_audio_start(struct hdmi_core_data *core, struct hdmi_wp_data *wp);
|
||||
void hdmi4_audio_stop(struct hdmi_core_data *core, struct hdmi_wp_data *wp);
|
||||
int hdmi4_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
|
||||
struct omap_dss_audio *audio, u32 pclk);
|
||||
int hdmi4_audio_get_dma_port(u32 *offset, u32 *size);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
423
drivers/video/omap2/dss/hdmi_common.c
Normal file
423
drivers/video/omap2/dss/hdmi_common.c
Normal file
|
|
@ -0,0 +1,423 @@
|
|||
|
||||
/*
|
||||
* Logic for the below structure :
|
||||
* user enters the CEA or VESA timings by specifying the HDMI/DVI code.
|
||||
* There is a correspondence between CEA/VESA timing and code, please
|
||||
* refer to section 6.3 in HDMI 1.3 specification for timing code.
|
||||
*
|
||||
* In the below structure, cea_vesa_timings corresponds to all OMAP4
|
||||
* supported CEA and VESA timing values.code_cea corresponds to the CEA
|
||||
* code, It is used to get the timing from cea_vesa_timing array.Similarly
|
||||
* with code_vesa. Code_index is used for back mapping, that is once EDID
|
||||
* is read from the TV, EDID is parsed to find the timing values and then
|
||||
* map it to corresponding CEA or VESA index.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/err.h>
|
||||
#include <video/omapdss.h>
|
||||
|
||||
#include "hdmi.h"
|
||||
|
||||
static const struct hdmi_config cea_timings[] = {
|
||||
{
|
||||
{ 640, 480, 25200, 96, 16, 48, 2, 10, 33,
|
||||
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
|
||||
false, },
|
||||
{ 1, HDMI_HDMI },
|
||||
},
|
||||
{
|
||||
{ 720, 480, 27027, 62, 16, 60, 6, 9, 30,
|
||||
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
|
||||
false, },
|
||||
{ 2, HDMI_HDMI },
|
||||
},
|
||||
{
|
||||
{ 1280, 720, 74250, 40, 110, 220, 5, 5, 20,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 4, HDMI_HDMI },
|
||||
},
|
||||
{
|
||||
{ 1920, 540, 74250, 44, 88, 148, 5, 2, 15,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
true, },
|
||||
{ 5, HDMI_HDMI },
|
||||
},
|
||||
{
|
||||
{ 1440, 240, 27027, 124, 38, 114, 3, 4, 15,
|
||||
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
|
||||
true, },
|
||||
{ 6, HDMI_HDMI },
|
||||
},
|
||||
{
|
||||
{ 1920, 1080, 148500, 44, 88, 148, 5, 4, 36,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 16, HDMI_HDMI },
|
||||
},
|
||||
{
|
||||
{ 720, 576, 27000, 64, 12, 68, 5, 5, 39,
|
||||
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
|
||||
false, },
|
||||
{ 17, HDMI_HDMI },
|
||||
},
|
||||
{
|
||||
{ 1280, 720, 74250, 40, 440, 220, 5, 5, 20,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 19, HDMI_HDMI },
|
||||
},
|
||||
{
|
||||
{ 1920, 540, 74250, 44, 528, 148, 5, 2, 15,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
true, },
|
||||
{ 20, HDMI_HDMI },
|
||||
},
|
||||
{
|
||||
{ 1440, 288, 27000, 126, 24, 138, 3, 2, 19,
|
||||
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
|
||||
true, },
|
||||
{ 21, HDMI_HDMI },
|
||||
},
|
||||
{
|
||||
{ 1440, 576, 54000, 128, 24, 136, 5, 5, 39,
|
||||
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
|
||||
false, },
|
||||
{ 29, HDMI_HDMI },
|
||||
},
|
||||
{
|
||||
{ 1920, 1080, 148500, 44, 528, 148, 5, 4, 36,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 31, HDMI_HDMI },
|
||||
},
|
||||
{
|
||||
{ 1920, 1080, 74250, 44, 638, 148, 5, 4, 36,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 32, HDMI_HDMI },
|
||||
},
|
||||
{
|
||||
{ 2880, 480, 108108, 248, 64, 240, 6, 9, 30,
|
||||
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
|
||||
false, },
|
||||
{ 35, HDMI_HDMI },
|
||||
},
|
||||
{
|
||||
{ 2880, 576, 108000, 256, 48, 272, 5, 5, 39,
|
||||
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
|
||||
false, },
|
||||
{ 37, HDMI_HDMI },
|
||||
},
|
||||
};
|
||||
|
||||
static const struct hdmi_config vesa_timings[] = {
|
||||
/* VESA From Here */
|
||||
{
|
||||
{ 640, 480, 25175, 96, 16, 48, 2, 11, 31,
|
||||
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
|
||||
false, },
|
||||
{ 4, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 800, 600, 40000, 128, 40, 88, 4, 1, 23,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 9, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 848, 480, 33750, 112, 16, 112, 8, 6, 23,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 0xE, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 1280, 768, 79500, 128, 64, 192, 7, 3, 20,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
|
||||
false, },
|
||||
{ 0x17, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 1280, 800, 83500, 128, 72, 200, 6, 3, 22,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
|
||||
false, },
|
||||
{ 0x1C, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 1360, 768, 85500, 112, 64, 256, 6, 3, 18,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 0x27, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 1280, 960, 108000, 112, 96, 312, 3, 1, 36,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 0x20, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 1280, 1024, 108000, 112, 48, 248, 3, 1, 38,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 0x23, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 1024, 768, 65000, 136, 24, 160, 6, 3, 29,
|
||||
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
|
||||
false, },
|
||||
{ 0x10, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 1400, 1050, 121750, 144, 88, 232, 4, 3, 32,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
|
||||
false, },
|
||||
{ 0x2A, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 1440, 900, 106500, 152, 80, 232, 6, 3, 25,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
|
||||
false, },
|
||||
{ 0x2F, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 1680, 1050, 146250, 176 , 104, 280, 6, 3, 30,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
|
||||
false, },
|
||||
{ 0x3A, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 1366, 768, 85500, 143, 70, 213, 3, 3, 24,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 0x51, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 1920, 1080, 148500, 44, 148, 80, 5, 4, 36,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 0x52, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 1280, 768, 68250, 32, 48, 80, 7, 3, 12,
|
||||
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 0x16, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 1400, 1050, 101000, 32, 48, 80, 4, 3, 23,
|
||||
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 0x29, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 1680, 1050, 119000, 32, 48, 80, 6, 3, 21,
|
||||
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 0x39, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 1280, 800, 79500, 32, 48, 80, 6, 3, 14,
|
||||
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 0x1B, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 1280, 720, 74250, 40, 110, 220, 5, 5, 20,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 0x55, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 1920, 1200, 154000, 32, 48, 80, 6, 3, 26,
|
||||
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 0x44, HDMI_DVI },
|
||||
},
|
||||
};
|
||||
|
||||
const struct hdmi_config *hdmi_default_timing(void)
|
||||
{
|
||||
return &vesa_timings[0];
|
||||
}
|
||||
|
||||
static const struct hdmi_config *hdmi_find_timing(int code,
|
||||
const struct hdmi_config *timings_arr, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (timings_arr[i].cm.code == code)
|
||||
return &timings_arr[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const struct hdmi_config *hdmi_get_timings(int mode, int code)
|
||||
{
|
||||
const struct hdmi_config *arr;
|
||||
int len;
|
||||
|
||||
if (mode == HDMI_DVI) {
|
||||
arr = vesa_timings;
|
||||
len = ARRAY_SIZE(vesa_timings);
|
||||
} else {
|
||||
arr = cea_timings;
|
||||
len = ARRAY_SIZE(cea_timings);
|
||||
}
|
||||
|
||||
return hdmi_find_timing(code, arr, len);
|
||||
}
|
||||
|
||||
static bool hdmi_timings_compare(struct omap_video_timings *timing1,
|
||||
const struct omap_video_timings *timing2)
|
||||
{
|
||||
int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync;
|
||||
|
||||
if ((DIV_ROUND_CLOSEST(timing2->pixel_clock, 1000) ==
|
||||
DIV_ROUND_CLOSEST(timing1->pixel_clock, 1000)) &&
|
||||
(timing2->x_res == timing1->x_res) &&
|
||||
(timing2->y_res == timing1->y_res)) {
|
||||
|
||||
timing2_hsync = timing2->hfp + timing2->hsw + timing2->hbp;
|
||||
timing1_hsync = timing1->hfp + timing1->hsw + timing1->hbp;
|
||||
timing2_vsync = timing2->vfp + timing2->vsw + timing2->vbp;
|
||||
timing1_vsync = timing1->vfp + timing1->vsw + timing1->vbp;
|
||||
|
||||
DSSDBG("timing1_hsync = %d timing1_vsync = %d"\
|
||||
"timing2_hsync = %d timing2_vsync = %d\n",
|
||||
timing1_hsync, timing1_vsync,
|
||||
timing2_hsync, timing2_vsync);
|
||||
|
||||
if ((timing1_hsync == timing2_hsync) &&
|
||||
(timing1_vsync == timing2_vsync)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing)
|
||||
{
|
||||
int i;
|
||||
struct hdmi_cm cm = {-1};
|
||||
DSSDBG("hdmi_get_code\n");
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cea_timings); i++) {
|
||||
if (hdmi_timings_compare(timing, &cea_timings[i].timings)) {
|
||||
cm = cea_timings[i].cm;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < ARRAY_SIZE(vesa_timings); i++) {
|
||||
if (hdmi_timings_compare(timing, &vesa_timings[i].timings)) {
|
||||
cm = vesa_timings[i].cm;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
return cm;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
|
||||
int hdmi_compute_acr(u32 pclk, u32 sample_freq, u32 *n, u32 *cts)
|
||||
{
|
||||
u32 deep_color;
|
||||
bool deep_color_correct = false;
|
||||
|
||||
if (n == NULL || cts == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
/* TODO: When implemented, query deep color mode here. */
|
||||
deep_color = 100;
|
||||
|
||||
/*
|
||||
* When using deep color, the default N value (as in the HDMI
|
||||
* specification) yields to an non-integer CTS. Hence, we
|
||||
* modify it while keeping the restrictions described in
|
||||
* section 7.2.1 of the HDMI 1.4a specification.
|
||||
*/
|
||||
switch (sample_freq) {
|
||||
case 32000:
|
||||
case 48000:
|
||||
case 96000:
|
||||
case 192000:
|
||||
if (deep_color == 125)
|
||||
if (pclk == 27027 || pclk == 74250)
|
||||
deep_color_correct = true;
|
||||
if (deep_color == 150)
|
||||
if (pclk == 27027)
|
||||
deep_color_correct = true;
|
||||
break;
|
||||
case 44100:
|
||||
case 88200:
|
||||
case 176400:
|
||||
if (deep_color == 125)
|
||||
if (pclk == 27027)
|
||||
deep_color_correct = true;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (deep_color_correct) {
|
||||
switch (sample_freq) {
|
||||
case 32000:
|
||||
*n = 8192;
|
||||
break;
|
||||
case 44100:
|
||||
*n = 12544;
|
||||
break;
|
||||
case 48000:
|
||||
*n = 8192;
|
||||
break;
|
||||
case 88200:
|
||||
*n = 25088;
|
||||
break;
|
||||
case 96000:
|
||||
*n = 16384;
|
||||
break;
|
||||
case 176400:
|
||||
*n = 50176;
|
||||
break;
|
||||
case 192000:
|
||||
*n = 32768;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
switch (sample_freq) {
|
||||
case 32000:
|
||||
*n = 4096;
|
||||
break;
|
||||
case 44100:
|
||||
*n = 6272;
|
||||
break;
|
||||
case 48000:
|
||||
*n = 6144;
|
||||
break;
|
||||
case 88200:
|
||||
*n = 12544;
|
||||
break;
|
||||
case 96000:
|
||||
*n = 12288;
|
||||
break;
|
||||
case 176400:
|
||||
*n = 25088;
|
||||
break;
|
||||
case 192000:
|
||||
*n = 24576;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
/* Calculate CTS. See HDMI 1.3a or 1.4a specifications */
|
||||
*cts = pclk * (*n / 128) * deep_color / (sample_freq / 10);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
160
drivers/video/omap2/dss/hdmi_phy.c
Normal file
160
drivers/video/omap2/dss/hdmi_phy.c
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
* HDMI PHY
|
||||
*
|
||||
* Copyright (C) 2013 Texas Instruments Incorporated
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <video/omapdss.h>
|
||||
|
||||
#include "dss.h"
|
||||
#include "hdmi.h"
|
||||
|
||||
void hdmi_phy_dump(struct hdmi_phy_data *phy, struct seq_file *s)
|
||||
{
|
||||
#define DUMPPHY(r) seq_printf(s, "%-35s %08x\n", #r,\
|
||||
hdmi_read_reg(phy->base, r))
|
||||
|
||||
DUMPPHY(HDMI_TXPHY_TX_CTRL);
|
||||
DUMPPHY(HDMI_TXPHY_DIGITAL_CTRL);
|
||||
DUMPPHY(HDMI_TXPHY_POWER_CTRL);
|
||||
DUMPPHY(HDMI_TXPHY_PAD_CFG_CTRL);
|
||||
}
|
||||
|
||||
static irqreturn_t hdmi_irq_handler(int irq, void *data)
|
||||
{
|
||||
struct hdmi_wp_data *wp = data;
|
||||
u32 irqstatus;
|
||||
|
||||
irqstatus = hdmi_wp_get_irqstatus(wp);
|
||||
hdmi_wp_set_irqstatus(wp, irqstatus);
|
||||
|
||||
if ((irqstatus & HDMI_IRQ_LINK_CONNECT) &&
|
||||
irqstatus & HDMI_IRQ_LINK_DISCONNECT) {
|
||||
/*
|
||||
* If we get both connect and disconnect interrupts at the same
|
||||
* time, turn off the PHY, clear interrupts, and restart, which
|
||||
* raises connect interrupt if a cable is connected, or nothing
|
||||
* if cable is not connected.
|
||||
*/
|
||||
hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_OFF);
|
||||
|
||||
hdmi_wp_set_irqstatus(wp, HDMI_IRQ_LINK_CONNECT |
|
||||
HDMI_IRQ_LINK_DISCONNECT);
|
||||
|
||||
hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON);
|
||||
} else if (irqstatus & HDMI_IRQ_LINK_CONNECT) {
|
||||
hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_TXON);
|
||||
} else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) {
|
||||
hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON);
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
int hdmi_phy_enable(struct hdmi_phy_data *phy, struct hdmi_wp_data *wp,
|
||||
struct hdmi_config *cfg)
|
||||
{
|
||||
u16 r = 0;
|
||||
u32 irqstatus;
|
||||
|
||||
hdmi_wp_clear_irqenable(wp, 0xffffffff);
|
||||
|
||||
irqstatus = hdmi_wp_get_irqstatus(wp);
|
||||
hdmi_wp_set_irqstatus(wp, irqstatus);
|
||||
|
||||
r = hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/*
|
||||
* Read address 0 in order to get the SCP reset done completed
|
||||
* Dummy access performed to make sure reset is done
|
||||
*/
|
||||
hdmi_read_reg(phy->base, HDMI_TXPHY_TX_CTRL);
|
||||
|
||||
/*
|
||||
* Write to phy address 0 to configure the clock
|
||||
* use HFBITCLK write HDMI_TXPHY_TX_CONTROL_FREQOUT field
|
||||
*/
|
||||
REG_FLD_MOD(phy->base, HDMI_TXPHY_TX_CTRL, 0x1, 31, 30);
|
||||
|
||||
/* Write to phy address 1 to start HDMI line (TXVALID and TMDSCLKEN) */
|
||||
hdmi_write_reg(phy->base, HDMI_TXPHY_DIGITAL_CTRL, 0xF0000000);
|
||||
|
||||
/* Setup max LDO voltage */
|
||||
REG_FLD_MOD(phy->base, HDMI_TXPHY_POWER_CTRL, 0xB, 3, 0);
|
||||
|
||||
/* Write to phy address 3 to change the polarity control */
|
||||
REG_FLD_MOD(phy->base, HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27);
|
||||
|
||||
r = request_threaded_irq(phy->irq, NULL, hdmi_irq_handler,
|
||||
IRQF_ONESHOT, "OMAP HDMI", wp);
|
||||
if (r) {
|
||||
DSSERR("HDMI IRQ request failed\n");
|
||||
hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_OFF);
|
||||
return r;
|
||||
}
|
||||
|
||||
hdmi_wp_set_irqenable(wp,
|
||||
HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hdmi_phy_disable(struct hdmi_phy_data *phy, struct hdmi_wp_data *wp)
|
||||
{
|
||||
free_irq(phy->irq, wp);
|
||||
|
||||
hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_OFF);
|
||||
}
|
||||
|
||||
#define PHY_OFFSET 0x300
|
||||
#define PHY_SIZE 0x100
|
||||
|
||||
int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy)
|
||||
{
|
||||
struct resource *res;
|
||||
struct resource temp_res;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi_txphy");
|
||||
if (!res) {
|
||||
DSSDBG("can't get PHY mem resource by name\n");
|
||||
/*
|
||||
* if hwmod/DT doesn't have the memory resource information
|
||||
* split into HDMI sub blocks by name, we try again by getting
|
||||
* the platform's first resource. this code will be removed when
|
||||
* the driver can get the mem resources by name
|
||||
*/
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
DSSERR("can't get PHY mem resource\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
temp_res.start = res->start + PHY_OFFSET;
|
||||
temp_res.end = temp_res.start + PHY_SIZE - 1;
|
||||
res = &temp_res;
|
||||
}
|
||||
|
||||
phy->base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
|
||||
if (!phy->base) {
|
||||
DSSERR("can't ioremap TX PHY\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
phy->irq = platform_get_irq(pdev, 0);
|
||||
if (phy->irq < 0) {
|
||||
DSSERR("platform_get_irq failed\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
230
drivers/video/omap2/dss/hdmi_pll.c
Normal file
230
drivers/video/omap2/dss/hdmi_pll.c
Normal file
|
|
@ -0,0 +1,230 @@
|
|||
/*
|
||||
* HDMI PLL
|
||||
*
|
||||
* Copyright (C) 2013 Texas Instruments Incorporated
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <video/omapdss.h>
|
||||
|
||||
#include "dss.h"
|
||||
#include "hdmi.h"
|
||||
|
||||
#define HDMI_DEFAULT_REGN 16
|
||||
#define HDMI_DEFAULT_REGM2 1
|
||||
|
||||
void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s)
|
||||
{
|
||||
#define DUMPPLL(r) seq_printf(s, "%-35s %08x\n", #r,\
|
||||
hdmi_read_reg(pll->base, r))
|
||||
|
||||
DUMPPLL(PLLCTRL_PLL_CONTROL);
|
||||
DUMPPLL(PLLCTRL_PLL_STATUS);
|
||||
DUMPPLL(PLLCTRL_PLL_GO);
|
||||
DUMPPLL(PLLCTRL_CFG1);
|
||||
DUMPPLL(PLLCTRL_CFG2);
|
||||
DUMPPLL(PLLCTRL_CFG3);
|
||||
DUMPPLL(PLLCTRL_SSC_CFG1);
|
||||
DUMPPLL(PLLCTRL_SSC_CFG2);
|
||||
DUMPPLL(PLLCTRL_CFG4);
|
||||
}
|
||||
|
||||
void hdmi_pll_compute(struct hdmi_pll_data *pll, unsigned long clkin, int phy)
|
||||
{
|
||||
struct hdmi_pll_info *pi = &pll->info;
|
||||
unsigned long refclk;
|
||||
u32 mf;
|
||||
|
||||
/* use our funky units */
|
||||
clkin /= 10000;
|
||||
|
||||
/*
|
||||
* Input clock is predivided by N + 1
|
||||
* out put of which is reference clk
|
||||
*/
|
||||
|
||||
pi->regn = HDMI_DEFAULT_REGN;
|
||||
|
||||
refclk = clkin / pi->regn;
|
||||
|
||||
pi->regm2 = HDMI_DEFAULT_REGM2;
|
||||
|
||||
/*
|
||||
* multiplier is pixel_clk/ref_clk
|
||||
* Multiplying by 100 to avoid fractional part removal
|
||||
*/
|
||||
pi->regm = phy * pi->regm2 / refclk;
|
||||
|
||||
/*
|
||||
* fractional multiplier is remainder of the difference between
|
||||
* multiplier and actual phy(required pixel clock thus should be
|
||||
* multiplied by 2^18(262144) divided by the reference clock
|
||||
*/
|
||||
mf = (phy - pi->regm / pi->regm2 * refclk) * 262144;
|
||||
pi->regmf = pi->regm2 * mf / refclk;
|
||||
|
||||
/*
|
||||
* Dcofreq should be set to 1 if required pixel clock
|
||||
* is greater than 1000MHz
|
||||
*/
|
||||
pi->dcofreq = phy > 1000 * 100;
|
||||
pi->regsd = ((pi->regm * clkin / 10) / (pi->regn * 250) + 5) / 10;
|
||||
|
||||
/* Set the reference clock to sysclk reference */
|
||||
pi->refsel = HDMI_REFSEL_SYSCLK;
|
||||
|
||||
DSSDBG("M = %d Mf = %d\n", pi->regm, pi->regmf);
|
||||
DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd);
|
||||
}
|
||||
|
||||
|
||||
static int hdmi_pll_config(struct hdmi_pll_data *pll)
|
||||
{
|
||||
u32 r;
|
||||
struct hdmi_pll_info *fmt = &pll->info;
|
||||
|
||||
/* PLL start always use manual mode */
|
||||
REG_FLD_MOD(pll->base, PLLCTRL_PLL_CONTROL, 0x0, 0, 0);
|
||||
|
||||
r = hdmi_read_reg(pll->base, PLLCTRL_CFG1);
|
||||
r = FLD_MOD(r, fmt->regm, 20, 9); /* CFG1_PLL_REGM */
|
||||
r = FLD_MOD(r, fmt->regn - 1, 8, 1); /* CFG1_PLL_REGN */
|
||||
hdmi_write_reg(pll->base, PLLCTRL_CFG1, r);
|
||||
|
||||
r = hdmi_read_reg(pll->base, PLLCTRL_CFG2);
|
||||
|
||||
r = FLD_MOD(r, 0x0, 12, 12); /* PLL_HIGHFREQ divide by 2 */
|
||||
r = FLD_MOD(r, 0x1, 13, 13); /* PLL_REFEN */
|
||||
r = FLD_MOD(r, 0x0, 14, 14); /* PHY_CLKINEN de-assert during locking */
|
||||
r = FLD_MOD(r, fmt->refsel, 22, 21); /* REFSEL */
|
||||
|
||||
if (fmt->dcofreq) {
|
||||
/* divider programming for frequency beyond 1000Mhz */
|
||||
REG_FLD_MOD(pll->base, PLLCTRL_CFG3, fmt->regsd, 17, 10);
|
||||
r = FLD_MOD(r, 0x4, 3, 1); /* 1000MHz and 2000MHz */
|
||||
} else {
|
||||
r = FLD_MOD(r, 0x2, 3, 1); /* 500MHz and 1000MHz */
|
||||
}
|
||||
|
||||
hdmi_write_reg(pll->base, PLLCTRL_CFG2, r);
|
||||
|
||||
r = hdmi_read_reg(pll->base, PLLCTRL_CFG4);
|
||||
r = FLD_MOD(r, fmt->regm2, 24, 18);
|
||||
r = FLD_MOD(r, fmt->regmf, 17, 0);
|
||||
hdmi_write_reg(pll->base, PLLCTRL_CFG4, r);
|
||||
|
||||
/* go now */
|
||||
REG_FLD_MOD(pll->base, PLLCTRL_PLL_GO, 0x1, 0, 0);
|
||||
|
||||
/* wait for bit change */
|
||||
if (hdmi_wait_for_bit_change(pll->base, PLLCTRL_PLL_GO,
|
||||
0, 0, 1) != 1) {
|
||||
pr_err("PLL GO bit not set\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
/* Wait till the lock bit is set in PLL status */
|
||||
if (hdmi_wait_for_bit_change(pll->base,
|
||||
PLLCTRL_PLL_STATUS, 1, 1, 1) != 1) {
|
||||
pr_err("cannot lock PLL\n");
|
||||
pr_err("CFG1 0x%x\n",
|
||||
hdmi_read_reg(pll->base, PLLCTRL_CFG1));
|
||||
pr_err("CFG2 0x%x\n",
|
||||
hdmi_read_reg(pll->base, PLLCTRL_CFG2));
|
||||
pr_err("CFG4 0x%x\n",
|
||||
hdmi_read_reg(pll->base, PLLCTRL_CFG4));
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
pr_debug("PLL locked!\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdmi_pll_reset(struct hdmi_pll_data *pll)
|
||||
{
|
||||
/* SYSRESET controlled by power FSM */
|
||||
REG_FLD_MOD(pll->base, PLLCTRL_PLL_CONTROL, 0x0, 3, 3);
|
||||
|
||||
/* READ 0x0 reset is in progress */
|
||||
if (hdmi_wait_for_bit_change(pll->base, PLLCTRL_PLL_STATUS, 0, 0, 1)
|
||||
!= 1) {
|
||||
pr_err("Failed to sysreset PLL\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hdmi_pll_enable(struct hdmi_pll_data *pll, struct hdmi_wp_data *wp)
|
||||
{
|
||||
u16 r = 0;
|
||||
|
||||
r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_BOTHON_ALLCLKS);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = hdmi_pll_reset(pll);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = hdmi_pll_config(pll);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hdmi_pll_disable(struct hdmi_pll_data *pll, struct hdmi_wp_data *wp)
|
||||
{
|
||||
hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF);
|
||||
}
|
||||
|
||||
#define PLL_OFFSET 0x200
|
||||
#define PLL_SIZE 0x100
|
||||
|
||||
int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll)
|
||||
{
|
||||
struct resource *res;
|
||||
struct resource temp_res;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi_pllctrl");
|
||||
if (!res) {
|
||||
DSSDBG("can't get PLL mem resource by name\n");
|
||||
/*
|
||||
* if hwmod/DT doesn't have the memory resource information
|
||||
* split into HDMI sub blocks by name, we try again by getting
|
||||
* the platform's first resource. this code will be removed when
|
||||
* the driver can get the mem resources by name
|
||||
*/
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
DSSERR("can't get PLL mem resource\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
temp_res.start = res->start + PLL_OFFSET;
|
||||
temp_res.end = temp_res.start + PLL_SIZE - 1;
|
||||
res = &temp_res;
|
||||
}
|
||||
|
||||
pll->base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
|
||||
if (!pll->base) {
|
||||
DSSERR("can't ioremap PLLCTRL\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue