Manjunath, I think set_layer_config(), get_layer_config and try_layer_config() can be split into standard fmt and crop sub device video ops. Could you investigate this? Murali On Wed, Nov 24, 2010 at 9:09 AM, Manjunath Hadli <manjunath.hadli@xxxxxx> wrote: > This patch implements the functionality of the OSD block > of the VPBE.The OSD in total supports 4 planes or Video > sources - 2 mainly RGB and 2 Video. The patch implements general > handling of all the planes, with specific emphasis on the Video > plane capabilities as the Video planes are supported through the > V4L2 driver. > > Signed-off-by: Manjunath Hadli <manjunath.hadli@xxxxxx> > Signed-off-by: Muralidharan Karicheri <m-karicheri2@xxxxxx> > --- > drivers/media/video/davinci/vpbe_osd.c | 1208 +++++++++++++++++++++++++++ > drivers/media/video/davinci/vpbe_osd_regs.h | 389 +++++++++ > include/media/davinci/vpbe_osd.h | 397 +++++++++ > 3 files changed, 1994 insertions(+), 0 deletions(-) > create mode 100644 drivers/media/video/davinci/vpbe_osd.c > create mode 100644 drivers/media/video/davinci/vpbe_osd_regs.h > create mode 100644 include/media/davinci/vpbe_osd.h > > diff --git a/drivers/media/video/davinci/vpbe_osd.c b/drivers/media/video/davinci/vpbe_osd.c > new file mode 100644 > index 0000000..64371b5 > --- /dev/null > +++ b/drivers/media/video/davinci/vpbe_osd.c > @@ -0,0 +1,1208 @@ > +/* > + * Copyright (C) 2007-2010 Texas Instruments Inc > + * Copyright (C) 2007 MontaVista Software, Inc. > + * > + * Andy Lowe (alowe@xxxxxxxxxx), MontaVista Software > + * - Initial version > + * Murali Karicheri (mkaricheri@xxxxxxxxx), Texas Instruments Ltd. > + * - ported to sub device interface > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > + * > + */ > +#include <linux/module.h> > +#include <linux/kernel.h> > +#include <linux/interrupt.h> > +#include <linux/platform_device.h> > +#include <linux/clk.h> > +#include <linux/slab.h> > + > +#include <mach/io.h> > +#include <mach/cputype.h> > +#include <mach/hardware.h> > + > +#include <media/davinci/vpss.h> > +#include <media/v4l2-device.h> > +#include <media/davinci/vpbe_types.h> > +#include <media/davinci/vpbe_osd.h> > + > +#include <linux/io.h> > +#include "vpbe_osd_regs.h" > + > +#define MODULE_NAME VPBE_OSD_SUBDEV_NAME > + > +/* register access routines */ > +static inline u32 osd_read(struct osd_state *sd, u32 offset) > +{ > + struct osd_state *osd = sd; > + return __raw_readl(osd->osd_base + offset); > +} > + > +static inline u32 osd_write(struct osd_state *sd, u32 val, u32 offset) > +{ > + struct osd_state *osd = sd; > + __raw_writel(val, osd->osd_base + offset); > + return val; > +} > + > +static inline u32 osd_set(struct osd_state *sd, u32 mask, u32 offset) > +{ > + struct osd_state *osd = sd; > + > + u32 addr = osd->osd_base + offset; > + u32 val = __raw_readl(addr) | mask; > + > + __raw_writel(val, addr); > + return val; > +} > + > +static inline u32 osd_clear(struct osd_state *sd, u32 mask, u32 offset) > +{ > + struct osd_state *osd = sd; > + u32 addr = osd->osd_base + offset; > + u32 val = __raw_readl(addr) & ~mask; > + > + __raw_writel(val, addr); > + return val; > +} > + > +static inline u32 osd_modify(struct osd_state *sd, u32 mask, u32 val, > + u32 offset) > +{ > + struct osd_state *osd = sd; > + > + u32 addr = osd->osd_base + offset; > + u32 new_val = (__raw_readl(addr) & ~mask) | (val & mask); > + __raw_writel(new_val, addr); > + return new_val; > +} > + > +/* define some macros for layer and pixfmt classification */ > +#define is_osd_win(layer) (((layer) == WIN_OSD0) || ((layer) == WIN_OSD1)) > +#define is_vid_win(layer) (((layer) == WIN_VID0) || ((layer) == WIN_VID1)) > +#define is_rgb_pixfmt(pixfmt) \ > + (((pixfmt) == PIXFMT_RGB565) || ((pixfmt) == PIXFMT_RGB888)) > +#define is_yc_pixfmt(pixfmt) \ > + (((pixfmt) == PIXFMT_YCbCrI) || ((pixfmt) == PIXFMT_YCrCbI) || \ > + ((pixfmt) == PIXFMT_NV12)) > +#define MAX_WIN_SIZE OSD_VIDWIN0XP_V0X > +#define MAX_LINE_LENGTH (OSD_VIDWIN0OFST_V0LO << 5) > + > + > +/** > + * _osd_dm6446_vid0_pingpong() - field inversion fix for DM6446 > + * @sd - ptr to struct osd_state > + * @field_inversion - inversion flag > + * @fb_base_phys - frame buffer address > + * @lconfig - ptr to layer config > + * > + * This routine implements a workaround for the field signal inversion silicon > + * erratum described in Advisory 1.3.8 for the DM6446. The fb_base_phys and > + * lconfig parameters apply to the vid0 window. This routine should be called > + * whenever the vid0 layer configuration or start address is modified, or when > + * the OSD field inversion setting is modified. > + * Returns: 1 if the ping-pong buffers need to be toggled in the vsync isr, or > + * 0 otherwise > + */ > +static int _osd_dm6446_vid0_pingpong(struct osd_state *sd, > + int field_inversion, > + unsigned long fb_base_phys, > + const struct osd_layer_config *lconfig) > +{ > + > +#ifdef CONFIG_DM6446_FIELD_INV_WORKAROUND > + if (!field_inversion || !lconfig->interlaced) { > + osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN0ADR); > + osd_write(sd, fb_base_phys & ~0x1F, OSD_PPVWIN0ADR); > + osd_modify(sd, OSD_MISCCTL_PPSW | OSD_MISCCTL_PPRV, 0, > + OSD_MISCCTL); > + return 0; > + } else { > + unsigned miscctl = OSD_MISCCTL_PPRV; > + > + osd_write(sd, (fb_base_phys & ~0x1F) - lconfig->line_length, > + OSD_VIDWIN0ADR); > + osd_write(sd, (fb_base_phys & ~0x1F) + lconfig->line_length, > + OSD_PPVWIN0ADR); > + osd_modify(sd, OSD_MISCCTL_PPSW | OSD_MISCCTL_PPRV, miscctl, > + OSD_MISCCTL); > + > + return 1; > + } > +#endif > + return 0; > +} > + > +static void _osd_set_field_inversion(struct osd_state *sd, int enable) > +{ > + unsigned fsinv = 0; > + > + if (enable) > + fsinv = OSD_MODE_FSINV; > + > + osd_modify(sd, OSD_MODE_FSINV, fsinv, OSD_MODE); > +} > + > +static void _osd_set_blink_attribute(struct osd_state *sd, int enable, > + enum osd_blink_interval blink) > +{ > + u32 osdatrmd = 0; > + > + if (enable) { > + osdatrmd |= OSD_OSDATRMD_BLNK; > + osdatrmd |= blink << OSD_OSDATRMD_BLNKINT_SHIFT; > + } > + /* caller must ensure that OSD1 is configured in attribute mode */ > + osd_modify(sd, OSD_OSDATRMD_BLNKINT | OSD_OSDATRMD_BLNK, osdatrmd, > + OSD_OSDATRMD); > +} > + > +static void _osd_set_rom_clut(struct osd_state *sd, > + enum osd_rom_clut rom_clut) > +{ > + if (rom_clut == ROM_CLUT0) > + osd_clear(sd, OSD_MISCCTL_RSEL, OSD_MISCCTL); > + else > + osd_set(sd, OSD_MISCCTL_RSEL, OSD_MISCCTL); > +} > + > +static void _osd_set_palette_map(struct osd_state *sd, > + enum osd_win_layer osdwin, > + unsigned char pixel_value, > + unsigned char clut_index, > + enum osd_pix_format pixfmt) > +{ > + int bmp_reg, bmp_offset, bmp_mask, bmp_shift; > + static const int map_1bpp[] = { 0, 15 }; > + static const int map_2bpp[] = { 0, 5, 10, 15 }; > + > + switch (pixfmt) { > + case PIXFMT_1BPP: > + bmp_reg = map_1bpp[pixel_value & 0x1]; > + break; > + case PIXFMT_2BPP: > + bmp_reg = map_2bpp[pixel_value & 0x3]; > + break; > + case PIXFMT_4BPP: > + bmp_reg = pixel_value & 0xf; > + break; > + default: > + return; > + } > + > + switch (osdwin) { > + case OSDWIN_OSD0: > + bmp_offset = OSD_W0BMP01 + (bmp_reg >> 1) * sizeof(u32); > + break; > + case OSDWIN_OSD1: > + bmp_offset = OSD_W1BMP01 + (bmp_reg >> 1) * sizeof(u32); > + break; > + default: > + return; > + } > + > + if (bmp_reg & 1) { > + bmp_shift = 8; > + bmp_mask = 0xff << 8; > + } else { > + bmp_shift = 0; > + bmp_mask = 0xff; > + } > + > + osd_modify(sd, bmp_mask, clut_index << bmp_shift, bmp_offset); > +} > + > +static void _osd_set_rec601_attenuation(struct osd_state *sd, > + enum osd_win_layer osdwin, int enable) > +{ > + switch (osdwin) { > + case OSDWIN_OSD0: > + osd_modify(sd, OSD_OSDWIN0MD_ATN0E, > + enable ? OSD_OSDWIN0MD_ATN0E : 0, > + OSD_OSDWIN0MD); > + break; > + case OSDWIN_OSD1: > + osd_modify(sd, OSD_OSDWIN1MD_ATN1E, > + enable ? OSD_OSDWIN1MD_ATN1E : 0, > + OSD_OSDWIN1MD); > + break; > + } > +} > + > +static void _osd_set_blending_factor(struct osd_state *sd, > + enum osd_win_layer osdwin, > + enum osd_blending_factor blend) > +{ > + switch (osdwin) { > + case OSDWIN_OSD0: > + osd_modify(sd, OSD_OSDWIN0MD_BLND0, > + blend << OSD_OSDWIN0MD_BLND0_SHIFT, OSD_OSDWIN0MD); > + break; > + case OSDWIN_OSD1: > + osd_modify(sd, OSD_OSDWIN1MD_BLND1, > + blend << OSD_OSDWIN1MD_BLND1_SHIFT, OSD_OSDWIN1MD); > + break; > + } > +} > + > +static void _osd_enable_color_key(struct osd_state *sd, > + enum osd_win_layer osdwin, > + unsigned colorkey, > + enum osd_pix_format pixfmt) > +{ > + switch (pixfmt) { > + case PIXFMT_RGB565: > + osd_write(sd, colorkey & OSD_TRANSPVAL_RGBTRANS, > + OSD_TRANSPVAL); > + break; > + default: > + break; > + } > + > + switch (osdwin) { > + case OSDWIN_OSD0: > + osd_set(sd, OSD_OSDWIN0MD_TE0, OSD_OSDWIN0MD); > + break; > + case OSDWIN_OSD1: > + osd_set(sd, OSD_OSDWIN1MD_TE1, OSD_OSDWIN1MD); > + break; > + } > +} > +static void _osd_disable_color_key(struct osd_state *sd, > + enum osd_win_layer osdwin) > +{ > + switch (osdwin) { > + case OSDWIN_OSD0: > + osd_clear(sd, OSD_OSDWIN0MD_TE0, OSD_OSDWIN0MD); > + break; > + case OSDWIN_OSD1: > + osd_clear(sd, OSD_OSDWIN1MD_TE1, OSD_OSDWIN1MD); > + break; > + } > +} > + > +static void _osd_set_osd_clut(struct osd_state *sd, > + enum osd_win_layer osdwin, > + enum osd_clut clut) > +{ > + u32 winmd = 0; > + > + switch (osdwin) { > + case OSDWIN_OSD0: > + if (clut == RAM_CLUT) > + winmd |= OSD_OSDWIN0MD_CLUTS0; > + osd_modify(sd, OSD_OSDWIN0MD_CLUTS0, winmd, OSD_OSDWIN0MD); > + break; > + case OSDWIN_OSD1: > + if (clut == RAM_CLUT) > + winmd |= OSD_OSDWIN1MD_CLUTS1; > + osd_modify(sd, OSD_OSDWIN1MD_CLUTS1, winmd, OSD_OSDWIN1MD); > + break; > + } > +} > + > +static void _osd_set_zoom(struct osd_state *sd, enum osd_layer layer, > + enum osd_zoom_factor h_zoom, > + enum osd_zoom_factor v_zoom) > +{ > + u32 winmd = 0; > + > + switch (layer) { > + case WIN_OSD0: > + winmd |= (h_zoom << OSD_OSDWIN0MD_OHZ0_SHIFT); > + winmd |= (v_zoom << OSD_OSDWIN0MD_OVZ0_SHIFT); > + osd_modify(sd, OSD_OSDWIN0MD_OHZ0 | OSD_OSDWIN0MD_OVZ0, winmd, > + OSD_OSDWIN0MD); > + break; > + case WIN_VID0: > + winmd |= (h_zoom << OSD_VIDWINMD_VHZ0_SHIFT); > + winmd |= (v_zoom << OSD_VIDWINMD_VVZ0_SHIFT); > + osd_modify(sd, OSD_VIDWINMD_VHZ0 | OSD_VIDWINMD_VVZ0, winmd, > + OSD_VIDWINMD); > + break; > + case WIN_OSD1: > + winmd |= (h_zoom << OSD_OSDWIN1MD_OHZ1_SHIFT); > + winmd |= (v_zoom << OSD_OSDWIN1MD_OVZ1_SHIFT); > + osd_modify(sd, OSD_OSDWIN1MD_OHZ1 | OSD_OSDWIN1MD_OVZ1, winmd, > + OSD_OSDWIN1MD); > + break; > + case WIN_VID1: > + winmd |= (h_zoom << OSD_VIDWINMD_VHZ1_SHIFT); > + winmd |= (v_zoom << OSD_VIDWINMD_VVZ1_SHIFT); > + osd_modify(sd, OSD_VIDWINMD_VHZ1 | OSD_VIDWINMD_VVZ1, winmd, > + OSD_VIDWINMD); > + break; > + } > +} > + > +static void _osd_disable_layer(struct osd_state *sd, enum osd_layer layer) > +{ > + switch (layer) { > + case WIN_OSD0: > + osd_clear(sd, OSD_OSDWIN0MD_OACT0, OSD_OSDWIN0MD); > + break; > + case WIN_VID0: > + osd_clear(sd, OSD_VIDWINMD_ACT0, OSD_VIDWINMD); > + break; > + case WIN_OSD1: > + /* disable attribute mode as well as disabling the window */ > + osd_clear(sd, OSD_OSDWIN1MD_OASW | OSD_OSDWIN1MD_OACT1, > + OSD_OSDWIN1MD); > + break; > + case WIN_VID1: > + osd_clear(sd, OSD_VIDWINMD_ACT1, OSD_VIDWINMD); > + break; > + } > +} > + > +static void osd_disable_layer(struct osd_state *sd, enum osd_layer layer) > +{ > + struct osd_state *osd = sd; > + struct osd_window_state *win = &osd->win[layer]; > + unsigned long flags; > + > + spin_lock_irqsave(&osd->lock, flags); > + > + if (!win->is_enabled) { > + spin_unlock_irqrestore(&osd->lock, flags); > + return; > + } > + win->is_enabled = 0; > + > + _osd_disable_layer(sd, layer); > + > + spin_unlock_irqrestore(&osd->lock, flags); > +} > + > +static void _osd_enable_attribute_mode(struct osd_state *sd) > +{ > + /* enable attribute mode for OSD1 */ > + osd_set(sd, OSD_OSDWIN1MD_OASW, OSD_OSDWIN1MD); > +} > + > +static void _osd_enable_layer(struct osd_state *sd, enum osd_layer layer) > +{ > + switch (layer) { > + case WIN_OSD0: > + osd_set(sd, OSD_OSDWIN0MD_OACT0, OSD_OSDWIN0MD); > + break; > + case WIN_VID0: > + osd_set(sd, OSD_VIDWINMD_ACT0, OSD_VIDWINMD); > + break; > + case WIN_OSD1: > + /* enable OSD1 and disable attribute mode */ > + osd_modify(sd, OSD_OSDWIN1MD_OASW | OSD_OSDWIN1MD_OACT1, > + OSD_OSDWIN1MD_OACT1, OSD_OSDWIN1MD); > + break; > + case WIN_VID1: > + osd_set(sd, OSD_VIDWINMD_ACT1, OSD_VIDWINMD); > + break; > + } > +} > + > +static int osd_enable_layer(struct osd_state *sd, enum osd_layer layer, > + int otherwin) > +{ > + struct osd_state *osd = sd; > + struct osd_window_state *win = &osd->win[layer]; > + unsigned long flags; > + > + spin_lock_irqsave(&osd->lock, flags); > + > + /* > + * use otherwin flag to know this is the other vid window > + * in YUV420 mode, if is, skip this check > + */ > + if (!otherwin && (!win->is_allocated || > + !win->fb_base_phys || > + !win->lconfig.line_length || > + !win->lconfig.xsize || > + !win->lconfig.ysize)) { > + spin_unlock_irqrestore(&osd->lock, flags); > + return -1; > + } > + > + if (win->is_enabled) { > + spin_unlock_irqrestore(&osd->lock, flags); > + return 0; > + } > + win->is_enabled = 1; > + > + if (win->lconfig.pixfmt != PIXFMT_OSD_ATTR) > + _osd_enable_layer(sd, layer); > + else { > + _osd_enable_attribute_mode(sd); > + _osd_set_blink_attribute(sd, osd->is_blinking, osd->blink); > + } > + > + spin_unlock_irqrestore(&osd->lock, flags); > + return 0; > +} > + > +static void _osd_start_layer(struct osd_state *sd, enum osd_layer layer, > + unsigned long fb_base_phys, > + unsigned long cbcr_ofst) > +{ > + switch (layer) { > + case WIN_OSD0: > + osd_write(sd, fb_base_phys & ~0x1F, OSD_OSDWIN0ADR); > + break; > + case WIN_VID0: > + osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN0ADR); > + break; > + case WIN_OSD1: > + osd_write(sd, fb_base_phys & ~0x1F, OSD_OSDWIN1ADR); > + break; > + case WIN_VID1: > + osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN1ADR); > + break; > + } > +} > + > +static void osd_start_layer(struct osd_state *sd, enum osd_layer layer, > + unsigned long fb_base_phys, > + unsigned long cbcr_ofst) > +{ > + struct osd_state *osd = sd; > + struct osd_window_state *win = &osd->win[layer]; > + unsigned long flags; > + > + spin_lock_irqsave(&osd->lock, flags); > + > + win->fb_base_phys = fb_base_phys & ~0x1F; > + _osd_start_layer(sd, layer, fb_base_phys, cbcr_ofst); > + > + if (layer == WIN_VID0) { > + osd->pingpong = > + _osd_dm6446_vid0_pingpong(sd, osd->field_inversion, > + win->fb_base_phys, > + &win->lconfig); > + } > + > + spin_unlock_irqrestore(&osd->lock, flags); > +} > + > +static void osd_get_layer_config(struct osd_state *sd, enum osd_layer layer, > + struct osd_layer_config *lconfig) > +{ > + struct osd_state *osd = sd; > + struct osd_window_state *win = &osd->win[layer]; > + unsigned long flags; > + > + spin_lock_irqsave(&osd->lock, flags); > + > + *lconfig = win->lconfig; > + > + spin_unlock_irqrestore(&osd->lock, flags); > +} > + > +/** > + * try_layer_config() - Try a specific configuration for the layer > + * @sd - ptr to struct osd_state > + * @layer - layer to configure > + * @lconfig - layer configuration to try > + * > + * If the requested lconfig is completely rejected and the value of lconfig on > + * exit is the current lconfig, then try_layer_config() returns 1. Otherwise, > + * try_layer_config() returns 0. A return value of 0 does not necessarily mean > + * that the value of lconfig on exit is identical to the value of lconfig on > + * entry, but merely that it represents a change from the current lconfig. > + */ > +static int try_layer_config(struct osd_state *sd, enum osd_layer layer, > + struct osd_layer_config *lconfig) > +{ > + struct osd_state *osd = sd; > + struct osd_window_state *win = &osd->win[layer]; > + int bad_config = 0; > + > + /* verify that the pixel format is compatible with the layer */ > + switch (lconfig->pixfmt) { > + case PIXFMT_1BPP: > + case PIXFMT_2BPP: > + case PIXFMT_4BPP: > + case PIXFMT_8BPP: > + case PIXFMT_RGB565: > + bad_config = !is_osd_win(layer); > + break; > + case PIXFMT_YCbCrI: > + case PIXFMT_YCrCbI: > + bad_config = !is_vid_win(layer); > + break; > + case PIXFMT_RGB888: > + bad_config = !is_vid_win(layer); > + break; > + case PIXFMT_NV12: > + bad_config = 1; > + break; > + case PIXFMT_OSD_ATTR: > + bad_config = (layer != WIN_OSD1); > + break; > + default: > + bad_config = 1; > + break; > + } > + if (bad_config) { > + /* > + * The requested pixel format is incompatible with the layer, > + * so keep the current layer configuration. > + */ > + *lconfig = win->lconfig; > + return bad_config; > + } > + > + /* DM6446: */ > + /* only one OSD window at a time can use RGB pixel formats */ > + if (is_osd_win(layer) && is_rgb_pixfmt(lconfig->pixfmt)) { > + enum osd_pix_format pixfmt; > + > + if (layer == WIN_OSD0) > + pixfmt = osd->win[WIN_OSD1].lconfig.pixfmt; > + else > + pixfmt = osd->win[WIN_OSD0].lconfig.pixfmt; > + > + if (is_rgb_pixfmt(pixfmt)) { > + /* > + * The other OSD window is already configured for an > + * RGB, so keep the current layer configuration. > + */ > + *lconfig = win->lconfig; > + return 1; > + } > + } > + > + /* DM6446: only one video window at a time can use RGB888 */ > + if (is_vid_win(layer) && lconfig->pixfmt == PIXFMT_RGB888) { > + enum osd_pix_format pixfmt; > + > + if (layer == WIN_VID0) > + pixfmt = osd->win[WIN_VID1].lconfig.pixfmt; > + else > + pixfmt = osd->win[WIN_VID0].lconfig.pixfmt; > + > + if (pixfmt == PIXFMT_RGB888) { > + /* > + * The other video window is already configured for > + * RGB888, so keep the current layer configuration. > + */ > + *lconfig = win->lconfig; > + return 1; > + } > + } > + > + /* window dimensions must be non-zero */ > + if (!lconfig->line_length || !lconfig->xsize || !lconfig->ysize) { > + *lconfig = win->lconfig; > + return 1; > + } > + > + /* round line_length up to a multiple of 32 */ > + lconfig->line_length = ((lconfig->line_length + 31) / 32) * 32; > + lconfig->line_length = > + min(lconfig->line_length, (unsigned)MAX_LINE_LENGTH); > + lconfig->xsize = min(lconfig->xsize, (unsigned)MAX_WIN_SIZE); > + lconfig->ysize = min(lconfig->ysize, (unsigned)MAX_WIN_SIZE); > + lconfig->xpos = min(lconfig->xpos, (unsigned)MAX_WIN_SIZE); > + lconfig->ypos = min(lconfig->ypos, (unsigned)MAX_WIN_SIZE); > + lconfig->interlaced = (lconfig->interlaced != 0); > + if (lconfig->interlaced) { > + /* ysize and ypos must be even for interlaced displays */ > + lconfig->ysize &= ~1; > + lconfig->ypos &= ~1; > + } > + > + return 0; > +} > + > +static void _osd_disable_vid_rgb888(struct osd_state *sd) > +{ > + /* > + * The DM6446 supports RGB888 pixel format in a single video window. > + * This routine disables RGB888 pixel format for both video windows. > + * The caller must ensure that neither video window is currently > + * configured for RGB888 pixel format. > + */ > + osd_clear(sd, OSD_MISCCTL_RGBEN, OSD_MISCCTL); > +} > + > +static void _osd_enable_vid_rgb888(struct osd_state *sd, > + enum osd_layer layer) > +{ > + /* > + * The DM6446 supports RGB888 pixel format in a single video window. > + * This routine enables RGB888 pixel format for the specified video > + * window. The caller must ensure that the other video window is not > + * currently configured for RGB888 pixel format, as this routine will > + * disable RGB888 pixel format for the other window. > + */ > + if (layer == WIN_VID0) { > + osd_modify(sd, OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN, > + OSD_MISCCTL_RGBEN, OSD_MISCCTL); > + } else if (layer == WIN_VID1) { > + osd_modify(sd, OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN, > + OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN, > + OSD_MISCCTL); > + } > +} > + > +static void _osd_set_cbcr_order(struct osd_state *sd, > + enum osd_pix_format pixfmt) > +{ > + /* > + * The caller must ensure that all windows using YC pixfmt use the same > + * Cb/Cr order. > + */ > + if (pixfmt == PIXFMT_YCbCrI) > + osd_clear(sd, OSD_MODE_CS, OSD_MODE); > + else if (pixfmt == PIXFMT_YCrCbI) > + osd_set(sd, OSD_MODE_CS, OSD_MODE); > +} > + > +static void _osd_set_layer_config(struct osd_state *sd, enum osd_layer layer, > + const struct osd_layer_config *lconfig) > +{ > + u32 winmd = 0, winmd_mask = 0, bmw = 0; > + > + _osd_set_cbcr_order(sd, lconfig->pixfmt); > + > + switch (layer) { > + case WIN_OSD0: > + winmd_mask |= OSD_OSDWIN0MD_RGB0E; > + if (lconfig->pixfmt == PIXFMT_RGB565) > + winmd |= OSD_OSDWIN0MD_RGB0E; > + > + winmd_mask |= OSD_OSDWIN0MD_BMW0 | OSD_OSDWIN0MD_OFF0; > + > + switch (lconfig->pixfmt) { > + case PIXFMT_1BPP: > + bmw = 0; > + break; > + case PIXFMT_2BPP: > + bmw = 1; > + break; > + case PIXFMT_4BPP: > + bmw = 2; > + break; > + case PIXFMT_8BPP: > + bmw = 3; > + break; > + default: > + break; > + } > + winmd |= (bmw << OSD_OSDWIN0MD_BMW0_SHIFT); > + > + if (lconfig->interlaced) > + winmd |= OSD_OSDWIN0MD_OFF0; > + > + osd_modify(sd, winmd_mask, winmd, OSD_OSDWIN0MD); > + osd_write(sd, lconfig->line_length >> 5, OSD_OSDWIN0OFST); > + osd_write(sd, lconfig->xpos, OSD_OSDWIN0XP); > + osd_write(sd, lconfig->xsize, OSD_OSDWIN0XL); > + if (lconfig->interlaced) { > + osd_write(sd, lconfig->ypos >> 1, OSD_OSDWIN0YP); > + osd_write(sd, lconfig->ysize >> 1, OSD_OSDWIN0YL); > + } else { > + osd_write(sd, lconfig->ypos, OSD_OSDWIN0YP); > + osd_write(sd, lconfig->ysize, OSD_OSDWIN0YL); > + } > + break; > + case WIN_VID0: > + winmd_mask |= OSD_VIDWINMD_VFF0; > + if (lconfig->interlaced) > + winmd |= OSD_VIDWINMD_VFF0; > + > + osd_modify(sd, winmd_mask, winmd, OSD_VIDWINMD); > + osd_write(sd, lconfig->line_length >> 5, OSD_VIDWIN0OFST); > + osd_write(sd, lconfig->xpos, OSD_VIDWIN0XP); > + osd_write(sd, lconfig->xsize, OSD_VIDWIN0XL); > + /* > + * For YUV420P format the register contents are > + * duplicated in both VID registers > + */ > + if (lconfig->interlaced) { > + osd_write(sd, lconfig->ypos >> 1, OSD_VIDWIN0YP); > + osd_write(sd, lconfig->ysize >> 1, OSD_VIDWIN0YL); > + } else { > + osd_write(sd, lconfig->ypos, OSD_VIDWIN0YP); > + osd_write(sd, lconfig->ysize, OSD_VIDWIN0YL); > + } > + break; > + case WIN_OSD1: > + /* > + * The caller must ensure that OSD1 is disabled prior to > + * switching from a normal mode to attribute mode or from > + * attribute mode to a normal mode. > + */ > + if (lconfig->pixfmt == PIXFMT_OSD_ATTR) { > + winmd_mask |= > + OSD_OSDWIN1MD_ATN1E | OSD_OSDWIN1MD_RGB1E | > + OSD_OSDWIN1MD_CLUTS1 | > + OSD_OSDWIN1MD_BLND1 | OSD_OSDWIN1MD_TE1; > + } else { > + winmd_mask |= OSD_OSDWIN1MD_RGB1E; > + if (lconfig->pixfmt == PIXFMT_RGB565) > + winmd |= OSD_OSDWIN1MD_RGB1E; > + > + winmd_mask |= OSD_OSDWIN1MD_BMW1; > + switch (lconfig->pixfmt) { > + case PIXFMT_1BPP: > + bmw = 0; > + break; > + case PIXFMT_2BPP: > + bmw = 1; > + break; > + case PIXFMT_4BPP: > + bmw = 2; > + break; > + case PIXFMT_8BPP: > + bmw = 3; > + break; > + default: > + break; > + } > + winmd |= (bmw << OSD_OSDWIN1MD_BMW1_SHIFT); > + } > + > + winmd_mask |= OSD_OSDWIN1MD_OFF1; > + if (lconfig->interlaced) > + winmd |= OSD_OSDWIN1MD_OFF1; > + > + osd_modify(sd, winmd_mask, winmd, OSD_OSDWIN1MD); > + osd_write(sd, lconfig->line_length >> 5, OSD_OSDWIN1OFST); > + osd_write(sd, lconfig->xpos, OSD_OSDWIN1XP); > + osd_write(sd, lconfig->xsize, OSD_OSDWIN1XL); > + if (lconfig->interlaced) { > + osd_write(sd, lconfig->ypos >> 1, OSD_OSDWIN1YP); > + osd_write(sd, lconfig->ysize >> 1, OSD_OSDWIN1YL); > + } else { > + osd_write(sd, lconfig->ypos, OSD_OSDWIN1YP); > + osd_write(sd, lconfig->ysize, OSD_OSDWIN1YL); > + } > + break; > + case WIN_VID1: > + winmd_mask |= OSD_VIDWINMD_VFF1; > + if (lconfig->interlaced) > + winmd |= OSD_VIDWINMD_VFF1; > + > + osd_modify(sd, winmd_mask, winmd, OSD_VIDWINMD); > + osd_write(sd, lconfig->line_length >> 5, OSD_VIDWIN1OFST); > + osd_write(sd, lconfig->xpos, OSD_VIDWIN1XP); > + osd_write(sd, lconfig->xsize, OSD_VIDWIN1XL); > + /* > + * For YUV420P format the register contents are > + * duplicated in both VID registers > + */ > + osd_modify(sd, OSD_MISCCTL_S420D, ~OSD_MISCCTL_S420D, > + OSD_MISCCTL); > + > + if (lconfig->interlaced) { > + osd_write(sd, lconfig->ypos >> 1, OSD_VIDWIN1YP); > + osd_write(sd, lconfig->ysize >> 1, OSD_VIDWIN1YL); > + } else { > + osd_write(sd, lconfig->ypos, OSD_VIDWIN1YP); > + osd_write(sd, lconfig->ysize, OSD_VIDWIN1YL); > + } > + break; > + } > +} > + > +static int osd_set_layer_config(struct osd_state *sd, enum osd_layer layer, > + struct osd_layer_config *lconfig) > +{ > + struct osd_state *osd = sd; > + struct osd_window_state *win = &osd->win[layer]; > + int reject_config; > + unsigned long flags; > + > + spin_lock_irqsave(&osd->lock, flags); > + > + reject_config = try_layer_config(sd, layer, lconfig); > + if (reject_config) { > + spin_unlock_irqrestore(&osd->lock, flags); > + return reject_config; > + } > + > + /* update the current Cb/Cr order */ > + if (is_yc_pixfmt(lconfig->pixfmt)) > + osd->yc_pixfmt = lconfig->pixfmt; > + > + /* > + * If we are switching OSD1 from normal mode to attribute mode or from > + * attribute mode to normal mode, then we must disable the window. > + */ > + if (layer == WIN_OSD1) { > + if (((lconfig->pixfmt == PIXFMT_OSD_ATTR) > + && (win->lconfig.pixfmt != PIXFMT_OSD_ATTR)) > + || ((lconfig->pixfmt != PIXFMT_OSD_ATTR) > + && (win->lconfig.pixfmt == PIXFMT_OSD_ATTR))) { > + win->is_enabled = 0; > + _osd_disable_layer(sd, layer); > + } > + } > + > + _osd_set_layer_config(sd, layer, lconfig); > + > + if (layer == WIN_OSD1) { > + struct osd_osdwin_state *osdwin_state = > + &osd->osdwin[OSDWIN_OSD1]; > + > + if ((lconfig->pixfmt != PIXFMT_OSD_ATTR) > + && (win->lconfig.pixfmt == PIXFMT_OSD_ATTR)) { > + /* > + * We just switched OSD1 from attribute mode to normal > + * mode, so we must initialize the CLUT select, the > + * blend factor, transparency colorkey enable, and > + * attenuation enable (DM6446 only) bits in the > + * OSDWIN1MD register. > + */ > + _osd_set_osd_clut(sd, OSDWIN_OSD1, > + osdwin_state->clut); > + _osd_set_blending_factor(sd, OSDWIN_OSD1, > + osdwin_state->blend); > + if (osdwin_state->colorkey_blending) { > + _osd_enable_color_key(sd, OSDWIN_OSD1, > + osdwin_state-> > + colorkey, > + lconfig->pixfmt); > + } else > + _osd_disable_color_key(sd, OSDWIN_OSD1); > + _osd_set_rec601_attenuation(sd, OSDWIN_OSD1, > + osdwin_state-> > + rec601_attenuation); > + } else if ((lconfig->pixfmt == PIXFMT_OSD_ATTR) > + && (win->lconfig.pixfmt != PIXFMT_OSD_ATTR)) { > + /* > + * We just switched OSD1 from normal mode to attribute > + * mode, so we must initialize the blink enable and > + * blink interval bits in the OSDATRMD register. > + */ > + _osd_set_blink_attribute(sd, osd->is_blinking, > + osd->blink); > + } > + } > + > + /* > + * If we just switched to a 1-, 2-, or 4-bits-per-pixel bitmap format > + * then configure a default palette map. > + */ > + if ((lconfig->pixfmt != win->lconfig.pixfmt) > + && ((lconfig->pixfmt == PIXFMT_1BPP) > + || (lconfig->pixfmt == PIXFMT_2BPP) > + || (lconfig->pixfmt == PIXFMT_4BPP))) { > + enum osd_win_layer osdwin = > + ((layer == WIN_OSD0) ? OSDWIN_OSD0 : OSDWIN_OSD1); > + struct osd_osdwin_state *osdwin_state = > + &osd->osdwin[osdwin]; > + unsigned char clut_index; > + unsigned char clut_entries = 0; > + > + switch (lconfig->pixfmt) { > + case PIXFMT_1BPP: > + clut_entries = 2; > + break; > + case PIXFMT_2BPP: > + clut_entries = 4; > + break; > + case PIXFMT_4BPP: > + clut_entries = 16; > + break; > + default: > + break; > + } > + /* > + * The default palette map maps the pixel value to the clut > + * index, i.e. pixel value 0 maps to clut entry 0, pixel value > + * 1 maps to clut entry 1, etc. > + */ > + for (clut_index = 0; clut_index < 16; clut_index++) { > + osdwin_state->palette_map[clut_index] = clut_index; > + if (clut_index < clut_entries) { > + _osd_set_palette_map(sd, osdwin, clut_index, > + clut_index, > + lconfig->pixfmt); > + } > + } > + } > + > + win->lconfig = *lconfig; > + /* DM6446: configure the RGB888 enable and window selection */ > + if (osd->win[WIN_VID0].lconfig.pixfmt == PIXFMT_RGB888) > + _osd_enable_vid_rgb888(sd, WIN_VID0); > + else if (osd->win[WIN_VID1].lconfig.pixfmt == PIXFMT_RGB888) > + _osd_enable_vid_rgb888(sd, WIN_VID1); > + else > + _osd_disable_vid_rgb888(sd); > + > + if (layer == WIN_VID0) { > + osd->pingpong = > + _osd_dm6446_vid0_pingpong(sd, osd->field_inversion, > + win->fb_base_phys, > + &win->lconfig); > + } > + > + spin_unlock_irqrestore(&osd->lock, flags); > + > + return 0; > +} > + > +static void osd_init_layer(struct osd_state *sd, enum osd_layer layer) > +{ > + struct osd_state *osd = sd; > + struct osd_window_state *win = &osd->win[layer]; > + enum osd_win_layer osdwin; > + struct osd_osdwin_state *osdwin_state; > + unsigned long flags; > + > + spin_lock_irqsave(&osd->lock, flags); > + > + win->is_enabled = 0; > + _osd_disable_layer(sd, layer); > + > + win->h_zoom = ZOOM_X1; > + win->v_zoom = ZOOM_X1; > + _osd_set_zoom(sd, layer, win->h_zoom, win->v_zoom); > + > + win->fb_base_phys = 0; > + _osd_start_layer(sd, layer, win->fb_base_phys, 0); > + > + win->lconfig.line_length = 0; > + win->lconfig.xsize = 0; > + win->lconfig.ysize = 0; > + win->lconfig.xpos = 0; > + win->lconfig.ypos = 0; > + win->lconfig.interlaced = 0; > + switch (layer) { > + case WIN_OSD0: > + case WIN_OSD1: > + osdwin = (layer == WIN_OSD0) ? OSDWIN_OSD0 : OSDWIN_OSD1; > + osdwin_state = &osd->osdwin[osdwin]; > + /* > + * Other code relies on the fact that OSD windows default to a > + * bitmap pixel format when they are deallocated, so don't > + * change this default pixel format. > + */ > + win->lconfig.pixfmt = PIXFMT_8BPP; > + _osd_set_layer_config(sd, layer, &win->lconfig); > + osdwin_state->clut = RAM_CLUT; > + _osd_set_osd_clut(sd, osdwin, osdwin_state->clut); > + osdwin_state->colorkey_blending = 0; > + _osd_disable_color_key(sd, osdwin); > + osdwin_state->blend = OSD_8_VID_0; > + _osd_set_blending_factor(sd, osdwin, osdwin_state->blend); > + osdwin_state->rec601_attenuation = 0; > + _osd_set_rec601_attenuation(sd, osdwin, > + osdwin_state-> > + rec601_attenuation); > + if (osdwin == OSDWIN_OSD1) { > + osd->is_blinking = 0; > + osd->blink = BLINK_X1; > + } > + break; > + case WIN_VID0: > + case WIN_VID1: > + win->lconfig.pixfmt = osd->yc_pixfmt; > + _osd_set_layer_config(sd, layer, &win->lconfig); > + break; > + } > + > + spin_unlock_irqrestore(&osd->lock, flags); > +} > + > +static void osd_release_layer(struct osd_state *sd, enum osd_layer layer) > +{ > + struct osd_state *osd = sd; > + struct osd_window_state *win = &osd->win[layer]; > + unsigned long flags; > + > + spin_lock_irqsave(&osd->lock, flags); > + > + if (!win->is_allocated) { > + spin_unlock_irqrestore(&osd->lock, flags); > + return; > + } > + > + spin_unlock_irqrestore(&osd->lock, flags); > + osd_init_layer(sd, layer); > + spin_lock_irqsave(&osd->lock, flags); > + > + win->is_allocated = 0; > + > + spin_unlock_irqrestore(&osd->lock, flags); > +} > + > +static int osd_request_layer(struct osd_state *sd, enum osd_layer layer) > +{ > + struct osd_state *osd = sd; > + struct osd_window_state *win = &osd->win[layer]; > + unsigned long flags; > + > + spin_lock_irqsave(&osd->lock, flags); > + > + if (win->is_allocated) { > + spin_unlock_irqrestore(&osd->lock, flags); > + return -1; > + } > + win->is_allocated = 1; > + > + spin_unlock_irqrestore(&osd->lock, flags); > + return 0; > +} > + > +static void _osd_init(struct osd_state *sd) > +{ > + osd_write(sd, 0, OSD_MODE); > + osd_write(sd, 0, OSD_VIDWINMD); > + osd_write(sd, 0, OSD_OSDWIN0MD); > + osd_write(sd, 0, OSD_OSDWIN1MD); > + osd_write(sd, 0, OSD_RECTCUR); > + osd_write(sd, 0, OSD_MISCCTL); > +} > + > +static void osd_set_left_margin(struct osd_state *sd, u32 val) > +{ > + osd_write(sd, val, OSD_BASEPX); > +} > + > +static void osd_set_top_margin(struct osd_state *sd, u32 val) > +{ > + osd_write(sd, val, OSD_BASEPY); > +} > + > +static int osd_initialize(struct osd_state *osd) > +{ > + if (osd == NULL) > + return -ENODEV; > + _osd_init(osd); > + > + /* set default Cb/Cr order */ > + osd->yc_pixfmt = PIXFMT_YCbCrI; > + > + _osd_set_field_inversion(osd, osd->field_inversion); > + _osd_set_rom_clut(osd, osd->rom_clut); > + > + osd_init_layer(osd, WIN_OSD0); > + osd_init_layer(osd, WIN_VID0); > + osd_init_layer(osd, WIN_OSD1); > + osd_init_layer(osd, WIN_VID1); > + > + return 0; > +} > + > +static const struct vpbe_osd_ops osd_ops = { > + .initialize = osd_initialize, > + .request_layer = osd_request_layer, > + .release_layer = osd_release_layer, > + .enable_layer = osd_enable_layer, > + .disable_layer = osd_disable_layer, > + .set_layer_config = osd_set_layer_config, > + .get_layer_config = osd_get_layer_config, > + .start_layer = osd_start_layer, > + .set_left_margin = osd_set_left_margin, > + .set_top_margin = osd_set_top_margin, > +}; > + > +static int osd_probe(struct platform_device *pdev) > +{ > + struct osd_state *osd; > + struct resource *res; > + int ret = 0; > + > + osd = kzalloc(sizeof(struct osd_state), GFP_KERNEL); > + if (osd == NULL) > + return -ENOMEM; > + > + osd->dev = &pdev->dev; > + osd->vpbe_type = (enum vpbe_types)pdev->dev.platform_data; > + if (NULL == pdev->dev.platform_data) { > + dev_err(osd->dev, "No platform data defined for OSD" > + " sub device\n"); > + ret = -ENOENT; > + goto free_mem; > + } > + > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > + if (!res) { > + dev_err(osd->dev, "Unable to get OSD register address map\n"); > + ret = -ENODEV; > + goto free_mem; > + } > + osd->osd_base_phys = res->start; > + osd->osd_size = res->end - res->start + 1; > + if (!request_mem_region(osd->osd_base_phys, osd->osd_size, > + MODULE_NAME)) { > + dev_err(osd->dev, "Unable to reserve OSD MMIO region\n"); > + ret = -ENODEV; > + goto free_mem; > + } > + osd->osd_base = (unsigned long)ioremap_nocache(res->start, > + osd->osd_size); > + if (!osd->osd_base) { > + dev_err(osd->dev, "Unable to map the OSD region\n"); > + ret = -ENODEV; > + goto release_mem_region; > + } > + spin_lock_init(&osd->lock); > + osd->ops = osd_ops; > + platform_set_drvdata(pdev, osd); > + dev_notice(osd->dev, "OSD sub device probe success\n"); > + return ret; > + > +release_mem_region: > + release_mem_region(osd->osd_base_phys, osd->osd_size); > +free_mem: > + kfree(osd); > + return ret; > +} > + > +static int osd_remove(struct platform_device *pdev) > +{ > + struct osd_state *osd = platform_get_drvdata(pdev); > + > + iounmap((void *)osd->osd_base); > + release_mem_region(osd->osd_base_phys, osd->osd_size); > + kfree(osd); > + return 0; > +} > + > +static struct platform_driver osd_driver = { > + .probe = osd_probe, > + .remove = osd_remove, > + .driver = { > + .name = MODULE_NAME, > + .owner = THIS_MODULE, > + }, > +}; > + > +static int osd_init(void) > +{ > + /* Register the driver */ > + if (platform_driver_register(&osd_driver)) { > + printk(KERN_ERR "Unable to register davinci osd driver\n"); > + return -ENODEV; > + } > + > + return 0; > +} > + > +static void osd_exit(void) > +{ > + platform_driver_unregister(&osd_driver); > +} > + > +module_init(osd_init); > +module_exit(osd_exit); > + > +MODULE_LICENSE("GPL"); > +MODULE_DESCRIPTION("DaVinci OSD Manager Driver"); > +MODULE_AUTHOR("Texas Instruments"); > diff --git a/drivers/media/video/davinci/vpbe_osd_regs.h b/drivers/media/video/davinci/vpbe_osd_regs.h > new file mode 100644 > index 0000000..9cd3839 > --- /dev/null > +++ b/drivers/media/video/davinci/vpbe_osd_regs.h > @@ -0,0 +1,389 @@ > +/* > + * Copyright (C) 2006-2010 Texas Instruments Inc > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > + */ > +#ifndef _VPBE_OSD_REGS_H > +#define _VPBE_OSD_REGS_H > + > +enum vpbe_soc_type { > + DM644x = 0, > + DM35x, > + DM36x, > +}; > + > +struct vpbe_osd_platform_data { > + enum vpbe_soc_type soc; > +}; > + > +#define DM644X_OSD_REG_BASE 0x01C72600 > +#define DM644X_VPBE_REG_BASE 0x01C72780 > + > +#define DM355_VPSSCLK_REG_BASE 0x01C70000 > +#define DM355_OSD_REG_BASE 0x01C70200 > + > +#define DM365_OSD_REG_BASE 0x01C71C00 > +#define DM365_ISP5_REG_BASE 0x01C70000 > + > +#define OSD_REG_SIZE 0x00000100 > + > +/* SYS register addresses */ > +#define SYS_VPSS_CLKCTL 0x01C40044 > + > +/* VPBE Global Registers */ > +#define VPBE_PID 0x0 > +#define VPBE_PCR 0x4 > + > +/* VPSS CLock Registers */ > +#define VPSSCLK_PID 0x00 > +#define VPSSCLK_CLKCTRL 0x04 > + > +/* VPSS Buffer Logic Registers */ > +#define VPSSBL_PID 0x00 > +#define VPSSBL_PCR 0x04 > +#define VPSSBL_BCR 0x08 > +#define VPSSBL_INTSTAT 0x0C > +#define VPSSBL_INTSEL 0x10 > +#define VPSSBL_EVTSEL 0x14 > +#define VPSSBL_MEMCTRL 0x18 > +#define VPSSBL_CCDCMUX 0x1C > + > +/* DM365 ISP5 system configuration */ > +#define ISP5_PID 0x0 > +#define ISP5_PCCR 0x4 > +#define ISP5_BCR 0x8 > +#define ISP5_INTSTAT 0xC > +#define ISP5_INTSEL1 0x10 > +#define ISP5_INTSEL2 0x14 > +#define ISP5_INTSEL3 0x18 > +#define ISP5_EVTSEL 0x1c > +#define ISP5_CCDCMUX 0x20 > + > +/* VPBE On-Screen Display Subsystem Registers (OSD) */ > +#define OSD_MODE 0x00 > +#define OSD_VIDWINMD 0x04 > +#define OSD_OSDWIN0MD 0x08 > +#define OSD_OSDWIN1MD 0x0C > +#define OSD_OSDATRMD 0x0C > +#define OSD_RECTCUR 0x10 > +#define OSD_VIDWIN0OFST 0x18 > +#define OSD_VIDWIN1OFST 0x1C > +#define OSD_OSDWIN0OFST 0x20 > +#define OSD_OSDWIN1OFST 0x24 > +#define OSD_VIDWINADH 0x28 > +#define OSD_VIDWIN0ADL 0x2C > +#define OSD_VIDWIN0ADR 0x2C > +#define OSD_VIDWIN1ADL 0x30 > +#define OSD_VIDWIN1ADR 0x30 > +#define OSD_OSDWINADH 0x34 > +#define OSD_OSDWIN0ADL 0x38 > +#define OSD_OSDWIN0ADR 0x38 > +#define OSD_OSDWIN1ADL 0x3C > +#define OSD_OSDWIN1ADR 0x3C > +#define OSD_BASEPX 0x40 > +#define OSD_BASEPY 0x44 > +#define OSD_VIDWIN0XP 0x48 > +#define OSD_VIDWIN0YP 0x4C > +#define OSD_VIDWIN0XL 0x50 > +#define OSD_VIDWIN0YL 0x54 > +#define OSD_VIDWIN1XP 0x58 > +#define OSD_VIDWIN1YP 0x5C > +#define OSD_VIDWIN1XL 0x60 > +#define OSD_VIDWIN1YL 0x64 > +#define OSD_OSDWIN0XP 0x68 > +#define OSD_OSDWIN0YP 0x6C > +#define OSD_OSDWIN0XL 0x70 > +#define OSD_OSDWIN0YL 0x74 > +#define OSD_OSDWIN1XP 0x78 > +#define OSD_OSDWIN1YP 0x7C > +#define OSD_OSDWIN1XL 0x80 > +#define OSD_OSDWIN1YL 0x84 > +#define OSD_CURXP 0x88 > +#define OSD_CURYP 0x8C > +#define OSD_CURXL 0x90 > +#define OSD_CURYL 0x94 > +#define OSD_W0BMP01 0xA0 > +#define OSD_W0BMP23 0xA4 > +#define OSD_W0BMP45 0xA8 > +#define OSD_W0BMP67 0xAC > +#define OSD_W0BMP89 0xB0 > +#define OSD_W0BMPAB 0xB4 > +#define OSD_W0BMPCD 0xB8 > +#define OSD_W0BMPEF 0xBC > +#define OSD_W1BMP01 0xC0 > +#define OSD_W1BMP23 0xC4 > +#define OSD_W1BMP45 0xC8 > +#define OSD_W1BMP67 0xCC > +#define OSD_W1BMP89 0xD0 > +#define OSD_W1BMPAB 0xD4 > +#define OSD_W1BMPCD 0xD8 > +#define OSD_W1BMPEF 0xDC > +#define OSD_VBNDRY 0xE0 > +#define OSD_EXTMODE 0xE4 > +#define OSD_MISCCTL 0xE8 > +#define OSD_CLUTRAMYCB 0xEC > +#define OSD_CLUTRAMCR 0xF0 > +#define OSD_TRANSPVAL 0xF4 > +#define OSD_TRANSPVALL 0xF4 > +#define OSD_TRANSPVALU 0xF8 > +#define OSD_TRANSPBMPIDX 0xFC > +#define OSD_PPVWIN0ADR 0xFC > + > +/* bit definitions */ > +#define VPBE_PCR_VENC_DIV (1 << 1) > +#define VPBE_PCR_CLK_OFF (1 << 0) > + > +#define VPSSBL_INTSTAT_HSSIINT (1 << 14) > +#define VPSSBL_INTSTAT_CFALDINT (1 << 13) > +#define VPSSBL_INTSTAT_IPIPE_INT5 (1 << 12) > +#define VPSSBL_INTSTAT_IPIPE_INT4 (1 << 11) > +#define VPSSBL_INTSTAT_IPIPE_INT3 (1 << 10) > +#define VPSSBL_INTSTAT_IPIPE_INT2 (1 << 9) > +#define VPSSBL_INTSTAT_IPIPE_INT1 (1 << 8) > +#define VPSSBL_INTSTAT_IPIPE_INT0 (1 << 7) > +#define VPSSBL_INTSTAT_IPIPEIFINT (1 << 6) > +#define VPSSBL_INTSTAT_OSDINT (1 << 5) > +#define VPSSBL_INTSTAT_VENCINT (1 << 4) > +#define VPSSBL_INTSTAT_H3AINT (1 << 3) > +#define VPSSBL_INTSTAT_CCDC_VDINT2 (1 << 2) > +#define VPSSBL_INTSTAT_CCDC_VDINT1 (1 << 1) > +#define VPSSBL_INTSTAT_CCDC_VDINT0 (1 << 0) > + > +/* DM365 ISP5 bit definitions */ > +#define ISP5_INTSTAT_VENCINT (1 << 21) > +#define ISP5_INTSTAT_OSDINT (1 << 20) > + > +/* VMOD TVTYP options for HDMD=0 */ > +#define SDTV_NTSC 0 > +#define SDTV_PAL 1 > +/* VMOD TVTYP options for HDMD=1 */ > +#define HDTV_525P 0 > +#define HDTV_625P 1 > +#define HDTV_1080I 2 > +#define HDTV_720P 3 > + > + > +#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_VVRSZ (1 << 11) > +#define OSD_MODE_VHRSZ (1 << 10) > +#define OSD_MODE_FSINV (1 << 9) > +#define OSD_MODE_BCLUT (1 << 8) > +#define OSD_MODE_CABG_SHIFT 0 > +#define OSD_MODE_CABG (0xff << 0) > + > +#define OSD_VIDWINMD_VFINV (1 << 15) > +#define OSD_VIDWINMD_V1EFC (1 << 14) > +#define OSD_VIDWINMD_VHZ1_SHIFT 12 > +#define OSD_VIDWINMD_VHZ1 (3 << 12) > +#define OSD_VIDWINMD_VVZ1_SHIFT 10 > +#define OSD_VIDWINMD_VVZ1 (3 << 10) > +#define OSD_VIDWINMD_VFF1 (1 << 9) > +#define OSD_VIDWINMD_ACT1 (1 << 8) > +#define OSD_VIDWINMD_V0EFC (1 << 6) > +#define OSD_VIDWINMD_VHZ0_SHIFT 4 > +#define OSD_VIDWINMD_VHZ0 (3 << 4) > +#define OSD_VIDWINMD_VVZ0_SHIFT 2 > +#define OSD_VIDWINMD_VVZ0 (3 << 2) > +#define OSD_VIDWINMD_VFF0 (1 << 1) > +#define OSD_VIDWINMD_ACT0 (1 << 0) > + > +#define OSD_OSDWIN0MD_ATN0E (1 << 14) > +#define OSD_OSDWIN0MD_RGB0E (1 << 13) > +#define OSD_OSDWIN0MD_BMP0MD_SHIFT 13 > +#define OSD_OSDWIN0MD_BMP0MD (3 << 13) > +#define OSD_OSDWIN0MD_CLUTS0 (1 << 12) > +#define OSD_OSDWIN0MD_OHZ0_SHIFT 10 > +#define OSD_OSDWIN0MD_OHZ0 (3 << 10) > +#define OSD_OSDWIN0MD_OVZ0_SHIFT 8 > +#define OSD_OSDWIN0MD_OVZ0 (3 << 8) > +#define OSD_OSDWIN0MD_BMW0_SHIFT 6 > +#define OSD_OSDWIN0MD_BMW0 (3 << 6) > +#define OSD_OSDWIN0MD_BLND0_SHIFT 3 > +#define OSD_OSDWIN0MD_BLND0 (7 << 3) > +#define OSD_OSDWIN0MD_TE0 (1 << 2) > +#define OSD_OSDWIN0MD_OFF0 (1 << 1) > +#define OSD_OSDWIN0MD_OACT0 (1 << 0) > + > +#define OSD_OSDWIN1MD_OASW (1 << 15) > +#define OSD_OSDWIN1MD_ATN1E (1 << 14) > +#define OSD_OSDWIN1MD_RGB1E (1 << 13) > +#define OSD_OSDWIN1MD_BMP1MD_SHIFT 13 > +#define OSD_OSDWIN1MD_BMP1MD (3 << 13) > +#define OSD_OSDWIN1MD_CLUTS1 (1 << 12) > +#define OSD_OSDWIN1MD_OHZ1_SHIFT 10 > +#define OSD_OSDWIN1MD_OHZ1 (3 << 10) > +#define OSD_OSDWIN1MD_OVZ1_SHIFT 8 > +#define OSD_OSDWIN1MD_OVZ1 (3 << 8) > +#define OSD_OSDWIN1MD_BMW1_SHIFT 6 > +#define OSD_OSDWIN1MD_BMW1 (3 << 6) > +#define OSD_OSDWIN1MD_BLND1_SHIFT 3 > +#define OSD_OSDWIN1MD_BLND1 (7 << 3) > +#define OSD_OSDWIN1MD_TE1 (1 << 2) > +#define OSD_OSDWIN1MD_OFF1 (1 << 1) > +#define OSD_OSDWIN1MD_OACT1 (1 << 0) > + > +#define OSD_OSDATRMD_OASW (1 << 15) > +#define OSD_OSDATRMD_OHZA_SHIFT 10 > +#define OSD_OSDATRMD_OHZA (3 << 10) > +#define OSD_OSDATRMD_OVZA_SHIFT 8 > +#define OSD_OSDATRMD_OVZA (3 << 8) > +#define OSD_OSDATRMD_BLNKINT_SHIFT 6 > +#define OSD_OSDATRMD_BLNKINT (3 << 6) > +#define OSD_OSDATRMD_OFFA (1 << 1) > +#define OSD_OSDATRMD_BLNK (1 << 0) > + > +#define OSD_RECTCUR_RCAD_SHIFT 8 > +#define OSD_RECTCUR_RCAD (0xff << 8) > +#define OSD_RECTCUR_CLUTSR (1 << 7) > +#define OSD_RECTCUR_RCHW_SHIFT 4 > +#define OSD_RECTCUR_RCHW (7 << 4) > +#define OSD_RECTCUR_RCVW_SHIFT 1 > +#define OSD_RECTCUR_RCVW (7 << 1) > +#define OSD_RECTCUR_RCACT (1 << 0) > + > +#define OSD_VIDWIN0OFST_V0LO (0x1ff << 0) > + > +#define OSD_VIDWIN1OFST_V1LO (0x1ff << 0) > + > +#define OSD_OSDWIN0OFST_O0LO (0x1ff << 0) > + > +#define OSD_OSDWIN1OFST_O1LO (0x1ff << 0) > + > +#define OSD_WINOFST_AH_SHIFT 9 > + > +#define OSD_VIDWIN0OFST_V0AH (0xf << 9) > +#define OSD_VIDWIN1OFST_V1AH (0xf << 9) > +#define OSD_OSDWIN0OFST_O0AH (0xf << 9) > +#define OSD_OSDWIN1OFST_O1AH (0xf << 9) > + > +#define OSD_VIDWINADH_V1AH_SHIFT 8 > +#define OSD_VIDWINADH_V1AH (0x7f << 8) > +#define OSD_VIDWINADH_V0AH_SHIFT 0 > +#define OSD_VIDWINADH_V0AH (0x7f << 0) > + > +#define OSD_VIDWIN0ADL_V0AL (0xffff << 0) > + > +#define OSD_VIDWIN1ADL_V1AL (0xffff << 0) > + > +#define OSD_OSDWINADH_O1AH_SHIFT 8 > +#define OSD_OSDWINADH_O1AH (0x7f << 8) > +#define OSD_OSDWINADH_O0AH_SHIFT 0 > +#define OSD_OSDWINADH_O0AH (0x7f << 0) > + > +#define OSD_OSDWIN0ADL_O0AL (0xffff << 0) > + > +#define OSD_OSDWIN1ADL_O1AL (0xffff << 0) > + > +#define OSD_BASEPX_BPX (0x3ff << 0) > + > +#define OSD_BASEPY_BPY (0x1ff << 0) > + > +#define OSD_VIDWIN0XP_V0X (0x7ff << 0) > + > +#define OSD_VIDWIN0YP_V0Y (0x7ff << 0) > + > +#define OSD_VIDWIN0XL_V0W (0x7ff << 0) > + > +#define OSD_VIDWIN0YL_V0H (0x7ff << 0) > + > +#define OSD_VIDWIN1XP_V1X (0x7ff << 0) > + > +#define OSD_VIDWIN1YP_V1Y (0x7ff << 0) > + > +#define OSD_VIDWIN1XL_V1W (0x7ff << 0) > + > +#define OSD_VIDWIN1YL_V1H (0x7ff << 0) > + > +#define OSD_OSDWIN0XP_W0X (0x7ff << 0) > + > +#define OSD_OSDWIN0YP_W0Y (0x7ff << 0) > + > +#define OSD_OSDWIN0XL_W0W (0x7ff << 0) > + > +#define OSD_OSDWIN0YL_W0H (0x7ff << 0) > + > +#define OSD_OSDWIN1XP_W1X (0x7ff << 0) > + > +#define OSD_OSDWIN1YP_W1Y (0x7ff << 0) > + > +#define OSD_OSDWIN1XL_W1W (0x7ff << 0) > + > +#define OSD_OSDWIN1YL_W1H (0x7ff << 0) > + > +#define OSD_CURXP_RCSX (0x7ff << 0) > + > +#define OSD_CURYP_RCSY (0x7ff << 0) > + > +#define OSD_CURXL_RCSW (0x7ff << 0) > + > +#define OSD_CURYL_RCSH (0x7ff << 0) > + > +#define OSD_EXTMODE_EXPMDSEL (1 << 15) > +#define OSD_EXTMODE_SCRNHEXP_SHIFT 13 > +#define OSD_EXTMODE_SCRNHEXP (3 << 13) > +#define OSD_EXTMODE_SCRNVEXP (1 << 12) > +#define OSD_EXTMODE_OSD1BLDCHR (1 << 11) > +#define OSD_EXTMODE_OSD0BLDCHR (1 << 10) > +#define OSD_EXTMODE_ATNOSD1EN (1 << 9) > +#define OSD_EXTMODE_ATNOSD0EN (1 << 8) > +#define OSD_EXTMODE_OSDHRSZ15 (1 << 7) > +#define OSD_EXTMODE_VIDHRSZ15 (1 << 6) > +#define OSD_EXTMODE_ZMFILV1HEN (1 << 5) > +#define OSD_EXTMODE_ZMFILV1VEN (1 << 4) > +#define OSD_EXTMODE_ZMFILV0HEN (1 << 3) > +#define OSD_EXTMODE_ZMFILV0VEN (1 << 2) > +#define OSD_EXTMODE_EXPFILHEN (1 << 1) > +#define OSD_EXTMODE_EXPFILVEN (1 << 0) > + > +#define OSD_MISCCTL_BLDSEL (1 << 15) > +#define OSD_MISCCTL_S420D (1 << 14) > +#define OSD_MISCCTL_BMAPT (1 << 13) > +#define OSD_MISCCTL_DM365M (1 << 12) > +#define OSD_MISCCTL_RGBEN (1 << 7) > +#define OSD_MISCCTL_RGBWIN (1 << 6) > +#define OSD_MISCCTL_DMANG (1 << 6) > +#define OSD_MISCCTL_TMON (1 << 5) > +#define OSD_MISCCTL_RSEL (1 << 4) > +#define OSD_MISCCTL_CPBSY (1 << 3) > +#define OSD_MISCCTL_PPSW (1 << 2) > +#define OSD_MISCCTL_PPRV (1 << 1) > + > +#define OSD_CLUTRAMYCB_Y_SHIFT 8 > +#define OSD_CLUTRAMYCB_Y (0xff << 8) > +#define OSD_CLUTRAMYCB_CB_SHIFT 0 > +#define OSD_CLUTRAMYCB_CB (0xff << 0) > + > +#define OSD_CLUTRAMCR_CR_SHIFT 8 > +#define OSD_CLUTRAMCR_CR (0xff << 8) > +#define OSD_CLUTRAMCR_CADDR_SHIFT 0 > +#define OSD_CLUTRAMCR_CADDR (0xff << 0) > + > +#define OSD_TRANSPVAL_RGBTRANS (0xffff << 0) > + > +#define OSD_TRANSPVALL_RGBL (0xffff << 0) > + > +#define OSD_TRANSPVALU_Y_SHIFT 8 > +#define OSD_TRANSPVALU_Y (0xff << 8) > +#define OSD_TRANSPVALU_RGBU_SHIFT 0 > +#define OSD_TRANSPVALU_RGBU (0xff << 0) > + > +#define OSD_TRANSPBMPIDX_BMP1_SHIFT 8 > +#define OSD_TRANSPBMPIDX_BMP1 (0xff << 8) > +#define OSD_TRANSPBMPIDX_BMP0_SHIFT 0 > +#define OSD_TRANSPBMPIDX_BMP0 0xff > + > +#endif /* _DAVINCI_VPBE_H_ */ > diff --git a/include/media/davinci/vpbe_osd.h b/include/media/davinci/vpbe_osd.h > new file mode 100644 > index 0000000..9549f3e > --- /dev/null > +++ b/include/media/davinci/vpbe_osd.h > @@ -0,0 +1,397 @@ > +/* > + * Copyright (C) 2007-2009 Texas Instruments Inc > + * Copyright (C) 2007 MontaVista Software, Inc. > + * > + * Andy Lowe (alowe@xxxxxxxxxx), MontaVista Software > + * - Initial version > + * Murali Karicheri (mkaricheri@xxxxxxxxx), Texas Instruments Ltd. > + * - ported to sub device interface > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > + * > + */ > +#ifndef _OSD_H > +#define _OSD_H > + > +#define VPBE_OSD_SUBDEV_NAME "vpbe-osd" > + > +/** > + * enum osd_layer > + * @WIN_OSD0: On-Screen Display Window 0 > + * @WIN_VID0: Video Window 0 > + * @WIN_OSD1: On-Screen Display Window 1 > + * @WIN_VID1: Video Window 1 > + * > + * Description: > + * An enumeration of the osd display layers. > + */ > +enum osd_layer { > + WIN_OSD0, > + WIN_VID0, > + WIN_OSD1, > + WIN_VID1, > +}; > + > +/** > + * enum osd_win_layer > + * @OSDWIN_OSD0: On-Screen Display Window 0 > + * @OSDWIN_OSD1: On-Screen Display Window 1 > + * > + * Description: > + * An enumeration of the OSD Window layers. > + */ > +enum osd_win_layer { > + OSDWIN_OSD0, > + OSDWIN_OSD1, > +}; > + > +/** > + * enum osd_pix_format > + * @PIXFMT_1BPP: 1-bit-per-pixel bitmap > + * @PIXFMT_2BPP: 2-bits-per-pixel bitmap > + * @PIXFMT_4BPP: 4-bits-per-pixel bitmap > + * @PIXFMT_8BPP: 8-bits-per-pixel bitmap > + * @PIXFMT_RGB565: 16-bits-per-pixel RGB565 > + * @PIXFMT_YCbCrI: YUV 4:2:2 > + * @PIXFMT_RGB888: 24-bits-per-pixel RGB888 > + * @PIXFMT_YCrCbI: YUV 4:2:2 with chroma swap > + * @PIXFMT_NV12: YUV 4:2:0 planar > + * @PIXFMT_OSD_ATTR: OSD Attribute Window pixel format (4bpp) > + * > + * Description: > + * An enumeration of the DaVinci pixel formats. > + */ > +enum osd_pix_format { > + PIXFMT_1BPP = 0, > + PIXFMT_2BPP, > + PIXFMT_4BPP, > + PIXFMT_8BPP, > + PIXFMT_RGB565, > + PIXFMT_YCbCrI, > + PIXFMT_RGB888, > + PIXFMT_YCrCbI, > + PIXFMT_NV12, > + PIXFMT_OSD_ATTR, > +}; > + > +/** > + * enum osd_h_exp_ratio > + * @H_EXP_OFF: no expansion (1/1) > + * @H_EXP_9_OVER_8: 9/8 expansion ratio > + * @H_EXP_3_OVER_2: 3/2 expansion ratio > + * > + * Description: > + * An enumeration of the available horizontal expansion ratios. > + */ > +enum osd_h_exp_ratio { > + H_EXP_OFF, > + H_EXP_9_OVER_8, > + H_EXP_3_OVER_2, > +}; > + > +/** > + * enum osd_v_exp_ratio > + * @V_EXP_OFF: no expansion (1/1) > + * @V_EXP_6_OVER_5: 6/5 expansion ratio > + * > + * Description: > + * An enumeration of the available vertical expansion ratios. > + */ > +enum osd_v_exp_ratio { > + V_EXP_OFF, > + V_EXP_6_OVER_5, > +}; > + > +/** > + * enum osd_zoom_factor > + * @ZOOM_X1: no zoom (x1) > + * @ZOOM_X2: x2 zoom > + * @ZOOM_X4: x4 zoom > + * > + * Description: > + * An enumeration of the available zoom factors. > + */ > +enum osd_zoom_factor { > + ZOOM_X1, > + ZOOM_X2, > + ZOOM_X4, > +}; > + > +/** > + * enum osd_clut > + * @ROM_CLUT: ROM CLUT > + * @RAM_CLUT: RAM CLUT > + * > + * Description: > + * An enumeration of the available Color Lookup Tables (CLUTs). > + */ > +enum osd_clut { > + ROM_CLUT, > + RAM_CLUT, > +}; > + > +/** > + * enum osd_rom_clut > + * @ROM_CLUT0: Macintosh CLUT > + * @ROM_CLUT1: CLUT from DM270 and prior devices > + * > + * Description: > + * An enumeration of the ROM Color Lookup Table (CLUT) options. > + */ > +enum osd_rom_clut { > + ROM_CLUT0, > + ROM_CLUT1, > +}; > + > +/** > + * enum osd_blending_factor > + * @OSD_0_VID_8: OSD pixels are fully transparent > + * @OSD_1_VID_7: OSD pixels contribute 1/8, video pixels contribute 7/8 > + * @OSD_2_VID_6: OSD pixels contribute 2/8, video pixels contribute 6/8 > + * @OSD_3_VID_5: OSD pixels contribute 3/8, video pixels contribute 5/8 > + * @OSD_4_VID_4: OSD pixels contribute 4/8, video pixels contribute 4/8 > + * @OSD_5_VID_3: OSD pixels contribute 5/8, video pixels contribute 3/8 > + * @OSD_6_VID_2: OSD pixels contribute 6/8, video pixels contribute 2/8 > + * @OSD_8_VID_0: OSD pixels are fully opaque > + * > + * Description: > + * An enumeration of the DaVinci pixel blending factor options. > + */ > +enum osd_blending_factor { > + OSD_0_VID_8, > + OSD_1_VID_7, > + OSD_2_VID_6, > + OSD_3_VID_5, > + OSD_4_VID_4, > + OSD_5_VID_3, > + OSD_6_VID_2, > + OSD_8_VID_0, > +}; > + > +/** > + * enum osd_blink_interval > + * @BLINK_X1: blink interval is 1 vertical refresh cycle > + * @BLINK_X2: blink interval is 2 vertical refresh cycles > + * @BLINK_X3: blink interval is 3 vertical refresh cycles > + * @BLINK_X4: blink interval is 4 vertical refresh cycles > + * > + * Description: > + * An enumeration of the DaVinci pixel blinking interval options. > + */ > +enum osd_blink_interval { > + BLINK_X1, > + BLINK_X2, > + BLINK_X3, > + BLINK_X4, > +}; > + > +/** > + * enum osd_cursor_h_width > + * @H_WIDTH_1: horizontal line width is 1 pixel > + * @H_WIDTH_4: horizontal line width is 4 pixels > + * @H_WIDTH_8: horizontal line width is 8 pixels > + * @H_WIDTH_12: horizontal line width is 12 pixels > + * @H_WIDTH_16: horizontal line width is 16 pixels > + * @H_WIDTH_20: horizontal line width is 20 pixels > + * @H_WIDTH_24: horizontal line width is 24 pixels > + * @H_WIDTH_28: horizontal line width is 28 pixels > + */ > +enum osd_cursor_h_width { > + H_WIDTH_1, > + H_WIDTH_4, > + H_WIDTH_8, > + H_WIDTH_12, > + H_WIDTH_16, > + H_WIDTH_20, > + H_WIDTH_24, > + H_WIDTH_28, > +}; > + > +/** > + * enum davinci_cursor_v_width > + * @V_WIDTH_1: vertical line width is 1 line > + * @V_WIDTH_2: vertical line width is 2 lines > + * @V_WIDTH_4: vertical line width is 4 lines > + * @V_WIDTH_6: vertical line width is 6 lines > + * @V_WIDTH_8: vertical line width is 8 lines > + * @V_WIDTH_10: vertical line width is 10 lines > + * @V_WIDTH_12: vertical line width is 12 lines > + * @V_WIDTH_14: vertical line width is 14 lines > + */ > +enum osd_cursor_v_width { > + V_WIDTH_1, > + V_WIDTH_2, > + V_WIDTH_4, > + V_WIDTH_6, > + V_WIDTH_8, > + V_WIDTH_10, > + V_WIDTH_12, > + V_WIDTH_14, > +}; > + > +/** > + * struct osd_cursor_config > + * @xsize: horizontal size in pixels > + * @ysize: vertical size in lines > + * @xpos: horizontal offset in pixels from the left edge of the display > + * @ypos: vertical offset in lines from the top of the display > + * @interlaced: Non-zero if the display is interlaced, or zero otherwise > + * @h_width: horizontal line width > + * @v_width: vertical line width > + * @clut: the CLUT selector (ROM or RAM) for the cursor color > + * @clut_index: an index into the CLUT for the cursor color > + * > + * Description: > + * A structure describing the configuration parameters of the hardware > + * rectangular cursor. > + */ > +struct osd_cursor_config { > + unsigned xsize; > + unsigned ysize; > + unsigned xpos; > + unsigned ypos; > + int interlaced; > + enum osd_cursor_h_width h_width; > + enum osd_cursor_v_width v_width; > + enum osd_clut clut; > + unsigned char clut_index; > +}; > + > +/** > + * struct osd_layer_config > + * @pixfmt: pixel format > + * @line_length: offset in bytes between start of each line in memory > + * @xsize: number of horizontal pixels displayed per line > + * @ysize: number of lines displayed > + * @xpos: horizontal offset in pixels from the left edge of the display > + * @ypos: vertical offset in lines from the top of the display > + * @interlaced: Non-zero if the display is interlaced, or zero otherwise > + * > + * Description: > + * A structure describing the configuration parameters of an On-Screen Display > + * (OSD) or video layer related to how the image is stored in memory. > + * @line_length must be a multiple of the cache line size (32 bytes). > + */ > +struct osd_layer_config { > + enum osd_pix_format pixfmt; > + unsigned line_length; > + unsigned xsize; > + unsigned ysize; > + unsigned xpos; > + unsigned ypos; > + int interlaced; > +}; > +/* OSD events. Should match with that in vpbe_venc.h */ > +#define OSD_END_OF_FRAME 1 > +#define OSD_FIRST_FIELD 2 > +#define OSD_SECOND_FIELD 4 > + > +/* parameters that apply on a per-window (OSD or video) basis */ > +struct osd_window_state { > + int is_allocated; > + int is_enabled; > + unsigned long fb_base_phys; > + enum osd_zoom_factor h_zoom; > + enum osd_zoom_factor v_zoom; > + struct osd_layer_config lconfig; > +}; > + > +/* parameters that apply on a per-OSD-window basis */ > +struct osd_osdwin_state { > + enum osd_clut clut; > + enum osd_blending_factor blend; > + int colorkey_blending; > + unsigned colorkey; > + int rec601_attenuation; > + /* index is pixel value */ > + unsigned char palette_map[16]; > +}; > + > +/* hardware rectangular cursor parameters */ > +struct osd_cursor_state { > + int is_enabled; > + struct osd_cursor_config config; > +}; > + > +struct osd_state; > + > +/* TBD. Some of these operations here are to be removed and implemented > + * as a ioctl call on the osd sub device node. Right now just trying to > + * make this work. > + */ > +struct vpbe_osd_ops { > + int (*initialize)(struct osd_state *sd); > + int (*request_layer)(struct osd_state *sd, enum osd_layer layer); > + void (*release_layer)(struct osd_state *sd, enum osd_layer layer); > + int (*enable_layer)(struct osd_state *sd, enum osd_layer layer, > + int otherwin); > + void (*disable_layer)(struct osd_state *sd, enum osd_layer layer); > + int (*set_layer_config)(struct osd_state *sd, enum osd_layer layer, > + struct osd_layer_config *lconfig); > + void (*get_layer_config)(struct osd_state *sd, enum osd_layer layer, > + struct osd_layer_config *lconfig); > + void (*start_layer)(struct osd_state *sd, enum osd_layer layer, > + unsigned long fb_base_phys, > + unsigned long cbcr_ofst); > + void (*set_left_margin)(struct osd_state *sd, u32 val); > + void (*set_top_margin)(struct osd_state *sd, u32 val); > + void (*set_interpolation_filter)(struct osd_state *sd, int filter); > + int (*set_vid_expansion)(struct osd_state *sd, > + enum osd_h_exp_ratio h_exp, > + enum osd_v_exp_ratio v_exp); > + void (*get_vid_expansion)(struct osd_state *sd, > + enum osd_h_exp_ratio *h_exp, > + enum osd_v_exp_ratio *v_exp); > + void (*set_zoom)(struct osd_state *sd, enum osd_layer layer, > + enum osd_zoom_factor h_zoom, > + enum osd_zoom_factor v_zoom); > +}; > + > +struct osd_state { > + enum vpbe_types vpbe_type; > + spinlock_t lock; > + struct device *dev; > + dma_addr_t osd_base_phys; > + unsigned long osd_base; > + unsigned long osd_size; > + /* 1-->the isr will toggle the VID0 ping-pong buffer */ > + int pingpong; > + int interpolation_filter; > + int field_inversion; > + enum osd_h_exp_ratio osd_h_exp; > + enum osd_v_exp_ratio osd_v_exp; > + enum osd_h_exp_ratio vid_h_exp; > + enum osd_v_exp_ratio vid_v_exp; > + enum osd_clut backg_clut; > + unsigned backg_clut_index; > + enum osd_rom_clut rom_clut; > + int is_blinking; > + /* attribute window blinking enabled */ > + enum osd_blink_interval blink; > + /* YCbCrI or YCrCbI */ > + enum osd_pix_format yc_pixfmt; > + /* columns are Y, Cb, Cr */ > + unsigned char clut_ram[256][3]; > + struct osd_cursor_state cursor; > + /* OSD0, VID0, OSD1, VID1 */ > + struct osd_window_state win[4]; > + /* OSD0, OSD1 */ > + struct osd_osdwin_state osdwin[2]; > + /* OSD device Operations */ > + struct vpbe_osd_ops ops; > +}; > + > + > +#endif > -- > 1.6.2.4 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-media" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html > -- Murali Karicheri mkaricheri@xxxxxxxxx -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html