@@ -139,6 +139,7 @@ static struct clk pll1_sysclk6 = {
.parent = &pll1_clk,
.flags = CLK_PLL,
.div_reg = PLLDIV6,
+ .set_rate = dm365_set_pll1_rate,
};
static struct clk pll1_sysclk7 = {
@@ -29,12 +29,16 @@
#include <linux/interrupt.h>
#include <linux/platform_device.h>
+#include <media/davinci/vpss.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <video/davincifb.h>
#include <asm/system.h>
+#include <mach/dm365.h>
+#include <mach/cputype.h>
+
#define MODULE_NAME "davincifb"
/* Output Format Selection */
@@ -78,49 +82,10 @@ static __inline__ u32 dispc_reg_merge(u32 reg, u32 val,
u32 mask)
/* usage: if (is_win(info->fix.id, OSD0)) ... */
#define is_win(name, x) ((strcmp(name, x ## _FBNAME) == 0) ? 1 : 0)
-struct dm_win_info {
- struct fb_info info;
-
- /* X and Y position */
- unsigned int x, y;
-
- /* framebuffer area */
- dma_addr_t fb_base_phys;
- unsigned long fb_base;
- unsigned long fb_size;
-
- u32 pseudo_palette[17];
-
- /* flag to identify if framebuffer area is fixed already or not */
- int alloc_fb_mem;
- unsigned long sdram_address;
- struct dm_info *dm;
-};
-
-static struct dm_info {
- struct dm_win_info *osd0;
- struct dm_win_info *osd1;
- struct dm_win_info *vid0;
- struct dm_win_info *vid1;
-
- /* to map the registers */
- dma_addr_t mmio_base_phys;
- unsigned long mmio_base;
- unsigned long mmio_size;
-
- wait_queue_head_t vsync_wait;
- unsigned long vsync_cnt;
- int timeout;
-
- /* this is the function that configures the output device
(NTSC/PAL/LCD)
- * for the required output format (composite/s-video/component/rgb)
- */
- void (*output_device_config) (int on);
-
- struct device *dev;
-} dm_static;
+static struct dm_info dm_static;
static struct dm_info *dm = &dm_static;
+
static struct fb_ops davincifb_ops;
#define BASEX 0x80
@@ -178,7 +143,7 @@ static struct fb_var_screeninfo osd0_default_var = {
.hsync_len = 4, /* pixclocks */
.vsync_len = 2, /* line clocks */
.sync = 0,
- .vmode = FB_VMODE_INTERLACED,
+ .vmode = FB_VMODE_NONINTERLACED,
};
/* Using the full screen for OSD1 by default */
@@ -326,6 +291,8 @@ static irqreturn_t davincifb_isr(int irq, void *arg)
dm->vid1->info.fix.line_length);
dm->vid1->sdram_address = 0;
}
+ ++dm->vsync_cnt; /* maybe for non-interlaced mode */
+ wake_up_interruptible(&dm->vsync_wait);
return IRQ_HANDLED;
} else {
++dm->vsync_cnt;
@@ -671,24 +638,28 @@ static void set_sdram_params(char *id, u32 addr, u32
line_length)
/* The parameters to be written to the registers should be in
* multiple of 32 bytes
*/
- addr = addr; /* div by 32 */
- line_length = line_length / 32;
+ addr = (addr - DAVINCI_DDR_BASE) >> 5; /* div by 32 */
+ line_length = line_length >> 5;
+
if (is_win(id, VID0)) {
- dispc_reg_out(OSD_VIDWIN0ADR, addr);
- dispc_reg_out(OSD_VIDWIN0OFST, line_length);
+ dispc_reg_out(OSD_VIDWIN0ADR, addr & 0xFFFF);
+ dispc_reg_merge(OSD_VIDWINADH, (addr & 0x7F0000) >> 16, 0x7F);
+ dispc_reg_out(OSD_VIDWIN0OFST, line_length | 0x1000);/* FIXME
understand why */
} else if (is_win(id, VID1)) {
- dispc_reg_out(OSD_VIDWIN1ADR, addr);
- dispc_reg_out(OSD_VIDWIN1OFST, line_length);
+ dispc_reg_out(OSD_VIDWIN1ADR, addr & 0xFFFF);
+ dispc_reg_merge(OSD_VIDWINADH, (addr & 0x7F0000) >> 8, 0x7F00);
+ dispc_reg_out(OSD_VIDWIN1OFST, line_length | 0x1000);/* FIXME
understand why */
} else if (is_win(id, OSD0)) {
- dispc_reg_out(OSD_OSDWIN0ADR, addr);
- dispc_reg_out(OSD_OSDWIN0OFST, line_length);
+ dispc_reg_out(OSD_OSDWIN0ADR, addr & 0xFFFF);
+ dispc_reg_out(OSD_OSDWIN0OFST, line_length | 0x1000);/* FIXME
understand why */
+ dispc_reg_merge(OSD_OSDWINADH, (addr & 0x7F0000) >> 16, 0x7F);
} else if (is_win(id, OSD1)) {
- dispc_reg_out(OSD_OSDWIN1ADR, addr);
- dispc_reg_out(OSD_OSDWIN1OFST, line_length);
+ dispc_reg_out(OSD_OSDWIN1ADR, addr & 0xFFFF);
+ dispc_reg_merge(OSD_OSDWINADH, (addr & 0x7F0000) >> 8, 0x7F00);
+ dispc_reg_out(OSD_OSDWIN1OFST, line_length | 0x1000);/* FIXME
understand why */
}
}
-
static void set_win_enable(char *id, unsigned int on)
{
on = (on == 0) ? 0 : ~0;
@@ -754,7 +725,7 @@ static int davincifb_set_par(struct fb_info *info)
start = (u32) w->fb_base_phys + offset;
set_sdram_params(info->fix.id, start, info->fix.line_length);
- set_interlaced(info->fix.id, 1);
+ set_interlaced(info->fix.id, info->var.vmode);
set_win_position(info->fix.id,
x_pos(w), y_pos(w), v->xres, v->yres / 2);
set_win_mode(info->fix.id);
@@ -774,7 +745,6 @@ static int davincifb_ioctl(struct fb_info *info,
unsigned int cmd,
struct fb_fillrect rect;
struct zoom_params zoom;
long std = 0;
-
switch (cmd) {
case FBIO_WAITFORVSYNC:
/* This ioctl accepts an integer argument to specify a
@@ -944,6 +914,22 @@ static int davincifb_pan_display(struct
fb_var_screeninfo *var,
*/
static int davincifb_blank(int blank_mode, struct fb_info *info)
{
+ if (blank_mode == 4)
+ {
+ dm->output_device_config(0);
+ dm->ops->davincifb_power(&dm->osd0->info,0);
+ dm->ops->davincifb_power(&dm->osd1->info,0);
+ dm->ops->davincifb_power(&dm->vid0->info,0);
+ dm->ops->davincifb_power(&dm->vid1->info,0);
+ }
+ else if (!blank_mode)
+ {
+ dm->output_device_config(1);
+ dm->ops->davincifb_power(&dm->osd0->info,1);
+ dm->ops->davincifb_power(&dm->osd1->info,1);
+ dm->ops->davincifb_power(&dm->vid0->info,1);
+ dm->ops->davincifb_power(&dm->vid1->info,1);
+ }
return 0;
}
@@ -1007,14 +993,12 @@ int __init davincifb_setup(char *options)
if (!strncmp(this_opt, "output=", 7)) {
if (!strncmp(this_opt + 7, "lcd", 3)) {
dmparams.output = LCD;
- dmparams.format = 0;
+ dmparams.format = RGB;
} else if (!strncmp(this_opt + 7, "ntsc", 4))
dmparams.output = NTSC;
else if (!strncmp(this_opt + 7, "pal", 3))
dmparams.output = PAL;
} else if (!strncmp(this_opt, "format=", 7)) {
- if (dmparams.output == LCD)
- continue;
if (!strncmp(this_opt + 7, "composite", 9))
dmparams.format = COMPOSITE;
else if (!strncmp(this_opt + 7, "s-video", 7))
@@ -1087,7 +1071,10 @@ int __init davincifb_setup(char *options)
format_yres = 480;
} else if (dmparams.output == PAL) {
format_yres = 576;
- } else {
+ } else if (dmparams.output == LCD)
+ format_yres = dmparams.osd0_yres;
+ else
+ {
printk(KERN_INFO
"DaVinci:invalid format..defaulting width to 480\n");
}
@@ -1207,11 +1194,15 @@ static struct fb_info *init_fb_info(struct
dm_win_info *w,
struct dm_info *dm = w->dm;
/* initialize the fb_info structure */
- info->flags = FBINFO_DEFAULT;
+ info->flags =
+ FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT
|
+ FBINFO_HWACCEL_IMAGEBLIT | FBINFO_HWACCEL_XPAN |
+ FBINFO_HWACCEL_YPAN;
info->fbops = &davincifb_ops;
info->screen_base = (char *)(w->fb_base);
info->pseudo_palette = w->pseudo_palette;
info->par = w;
+ info->screen_size = w->fb_size;
/* Initialize variable screeninfo.
* The variable screeninfo can be directly specified by the user
@@ -1224,6 +1215,8 @@ static struct fb_info *init_fb_info(struct dm_win_info
*w,
* The fixed screeninfo cannot be directly specified by the user, but
* it may change to reflect changes to the var info.
*/
+ info->var.xres_virtual = info->var.xres;
+ info->var.yres_virtual = info->var.yres;
strlcpy(info->fix.id, id, sizeof(info->fix.id));
info->fix.smem_start = w->fb_base_phys;
info->fix.line_length =
@@ -1241,6 +1234,8 @@ static struct fb_info *init_fb_info(struct dm_win_info
*w,
info->fix.accel = FB_ACCEL_NONE;
w->sdram_address = 0;
+
+
return info;
}
@@ -1261,6 +1256,9 @@ static void davincifb_ntsc_composite_config(int on)
/* Enable all DACs */
dispc_reg_out(VENC_DACTST, 0);
+
+ dispc_reg_out(OSD_BASEPX, BASEX);
+ dispc_reg_out(OSD_BASEPY, BASEY);
} else {
/* Reset video encoder module */
dispc_reg_out(VENC_VMOD, 0);
@@ -1287,6 +1285,9 @@ static void davincifb_ntsc_svideo_config(int on)
/* Enable all DACs */
dispc_reg_out(VENC_DACTST, 0);
+
+ dispc_reg_out(OSD_BASEPX, BASEX);
+ dispc_reg_out(OSD_BASEPY, BASEY);
} else {
/* Reset video encoder module */
dispc_reg_out(VENC_VMOD, 0);
@@ -1313,6 +1314,9 @@ static void davincifb_ntsc_component_config(int on)
/* Enable all DACs */
dispc_reg_out(VENC_DACTST, 0);
+
+ dispc_reg_out(OSD_BASEPX, BASEX);
+ dispc_reg_out(OSD_BASEPY, BASEY);
} else {
/* Reset video encoder module */
dispc_reg_out(VENC_VMOD, 0);
@@ -1336,6 +1340,9 @@ static void davincifb_pal_composite_config(int on)
/* Enable all DACs */
dispc_reg_out(VENC_DACTST, 0);
+
+ dispc_reg_out(OSD_BASEPX, BASEX);
+ dispc_reg_out(OSD_BASEPY, BASEY);
} else {
/* Reset video encoder module */
dispc_reg_out(VENC_VMOD, 0);
@@ -1362,6 +1369,9 @@ static void davincifb_pal_svideo_config(int on)
/* Enable all DACs */
dispc_reg_out(VENC_DACTST, 0);
+
+ dispc_reg_out(OSD_BASEPX, BASEX);
+ dispc_reg_out(OSD_BASEPY, BASEY);
} else {
/* Reset video encoder module */
dispc_reg_out(VENC_VMOD, 0);
@@ -1388,12 +1398,128 @@ static void davincifb_pal_component_config(int on)
/* Enable all DACs */
dispc_reg_out(VENC_DACTST, 0);
+
+ dispc_reg_out(OSD_BASEPX, BASEX);
+ dispc_reg_out(OSD_BASEPY, BASEY);
+ } else {
+ /* Reset video encoder module */
+ dispc_reg_out(VENC_VMOD, 0);
+ }
+}
+
+int dm365_set_pixelclock(int pixclock)
+{
+ u32 pllfreq;
+ int ret;
+ struct clk *clk6;
+
+ pixclock /= 1000;
+ pllfreq = 1000000000 / pixclock;
+
+ clk6 = clk_get(dm->dev, "pll1_sysclk6");
+ if (clk_set_rate(clk6, pllfreq))
+ {
+ dispc_reg_out(VENC_DCLKCTL, 0x03);
+ dispc_reg_out(VENC_DCLKPTN0, 0x03);
+ dispc_reg_out(VENC_DCLKPTN1, 0x0);
+ dispc_reg_out(VENC_DCLKPTN2, 0x0);
+ dispc_reg_out(VENC_DCLKPTN3, 0x0);
+ ret = 4;
+ clk_set_rate(clk6, pllfreq * 4);
+ }
+ else
+ {
+ dispc_reg_out(VENC_DCLKCTL, 0x801);
+ dispc_reg_out(VENC_DCLKPTN0, 0x03);
+ dispc_reg_out(VENC_DCLKPTN1, 0x0);
+ dispc_reg_out(VENC_DCLKPTN2, 0x0);
+ dispc_reg_out(VENC_DCLKPTN3, 0x0);
+ ret = 1;
+ }
+ pllfreq = clk_get_rate(clk6);
+ return ret;
+}
+
+static void davincifb_lcd_rgb_config(int on)
+{
+ u32 divisor = 1;
+
+ if (on) {
+ /* Reset video encoder module */
+ dispc_reg_out(VENC_VMOD, 0x0);
+ dispc_reg_out(VENC_VIDCTL, 0x0);
+
+ if (cpu_is_davinci_dm365())
+ {
+ divisor = dm365_set_pixelclock(dm->osd0->info.var.pixclock);
+ }
+
+ /* set hsync pulse width */
+ dispc_reg_out(VENC_HSPLS, (dm->osd0->info.var.hsync_len) *
divisor);
+ /* set vsync pulse width */
+ dispc_reg_out(VENC_VSPLS, dm->osd0->info.var.vsync_len);
+ /* set horizontal interval */
+ dispc_reg_out(VENC_HINT, ( (dm->osd0->info.var.left_margin + \
+ dm->osd0->info.var.right_margin + dm->osd0->info.var.width) * \
+ divisor ) - 1);
+ /* set horizontal data valid start position */
+ dispc_reg_out(VENC_HSTART, (dm->osd0->info.var.left_margin) *
divisor);
+ /* set Horizontal data valid range */
+ dispc_reg_out(VENC_HVALID, (dm->osd0->info.var.width) * divisor);
+ /* set Vertical interval */
+ dispc_reg_out(VENC_VINT, dm->osd0->info.var.upper_margin + \
+ dm->osd0->info.var.lower_margin + dm->osd0->info.var.height -
1);
+ /* set Vertical data valid start position */
+ dispc_reg_out(VENC_VSTART, dm->osd0->info.var.upper_margin);
+ /* set Horizontal data valid range */
+ dispc_reg_out(VENC_VVALID, dm->osd0->info.var.height);
+ /* Enable VCLK */
+ dispc_reg_out(VENC_OSDCLK1, 3);
+ dispc_reg_out(VENC_LCDOUT, 0x81);
+ dispc_reg_out(VENC_OSDCLK0, 0x0);
+ dispc_reg_out(VENC_OSDCLK1, 0xFFFF);
+ dispc_reg_out(VENC_CLKCTL, 0x10);
+ dispc_reg_out(VENC_SYNCCTL, 0x0F);
+ dispc_reg_merge(VENC_VIDCTL, \
+ ( (dm->osd0->info.var.sync & FB_SYNC_PIXCLOCK_HIGH_ACT) \
+ == FB_SYNC_PIXCLOCK_HIGH_ACT) << 14, VENC_VIDCTL_VCLKP);
+ dispc_reg_merge(VENC_SYNCCTL, \
+ ( (dm->osd0->info.var.sync & FB_SYNC_VERT_HIGH_ACT) \
+ != FB_SYNC_VERT_HIGH_ACT) << 3 ,VENC_SYNCCTL_VPL);
+ dispc_reg_merge(VENC_SYNCCTL, \
+ ( (dm->osd0->info.var.sync & FB_SYNC_HOR_HIGH_ACT) \
+ != FB_SYNC_HOR_HIGH_ACT) << 2, VENC_SYNCCTL_HPL);
+
+ /* set osd window */
+ dispc_reg_out(OSD_VIDWINMD, 0x22);
+ dispc_reg_out(OSD_OSDWIN0MD, 0x2933);
+ dispc_reg_out(OSD_OSDWIN0XP, dm->osd0->info.var.xoffset);
+ dispc_reg_out(OSD_OSDWIN0YP, dm->osd0->info.var.yoffset);
+ dispc_reg_out(OSD_OSDWIN0XL, dm->osd0->info.var.xres * divisor);
+ dispc_reg_out(OSD_OSDWIN0YL, dm->osd0->info.var.yres);
+
+ /* Set RGB565 mode */
+ dispc_reg_merge(OSD_OSDWIN0MD, OSD_OSDWIN0MD_RGB0E,
OSD_OSDWIN0MD_RGB0E);
+ dispc_reg_merge(OSD_OSDWIN0MD, on, OSD_OSDWIN0MD_OACT0);
+
+ dispc_reg_merge(VENC_VIDCTL, VENC_VIDCTL_VCLKE, VENC_VIDCTL_VCLKE);
+ /* set origin position */
+ /* Values manually defined
+ dispc_reg_out(OSD_BASEPX, 0x32);
+ dispc_reg_out(OSD_BASEPY, 0x08);*/
+ dispc_reg_out(OSD_BASEPX, 20 + dm->osd0->info.var.left_margin);
+ dispc_reg_out(OSD_BASEPY, dm->osd0->info.var.upper_margin);
+
+
dispc_reg_out(VENC_VMOD,(VENC_VMOD_VDMD_RGB666<<VENC_VMOD_VDMD_SHIFT) \
+ |VENC_VMOD_ITLCL | VENC_VMOD_HDMD | VENC_VMOD_VIE |
VENC_VMOD_VENC \
+ | VENC_VMOD_VMD);
} else {
/* Reset video encoder module */
dispc_reg_out(VENC_VMOD, 0);
}
}
+
static inline void fix_default_var(struct dm_win_info *w,
u32 xres, u32 yres, u32 xpos, u32 ypos,
int n_buf)
@@ -1435,6 +1561,10 @@ static int davincifb_remove(struct platform_device
*pdev)
/* Turn OFF the output device */
dm->output_device_config(0);
+ dm->ops->davincifb_power(&dm->osd0->info,0);
+ dm->ops->davincifb_power(&dm->osd1->info,0);
+ dm->ops->davincifb_power(&dm->vid0->info,0);
+ dm->ops->davincifb_power(&dm->vid1->info,0);
if (dm->mmio_base)
iounmap((void *)dm->mmio_base);
@@ -1449,6 +1579,8 @@ static int davincifb_remove(struct platform_device
*pdev)
static int davincifb_probe(struct platform_device *pdev)
{
struct fb_info *info;
+ struct davincifb_platform_data *pdata;
+
if (dmparams.windows == 0)
return 0; /* user disabled all windows through bootargs */
@@ -1462,6 +1594,10 @@ static int davincifb_probe(struct platform_device
*pdev)
return (-ENODEV);
}
+
+ pdata = pdev->dev.platform_data;
+ dm->ops = pdata->ops;
+
/* map the regions */
dm->mmio_base =
(unsigned long)ioremap(dm->mmio_base_phys, dm->mmio_size);
@@ -1486,31 +1622,31 @@ static int davincifb_probe(struct platform_device
*pdev)
dm->output_device_config = davincifb_pal_svideo_config;
else if ((dmparams.output == PAL) && (dmparams.format == COMPONENT))
dm->output_device_config = davincifb_pal_component_config;
+ else if ((dmparams.output == LCD) && (dmparams.format == RGB))
+ dm->output_device_config = davincifb_lcd_rgb_config;
/* Add support for other displays here */
else {
printk(KERN_WARNING "Unsupported output device!\n");
dm->output_device_config = NULL;
}
- printk("Setting Up Clocks for DM420 OSD\n");
+ printk("Setting Up Clocks for Davinci OSD\n");
/* Initialize the VPSS Clock Control register */
dispc_reg_out(VPSS_CLKCTL, 0x18);
-
/* Set Base Pixel X and Base Pixel Y */
- dispc_reg_out(OSD_BASEPX, BASEX);
- dispc_reg_out(OSD_BASEPY, BASEY);
+ /* dispc_reg_out(OSD_BASEPX, BASEX); */
+ /* dispc_reg_out(OSD_BASEPY, BASEY); */
/* Reset OSD registers to default. */
dispc_reg_out(OSD_MODE, 0);
dispc_reg_out(OSD_OSDWIN0MD, 0);
/* Set blue background color */
- set_bg_color(0, 162);
+ /* set_bg_color(0, 162); */
/* Field Inversion Workaround */
- dispc_reg_out(OSD_MODE, 0x200);
-
+ /* dispc_reg_out(OSD_MODE, 0x200); */
/* Setup VID0 framebuffer */
if (!(dmparams.windows & (1 << VID0))) {
printk(KERN_WARNING "No video/osd windows will be enabled "
@@ -1535,18 +1671,67 @@ static int davincifb_probe(struct platform_device
*pdev)
/* Setup OSD0 framebuffer */
if ((dmparams.windows & (1 << OSD0)) &&
- (!mem_alloc(&dm->osd0, OSD0_FB_PHY, OSD0_FB_SIZE, OSD0_FBNAME))) {
+ (!mem_alloc(&dm->osd0, OSD0_FB_PHY, \
+ round_32((pdata->xres)*pdata->bits_per_pixel/8) * \
+ pdata->yres * DOUBLE_BUF, OSD0_FBNAME))) {
+
dm->osd0->dm = dm;
- fix_default_var(dm->osd0,
- dmparams.osd0_xres, dmparams.osd0_yres,
- dmparams.osd0_xpos, dmparams.osd0_ypos,
- DOUBLE_BUF);
info = init_fb_info(dm->osd0, &osd0_default_var, OSD0_FBNAME);
+ if (pdata->xres)
+ {
+ dmparams.osd0_xres = pdata->xres;
+ dm->osd0->info.var.xres = pdata->xres;
+ dm->osd0->info.var.xres_virtual = pdata->xres;
+ }
+ if (pdata->yres)
+ {
+ dmparams.osd0_yres = pdata->yres;
+ dm->osd0->info.var.yres = pdata->yres;
+ dm->osd0->info.var.yres_virtual = pdata->yres * DOUBLE_BUF;
+ }
+ if (pdata->xoffset)
+ {
+ dmparams.osd0_xpos = pdata->xoffset;
+ dm->osd0->info.var.xoffset = pdata->xoffset;
+ }
+ if (pdata->yoffset)
+ {
+ dmparams.osd0_ypos = pdata->yoffset;
+ dm->osd0->info.var.yoffset = pdata->yoffset;
+ }
+ if (pdata->bits_per_pixel)
+ dm->osd0->info.var.bits_per_pixel = pdata->bits_per_pixel;
+ if (pdata->height)
+ dm->osd0->info.var.height = pdata->height;
+ if (pdata->width)
+ {
+ dm->osd0->info.var.width = pdata->width;
+ dm->osd0->info.fix.line_length = pdata->width * \
+ pdata->bits_per_pixel / 8;
+ }
+ if (pdata->pixclock)
+ dm->osd0->info.var.pixclock = pdata->pixclock;
+ if (pdata->left_margin)
+ dm->osd0->info.var.left_margin = pdata->left_margin;
+ if (pdata->right_margin)
+ dm->osd0->info.var.right_margin = pdata->right_margin;
+ if (pdata->upper_margin)
+ dm->osd0->info.var.upper_margin = pdata->upper_margin;
+ if (pdata->lower_margin)
+ dm->osd0->info.var.lower_margin = pdata->lower_margin;
+ if (pdata->hsync_len)
+ dm->osd0->info.var.hsync_len = pdata->hsync_len;
+ if (pdata->vsync_len)
+ dm->osd0->info.var.vsync_len = pdata->vsync_len;
+ if (pdata->vmode)
+ dm->osd0->info.var.vmode = pdata->vmode;
+ dm->osd0->info.var.sync = pdata->sync;
+
if (davincifb_check_var(&info->var, info)) {
dev_err(dm->dev, ": invalid default video mode\n");
mem_release(dm->osd0);
} else
- memset((void *)dm->osd0->fb_base, 0, dm->osd0->fb_size);
+ memset((void *)dm->osd0->fb_base, 0x37, dm->osd0->fb_size);
}
/* Setup OSD1 framebuffer */
@@ -1639,10 +1824,8 @@ static int davincifb_probe(struct platform_device
*pdev)
davincifb_set_par(info);
}
}
-
/* install our interrupt service routine */
- if (request_irq(IRQ_VENCINT, davincifb_isr, IRQF_SHARED, MODULE_NAME,
- dm)) {
+ if (request_irq(IRQ_VENCINT, davincifb_isr, IRQF_SHARED, MODULE_NAME,
dm)) {
dev_err(dm->dev, MODULE_NAME
": could not install interrupt service routine\n");
goto exit;
@@ -1650,6 +1833,11 @@ static int davincifb_probe(struct platform_device
*pdev)
/* Turn ON the output device */
dm->output_device_config(1);
+ dm->ops->davincifb_power(&dm->osd0->info,1);
+ dm->ops->davincifb_power(&dm->osd1->info,1);
+ dm->ops->davincifb_power(&dm->vid0->info,1);
+ dm->ops->davincifb_power(&dm->vid1->info,1);
+
return (0);
@@ -1714,7 +1902,7 @@ int __init davincifb_init(void)
/* Register the driver with LDM */
if (platform_driver_register(&davincifb_driver)) {
- pr_debug("failed to register omapfb driver\n");
+ pr_debug("failed to register davincifb driver\n");
return -ENODEV;
}
@@ -14,12 +14,12 @@
#define _DAVINCIFB_H_
#include <mach/io.h>
+#include <linux/fb.h>
/* Base registers */
-#define VPBE_REG_BASE 0x01c72780
-#define VENC_REG_BASE 0x01c72400
-#define OSD_REG_BASE 0x01c72600
-#define OSD_REG_SIZE 0x00000180
+#define VENC_REG_BASE 0x01C71E00
+#define OSD_REG_BASE 0x01C71C00
+#define OSD_REG_SIZE 0x00000100
/* VPBE Global Registers */
#define VPBE_PID (VPBE_BASE + 0x0)
@@ -32,7 +32,7 @@
#define VENC_VMOD (VENC_REG_BASE + 0x00)
#define VENC_VIDCTL (VENC_REG_BASE + 0x04)
#define VENC_VDPRO (VENC_REG_BASE + 0x08)
-#define VENC_SYNCCTL (VENC_REG_BASE + 0x0C)
+#define VENC_SYNCCTL (VENC_REG_BASE + 0x0C)
#define VENC_HSPLS (VENC_REG_BASE + 0x10)
#define VENC_VSPLS (VENC_REG_BASE + 0x14)
#define VENC_HINT (VENC_REG_BASE + 0x18)
@@ -46,25 +46,25 @@
#define VENC_YCCCTL (VENC_REG_BASE + 0x38)
#define VENC_RGBCTL (VENC_REG_BASE + 0x3C)
#define VENC_RGBCLP (VENC_REG_BASE + 0x40)
-#define VENC_LINECTL (VENC_REG_BASE + 0x44)
-#define VENC_CULLLINE (VENC_REG_BASE + 0x48)
+#define VENC_LINECTL (VENC_REG_BASE + 0x44)
+#define VENC_CULLLINE (VENC_REG_BASE + 0x48)
#define VENC_LCDOUT (VENC_REG_BASE + 0x4C)
#define VENC_BRTS (VENC_REG_BASE + 0x50)
#define VENC_BRTW (VENC_REG_BASE + 0x54)
#define VENC_ACCTL (VENC_REG_BASE + 0x58)
#define VENC_PWMP (VENC_REG_BASE + 0x5C)
#define VENC_PWMW (VENC_REG_BASE + 0x60)
-#define VENC_DCLKCTL (VENC_REG_BASE + 0x64)
-#define VENC_DCLKPTN0 (VENC_REG_BASE + 0x68)
-#define VENC_DCLKPTN1 (VENC_REG_BASE + 0x6C)
-#define VENC_DCLKPTN2 (VENC_REG_BASE + 0x70)
-#define VENC_DCLKPTN3 (VENC_REG_BASE + 0x74)
-#define VENC_DCLKPTN0A (VENC_REG_BASE + 0x78)
-#define VENC_DCLKPTN1A (VENC_REG_BASE + 0x7C)
-#define VENC_DCLKPTN2A (VENC_REG_BASE + 0x80)
-#define VENC_DCLKPTN3A (VENC_REG_BASE + 0x84)
+#define VENC_DCLKCTL (VENC_REG_BASE + 0x64)
+#define VENC_DCLKPTN0 (VENC_REG_BASE + 0x68)
+#define VENC_DCLKPTN1 (VENC_REG_BASE + 0x6C)
+#define VENC_DCLKPTN2 (VENC_REG_BASE + 0x70)
+#define VENC_DCLKPTN3 (VENC_REG_BASE + 0x74)
+#define VENC_DCLKPTN0A (VENC_REG_BASE + 0x78)
+#define VENC_DCLKPTN1A (VENC_REG_BASE + 0x7C)
+#define VENC_DCLKPTN2A (VENC_REG_BASE + 0x80)
+#define VENC_DCLKPTN3A (VENC_REG_BASE + 0x84)
#define VENC_DCLKHS (VENC_REG_BASE + 0x88)
-#define VENC_DCLKHSA (VENC_REG_BASE + 0x8C)
+#define VENC_DCLKHSA (VENC_REG_BASE + 0x8C)
#define VENC_DCLKHR (VENC_REG_BASE + 0x90)
#define VENC_DCLKVS (VENC_REG_BASE + 0x94)
#define VENC_DCLKVR (VENC_REG_BASE + 0x98)
@@ -74,13 +74,13 @@
#define VENC_ATR0 (VENC_REG_BASE + 0xA8)
#define VENC_ATR1 (VENC_REG_BASE + 0xAC)
#define VENC_ATR2 (VENC_REG_BASE + 0xB0)
-#define VENC_EPSON_LCDCTL (VENC_REG_BASE + 0xB4)
-#define VENC_CASIO_LCDCTL (VENC_REG_BASE + 0xB4)
-#define VENC_UDISP_LCDCT (VENC_REG_BASE + 0xB4)
-#define VENC_STN_LCDCT (VENC_REG_BASE + 0xB4)
+#define VENC_EPSON_LCDCTL (VENC_REG_BASE + 0xB4)
+#define VENC_CASIO_LCDCTL (VENC_REG_BASE + 0xB4)
+#define VENC_UDISP_LCDCT (VENC_REG_BASE + 0xB4)
+#define VENC_STN_LCDCT (VENC_REG_BASE + 0xB4)
#define VENC_VSTAT (VENC_REG_BASE + 0xB8)
#define VENC_RAMADR (VENC_REG_BASE + 0xBC)
-#define VENC_RAMPORT (VENC_REG_BASE + 0xC0)
+#define VENC_RAMPORT (VENC_REG_BASE + 0xC0)
#define VENC_DACTST (VENC_REG_BASE + 0xC4)
#define VENC_YCOLVL (VENC_REG_BASE + 0xC8)
#define VENC_SCPROG (VENC_REG_BASE + 0xCC)
@@ -101,12 +101,13 @@
#define VENC_DRGBX2 (VENC_REG_BASE + 0x11C)
#define VENC_DRGBX3 (VENC_REG_BASE + 0x120)
#define VENC_DRGBX4 (VENC_REG_BASE + 0x124)
-#define VENC_VSTARTA (VENC_REG_BASE + 0x128)
-#define VENC_OSDCLK0 (VENC_REG_BASE + 0x12C)
-#define VENC_OSDCLK1 (VENC_REG_BASE + 0x130)
-#define VENC_HVLDCL0 (VENC_REG_BASE + 0x134)
-#define VENC_HVLDCL1 (VENC_REG_BASE + 0x138)
+#define VENC_VSTARTA (VENC_REG_BASE + 0x128)
+#define VENC_OSDCLK0 (VENC_REG_BASE + 0x12C)
+#define VENC_OSDCLK1 (VENC_REG_BASE + 0x130)
+#define VENC_HVLDCL0 (VENC_REG_BASE + 0x134)
+#define VENC_HVLDCL1 (VENC_REG_BASE + 0x138)
#define VENC_OSDHAD (VENC_REG_BASE + 0x13C)
+#define VENC_CLKCTL (VENC_REG_BASE + 0x140)
#define VID0 0
#define VID1 1
@@ -115,43 +116,45 @@
/* VPBE On-Screen Display Subsystem Registers (OSD) */
#define OSD_MODE (OSD_REG_BASE + 0x00)
-#define OSD_VIDWINMD (OSD_REG_BASE + 0x04)
-#define OSD_OSDWIN0MD (OSD_REG_BASE + 0x08)
-#define OSD_OSDWIN1MD (OSD_REG_BASE + 0x0C)
-#define OSD_OSDATRMD (OSD_REG_BASE + 0x0C)
+#define OSD_VIDWINMD (OSD_REG_BASE + 0x04)
+#define OSD_OSDWIN0MD (OSD_REG_BASE + 0x08)
+#define OSD_OSDWIN1MD (OSD_REG_BASE + 0x0C)
+#define OSD_OSDATRMD (OSD_REG_BASE + 0x0C)
#define OSD_RECTCUR (OSD_REG_BASE + 0x10)
-#define OSD_WINOFST(i) (OSD_REG_BASE + 0x18 + (i)*0x4)
-#define OSD_VIDWIN0OFST (OSD_REG_BASE + 0x18)
-#define OSD_VIDWIN1OFST (OSD_REG_BASE + 0x1C)
-#define OSD_OSDWIN0OFST (OSD_REG_BASE + 0x20)
-#define OSD_OSDWIN1OFST (OSD_REG_BASE + 0x24)
-#define OSD_WINADR(i) (OSD_REG_BASE + 0x2C + (i)*0x4)
-#define OSD_VIDWIN0ADR (OSD_REG_BASE + 0x2C)
-#define OSD_VIDWIN1ADR (OSD_REG_BASE + 0x30)
-#define OSD_OSDWIN0ADR (OSD_REG_BASE + 0x38)
-#define OSD_OSDWIN1ADR (OSD_REG_BASE + 0x3C)
+#define OSD_WINOFST(i) (OSD_REG_BASE + 0x18 + (i)*0x4)
+#define OSD_VIDWIN0OFST (OSD_REG_BASE + 0x18)
+#define OSD_VIDWIN1OFST (OSD_REG_BASE + 0x1C)
+#define OSD_OSDWIN0OFST (OSD_REG_BASE + 0x20)
+#define OSD_OSDWIN1OFST (OSD_REG_BASE + 0x24)
+#define OSD_VIDWINADH (OSD_REG_BASE + 0x28)
+#define OSD_WINADR(i) (OSD_REG_BASE + 0x2C + (i)*0x4)
+#define OSD_VIDWIN0ADR (OSD_REG_BASE + 0x2C)
+#define OSD_VIDWIN1ADR (OSD_REG_BASE + 0x30)
+#define OSD_OSDWINADH (OSD_REG_BASE + 0x34)
+#define OSD_OSDWIN0ADR (OSD_REG_BASE + 0x38)
+#define OSD_OSDWIN1ADR (OSD_REG_BASE + 0x3C)
#define OSD_BASEPX (OSD_REG_BASE + 0x40)
#define OSD_BASEPY (OSD_REG_BASE + 0x44)
-#define OSD_WINXP(i) (OSD_REG_BASE + 0x48 + (i)*0x10)
-#define OSD_WINYP(i) (OSD_REG_BASE + 0x4C + (i)*0x10)
-#define OSD_WINXL(i) (OSD_REG_BASE + 0x50 + (i)*0x10)
-#define OSD_WINYL(i) (OSD_REG_BASE + 0x54 + (i)*0x10)
-#define OSD_VIDWIN0XP (OSD_REG_BASE + 0x48)
-#define OSD_VIDWIN0YP (OSD_REG_BASE + 0x4C)
-#define OSD_VIDWIN0XL (OSD_REG_BASE + 0x50)
-#define OSD_VIDWIN0YL (OSD_REG_BASE + 0x54)
-#define OSD_VIDWIN1XP (OSD_REG_BASE + 0x58)
-#define OSD_VIDWIN1YP (OSD_REG_BASE + 0x5C)
-#define OSD_VIDWIN1XL (OSD_REG_BASE + 0x60)
-#define OSD_VIDWIN1YL (OSD_REG_BASE + 0x64)
-#define OSD_OSDWIN0XP (OSD_REG_BASE + 0x68)
-#define OSD_OSDWIN0YP (OSD_REG_BASE + 0x6C)
-#define OSD_OSDWIN0XL (OSD_REG_BASE + 0x70)
-#define OSD_OSDWIN0YL (OSD_REG_BASE + 0x74)
-#define OSD_OSDWIN1XP (OSD_REG_BASE + 0x78)
-#define OSD_OSDWIN1YP (OSD_REG_BASE + 0x7C)
-#define OSD_OSDWIN1XL (OSD_REG_BASE + 0x80)
-#define OSD_OSDWIN1YL (OSD_REG_BASE + 0x84)
+#define OSD_WINXP(i) (OSD_REG_BASE + 0x48 + (i)*0x10)
+#define OSD_WINYP(i) (OSD_REG_BASE + 0x4C + (i)*0x10)
+#define OSD_WINXL(i) (OSD_REG_BASE + 0x50 + (i)*0x10)
+#define OSD_WINYL(i) (OSD_REG_BASE + 0x54 + (i)*0x10)
+#define OSD_VIDWIN0XP (OSD_REG_BASE + 0x48)
+#define OSD_VIDWIN0YP (OSD_REG_BASE + 0x4C)
+#define OSD_VIDWIN0XL (OSD_REG_BASE + 0x50)
+#define OSD_VIDWIN0YL (OSD_REG_BASE + 0x54)
+#define OSD_VIDWIN1XP (OSD_REG_BASE + 0x58)
+#define OSD_VIDWIN1YP (OSD_REG_BASE + 0x5C)
+#define OSD_VIDWIN1XL (OSD_REG_BASE + 0x60)
+#define OSD_VIDWIN1YL (OSD_REG_BASE + 0x64)
+#define OSD_OSDWIN0XP (OSD_REG_BASE + 0x68)
+#define OSD_OSDWIN0YP (OSD_REG_BASE + 0x6C)
+#define OSD_OSDWIN0XL (OSD_REG_BASE + 0x70)
+#define OSD_OSDWIN0YL (OSD_REG_BASE + 0x74)
+#define OSD_OSDWIN1XP (OSD_REG_BASE + 0x78)
+#define OSD_OSDWIN1YP (OSD_REG_BASE + 0x7C)
+#define OSD_OSDWIN1XL (OSD_REG_BASE + 0x80)
+#define OSD_OSDWIN1YL (OSD_REG_BASE + 0x84)
#define OSD_CURXP (OSD_REG_BASE + 0x88)
#define OSD_CURYP (OSD_REG_BASE + 0x8C)
#define OSD_CURXL (OSD_REG_BASE + 0x90)
@@ -174,10 +177,10 @@
#define OSD_W1BMPE (OSD_REG_BASE + 0xDC)
#define OSD_TI_TES (OSD_REG_BASE + 0xE0)
#define OSD_MISCCT (OSD_REG_BASE + 0xE8)
-#define OSD_CLUTRAMYC (OSD_REG_BASE + 0xEC)
-#define OSD_CLUTRAMC (OSD_REG_BASE + 0xF0)
-#define OSD_TRANSPVA (OSD_REG_BASE + 0xF0)
-#define OSD_PPVWIN0AD (OSD_REG_BASE + 0xFC)
+#define OSD_CLUTRAMYC (OSD_REG_BASE + 0xEC)
+#define OSD_CLUTRAMC (OSD_REG_BASE + 0xF0)
+#define OSD_TRANSPVA (OSD_REG_BASE + 0xF0)
+#define OSD_PPVWIN0AD (OSD_REG_BASE + 0xFC)
/* bit definitions */
#define VPBE_PCR_VENC_DIV (1 << 1)
@@ -186,7 +189,7 @@
#define VENC_VMOD_VDMD_YCBCR16 0
#define VENC_VMOD_VDMD_YCBCR8 1
#define VENC_VMOD_VDMD_RGB666 2
-#define VENC_VMOD_VDMD_RGB8 3
+#define VENC_VMOD_VDMD_RGB8 3
#define VENC_VMOD_VDMD_EPSON 4
#define VENC_VMOD_VDMD_CASIO 5
#define VENC_VMOD_VDMD_UDISPQVGA 6
@@ -202,12 +205,18 @@
#define VENC_VMOD_BLNK (1 << 3)
#define VENC_VMOD_VIE (1 << 1)
#define VENC_VMOD_VENC (1 << 0)
+
+#define VENC_VIDCTL_VCLKE (1 << 13)
+#define VENC_VIDCTL_VCLKP (1 << 14)
+#define VENC_SYNCCTL_HPL (1 << 2)
+#define VENC_SYNCCTL_VPL (1 << 3)
+
/* other VENC registers' bit positions not defined yet */
-#define OSD_MODE_CS (1 << 15)
+#define OSD_MODE_CS (1 << 15)
#define OSD_MODE_OVRSZ (1 << 14)
#define OSD_MODE_OHRSZ (1 << 13)
-#define OSD_MODE_EF (1 << 12)
+#define OSD_MODE_EF (1 << 12)
#define OSD_MODE_VVRSZ (1 << 11)
#define OSD_MODE_VHRSZ (1 << 10)
#define OSD_MODE_FSINV (1 << 9)
@@ -233,7 +242,7 @@
#define OSD_OSDWIN0MD_ATN0E (1 << 14)
#define OSD_OSDWIN0MD_RGB0E (1 << 13)
-#define OSD_OSDWIN0MD_CLUTS0 (1 << 12)
+#define OSD_OSDWIN0MD_CLUTS0 (1 << 12)
#define OSD_OSDWIN0MD_OHZ0 (3 << 10)
#define OSD_OSDWIN0MD_OHZ0_SHIFT 10
#define OSD_OSDWIN0MD_OVZ0 (3 << 8)
@@ -249,7 +258,7 @@
#define OSD_OSDWIN1MD_OASW (1 << 15)
#define OSD_OSDWIN1MD_ATN1E (1 << 14)
#define OSD_OSDWIN1MD_RGB1E (1 << 13)
-#define OSD_OSDWIN1MD_CLUTS1 (1 << 12)
+#define OSD_OSDWIN1MD_CLUTS1 (1 << 12)
#define OSD_OSDWIN1MD_OHZ1 (3 << 10)
#define OSD_OSDWIN1MD_OHZ1_SHIFT 10
#define OSD_OSDWIN1MD_OVZ1 (3 << 8)
@@ -268,7 +277,7 @@
#define OSD_OSDATRMD_OHZA_SHIFT 10
#define OSD_OSDATRMD_OVZA (3 << 8)
#define OSD_OSDATRMD_OVZA_SHIFT 8
-#define OSD_OSDATRMD_BLNKINT (3 << 6)
+#define OSD_OSDATRMD_BLNKINT (3 << 6)
#define OSD_OSDATRMD_BLNKINT_SHIFT 6
#define OSD_OSDATRMD_OFFA (1 << 1)
#define OSD_OSDATRMD_BLNK (1 << 0)
@@ -413,7 +422,7 @@
#define OSD_CLUTRAM_CR_SHIFT 8
#define OSD_CLUTRAM_CADDR (0xff << 0)
#define OSD_CLUTRAM_CADDR_SHIFT 0
-#define OSD_TRANSPVA_RGBTRANS (0xff << 0)
+#define OSD_TRANSPVA_RGBTRANS (0xff << 0)
#define OSD_TRANSPVA_RGBTRANS_SHIFT 0
@@ -437,6 +446,88 @@ struct zoom_params
u_int32_t zoom_h;
u_int32_t zoom_v;
};
-#define FBIO_SETZOOM _IOW('F', 0x24, struct zoom_params)
+
+
+/*
+ * davincifb operations
+ *
+ * This functions are used in order to manage external hw that is platform
+ * dependent according to what is done on the framebuffer (turn LCD on/off,
+ * manage backlight, ...)
+ */
+
+struct davincifb_ops {
+ int (*davincifb_power)(struct fb_info *info, int on);
+ int (*davincifb_backlight)(struct fb_info *info, int on, int
level);
+};
+
+struct davincifb_platform_data {
+ u32 xres;
+ u32 yres;
+ u32 xoffset;
+ u32 yoffset;
+ u32 bits_per_pixel;
+ u32 height;
+ u32 width;
+ u32 pixclock; /* picoseconds */
+ u32 left_margin; /* pixclocks */
+ u32 right_margin; /* pixclocks */
+ u32 upper_margin; /* line clocks */
+ u32 lower_margin; /* line clocks */
+ u32 hsync_len; /* pixclocks */
+ u32 vsync_len; /* line clocks */
+ u32 vmode;
+ u32 sync;
+ struct davincifb_ops *ops;
+};
+
+struct dm_win_info {
+ struct fb_info info;
+
+ /* X and Y position */
+ unsigned int x, y;
+
+ /* framebuffer area */
+ dma_addr_t fb_base_phys;
+ unsigned long fb_base;
+ unsigned long fb_size;
+
+ u32 pseudo_palette[17];
+
+ /* flag to identify if framebuffer area is fixed already or not */
+ int alloc_fb_mem;
+ unsigned long sdram_address;
+ struct dm_info *dm;
+};
+
+struct dm_info {
+ struct dm_win_info *osd0;
+ struct dm_win_info *osd1;
+ struct dm_win_info *vid0;
+ struct dm_win_info *vid1;
+
+ /* to map the registers */
+ dma_addr_t mmio_base_phys;
+ unsigned long mmio_base;
+ unsigned long mmio_size;
+
+ wait_queue_head_t vsync_wait;
+ unsigned long vsync_cnt;
+ int timeout;
+// struct davinci_disp_callback vsync_callback;
+ /* this is the function that configures the output device
(NTSC/PAL/LCD)
+ * for the required output format (composite/s-video/component/rgb)
+ */
+ void (*output_device_config) (int on);
+ struct davincifb_ops *ops;
+
+ struct device *dev;
+ struct davincifb_platform_data *platform_data;
+
+};
+
+
+
+#define FBIO_SETZOOM _IOW('F', 0x24, struct zoom_params)