/*
* Copyright (C) 2007-2010 Texas Instruments Inc
* Copyright (C) 2007 MontaVista Software, Inc.
*
* Andy Lowe (alowe@mvista.com), MontaVista Software
* - Initial version
* Murali Karicheri (mkaricheri@gmail.com), 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 version 2.
*
* 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 readl(osd->osd_base + offset);
}
static inline u32 osd_write(struct osd_state *sd, u32 val, u32 offset)
{
struct osd_state *osd = sd;
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 = readl(addr) | mask;
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 = readl(addr) & ~mask;
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 = (readl(addr) & ~mask) | (val & mask);
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 modifi