media: davinci: remove vpbe support
The davinci dm3xx/dm644x platforms are gone now, and the remaining da8xx platforms do not use the vpbe driver, so the driver can be removed as well. Acked-by: Lad Prabhakar <prabhakar.csengg@gmail.com> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
Родитель
582603a957
Коммит
eeee697393
|
@ -1,65 +0,0 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
The VPBE V4L2 driver design
|
||||
===========================
|
||||
|
||||
Functional partitioning
|
||||
-----------------------
|
||||
|
||||
Consists of the following:
|
||||
|
||||
1. V4L2 display driver
|
||||
|
||||
Implements creation of video2 and video3 device nodes and
|
||||
provides v4l2 device interface to manage VID0 and VID1 layers.
|
||||
|
||||
2. Display controller
|
||||
|
||||
Loads up VENC, OSD and external encoders such as ths8200. It provides
|
||||
a set of API calls to V4L2 drivers to set the output/standards
|
||||
in the VENC or external sub devices. It also provides
|
||||
a device object to access the services from OSD subdevice
|
||||
using sub device ops. The connection of external encoders to VENC LCD
|
||||
controller port is done at init time based on default output and standard
|
||||
selection or at run time when application change the output through
|
||||
V4L2 IOCTLs.
|
||||
|
||||
When connected to an external encoder, vpbe controller is also responsible
|
||||
for setting up the interface between VENC and external encoders based on
|
||||
board specific settings (specified in board-xxx-evm.c). This allows
|
||||
interfacing external encoders such as ths8200. The setup_if_config()
|
||||
is implemented for this as well as configure_venc() (part of the next patch)
|
||||
API to set timings in VENC for a specific display resolution. As of this
|
||||
patch series, the interconnection and enabling and setting of the external
|
||||
encoders is not present, and would be a part of the next patch series.
|
||||
|
||||
3. VENC subdevice module
|
||||
|
||||
Responsible for setting outputs provided through internal DACs and also
|
||||
setting timings at LCD controller port when external encoders are connected
|
||||
at the port or LCD panel timings required. When external encoder/LCD panel
|
||||
is connected, the timings for a specific standard/preset is retrieved from
|
||||
the board specific table and the values are used to set the timings in
|
||||
venc using non-standard timing mode.
|
||||
|
||||
Support LCD Panel displays using the VENC. For example to support a Logic
|
||||
PD display, it requires setting up the LCD controller port with a set of
|
||||
timings for the resolution supported and setting the dot clock. So we could
|
||||
add the available outputs as a board specific entry (i.e add the "LogicPD"
|
||||
output name to board-xxx-evm.c). A table of timings for various LCDs
|
||||
supported can be maintained in the board specific setup file to support
|
||||
various LCD displays.As of this patch a basic driver is present, and this
|
||||
support for external encoders and displays forms a part of the next
|
||||
patch series.
|
||||
|
||||
4. OSD module
|
||||
|
||||
OSD module implements all OSD layer management and hardware specific
|
||||
features. The VPBE module interacts with the OSD for enabling and
|
||||
disabling appropriate features of the OSD.
|
||||
|
||||
Current status
|
||||
--------------
|
||||
|
||||
A fully functional working version of the V4L2 driver is available. This
|
||||
driver has been tested with NTSC and PAL standards and buffer streaming.
|
|
@ -73,7 +73,6 @@ via-camera VIAFB camera controller
|
|||
video-mux Video Multiplexer
|
||||
vpif_display TI DaVinci VPIF V4L2-Display
|
||||
vpif_capture TI DaVinci VPIF video capture
|
||||
vpss TI DaVinci VPBE V4L2-Display
|
||||
vsp1 Renesas VSP1 Video Processing Engine
|
||||
xilinx-tpg Xilinx Video Test Pattern Generator
|
||||
xilinx-video Xilinx Video IP (EXPERIMENTAL)
|
||||
|
|
|
@ -13,7 +13,6 @@ Video4Linux (V4L) driver-specific documentation
|
|||
cafe_ccic
|
||||
cpia2
|
||||
cx88
|
||||
davinci-vpbe
|
||||
fimc
|
||||
imx
|
||||
imx7
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
The VPBE V4L2 driver design
|
||||
===========================
|
||||
|
||||
File partitioning
|
||||
-----------------
|
||||
|
||||
V4L2 display device driver
|
||||
drivers/media/platform/ti/davinci/vpbe_display.c
|
||||
drivers/media/platform/ti/davinci/vpbe_display.h
|
||||
|
||||
VPBE display controller
|
||||
drivers/media/platform/ti/davinci/vpbe.c
|
||||
drivers/media/platform/ti/davinci/vpbe.h
|
||||
|
||||
VPBE venc sub device driver
|
||||
drivers/media/platform/ti/davinci/vpbe_venc.c
|
||||
drivers/media/platform/ti/davinci/vpbe_venc.h
|
||||
drivers/media/platform/ti/davinci/vpbe_venc_regs.h
|
||||
|
||||
VPBE osd driver
|
||||
drivers/media/platform/ti/davinci/vpbe_osd.c
|
||||
drivers/media/platform/ti/davinci/vpbe_osd.h
|
||||
drivers/media/platform/ti/davinci/vpbe_osd_regs.h
|
||||
|
||||
To be done
|
||||
----------
|
||||
|
||||
vpbe display controller
|
||||
- Add support for external encoders.
|
||||
- add support for selecting external encoder as default at probe time.
|
||||
|
||||
vpbe venc sub device
|
||||
- add timings for supporting ths8200
|
||||
- add support for LogicPD LCD.
|
||||
|
||||
FB drivers
|
||||
- Add support for fbdev drivers.- Ready and part of subsequent patches.
|
|
@ -16,7 +16,6 @@ Video4Linux (V4L) drivers
|
|||
cpia2_devel
|
||||
cx2341x-devel
|
||||
cx88-devel
|
||||
davinci-vpbe-devel
|
||||
fimc-devel
|
||||
pvrusb2
|
||||
pxa_camera
|
||||
|
|
|
@ -31,19 +31,3 @@ config VIDEO_DAVINCI_VPIF_CAPTURE
|
|||
|
||||
To compile this driver as a module, choose M here. There will
|
||||
be two modules called vpif.ko and vpif_capture.ko
|
||||
|
||||
config VIDEO_DAVINCI_VPBE_DISPLAY
|
||||
tristate "TI DaVinci VPBE V4L2-Display driver"
|
||||
depends on V4L_PLATFORM_DRIVERS
|
||||
depends on VIDEO_DEV
|
||||
depends on ARCH_DAVINCI || COMPILE_TEST
|
||||
depends on I2C
|
||||
select VIDEOBUF2_DMA_CONTIG
|
||||
help
|
||||
Enables Davinci VPBE module used for display devices.
|
||||
This module is used for display on TI DM644x/DM365/DM355
|
||||
based display devices.
|
||||
|
||||
To compile this driver as a module, choose M here. There will
|
||||
be five modules created called vpss.ko, vpbe.ko, vpbe_osd.ko,
|
||||
vpbe_venc.ko and vpbe_display.ko
|
||||
|
|
|
@ -7,6 +7,3 @@
|
|||
obj-$(CONFIG_VIDEO_DAVINCI_VPIF_DISPLAY) += vpif.o vpif_display.o
|
||||
#VPIF Capture driver
|
||||
obj-$(CONFIG_VIDEO_DAVINCI_VPIF_CAPTURE) += vpif.o vpif_capture.o
|
||||
|
||||
obj-$(CONFIG_VIDEO_DAVINCI_VPBE_DISPLAY) += vpss.o vpbe.o vpbe_osd.o \
|
||||
vpbe_venc.o vpbe_display.o
|
||||
|
|
|
@ -1,840 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2010 Texas Instruments Inc
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/davinci/vpbe_types.h>
|
||||
#include <media/davinci/vpbe.h>
|
||||
#include <media/davinci/vpss.h>
|
||||
#include <media/davinci/vpbe_venc.h>
|
||||
|
||||
#define VPBE_DEFAULT_OUTPUT "Composite"
|
||||
#define VPBE_DEFAULT_MODE "ntsc"
|
||||
|
||||
static char *def_output = VPBE_DEFAULT_OUTPUT;
|
||||
static char *def_mode = VPBE_DEFAULT_MODE;
|
||||
static int debug;
|
||||
|
||||
module_param(def_output, charp, S_IRUGO);
|
||||
module_param(def_mode, charp, S_IRUGO);
|
||||
module_param(debug, int, 0644);
|
||||
|
||||
MODULE_PARM_DESC(def_output, "vpbe output name (default:Composite)");
|
||||
MODULE_PARM_DESC(def_mode, "vpbe output mode name (default:ntsc");
|
||||
MODULE_PARM_DESC(debug, "Debug level 0-1");
|
||||
|
||||
MODULE_DESCRIPTION("TI DMXXX VPBE Display controller");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Texas Instruments");
|
||||
|
||||
/**
|
||||
* vpbe_current_encoder_info - Get config info for current encoder
|
||||
* @vpbe_dev: vpbe device ptr
|
||||
*
|
||||
* Return ptr to current encoder config info
|
||||
*/
|
||||
static struct encoder_config_info*
|
||||
vpbe_current_encoder_info(struct vpbe_device *vpbe_dev)
|
||||
{
|
||||
struct vpbe_config *cfg = vpbe_dev->cfg;
|
||||
int index = vpbe_dev->current_sd_index;
|
||||
|
||||
return ((index == 0) ? &cfg->venc :
|
||||
&cfg->ext_encoders[index-1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* vpbe_find_encoder_sd_index - Given a name find encoder sd index
|
||||
*
|
||||
* @cfg: ptr to vpbe cfg
|
||||
* @index: index used by application
|
||||
*
|
||||
* Return sd index of the encoder
|
||||
*/
|
||||
static int vpbe_find_encoder_sd_index(struct vpbe_config *cfg,
|
||||
int index)
|
||||
{
|
||||
char *encoder_name = cfg->outputs[index].subdev_name;
|
||||
int i;
|
||||
|
||||
/* Venc is always first */
|
||||
if (!strcmp(encoder_name, cfg->venc.module_name))
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < cfg->num_ext_encoders; i++) {
|
||||
if (!strcmp(encoder_name,
|
||||
cfg->ext_encoders[i].module_name))
|
||||
return i+1;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* vpbe_enum_outputs - enumerate outputs
|
||||
* @vpbe_dev: vpbe device ptr
|
||||
* @output: ptr to v4l2_output structure
|
||||
*
|
||||
* Enumerates the outputs available at the vpbe display
|
||||
* returns the status, -EINVAL if end of output list
|
||||
*/
|
||||
static int vpbe_enum_outputs(struct vpbe_device *vpbe_dev,
|
||||
struct v4l2_output *output)
|
||||
{
|
||||
struct vpbe_config *cfg = vpbe_dev->cfg;
|
||||
unsigned int temp_index = output->index;
|
||||
|
||||
if (temp_index >= cfg->num_outputs)
|
||||
return -EINVAL;
|
||||
|
||||
*output = cfg->outputs[temp_index].output;
|
||||
output->index = temp_index;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vpbe_get_mode_info(struct vpbe_device *vpbe_dev, char *mode,
|
||||
int output_index)
|
||||
{
|
||||
struct vpbe_config *cfg = vpbe_dev->cfg;
|
||||
struct vpbe_enc_mode_info var;
|
||||
int curr_output = output_index;
|
||||
int i;
|
||||
|
||||
if (!mode)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < cfg->outputs[curr_output].num_modes; i++) {
|
||||
var = cfg->outputs[curr_output].modes[i];
|
||||
if (!strcmp(mode, var.name)) {
|
||||
vpbe_dev->current_timings = var;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int vpbe_get_current_mode_info(struct vpbe_device *vpbe_dev,
|
||||
struct vpbe_enc_mode_info *mode_info)
|
||||
{
|
||||
if (!mode_info)
|
||||
return -EINVAL;
|
||||
|
||||
*mode_info = vpbe_dev->current_timings;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get std by std id */
|
||||
static int vpbe_get_std_info(struct vpbe_device *vpbe_dev,
|
||||
v4l2_std_id std_id)
|
||||
{
|
||||
struct vpbe_config *cfg = vpbe_dev->cfg;
|
||||
struct vpbe_enc_mode_info var;
|
||||
int curr_output = vpbe_dev->current_out_index;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < vpbe_dev->cfg->outputs[curr_output].num_modes; i++) {
|
||||
var = cfg->outputs[curr_output].modes[i];
|
||||
if ((var.timings_type & VPBE_ENC_STD) &&
|
||||
(var.std_id & std_id)) {
|
||||
vpbe_dev->current_timings = var;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int vpbe_get_std_info_by_name(struct vpbe_device *vpbe_dev,
|
||||
char *std_name)
|
||||
{
|
||||
struct vpbe_config *cfg = vpbe_dev->cfg;
|
||||
struct vpbe_enc_mode_info var;
|
||||
int curr_output = vpbe_dev->current_out_index;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < vpbe_dev->cfg->outputs[curr_output].num_modes; i++) {
|
||||
var = cfg->outputs[curr_output].modes[i];
|
||||
if (!strcmp(var.name, std_name)) {
|
||||
vpbe_dev->current_timings = var;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* vpbe_set_output - Set output
|
||||
* @vpbe_dev: vpbe device ptr
|
||||
* @index: index of output
|
||||
*
|
||||
* Set vpbe output to the output specified by the index
|
||||
*/
|
||||
static int vpbe_set_output(struct vpbe_device *vpbe_dev, int index)
|
||||
{
|
||||
struct encoder_config_info *curr_enc_info =
|
||||
vpbe_current_encoder_info(vpbe_dev);
|
||||
struct vpbe_config *cfg = vpbe_dev->cfg;
|
||||
struct venc_platform_data *venc_device = vpbe_dev->venc_device;
|
||||
int enc_out_index;
|
||||
int sd_index;
|
||||
int ret;
|
||||
|
||||
if (index >= cfg->num_outputs)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&vpbe_dev->lock);
|
||||
|
||||
sd_index = vpbe_dev->current_sd_index;
|
||||
enc_out_index = cfg->outputs[index].output.index;
|
||||
/*
|
||||
* Currently we switch the encoder based on output selected
|
||||
* by the application. If media controller is implemented later
|
||||
* there is will be an API added to setup_link between venc
|
||||
* and external encoder. So in that case below comparison always
|
||||
* match and encoder will not be switched. But if application
|
||||
* chose not to use media controller, then this provides current
|
||||
* way of switching encoder at the venc output.
|
||||
*/
|
||||
if (strcmp(curr_enc_info->module_name,
|
||||
cfg->outputs[index].subdev_name)) {
|
||||
/* Need to switch the encoder at the output */
|
||||
sd_index = vpbe_find_encoder_sd_index(cfg, index);
|
||||
if (sd_index < 0) {
|
||||
ret = -EINVAL;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
ret = venc_device->setup_if_config(cfg->outputs[index].if_params);
|
||||
if (ret)
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
/* Set output at the encoder */
|
||||
ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video,
|
||||
s_routing, 0, enc_out_index, 0);
|
||||
if (ret)
|
||||
goto unlock;
|
||||
|
||||
/*
|
||||
* It is assumed that venc or external encoder will set a default
|
||||
* mode in the sub device. For external encoder or LCD pannel output,
|
||||
* we also need to set up the lcd port for the required mode. So setup
|
||||
* the lcd port for the default mode that is configured in the board
|
||||
* arch/arm/mach-davinci/board-dm355-evm.setup file for the external
|
||||
* encoder.
|
||||
*/
|
||||
ret = vpbe_get_mode_info(vpbe_dev,
|
||||
cfg->outputs[index].default_mode, index);
|
||||
if (!ret) {
|
||||
struct osd_state *osd_device = vpbe_dev->osd_device;
|
||||
|
||||
osd_device->ops.set_left_margin(osd_device,
|
||||
vpbe_dev->current_timings.left_margin);
|
||||
osd_device->ops.set_top_margin(osd_device,
|
||||
vpbe_dev->current_timings.upper_margin);
|
||||
vpbe_dev->current_sd_index = sd_index;
|
||||
vpbe_dev->current_out_index = index;
|
||||
}
|
||||
unlock:
|
||||
mutex_unlock(&vpbe_dev->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int vpbe_set_default_output(struct vpbe_device *vpbe_dev)
|
||||
{
|
||||
struct vpbe_config *cfg = vpbe_dev->cfg;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < cfg->num_outputs; i++) {
|
||||
if (!strcmp(def_output,
|
||||
cfg->outputs[i].output.name)) {
|
||||
int ret = vpbe_set_output(vpbe_dev, i);
|
||||
|
||||
if (!ret)
|
||||
vpbe_dev->current_out_index = i;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* vpbe_get_output - Get output
|
||||
* @vpbe_dev: vpbe device ptr
|
||||
*
|
||||
* return current vpbe output to the index
|
||||
*/
|
||||
static unsigned int vpbe_get_output(struct vpbe_device *vpbe_dev)
|
||||
{
|
||||
return vpbe_dev->current_out_index;
|
||||
}
|
||||
|
||||
/*
|
||||
* vpbe_s_dv_timings - Set the given preset timings in the encoder
|
||||
*
|
||||
* Sets the timings if supported by the current encoder. Return the status.
|
||||
* 0 - success & -EINVAL on error
|
||||
*/
|
||||
static int vpbe_s_dv_timings(struct vpbe_device *vpbe_dev,
|
||||
struct v4l2_dv_timings *dv_timings)
|
||||
{
|
||||
struct vpbe_config *cfg = vpbe_dev->cfg;
|
||||
int out_index = vpbe_dev->current_out_index;
|
||||
struct vpbe_output *output = &cfg->outputs[out_index];
|
||||
int sd_index = vpbe_dev->current_sd_index;
|
||||
int ret, i;
|
||||
|
||||
|
||||
if (!(cfg->outputs[out_index].output.capabilities &
|
||||
V4L2_OUT_CAP_DV_TIMINGS))
|
||||
return -ENODATA;
|
||||
|
||||
for (i = 0; i < output->num_modes; i++) {
|
||||
if (output->modes[i].timings_type == VPBE_ENC_DV_TIMINGS &&
|
||||
!memcmp(&output->modes[i].dv_timings,
|
||||
dv_timings, sizeof(*dv_timings)))
|
||||
break;
|
||||
}
|
||||
if (i >= output->num_modes)
|
||||
return -EINVAL;
|
||||
vpbe_dev->current_timings = output->modes[i];
|
||||
mutex_lock(&vpbe_dev->lock);
|
||||
|
||||
ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video,
|
||||
s_dv_timings, dv_timings);
|
||||
if (!ret && vpbe_dev->amp) {
|
||||
/* Call amplifier subdevice */
|
||||
ret = v4l2_subdev_call(vpbe_dev->amp, video,
|
||||
s_dv_timings, dv_timings);
|
||||
}
|
||||
/* set the lcd controller output for the given mode */
|
||||
if (!ret) {
|
||||
struct osd_state *osd_device = vpbe_dev->osd_device;
|
||||
|
||||
osd_device->ops.set_left_margin(osd_device,
|
||||
vpbe_dev->current_timings.left_margin);
|
||||
osd_device->ops.set_top_margin(osd_device,
|
||||
vpbe_dev->current_timings.upper_margin);
|
||||
}
|
||||
mutex_unlock(&vpbe_dev->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* vpbe_g_dv_timings - Get the timings in the current encoder
|
||||
*
|
||||
* Get the timings in the current encoder. Return the status. 0 - success
|
||||
* -EINVAL on error
|
||||
*/
|
||||
static int vpbe_g_dv_timings(struct vpbe_device *vpbe_dev,
|
||||
struct v4l2_dv_timings *dv_timings)
|
||||
{
|
||||
struct vpbe_config *cfg = vpbe_dev->cfg;
|
||||
int out_index = vpbe_dev->current_out_index;
|
||||
|
||||
if (!(cfg->outputs[out_index].output.capabilities &
|
||||
V4L2_OUT_CAP_DV_TIMINGS))
|
||||
return -ENODATA;
|
||||
|
||||
if (vpbe_dev->current_timings.timings_type &
|
||||
VPBE_ENC_DV_TIMINGS) {
|
||||
*dv_timings = vpbe_dev->current_timings.dv_timings;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* vpbe_enum_dv_timings - Enumerate the dv timings in the current encoder
|
||||
*
|
||||
* Get the timings in the current encoder. Return the status. 0 - success
|
||||
* -EINVAL on error
|
||||
*/
|
||||
static int vpbe_enum_dv_timings(struct vpbe_device *vpbe_dev,
|
||||
struct v4l2_enum_dv_timings *timings)
|
||||
{
|
||||
struct vpbe_config *cfg = vpbe_dev->cfg;
|
||||
int out_index = vpbe_dev->current_out_index;
|
||||
struct vpbe_output *output = &cfg->outputs[out_index];
|
||||
int j = 0;
|
||||
int i;
|
||||
|
||||
if (!(output->output.capabilities & V4L2_OUT_CAP_DV_TIMINGS))
|
||||
return -ENODATA;
|
||||
|
||||
for (i = 0; i < output->num_modes; i++) {
|
||||
if (output->modes[i].timings_type == VPBE_ENC_DV_TIMINGS) {
|
||||
if (j == timings->index)
|
||||
break;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == output->num_modes)
|
||||
return -EINVAL;
|
||||
timings->timings = output->modes[i].dv_timings;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* vpbe_s_std - Set the given standard in the encoder
|
||||
*
|
||||
* Sets the standard if supported by the current encoder. Return the status.
|
||||
* 0 - success & -EINVAL on error
|
||||
*/
|
||||
static int vpbe_s_std(struct vpbe_device *vpbe_dev, v4l2_std_id std_id)
|
||||
{
|
||||
struct vpbe_config *cfg = vpbe_dev->cfg;
|
||||
int out_index = vpbe_dev->current_out_index;
|
||||
int sd_index = vpbe_dev->current_sd_index;
|
||||
int ret;
|
||||
|
||||
if (!(cfg->outputs[out_index].output.capabilities &
|
||||
V4L2_OUT_CAP_STD))
|
||||
return -ENODATA;
|
||||
|
||||
ret = vpbe_get_std_info(vpbe_dev, std_id);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mutex_lock(&vpbe_dev->lock);
|
||||
|
||||
ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video,
|
||||
s_std_output, std_id);
|
||||
/* set the lcd controller output for the given mode */
|
||||
if (!ret) {
|
||||
struct osd_state *osd_device = vpbe_dev->osd_device;
|
||||
|
||||
osd_device->ops.set_left_margin(osd_device,
|
||||
vpbe_dev->current_timings.left_margin);
|
||||
osd_device->ops.set_top_margin(osd_device,
|
||||
vpbe_dev->current_timings.upper_margin);
|
||||
}
|
||||
mutex_unlock(&vpbe_dev->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* vpbe_g_std - Get the standard in the current encoder
|
||||
*
|
||||
* Get the standard in the current encoder. Return the status. 0 - success
|
||||
* -EINVAL on error
|
||||
*/
|
||||
static int vpbe_g_std(struct vpbe_device *vpbe_dev, v4l2_std_id *std_id)
|
||||
{
|
||||
struct vpbe_enc_mode_info *cur_timings = &vpbe_dev->current_timings;
|
||||
struct vpbe_config *cfg = vpbe_dev->cfg;
|
||||
int out_index = vpbe_dev->current_out_index;
|
||||
|
||||
if (!(cfg->outputs[out_index].output.capabilities & V4L2_OUT_CAP_STD))
|
||||
return -ENODATA;
|
||||
|
||||
if (cur_timings->timings_type & VPBE_ENC_STD) {
|
||||
*std_id = cur_timings->std_id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* vpbe_set_mode - Set mode in the current encoder using mode info
|
||||
*
|
||||
* Use the mode string to decide what timings to set in the encoder
|
||||
* This is typically useful when fbset command is used to change the current
|
||||
* timings by specifying a string to indicate the timings.
|
||||
*/
|
||||
static int vpbe_set_mode(struct vpbe_device *vpbe_dev,
|
||||
struct vpbe_enc_mode_info *mode_info)
|
||||
{
|
||||
struct vpbe_enc_mode_info *preset_mode = NULL;
|
||||
struct vpbe_config *cfg = vpbe_dev->cfg;
|
||||
struct v4l2_dv_timings dv_timings;
|
||||
struct osd_state *osd_device;
|
||||
int out_index = vpbe_dev->current_out_index;
|
||||
int i;
|
||||
|
||||
if (!mode_info || !mode_info->name)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < cfg->outputs[out_index].num_modes; i++) {
|
||||
if (!strcmp(mode_info->name,
|
||||
cfg->outputs[out_index].modes[i].name)) {
|
||||
preset_mode = &cfg->outputs[out_index].modes[i];
|
||||
/*
|
||||
* it may be one of the 3 timings type. Check and
|
||||
* invoke right API
|
||||
*/
|
||||
if (preset_mode->timings_type & VPBE_ENC_STD)
|
||||
return vpbe_s_std(vpbe_dev,
|
||||
preset_mode->std_id);
|
||||
if (preset_mode->timings_type &
|
||||
VPBE_ENC_DV_TIMINGS) {
|
||||
dv_timings =
|
||||
preset_mode->dv_timings;
|
||||
return vpbe_s_dv_timings(vpbe_dev, &dv_timings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Only custom timing should reach here */
|
||||
if (!preset_mode)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&vpbe_dev->lock);
|
||||
|
||||
osd_device = vpbe_dev->osd_device;
|
||||
vpbe_dev->current_timings = *preset_mode;
|
||||
osd_device->ops.set_left_margin(osd_device,
|
||||
vpbe_dev->current_timings.left_margin);
|
||||
osd_device->ops.set_top_margin(osd_device,
|
||||
vpbe_dev->current_timings.upper_margin);
|
||||
|
||||
mutex_unlock(&vpbe_dev->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vpbe_set_default_mode(struct vpbe_device *vpbe_dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = vpbe_get_std_info_by_name(vpbe_dev, def_mode);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* set the default mode in the encoder */
|
||||
return vpbe_set_mode(vpbe_dev, &vpbe_dev->current_timings);
|
||||
}
|
||||
|
||||
static int platform_device_get(struct device *dev, void *data)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct vpbe_device *vpbe_dev = data;
|
||||
|
||||
if (strstr(pdev->name, "vpbe-osd"))
|
||||
vpbe_dev->osd_device = platform_get_drvdata(pdev);
|
||||
if (strstr(pdev->name, "vpbe-venc"))
|
||||
vpbe_dev->venc_device = dev_get_platdata(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* vpbe_initialize() - Initialize the vpbe display controller
|
||||
* @dev: Master and slave device ptr
|
||||
* @vpbe_dev: vpbe device ptr
|
||||
*
|
||||
* Master frame buffer device drivers calls this to initialize vpbe
|
||||
* display controller. This will then registers v4l2 device and the sub
|
||||
* devices and sets a current encoder sub device for display. v4l2 display
|
||||
* device driver is the master and frame buffer display device driver is
|
||||
* the slave. Frame buffer display driver checks the initialized during
|
||||
* probe and exit if not initialized. Returns status.
|
||||
*/
|
||||
static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev)
|
||||
{
|
||||
struct encoder_config_info *enc_info;
|
||||
struct amp_config_info *amp_info;
|
||||
struct v4l2_subdev **enc_subdev;
|
||||
struct osd_state *osd_device;
|
||||
struct i2c_adapter *i2c_adap;
|
||||
int num_encoders;
|
||||
int ret = 0;
|
||||
int err;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* v4l2 abd FBDev frame buffer devices will get the vpbe_dev pointer
|
||||
* from the platform device by iteration of platform drivers and
|
||||
* matching with device name
|
||||
*/
|
||||
if (!vpbe_dev || !dev) {
|
||||
printk(KERN_ERR "Null device pointers.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (vpbe_dev->initialized)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&vpbe_dev->lock);
|
||||
|
||||
if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) {
|
||||
/* We have dac clock available for platform */
|
||||
vpbe_dev->dac_clk = clk_get(vpbe_dev->pdev, "vpss_dac");
|
||||
if (IS_ERR(vpbe_dev->dac_clk)) {
|
||||
ret = PTR_ERR(vpbe_dev->dac_clk);
|
||||
goto fail_mutex_unlock;
|
||||
}
|
||||
if (clk_prepare_enable(vpbe_dev->dac_clk)) {
|
||||
ret = -ENODEV;
|
||||
clk_put(vpbe_dev->dac_clk);
|
||||
goto fail_mutex_unlock;
|
||||
}
|
||||
}
|
||||
|
||||
/* first enable vpss clocks */
|
||||
vpss_enable_clock(VPSS_VPBE_CLOCK, 1);
|
||||
|
||||
/* First register a v4l2 device */
|
||||
ret = v4l2_device_register(dev, &vpbe_dev->v4l2_dev);
|
||||
if (ret) {
|
||||
v4l2_err(dev->driver,
|
||||
"Unable to register v4l2 device.\n");
|
||||
goto fail_clk_put;
|
||||
}
|
||||
v4l2_info(&vpbe_dev->v4l2_dev, "vpbe v4l2 device registered\n");
|
||||
|
||||
err = bus_for_each_dev(&platform_bus_type, NULL, vpbe_dev,
|
||||
platform_device_get);
|
||||
if (err < 0) {
|
||||
ret = err;
|
||||
goto fail_dev_unregister;
|
||||
}
|
||||
|
||||
vpbe_dev->venc = venc_sub_dev_init(&vpbe_dev->v4l2_dev,
|
||||
vpbe_dev->cfg->venc.module_name);
|
||||
/* register venc sub device */
|
||||
if (!vpbe_dev->venc) {
|
||||
v4l2_err(&vpbe_dev->v4l2_dev,
|
||||
"vpbe unable to init venc sub device\n");
|
||||
ret = -ENODEV;
|
||||
goto fail_dev_unregister;
|
||||
}
|
||||
/* initialize osd device */
|
||||
osd_device = vpbe_dev->osd_device;
|
||||
if (osd_device->ops.initialize) {
|
||||
err = osd_device->ops.initialize(osd_device);
|
||||
if (err) {
|
||||
v4l2_err(&vpbe_dev->v4l2_dev,
|
||||
"unable to initialize the OSD device");
|
||||
ret = -ENOMEM;
|
||||
goto fail_dev_unregister;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Register any external encoders that are configured. At index 0 we
|
||||
* store venc sd index.
|
||||
*/
|
||||
num_encoders = vpbe_dev->cfg->num_ext_encoders + 1;
|
||||
vpbe_dev->encoders = kmalloc_array(num_encoders,
|
||||
sizeof(*vpbe_dev->encoders),
|
||||
GFP_KERNEL);
|
||||
if (!vpbe_dev->encoders) {
|
||||
ret = -ENOMEM;
|
||||
goto fail_dev_unregister;
|
||||
}
|
||||
|
||||
i2c_adap = i2c_get_adapter(vpbe_dev->cfg->i2c_adapter_id);
|
||||
for (i = 0; i < (vpbe_dev->cfg->num_ext_encoders + 1); i++) {
|
||||
if (i == 0) {
|
||||
/* venc is at index 0 */
|
||||
enc_subdev = &vpbe_dev->encoders[i];
|
||||
*enc_subdev = vpbe_dev->venc;
|
||||
continue;
|
||||
}
|
||||
enc_info = &vpbe_dev->cfg->ext_encoders[i];
|
||||
if (enc_info->is_i2c) {
|
||||
enc_subdev = &vpbe_dev->encoders[i];
|
||||
*enc_subdev = v4l2_i2c_new_subdev_board(
|
||||
&vpbe_dev->v4l2_dev, i2c_adap,
|
||||
&enc_info->board_info, NULL);
|
||||
if (*enc_subdev)
|
||||
v4l2_info(&vpbe_dev->v4l2_dev,
|
||||
"v4l2 sub device %s registered\n",
|
||||
enc_info->module_name);
|
||||
else {
|
||||
v4l2_err(&vpbe_dev->v4l2_dev, "encoder %s failed to register",
|
||||
enc_info->module_name);
|
||||
ret = -ENODEV;
|
||||
goto fail_kfree_encoders;
|
||||
}
|
||||
} else
|
||||
v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c encoders currently not supported");
|
||||
}
|
||||
/* Add amplifier subdevice for dm365 */
|
||||
if ((strcmp(vpbe_dev->cfg->module_name, "dm365-vpbe-display") == 0) &&
|
||||
vpbe_dev->cfg->amp) {
|
||||
amp_info = vpbe_dev->cfg->amp;
|
||||
if (amp_info->is_i2c) {
|
||||
vpbe_dev->amp = v4l2_i2c_new_subdev_board(
|
||||
&vpbe_dev->v4l2_dev, i2c_adap,
|
||||
&_info->board_info, NULL);
|
||||
if (!vpbe_dev->amp) {
|
||||
v4l2_err(&vpbe_dev->v4l2_dev,
|
||||
"amplifier %s failed to register",
|
||||
amp_info->module_name);
|
||||
ret = -ENODEV;
|
||||
goto fail_kfree_encoders;
|
||||
}
|
||||
v4l2_info(&vpbe_dev->v4l2_dev,
|
||||
"v4l2 sub device %s registered\n",
|
||||
amp_info->module_name);
|
||||
} else {
|
||||
vpbe_dev->amp = NULL;
|
||||
v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c amplifiers currently not supported");
|
||||
}
|
||||
} else {
|
||||
vpbe_dev->amp = NULL;
|
||||
}
|
||||
|
||||
/* set the current encoder and output to that of venc by default */
|
||||
vpbe_dev->current_sd_index = 0;
|
||||
vpbe_dev->current_out_index = 0;
|
||||
|
||||
mutex_unlock(&vpbe_dev->lock);
|
||||
|
||||
printk(KERN_NOTICE "Setting default output to %s\n", def_output);
|
||||
ret = vpbe_set_default_output(vpbe_dev);
|
||||
if (ret) {
|
||||
v4l2_err(&vpbe_dev->v4l2_dev, "Failed to set default output %s",
|
||||
def_output);
|
||||
goto fail_kfree_amp;
|
||||
}
|
||||
|
||||
printk(KERN_NOTICE "Setting default mode to %s\n", def_mode);
|
||||
ret = vpbe_set_default_mode(vpbe_dev);
|
||||
if (ret) {
|
||||
v4l2_err(&vpbe_dev->v4l2_dev, "Failed to set default mode %s",
|
||||
def_mode);
|
||||
goto fail_kfree_amp;
|
||||
}
|
||||
vpbe_dev->initialized = 1;
|
||||
/* TBD handling of bootargs for default output and mode */
|
||||
return 0;
|
||||
|
||||
fail_kfree_amp:
|
||||
mutex_lock(&vpbe_dev->lock);
|
||||
kfree(vpbe_dev->amp);
|
||||
fail_kfree_encoders:
|
||||
kfree(vpbe_dev->encoders);
|
||||
fail_dev_unregister:
|
||||
v4l2_device_unregister(&vpbe_dev->v4l2_dev);
|
||||
fail_clk_put:
|
||||
if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) {
|
||||
clk_disable_unprepare(vpbe_dev->dac_clk);
|
||||
clk_put(vpbe_dev->dac_clk);
|
||||
}
|
||||
fail_mutex_unlock:
|
||||
mutex_unlock(&vpbe_dev->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* vpbe_deinitialize() - de-initialize the vpbe display controller
|
||||
* @dev: Master and slave device ptr
|
||||
* @vpbe_dev: vpbe device ptr
|
||||
*
|
||||
* vpbe_master and slave frame buffer devices calls this to de-initialize
|
||||
* the display controller. It is called when master and slave device
|
||||
* driver modules are removed and no longer requires the display controller.
|
||||
*/
|
||||
static void vpbe_deinitialize(struct device *dev, struct vpbe_device *vpbe_dev)
|
||||
{
|
||||
v4l2_device_unregister(&vpbe_dev->v4l2_dev);
|
||||
if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) {
|
||||
clk_disable_unprepare(vpbe_dev->dac_clk);
|
||||
clk_put(vpbe_dev->dac_clk);
|
||||
}
|
||||
|
||||
kfree(vpbe_dev->amp);
|
||||
kfree(vpbe_dev->encoders);
|
||||
vpbe_dev->initialized = 0;
|
||||
/* disable vpss clocks */
|
||||
vpss_enable_clock(VPSS_VPBE_CLOCK, 0);
|
||||
}
|
||||
|
||||
static const struct vpbe_device_ops vpbe_dev_ops = {
|
||||
.enum_outputs = vpbe_enum_outputs,
|
||||
.set_output = vpbe_set_output,
|
||||
.get_output = vpbe_get_output,
|
||||
.s_dv_timings = vpbe_s_dv_timings,
|
||||
.g_dv_timings = vpbe_g_dv_timings,
|
||||
.enum_dv_timings = vpbe_enum_dv_timings,
|
||||
.s_std = vpbe_s_std,
|
||||
.g_std = vpbe_g_std,
|
||||
.initialize = vpbe_initialize,
|
||||
.deinitialize = vpbe_deinitialize,
|
||||
.get_mode_info = vpbe_get_current_mode_info,
|
||||
.set_mode = vpbe_set_mode,
|
||||
};
|
||||
|
||||
static int vpbe_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct vpbe_device *vpbe_dev;
|
||||
struct vpbe_config *cfg;
|
||||
|
||||
if (!pdev->dev.platform_data) {
|
||||
v4l2_err(pdev->dev.driver, "No platform data\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
cfg = pdev->dev.platform_data;
|
||||
|
||||
if (!cfg->module_name[0] ||
|
||||
!cfg->osd.module_name[0] ||
|
||||
!cfg->venc.module_name[0]) {
|
||||
v4l2_err(pdev->dev.driver, "vpbe display module names not defined\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
vpbe_dev = kzalloc(sizeof(*vpbe_dev), GFP_KERNEL);
|
||||
if (!vpbe_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
vpbe_dev->cfg = cfg;
|
||||
vpbe_dev->ops = vpbe_dev_ops;
|
||||
vpbe_dev->pdev = &pdev->dev;
|
||||
|
||||
if (cfg->outputs->num_modes > 0)
|
||||
vpbe_dev->current_timings = vpbe_dev->cfg->outputs[0].modes[0];
|
||||
else {
|
||||
kfree(vpbe_dev);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* set the driver data in platform device */
|
||||
platform_set_drvdata(pdev, vpbe_dev);
|
||||
mutex_init(&vpbe_dev->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vpbe_remove(struct platform_device *device)
|
||||
{
|
||||
struct vpbe_device *vpbe_dev = platform_get_drvdata(device);
|
||||
|
||||
kfree(vpbe_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver vpbe_driver = {
|
||||
.driver = {
|
||||
.name = "vpbe_controller",
|
||||
},
|
||||
.probe = vpbe_probe,
|
||||
.remove = vpbe_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(vpbe_driver);
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,352 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) 2006-2010 Texas Instruments Inc
|
||||
*/
|
||||
#ifndef _VPBE_OSD_REGS_H
|
||||
#define _VPBE_OSD_REGS_H
|
||||
|
||||
/* 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_ */
|
|
@ -1,676 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2010 Texas Instruments Inc
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <linux/platform_data/i2c-davinci.h>
|
||||
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <media/davinci/vpbe_types.h>
|
||||
#include <media/davinci/vpbe_venc.h>
|
||||
#include <media/davinci/vpss.h>
|
||||
#include <media/v4l2-device.h>
|
||||
|
||||
#include "vpbe_venc_regs.h"
|
||||
|
||||
#define MODULE_NAME "davinci-vpbe-venc"
|
||||
|
||||
static const struct platform_device_id vpbe_venc_devtype[] = {
|
||||
{
|
||||
.name = DM644X_VPBE_VENC_SUBDEV_NAME,
|
||||
.driver_data = VPBE_VERSION_1,
|
||||
}, {
|
||||
.name = DM365_VPBE_VENC_SUBDEV_NAME,
|
||||
.driver_data = VPBE_VERSION_2,
|
||||
}, {
|
||||
.name = DM355_VPBE_VENC_SUBDEV_NAME,
|
||||
.driver_data = VPBE_VERSION_3,
|
||||
},
|
||||
{
|
||||
/* sentinel */
|
||||
}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(platform, vpbe_venc_devtype);
|
||||
|
||||
static int debug = 2;
|
||||
module_param(debug, int, 0644);
|
||||
MODULE_PARM_DESC(debug, "Debug level 0-2");
|
||||
|
||||
struct venc_state {
|
||||
struct v4l2_subdev sd;
|
||||
struct venc_callback *callback;
|
||||
struct venc_platform_data *pdata;
|
||||
struct device *pdev;
|
||||
u32 output;
|
||||
v4l2_std_id std;
|
||||
spinlock_t lock;
|
||||
void __iomem *venc_base;
|
||||
void __iomem *vdaccfg_reg;
|
||||
enum vpbe_version venc_type;
|
||||
};
|
||||
|
||||
static inline struct venc_state *to_state(struct v4l2_subdev *sd)
|
||||
{
|
||||
return container_of(sd, struct venc_state, sd);
|
||||
}
|
||||
|
||||
static inline u32 venc_read(struct v4l2_subdev *sd, u32 offset)
|
||||
{
|
||||
struct venc_state *venc = to_state(sd);
|
||||
|
||||
return readl(venc->venc_base + offset);
|
||||
}
|
||||
|
||||
static inline u32 venc_write(struct v4l2_subdev *sd, u32 offset, u32 val)
|
||||
{
|
||||
struct venc_state *venc = to_state(sd);
|
||||
|
||||
writel(val, (venc->venc_base + offset));
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline u32 venc_modify(struct v4l2_subdev *sd, u32 offset,
|
||||
u32 val, u32 mask)
|
||||
{
|
||||
u32 new_val = (venc_read(sd, offset) & ~mask) | (val & mask);
|
||||
|
||||
venc_write(sd, offset, new_val);
|
||||
|
||||
return new_val;
|
||||
}
|
||||
|
||||
static inline u32 vdaccfg_write(struct v4l2_subdev *sd, u32 val)
|
||||
{
|
||||
struct venc_state *venc = to_state(sd);
|
||||
|
||||
writel(val, venc->vdaccfg_reg);
|
||||
|
||||
val = readl(venc->vdaccfg_reg);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
#define VDAC_COMPONENT 0x543
|
||||
#define VDAC_S_VIDEO 0x210
|
||||
/* This function sets the dac of the VPBE for various outputs
|
||||
*/
|
||||
static int venc_set_dac(struct v4l2_subdev *sd, u32 out_index)
|
||||
{
|
||||
switch (out_index) {
|
||||
case 0:
|
||||
v4l2_dbg(debug, 1, sd, "Setting output to Composite\n");
|
||||
venc_write(sd, VENC_DACSEL, 0);
|
||||
break;
|
||||
case 1:
|
||||
v4l2_dbg(debug, 1, sd, "Setting output to Component\n");
|
||||
venc_write(sd, VENC_DACSEL, VDAC_COMPONENT);
|
||||
break;
|
||||
case 2:
|
||||
v4l2_dbg(debug, 1, sd, "Setting output to S-video\n");
|
||||
venc_write(sd, VENC_DACSEL, VDAC_S_VIDEO);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void venc_enabledigitaloutput(struct v4l2_subdev *sd, int benable)
|
||||
{
|
||||
struct venc_state *venc = to_state(sd);
|
||||
|
||||
v4l2_dbg(debug, 2, sd, "venc_enabledigitaloutput\n");
|
||||
|
||||
if (benable) {
|
||||
venc_write(sd, VENC_VMOD, 0);
|
||||
venc_write(sd, VENC_CVBS, 0);
|
||||
venc_write(sd, VENC_LCDOUT, 0);
|
||||
venc_write(sd, VENC_HSPLS, 0);
|
||||
venc_write(sd, VENC_HSTART, 0);
|
||||
venc_write(sd, VENC_HVALID, 0);
|
||||
venc_write(sd, VENC_HINT, 0);
|
||||
venc_write(sd, VENC_VSPLS, 0);
|
||||
venc_write(sd, VENC_VSTART, 0);
|
||||
venc_write(sd, VENC_VVALID, 0);
|
||||
venc_write(sd, VENC_VINT, 0);
|
||||
venc_write(sd, VENC_YCCCTL, 0);
|
||||
venc_write(sd, VENC_DACSEL, 0);
|
||||
|
||||
} else {
|
||||
venc_write(sd, VENC_VMOD, 0);
|
||||
/* disable VCLK output pin enable */
|
||||
venc_write(sd, VENC_VIDCTL, 0x141);
|
||||
|
||||
/* Disable output sync pins */
|
||||
venc_write(sd, VENC_SYNCCTL, 0);
|
||||
|
||||
/* Disable DCLOCK */
|
||||
venc_write(sd, VENC_DCLKCTL, 0);
|
||||
venc_write(sd, VENC_DRGBX1, 0x0000057C);
|
||||
|
||||
/* Disable LCD output control (accepting default polarity) */
|
||||
venc_write(sd, VENC_LCDOUT, 0);
|
||||
if (venc->venc_type != VPBE_VERSION_3)
|
||||
venc_write(sd, VENC_CMPNT, 0x100);
|
||||
venc_write(sd, VENC_HSPLS, 0);
|
||||
venc_write(sd, VENC_HINT, 0);
|
||||
venc_write(sd, VENC_HSTART, 0);
|
||||
venc_write(sd, VENC_HVALID, 0);
|
||||
|
||||
venc_write(sd, VENC_VSPLS, 0);
|
||||
venc_write(sd, VENC_VINT, 0);
|
||||
venc_write(sd, VENC_VSTART, 0);
|
||||
venc_write(sd, VENC_VVALID, 0);
|
||||
|
||||
venc_write(sd, VENC_HSDLY, 0);
|
||||
venc_write(sd, VENC_VSDLY, 0);
|
||||
|
||||
venc_write(sd, VENC_YCCCTL, 0);
|
||||
venc_write(sd, VENC_VSTARTA, 0);
|
||||
|
||||
/* Set OSD clock and OSD Sync Adavance registers */
|
||||
venc_write(sd, VENC_OSDCLK0, 1);
|
||||
venc_write(sd, VENC_OSDCLK1, 2);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
venc_enable_vpss_clock(int venc_type,
|
||||
enum vpbe_enc_timings_type type,
|
||||
unsigned int pclock)
|
||||
{
|
||||
if (venc_type == VPBE_VERSION_1)
|
||||
return;
|
||||
|
||||
if (venc_type == VPBE_VERSION_2 && (type == VPBE_ENC_STD || (type ==
|
||||
VPBE_ENC_DV_TIMINGS && pclock <= 27000000))) {
|
||||
vpss_enable_clock(VPSS_VENC_CLOCK_SEL, 1);
|
||||
vpss_enable_clock(VPSS_VPBE_CLOCK, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (venc_type == VPBE_VERSION_3 && type == VPBE_ENC_STD)
|
||||
vpss_enable_clock(VPSS_VENC_CLOCK_SEL, 0);
|
||||
}
|
||||
|
||||
#define VDAC_CONFIG_SD_V3 0x0E21A6B6
|
||||
#define VDAC_CONFIG_SD_V2 0x081141CF
|
||||
/*
|
||||
* setting NTSC mode
|
||||
*/
|
||||
static int venc_set_ntsc(struct v4l2_subdev *sd)
|
||||
{
|
||||
struct venc_state *venc = to_state(sd);
|
||||
struct venc_platform_data *pdata = venc->pdata;
|
||||
|
||||
v4l2_dbg(debug, 2, sd, "venc_set_ntsc\n");
|
||||
|
||||
/* Setup clock at VPSS & VENC for SD */
|
||||
vpss_enable_clock(VPSS_VENC_CLOCK_SEL, 1);
|
||||
if (pdata->setup_clock(VPBE_ENC_STD, V4L2_STD_525_60) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
venc_enable_vpss_clock(venc->venc_type, VPBE_ENC_STD, V4L2_STD_525_60);
|
||||
venc_enabledigitaloutput(sd, 0);
|
||||
|
||||
if (venc->venc_type == VPBE_VERSION_3) {
|
||||
venc_write(sd, VENC_CLKCTL, 0x01);
|
||||
venc_write(sd, VENC_VIDCTL, 0);
|
||||
vdaccfg_write(sd, VDAC_CONFIG_SD_V3);
|
||||
} else if (venc->venc_type == VPBE_VERSION_2) {
|
||||
venc_write(sd, VENC_CLKCTL, 0x01);
|
||||
venc_write(sd, VENC_VIDCTL, 0);
|
||||
vdaccfg_write(sd, VDAC_CONFIG_SD_V2);
|
||||
} else {
|
||||
/* to set VENC CLK DIV to 1 - final clock is 54 MHz */
|
||||
venc_modify(sd, VENC_VIDCTL, 0, 1 << 1);
|
||||
/* Set REC656 Mode */
|
||||
venc_write(sd, VENC_YCCCTL, 0x1);
|
||||
venc_modify(sd, VENC_VDPRO, 0, VENC_VDPRO_DAFRQ);
|
||||
venc_modify(sd, VENC_VDPRO, 0, VENC_VDPRO_DAUPS);
|
||||
}
|
||||
|
||||
venc_write(sd, VENC_VMOD, 0);
|
||||
venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
|
||||
VENC_VMOD_VIE);
|
||||
venc_modify(sd, VENC_VMOD, (0 << VENC_VMOD_VMD), VENC_VMOD_VMD);
|
||||
venc_modify(sd, VENC_VMOD, (0 << VENC_VMOD_TVTYP_SHIFT),
|
||||
VENC_VMOD_TVTYP);
|
||||
venc_write(sd, VENC_DACTST, 0x0);
|
||||
venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* setting PAL mode
|
||||
*/
|
||||
static int venc_set_pal(struct v4l2_subdev *sd)
|
||||
{
|
||||
struct venc_state *venc = to_state(sd);
|
||||
|
||||
v4l2_dbg(debug, 2, sd, "venc_set_pal\n");
|
||||
|
||||
/* Setup clock at VPSS & VENC for SD */
|
||||
vpss_enable_clock(VPSS_VENC_CLOCK_SEL, 1);
|
||||
if (venc->pdata->setup_clock(VPBE_ENC_STD, V4L2_STD_625_50) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
venc_enable_vpss_clock(venc->venc_type, VPBE_ENC_STD, V4L2_STD_625_50);
|
||||
venc_enabledigitaloutput(sd, 0);
|
||||
|
||||
if (venc->venc_type == VPBE_VERSION_3) {
|
||||
venc_write(sd, VENC_CLKCTL, 0x1);
|
||||
venc_write(sd, VENC_VIDCTL, 0);
|
||||
vdaccfg_write(sd, VDAC_CONFIG_SD_V3);
|
||||
} else if (venc->venc_type == VPBE_VERSION_2) {
|
||||
venc_write(sd, VENC_CLKCTL, 0x1);
|
||||
venc_write(sd, VENC_VIDCTL, 0);
|
||||
vdaccfg_write(sd, VDAC_CONFIG_SD_V2);
|
||||
} else {
|
||||
/* to set VENC CLK DIV to 1 - final clock is 54 MHz */
|
||||
venc_modify(sd, VENC_VIDCTL, 0, 1 << 1);
|
||||
/* Set REC656 Mode */
|
||||
venc_write(sd, VENC_YCCCTL, 0x1);
|
||||
}
|
||||
|
||||
venc_modify(sd, VENC_SYNCCTL, 1 << VENC_SYNCCTL_OVD_SHIFT,
|
||||
VENC_SYNCCTL_OVD);
|
||||
venc_write(sd, VENC_VMOD, 0);
|
||||
venc_modify(sd, VENC_VMOD,
|
||||
(1 << VENC_VMOD_VIE_SHIFT),
|
||||
VENC_VMOD_VIE);
|
||||
venc_modify(sd, VENC_VMOD,
|
||||
(0 << VENC_VMOD_VMD), VENC_VMOD_VMD);
|
||||
venc_modify(sd, VENC_VMOD,
|
||||
(1 << VENC_VMOD_TVTYP_SHIFT),
|
||||
VENC_VMOD_TVTYP);
|
||||
venc_write(sd, VENC_DACTST, 0x0);
|
||||
venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define VDAC_CONFIG_HD_V2 0x081141EF
|
||||
/*
|
||||
* venc_set_480p59_94
|
||||
*
|
||||
* This function configures the video encoder to EDTV(525p) component setting.
|
||||
*/
|
||||
static int venc_set_480p59_94(struct v4l2_subdev *sd)
|
||||
{
|
||||
struct venc_state *venc = to_state(sd);
|
||||
struct venc_platform_data *pdata = venc->pdata;
|
||||
|
||||
v4l2_dbg(debug, 2, sd, "venc_set_480p59_94\n");
|
||||
if (venc->venc_type != VPBE_VERSION_1 &&
|
||||
venc->venc_type != VPBE_VERSION_2)
|
||||
return -EINVAL;
|
||||
|
||||
/* Setup clock at VPSS & VENC for SD */
|
||||
if (pdata->setup_clock(VPBE_ENC_DV_TIMINGS, 27000000) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
venc_enable_vpss_clock(venc->venc_type, VPBE_ENC_DV_TIMINGS, 27000000);
|
||||
venc_enabledigitaloutput(sd, 0);
|
||||
|
||||
if (venc->venc_type == VPBE_VERSION_2)
|
||||
vdaccfg_write(sd, VDAC_CONFIG_HD_V2);
|
||||
venc_write(sd, VENC_OSDCLK0, 0);
|
||||
venc_write(sd, VENC_OSDCLK1, 1);
|
||||
|
||||
if (venc->venc_type == VPBE_VERSION_1) {
|
||||
venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAFRQ,
|
||||
VENC_VDPRO_DAFRQ);
|
||||
venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAUPS,
|
||||
VENC_VDPRO_DAUPS);
|
||||
}
|
||||
|
||||
venc_write(sd, VENC_VMOD, 0);
|
||||
venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
|
||||
VENC_VMOD_VIE);
|
||||
venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD);
|
||||
venc_modify(sd, VENC_VMOD, (HDTV_525P << VENC_VMOD_TVTYP_SHIFT),
|
||||
VENC_VMOD_TVTYP);
|
||||
venc_modify(sd, VENC_VMOD, VENC_VMOD_VDMD_YCBCR8 <<
|
||||
VENC_VMOD_VDMD_SHIFT, VENC_VMOD_VDMD);
|
||||
|
||||
venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* venc_set_625p
|
||||
*
|
||||
* This function configures the video encoder to HDTV(625p) component setting
|
||||
*/
|
||||
static int venc_set_576p50(struct v4l2_subdev *sd)
|
||||
{
|
||||
struct venc_state *venc = to_state(sd);
|
||||
struct venc_platform_data *pdata = venc->pdata;
|
||||
|
||||
v4l2_dbg(debug, 2, sd, "venc_set_576p50\n");
|
||||
|
||||
if (venc->venc_type != VPBE_VERSION_1 &&
|
||||
venc->venc_type != VPBE_VERSION_2)
|
||||
return -EINVAL;
|
||||
/* Setup clock at VPSS & VENC for SD */
|
||||
if (pdata->setup_clock(VPBE_ENC_DV_TIMINGS, 27000000) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
venc_enable_vpss_clock(venc->venc_type, VPBE_ENC_DV_TIMINGS, 27000000);
|
||||
venc_enabledigitaloutput(sd, 0);
|
||||
|
||||
if (venc->venc_type == VPBE_VERSION_2)
|
||||
vdaccfg_write(sd, VDAC_CONFIG_HD_V2);
|
||||
|
||||
venc_write(sd, VENC_OSDCLK0, 0);
|
||||
venc_write(sd, VENC_OSDCLK1, 1);
|
||||
|
||||
if (venc->venc_type == VPBE_VERSION_1) {
|
||||
venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAFRQ,
|
||||
VENC_VDPRO_DAFRQ);
|
||||
venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAUPS,
|
||||
VENC_VDPRO_DAUPS);
|
||||
}
|
||||
|
||||
venc_write(sd, VENC_VMOD, 0);
|
||||
venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
|
||||
VENC_VMOD_VIE);
|
||||
venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD);
|
||||
venc_modify(sd, VENC_VMOD, (HDTV_625P << VENC_VMOD_TVTYP_SHIFT),
|
||||
VENC_VMOD_TVTYP);
|
||||
|
||||
venc_modify(sd, VENC_VMOD, VENC_VMOD_VDMD_YCBCR8 <<
|
||||
VENC_VMOD_VDMD_SHIFT, VENC_VMOD_VDMD);
|
||||
venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* venc_set_720p60_internal - Setup 720p60 in venc for dm365 only
|
||||
*/
|
||||
static int venc_set_720p60_internal(struct v4l2_subdev *sd)
|
||||
{
|
||||
struct venc_state *venc = to_state(sd);
|
||||
struct venc_platform_data *pdata = venc->pdata;
|
||||
|
||||
if (pdata->setup_clock(VPBE_ENC_DV_TIMINGS, 74250000) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
venc_enable_vpss_clock(venc->venc_type, VPBE_ENC_DV_TIMINGS, 74250000);
|
||||
venc_enabledigitaloutput(sd, 0);
|
||||
|
||||
venc_write(sd, VENC_OSDCLK0, 0);
|
||||
venc_write(sd, VENC_OSDCLK1, 1);
|
||||
|
||||
venc_write(sd, VENC_VMOD, 0);
|
||||
/* DM365 component HD mode */
|
||||
venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
|
||||
VENC_VMOD_VIE);
|
||||
venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD);
|
||||
venc_modify(sd, VENC_VMOD, (HDTV_720P << VENC_VMOD_TVTYP_SHIFT),
|
||||
VENC_VMOD_TVTYP);
|
||||
venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
|
||||
venc_write(sd, VENC_XHINTVL, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* venc_set_1080i30_internal - Setup 1080i30 in venc for dm365 only
|
||||
*/
|
||||
static int venc_set_1080i30_internal(struct v4l2_subdev *sd)
|
||||
{
|
||||
struct venc_state *venc = to_state(sd);
|
||||
struct venc_platform_data *pdata = venc->pdata;
|
||||
|
||||
if (pdata->setup_clock(VPBE_ENC_DV_TIMINGS, 74250000) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
venc_enable_vpss_clock(venc->venc_type, VPBE_ENC_DV_TIMINGS, 74250000);
|
||||
venc_enabledigitaloutput(sd, 0);
|
||||
|
||||
venc_write(sd, VENC_OSDCLK0, 0);
|
||||
venc_write(sd, VENC_OSDCLK1, 1);
|
||||
|
||||
|
||||
venc_write(sd, VENC_VMOD, 0);
|
||||
/* DM365 component HD mode */
|
||||
venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
|
||||
VENC_VMOD_VIE);
|
||||
venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD);
|
||||
venc_modify(sd, VENC_VMOD, (HDTV_1080I << VENC_VMOD_TVTYP_SHIFT),
|
||||
VENC_VMOD_TVTYP);
|
||||
venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
|
||||
venc_write(sd, VENC_XHINTVL, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int venc_s_std_output(struct v4l2_subdev *sd, v4l2_std_id norm)
|
||||
{
|
||||
v4l2_dbg(debug, 1, sd, "venc_s_std_output\n");
|
||||
|
||||
if (norm & V4L2_STD_525_60)
|
||||
return venc_set_ntsc(sd);
|
||||
else if (norm & V4L2_STD_625_50)
|
||||
return venc_set_pal(sd);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int venc_s_dv_timings(struct v4l2_subdev *sd,
|
||||
struct v4l2_dv_timings *dv_timings)
|
||||
{
|
||||
struct venc_state *venc = to_state(sd);
|
||||
u32 height = dv_timings->bt.height;
|
||||
int ret;
|
||||
|
||||
v4l2_dbg(debug, 1, sd, "venc_s_dv_timings\n");
|
||||
|
||||
if (height == 576)
|
||||
return venc_set_576p50(sd);
|
||||
else if (height == 480)
|
||||
return venc_set_480p59_94(sd);
|
||||
else if ((height == 720) &&
|
||||
(venc->venc_type == VPBE_VERSION_2)) {
|
||||
/* TBD setup internal 720p mode here */
|
||||
ret = venc_set_720p60_internal(sd);
|
||||
/* for DM365 VPBE, there is DAC inside */
|
||||
vdaccfg_write(sd, VDAC_CONFIG_HD_V2);
|
||||
return ret;
|
||||
} else if ((height == 1080) &&
|
||||
(venc->venc_type == VPBE_VERSION_2)) {
|
||||
/* TBD setup internal 1080i mode here */
|
||||
ret = venc_set_1080i30_internal(sd);
|
||||
/* for DM365 VPBE, there is DAC inside */
|
||||
vdaccfg_write(sd, VDAC_CONFIG_HD_V2);
|
||||
return ret;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int venc_s_routing(struct v4l2_subdev *sd, u32 input, u32 output,
|
||||
u32 config)
|
||||
{
|
||||
struct venc_state *venc = to_state(sd);
|
||||
int ret;
|
||||
|
||||
v4l2_dbg(debug, 1, sd, "venc_s_routing\n");
|
||||
|
||||
ret = venc_set_dac(sd, output);
|
||||
if (!ret)
|
||||
venc->output = output;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long venc_command(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
switch (cmd) {
|
||||
case VENC_GET_FLD:
|
||||
val = venc_read(sd, VENC_VSTAT);
|
||||
*((int *)arg) = ((val & VENC_VSTAT_FIDST) ==
|
||||
VENC_VSTAT_FIDST);
|
||||
break;
|
||||
default:
|
||||
v4l2_err(sd, "Wrong IOCTL cmd\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct v4l2_subdev_core_ops venc_core_ops = {
|
||||
.command = venc_command,
|
||||
};
|
||||
|
||||
static const struct v4l2_subdev_video_ops venc_video_ops = {
|
||||
.s_routing = venc_s_routing,
|
||||
.s_std_output = venc_s_std_output,
|
||||
.s_dv_timings = venc_s_dv_timings,
|
||||
};
|
||||
|
||||
static const struct v4l2_subdev_ops venc_ops = {
|
||||
.core = &venc_core_ops,
|
||||
.video = &venc_video_ops,
|
||||
};
|
||||
|
||||
static int venc_initialize(struct v4l2_subdev *sd)
|
||||
{
|
||||
struct venc_state *venc = to_state(sd);
|
||||
int ret;
|
||||
|
||||
/* Set default to output to composite and std to NTSC */
|
||||
venc->output = 0;
|
||||
venc->std = V4L2_STD_525_60;
|
||||
|
||||
ret = venc_s_routing(sd, 0, venc->output, 0);
|
||||
if (ret < 0) {
|
||||
v4l2_err(sd, "Error setting output during init\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = venc_s_std_output(sd, venc->std);
|
||||
if (ret < 0) {
|
||||
v4l2_err(sd, "Error setting std during init\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int venc_device_get(struct device *dev, void *data)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct venc_state **venc = data;
|
||||
|
||||
if (strstr(pdev->name, "vpbe-venc") != NULL)
|
||||
*venc = platform_get_drvdata(pdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct v4l2_subdev *venc_sub_dev_init(struct v4l2_device *v4l2_dev,
|
||||
const char *venc_name)
|
||||
{
|
||||
struct venc_state *venc = NULL;
|
||||
|
||||
bus_for_each_dev(&platform_bus_type, NULL, &venc,
|
||||
venc_device_get);
|
||||
if (venc == NULL)
|
||||
return NULL;
|
||||
|
||||
v4l2_subdev_init(&venc->sd, &venc_ops);
|
||||
|
||||
strscpy(venc->sd.name, venc_name, sizeof(venc->sd.name));
|
||||
if (v4l2_device_register_subdev(v4l2_dev, &venc->sd) < 0) {
|
||||
v4l2_err(v4l2_dev,
|
||||
"vpbe unable to register venc sub device\n");
|
||||
return NULL;
|
||||
}
|
||||
if (venc_initialize(&venc->sd)) {
|
||||
v4l2_err(v4l2_dev,
|
||||
"vpbe venc initialization failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &venc->sd;
|
||||
}
|
||||
EXPORT_SYMBOL(venc_sub_dev_init);
|
||||
|
||||
static int venc_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct platform_device_id *pdev_id;
|
||||
struct venc_state *venc;
|
||||
|
||||
if (!pdev->dev.platform_data) {
|
||||
dev_err(&pdev->dev, "No platform data for VENC sub device");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pdev_id = platform_get_device_id(pdev);
|
||||
if (!pdev_id)
|
||||
return -EINVAL;
|
||||
|
||||
venc = devm_kzalloc(&pdev->dev, sizeof(struct venc_state), GFP_KERNEL);
|
||||
if (venc == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
venc->venc_type = pdev_id->driver_data;
|
||||
venc->pdev = &pdev->dev;
|
||||
venc->pdata = pdev->dev.platform_data;
|
||||
|
||||
venc->venc_base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(venc->venc_base))
|
||||
return PTR_ERR(venc->venc_base);
|
||||
|
||||
if (venc->venc_type != VPBE_VERSION_1) {
|
||||
venc->vdaccfg_reg = devm_platform_ioremap_resource(pdev, 1);
|
||||
if (IS_ERR(venc->vdaccfg_reg))
|
||||
return PTR_ERR(venc->vdaccfg_reg);
|
||||
}
|
||||
spin_lock_init(&venc->lock);
|
||||
platform_set_drvdata(pdev, venc);
|
||||
dev_notice(venc->pdev, "VENC sub device probe success\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int venc_remove(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver venc_driver = {
|
||||
.probe = venc_probe,
|
||||
.remove = venc_remove,
|
||||
.driver = {
|
||||
.name = MODULE_NAME,
|
||||
},
|
||||
.id_table = vpbe_venc_devtype
|
||||
};
|
||||
|
||||
module_platform_driver(venc_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("VPBE VENC Driver");
|
||||
MODULE_AUTHOR("Texas Instruments");
|
|
@ -1,165 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) 2006-2010 Texas Instruments Inc
|
||||
*/
|
||||
#ifndef _VPBE_VENC_REGS_H
|
||||
#define _VPBE_VENC_REGS_H
|
||||
|
||||
/* VPBE Video Encoder / Digital LCD Subsystem Registers (VENC) */
|
||||
#define VENC_VMOD 0x00
|
||||
#define VENC_VIDCTL 0x04
|
||||
#define VENC_VDPRO 0x08
|
||||
#define VENC_SYNCCTL 0x0C
|
||||
#define VENC_HSPLS 0x10
|
||||
#define VENC_VSPLS 0x14
|
||||
#define VENC_HINT 0x18
|
||||
#define VENC_HSTART 0x1C
|
||||
#define VENC_HVALID 0x20
|
||||
#define VENC_VINT 0x24
|
||||
#define VENC_VSTART 0x28
|
||||
#define VENC_VVALID 0x2C
|
||||
#define VENC_HSDLY 0x30
|
||||
#define VENC_VSDLY 0x34
|
||||
#define VENC_YCCCTL 0x38
|
||||
#define VENC_RGBCTL 0x3C
|
||||
#define VENC_RGBCLP 0x40
|
||||
#define VENC_LINECTL 0x44
|
||||
#define VENC_CULLLINE 0x48
|
||||
#define VENC_LCDOUT 0x4C
|
||||
#define VENC_BRTS 0x50
|
||||
#define VENC_BRTW 0x54
|
||||
#define VENC_ACCTL 0x58
|
||||
#define VENC_PWMP 0x5C
|
||||
#define VENC_PWMW 0x60
|
||||
#define VENC_DCLKCTL 0x64
|
||||
#define VENC_DCLKPTN0 0x68
|
||||
#define VENC_DCLKPTN1 0x6C
|
||||
#define VENC_DCLKPTN2 0x70
|
||||
#define VENC_DCLKPTN3 0x74
|
||||
#define VENC_DCLKPTN0A 0x78
|
||||
#define VENC_DCLKPTN1A 0x7C
|
||||
#define VENC_DCLKPTN2A 0x80
|
||||
#define VENC_DCLKPTN3A 0x84
|
||||
#define VENC_DCLKHS 0x88
|
||||
#define VENC_DCLKHSA 0x8C
|
||||
#define VENC_DCLKHR 0x90
|
||||
#define VENC_DCLKVS 0x94
|
||||
#define VENC_DCLKVR 0x98
|
||||
#define VENC_CAPCTL 0x9C
|
||||
#define VENC_CAPDO 0xA0
|
||||
#define VENC_CAPDE 0xA4
|
||||
#define VENC_ATR0 0xA8
|
||||
#define VENC_ATR1 0xAC
|
||||
#define VENC_ATR2 0xB0
|
||||
#define VENC_VSTAT 0xB8
|
||||
#define VENC_RAMADR 0xBC
|
||||
#define VENC_RAMPORT 0xC0
|
||||
#define VENC_DACTST 0xC4
|
||||
#define VENC_YCOLVL 0xC8
|
||||
#define VENC_SCPROG 0xCC
|
||||
#define VENC_CVBS 0xDC
|
||||
#define VENC_CMPNT 0xE0
|
||||
#define VENC_ETMG0 0xE4
|
||||
#define VENC_ETMG1 0xE8
|
||||
#define VENC_ETMG2 0xEC
|
||||
#define VENC_ETMG3 0xF0
|
||||
#define VENC_DACSEL 0xF4
|
||||
#define VENC_ARGBX0 0x100
|
||||
#define VENC_ARGBX1 0x104
|
||||
#define VENC_ARGBX2 0x108
|
||||
#define VENC_ARGBX3 0x10C
|
||||
#define VENC_ARGBX4 0x110
|
||||
#define VENC_DRGBX0 0x114
|
||||
#define VENC_DRGBX1 0x118
|
||||
#define VENC_DRGBX2 0x11C
|
||||
#define VENC_DRGBX3 0x120
|
||||
#define VENC_DRGBX4 0x124
|
||||
#define VENC_VSTARTA 0x128
|
||||
#define VENC_OSDCLK0 0x12C
|
||||
#define VENC_OSDCLK1 0x130
|
||||
#define VENC_HVLDCL0 0x134
|
||||
#define VENC_HVLDCL1 0x138
|
||||
#define VENC_OSDHADV 0x13C
|
||||
#define VENC_CLKCTL 0x140
|
||||
#define VENC_GAMCTL 0x144
|
||||
#define VENC_XHINTVL 0x174
|
||||
|
||||
/* bit definitions */
|
||||
#define VPBE_PCR_VENC_DIV (1 << 1)
|
||||
#define VPBE_PCR_CLK_OFF (1 << 0)
|
||||
|
||||
#define VENC_VMOD_VDMD_SHIFT 12
|
||||
#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_EPSON 4
|
||||
#define VENC_VMOD_VDMD_CASIO 5
|
||||
#define VENC_VMOD_VDMD_UDISPQVGA 6
|
||||
#define VENC_VMOD_VDMD_STNLCD 7
|
||||
#define VENC_VMOD_VIE_SHIFT 1
|
||||
#define VENC_VMOD_VDMD (7 << 12)
|
||||
#define VENC_VMOD_ITLCL (1 << 11)
|
||||
#define VENC_VMOD_ITLC (1 << 10)
|
||||
#define VENC_VMOD_NSIT (1 << 9)
|
||||
#define VENC_VMOD_HDMD (1 << 8)
|
||||
#define VENC_VMOD_TVTYP_SHIFT 6
|
||||
#define VENC_VMOD_TVTYP (3 << 6)
|
||||
#define VENC_VMOD_SLAVE (1 << 5)
|
||||
#define VENC_VMOD_VMD (1 << 4)
|
||||
#define VENC_VMOD_BLNK (1 << 3)
|
||||
#define VENC_VMOD_VIE (1 << 1)
|
||||
#define VENC_VMOD_VENC (1 << 0)
|
||||
|
||||
/* 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 VENC_VIDCTL_VCLKP (1 << 14)
|
||||
#define VENC_VIDCTL_VCLKE_SHIFT 13
|
||||
#define VENC_VIDCTL_VCLKE (1 << 13)
|
||||
#define VENC_VIDCTL_VCLKZ_SHIFT 12
|
||||
#define VENC_VIDCTL_VCLKZ (1 << 12)
|
||||
#define VENC_VIDCTL_SYDIR_SHIFT 8
|
||||
#define VENC_VIDCTL_SYDIR (1 << 8)
|
||||
#define VENC_VIDCTL_DOMD_SHIFT 4
|
||||
#define VENC_VIDCTL_DOMD (3 << 4)
|
||||
#define VENC_VIDCTL_YCDIR_SHIFT 0
|
||||
#define VENC_VIDCTL_YCDIR (1 << 0)
|
||||
|
||||
#define VENC_VDPRO_ATYCC_SHIFT 5
|
||||
#define VENC_VDPRO_ATYCC (1 << 5)
|
||||
#define VENC_VDPRO_ATCOM_SHIFT 4
|
||||
#define VENC_VDPRO_ATCOM (1 << 4)
|
||||
#define VENC_VDPRO_DAFRQ (1 << 3)
|
||||
#define VENC_VDPRO_DAUPS (1 << 2)
|
||||
#define VENC_VDPRO_CUPS (1 << 1)
|
||||
#define VENC_VDPRO_YUPS (1 << 0)
|
||||
|
||||
#define VENC_SYNCCTL_VPL_SHIFT 3
|
||||
#define VENC_SYNCCTL_VPL (1 << 3)
|
||||
#define VENC_SYNCCTL_HPL_SHIFT 2
|
||||
#define VENC_SYNCCTL_HPL (1 << 2)
|
||||
#define VENC_SYNCCTL_SYEV_SHIFT 1
|
||||
#define VENC_SYNCCTL_SYEV (1 << 1)
|
||||
#define VENC_SYNCCTL_SYEH_SHIFT 0
|
||||
#define VENC_SYNCCTL_SYEH (1 << 0)
|
||||
#define VENC_SYNCCTL_OVD_SHIFT 14
|
||||
#define VENC_SYNCCTL_OVD (1 << 14)
|
||||
|
||||
#define VENC_DCLKCTL_DCKEC_SHIFT 11
|
||||
#define VENC_DCLKCTL_DCKEC (1 << 11)
|
||||
#define VENC_DCLKCTL_DCKPW_SHIFT 0
|
||||
#define VENC_DCLKCTL_DCKPW (0x3f << 0)
|
||||
|
||||
#define VENC_VSTAT_FIDST (1 << 4)
|
||||
|
||||
#define VENC_CMPNT_MRGB_SHIFT 14
|
||||
#define VENC_CMPNT_MRGB (1 << 14)
|
||||
|
||||
#endif /* _VPBE_VENC_REGS_H */
|
|
@ -1,529 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (C) 2009 Texas Instruments.
|
||||
*
|
||||
* common vpss system module platform driver for all video drivers.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
#include <media/davinci/vpss.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("VPSS Driver");
|
||||
MODULE_AUTHOR("Texas Instruments");
|
||||
|
||||
/* DM644x defines */
|
||||
#define DM644X_SBL_PCR_VPSS (4)
|
||||
|
||||
#define DM355_VPSSBL_INTSEL 0x10
|
||||
#define DM355_VPSSBL_EVTSEL 0x14
|
||||
/* vpss BL register offsets */
|
||||
#define DM355_VPSSBL_CCDCMUX 0x1c
|
||||
/* vpss CLK register offsets */
|
||||
#define DM355_VPSSCLK_CLKCTRL 0x04
|
||||
/* masks and shifts */
|
||||
#define VPSS_HSSISEL_SHIFT 4
|
||||
/*
|
||||
* VDINT0 - vpss_int0, VDINT1 - vpss_int1, H3A - vpss_int4,
|
||||
* IPIPE_INT1_SDR - vpss_int5
|
||||
*/
|
||||
#define DM355_VPSSBL_INTSEL_DEFAULT 0xff83ff10
|
||||
/* VENCINT - vpss_int8 */
|
||||
#define DM355_VPSSBL_EVTSEL_DEFAULT 0x4
|
||||
|
||||
#define DM365_ISP5_PCCR 0x04
|
||||
#define DM365_ISP5_PCCR_BL_CLK_ENABLE BIT(0)
|
||||
#define DM365_ISP5_PCCR_ISIF_CLK_ENABLE BIT(1)
|
||||
#define DM365_ISP5_PCCR_H3A_CLK_ENABLE BIT(2)
|
||||
#define DM365_ISP5_PCCR_RSZ_CLK_ENABLE BIT(3)
|
||||
#define DM365_ISP5_PCCR_IPIPE_CLK_ENABLE BIT(4)
|
||||
#define DM365_ISP5_PCCR_IPIPEIF_CLK_ENABLE BIT(5)
|
||||
#define DM365_ISP5_PCCR_RSV BIT(6)
|
||||
|
||||
#define DM365_ISP5_BCR 0x08
|
||||
#define DM365_ISP5_BCR_ISIF_OUT_ENABLE BIT(1)
|
||||
|
||||
#define DM365_ISP5_INTSEL1 0x10
|
||||
#define DM365_ISP5_INTSEL2 0x14
|
||||
#define DM365_ISP5_INTSEL3 0x18
|
||||
#define DM365_ISP5_CCDCMUX 0x20
|
||||
#define DM365_ISP5_PG_FRAME_SIZE 0x28
|
||||
#define DM365_VPBE_CLK_CTRL 0x00
|
||||
|
||||
#define VPSS_CLK_CTRL 0x01c40044
|
||||
#define VPSS_CLK_CTRL_VENCCLKEN BIT(3)
|
||||
#define VPSS_CLK_CTRL_DACCLKEN BIT(4)
|
||||
|
||||
/*
|
||||
* vpss interrupts. VDINT0 - vpss_int0, VDINT1 - vpss_int1,
|
||||
* AF - vpss_int3
|
||||
*/
|
||||
#define DM365_ISP5_INTSEL1_DEFAULT 0x0b1f0100
|
||||
/* AEW - vpss_int6, RSZ_INT_DMA - vpss_int5 */
|
||||
#define DM365_ISP5_INTSEL2_DEFAULT 0x1f0a0f1f
|
||||
/* VENC - vpss_int8 */
|
||||
#define DM365_ISP5_INTSEL3_DEFAULT 0x00000015
|
||||
|
||||
/* masks and shifts for DM365*/
|
||||
#define DM365_CCDC_PG_VD_POL_SHIFT 0
|
||||
#define DM365_CCDC_PG_HD_POL_SHIFT 1
|
||||
|
||||
#define CCD_SRC_SEL_MASK (BIT_MASK(5) | BIT_MASK(4))
|
||||
#define CCD_SRC_SEL_SHIFT 4
|
||||
|
||||
/* Different SoC platforms supported by this driver */
|
||||
enum vpss_platform_type {
|
||||
DM644X,
|
||||
DM355,
|
||||
DM365,
|
||||
};
|
||||
|
||||
/*
|
||||
* vpss operations. Depends on platform. Not all functions are available
|
||||
* on all platforms. The api, first check if a function is available before
|
||||
* invoking it. In the probe, the function ptrs are initialized based on
|
||||
* vpss name. vpss name can be "dm355_vpss", "dm644x_vpss" etc.
|
||||
*/
|
||||
struct vpss_hw_ops {
|
||||
/* enable clock */
|
||||
int (*enable_clock)(enum vpss_clock_sel clock_sel, int en);
|
||||
/* select input to ccdc */
|
||||
void (*select_ccdc_source)(enum vpss_ccdc_source_sel src_sel);
|
||||
/* clear wbl overflow bit */
|
||||
int (*clear_wbl_overflow)(enum vpss_wbl_sel wbl_sel);
|
||||
/* set sync polarity */
|
||||
void (*set_sync_pol)(struct vpss_sync_pol);
|
||||
/* set the PG_FRAME_SIZE register*/
|
||||
void (*set_pg_frame_size)(struct vpss_pg_frame_size);
|
||||
/* check and clear interrupt if occurred */
|
||||
int (*dma_complete_interrupt)(void);
|
||||
};
|
||||
|
||||
/* vpss configuration */
|
||||
struct vpss_oper_config {
|
||||
__iomem void *vpss_regs_base0;
|
||||
__iomem void *vpss_regs_base1;
|
||||
__iomem void *vpss_regs_base2;
|
||||
enum vpss_platform_type platform;
|
||||
spinlock_t vpss_lock;
|
||||
struct vpss_hw_ops hw_ops;
|
||||
};
|
||||
|
||||
static struct vpss_oper_config oper_cfg;
|
||||
|
||||
/* register access routines */
|
||||
static inline u32 bl_regr(u32 offset)
|
||||
{
|
||||
return __raw_readl(oper_cfg.vpss_regs_base0 + offset);
|
||||
}
|
||||
|
||||
static inline void bl_regw(u32 val, u32 offset)
|
||||
{
|
||||
__raw_writel(val, oper_cfg.vpss_regs_base0 + offset);
|
||||
}
|
||||
|
||||
static inline u32 vpss_regr(u32 offset)
|
||||
{
|
||||
return __raw_readl(oper_cfg.vpss_regs_base1 + offset);
|
||||
}
|
||||
|
||||
static inline void vpss_regw(u32 val, u32 offset)
|
||||
{
|
||||
__raw_writel(val, oper_cfg.vpss_regs_base1 + offset);
|
||||
}
|
||||
|
||||
/* For DM365 only */
|
||||
static inline u32 isp5_read(u32 offset)
|
||||
{
|
||||
return __raw_readl(oper_cfg.vpss_regs_base0 + offset);
|
||||
}
|
||||
|
||||
/* For DM365 only */
|
||||
static inline void isp5_write(u32 val, u32 offset)
|
||||
{
|
||||
__raw_writel(val, oper_cfg.vpss_regs_base0 + offset);
|
||||
}
|
||||
|
||||
static void dm365_select_ccdc_source(enum vpss_ccdc_source_sel src_sel)
|
||||
{
|
||||
u32 temp = isp5_read(DM365_ISP5_CCDCMUX) & ~CCD_SRC_SEL_MASK;
|
||||
|
||||
/* if we are using pattern generator, enable it */
|
||||
if (src_sel == VPSS_PGLPBK || src_sel == VPSS_CCDCPG)
|
||||
temp |= 0x08;
|
||||
|
||||
temp |= (src_sel << CCD_SRC_SEL_SHIFT);
|
||||
isp5_write(temp, DM365_ISP5_CCDCMUX);
|
||||
}
|
||||
|
||||
static void dm355_select_ccdc_source(enum vpss_ccdc_source_sel src_sel)
|
||||
{
|
||||
bl_regw(src_sel << VPSS_HSSISEL_SHIFT, DM355_VPSSBL_CCDCMUX);
|
||||
}
|
||||
|
||||
int vpss_dma_complete_interrupt(void)
|
||||
{
|
||||
if (!oper_cfg.hw_ops.dma_complete_interrupt)
|
||||
return 2;
|
||||
return oper_cfg.hw_ops.dma_complete_interrupt();
|
||||
}
|
||||
EXPORT_SYMBOL(vpss_dma_complete_interrupt);
|
||||
|
||||
int vpss_select_ccdc_source(enum vpss_ccdc_source_sel src_sel)
|
||||
{
|
||||
if (!oper_cfg.hw_ops.select_ccdc_source)
|
||||
return -EINVAL;
|
||||
|
||||
oper_cfg.hw_ops.select_ccdc_source(src_sel);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(vpss_select_ccdc_source);
|
||||
|
||||
static int dm644x_clear_wbl_overflow(enum vpss_wbl_sel wbl_sel)
|
||||
{
|
||||
u32 mask = 1, val;
|
||||
|
||||
if (wbl_sel < VPSS_PCR_AEW_WBL_0 ||
|
||||
wbl_sel > VPSS_PCR_CCDC_WBL_O)
|
||||
return -EINVAL;
|
||||
|
||||
/* writing a 0 clear the overflow */
|
||||
mask = ~(mask << wbl_sel);
|
||||
val = bl_regr(DM644X_SBL_PCR_VPSS) & mask;
|
||||
bl_regw(val, DM644X_SBL_PCR_VPSS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void vpss_set_sync_pol(struct vpss_sync_pol sync)
|
||||
{
|
||||
if (!oper_cfg.hw_ops.set_sync_pol)
|
||||
return;
|
||||
|
||||
oper_cfg.hw_ops.set_sync_pol(sync);
|
||||
}
|
||||
EXPORT_SYMBOL(vpss_set_sync_pol);
|
||||
|
||||
int vpss_clear_wbl_overflow(enum vpss_wbl_sel wbl_sel)
|
||||
{
|
||||
if (!oper_cfg.hw_ops.clear_wbl_overflow)
|
||||
return -EINVAL;
|
||||
|
||||
return oper_cfg.hw_ops.clear_wbl_overflow(wbl_sel);
|
||||
}
|
||||
EXPORT_SYMBOL(vpss_clear_wbl_overflow);
|
||||
|
||||
/*
|
||||
* dm355_enable_clock - Enable VPSS Clock
|
||||
* @clock_sel: Clock to be enabled/disabled
|
||||
* @en: enable/disable flag
|
||||
*
|
||||
* This is called to enable or disable a vpss clock
|
||||
*/
|
||||
static int dm355_enable_clock(enum vpss_clock_sel clock_sel, int en)
|
||||
{
|
||||
unsigned long flags;
|
||||
u32 utemp, mask = 0x1, shift = 0;
|
||||
|
||||
switch (clock_sel) {
|
||||
case VPSS_VPBE_CLOCK:
|
||||
/* nothing since lsb */
|
||||
break;
|
||||
case VPSS_VENC_CLOCK_SEL:
|
||||
shift = 2;
|
||||
break;
|
||||
case VPSS_CFALD_CLOCK:
|
||||
shift = 3;
|
||||
break;
|
||||
case VPSS_H3A_CLOCK:
|
||||
shift = 4;
|
||||
break;
|
||||
case VPSS_IPIPE_CLOCK:
|
||||
shift = 5;
|
||||
break;
|
||||
case VPSS_CCDC_CLOCK:
|
||||
shift = 6;
|
||||
break;
|
||||
default:
|
||||
printk(KERN_ERR "dm355_enable_clock: Invalid selector: %d\n",
|
||||
clock_sel);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&oper_cfg.vpss_lock, flags);
|
||||
utemp = vpss_regr(DM355_VPSSCLK_CLKCTRL);
|
||||
if (!en)
|
||||
utemp &= ~(mask << shift);
|
||||
else
|
||||
utemp |= (mask << shift);
|
||||
|
||||
vpss_regw(utemp, DM355_VPSSCLK_CLKCTRL);
|
||||
spin_unlock_irqrestore(&oper_cfg.vpss_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dm365_enable_clock(enum vpss_clock_sel clock_sel, int en)
|
||||
{
|
||||
unsigned long flags;
|
||||
u32 utemp, mask = 0x1, shift = 0, offset = DM365_ISP5_PCCR;
|
||||
u32 (*read)(u32 offset) = isp5_read;
|
||||
void(*write)(u32 val, u32 offset) = isp5_write;
|
||||
|
||||
switch (clock_sel) {
|
||||
case VPSS_BL_CLOCK:
|
||||
break;
|
||||
case VPSS_CCDC_CLOCK:
|
||||
shift = 1;
|
||||
break;
|
||||
case VPSS_H3A_CLOCK:
|
||||
shift = 2;
|
||||
break;
|
||||
case VPSS_RSZ_CLOCK:
|
||||
shift = 3;
|
||||
break;
|
||||
case VPSS_IPIPE_CLOCK:
|
||||
shift = 4;
|
||||
break;
|
||||
case VPSS_IPIPEIF_CLOCK:
|
||||
shift = 5;
|
||||
break;
|
||||
case VPSS_PCLK_INTERNAL:
|
||||
shift = 6;
|
||||
break;
|
||||
case VPSS_PSYNC_CLOCK_SEL:
|
||||
shift = 7;
|
||||
break;
|
||||
case VPSS_VPBE_CLOCK:
|
||||
read = vpss_regr;
|
||||
write = vpss_regw;
|
||||
offset = DM365_VPBE_CLK_CTRL;
|
||||
break;
|
||||
case VPSS_VENC_CLOCK_SEL:
|
||||
shift = 2;
|
||||
read = vpss_regr;
|
||||
write = vpss_regw;
|
||||
offset = DM365_VPBE_CLK_CTRL;
|
||||
break;
|
||||
case VPSS_LDC_CLOCK:
|
||||
shift = 3;
|
||||
read = vpss_regr;
|
||||
write = vpss_regw;
|
||||
offset = DM365_VPBE_CLK_CTRL;
|
||||
break;
|
||||
case VPSS_FDIF_CLOCK:
|
||||
shift = 4;
|
||||
read = vpss_regr;
|
||||
write = vpss_regw;
|
||||
offset = DM365_VPBE_CLK_CTRL;
|
||||
break;
|
||||
case VPSS_OSD_CLOCK_SEL:
|
||||
shift = 6;
|
||||
read = vpss_regr;
|
||||
write = vpss_regw;
|
||||
offset = DM365_VPBE_CLK_CTRL;
|
||||
break;
|
||||
case VPSS_LDC_CLOCK_SEL:
|
||||
shift = 7;
|
||||
read = vpss_regr;
|
||||
write = vpss_regw;
|
||||
offset = DM365_VPBE_CLK_CTRL;
|
||||
break;
|
||||
default:
|
||||
printk(KERN_ERR "dm365_enable_clock: Invalid selector: %d\n",
|
||||
clock_sel);
|
||||
return -1;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&oper_cfg.vpss_lock, flags);
|
||||
utemp = read(offset);
|
||||
if (!en) {
|
||||
mask = ~mask;
|
||||
utemp &= (mask << shift);
|
||||
} else
|
||||
utemp |= (mask << shift);
|
||||
|
||||
write(utemp, offset);
|
||||
spin_unlock_irqrestore(&oper_cfg.vpss_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vpss_enable_clock(enum vpss_clock_sel clock_sel, int en)
|
||||
{
|
||||
if (!oper_cfg.hw_ops.enable_clock)
|
||||
return -EINVAL;
|
||||
|
||||
return oper_cfg.hw_ops.enable_clock(clock_sel, en);
|
||||
}
|
||||
EXPORT_SYMBOL(vpss_enable_clock);
|
||||
|
||||
void dm365_vpss_set_sync_pol(struct vpss_sync_pol sync)
|
||||
{
|
||||
int val = 0;
|
||||
val = isp5_read(DM365_ISP5_CCDCMUX);
|
||||
|
||||
val |= (sync.ccdpg_hdpol << DM365_CCDC_PG_HD_POL_SHIFT);
|
||||
val |= (sync.ccdpg_vdpol << DM365_CCDC_PG_VD_POL_SHIFT);
|
||||
|
||||
isp5_write(val, DM365_ISP5_CCDCMUX);
|
||||
}
|
||||
EXPORT_SYMBOL(dm365_vpss_set_sync_pol);
|
||||
|
||||
void vpss_set_pg_frame_size(struct vpss_pg_frame_size frame_size)
|
||||
{
|
||||
if (!oper_cfg.hw_ops.set_pg_frame_size)
|
||||
return;
|
||||
|
||||
oper_cfg.hw_ops.set_pg_frame_size(frame_size);
|
||||
}
|
||||
EXPORT_SYMBOL(vpss_set_pg_frame_size);
|
||||
|
||||
void dm365_vpss_set_pg_frame_size(struct vpss_pg_frame_size frame_size)
|
||||
{
|
||||
int current_reg = ((frame_size.hlpfr >> 1) - 1) << 16;
|
||||
|
||||
current_reg |= (frame_size.pplen - 1);
|
||||
isp5_write(current_reg, DM365_ISP5_PG_FRAME_SIZE);
|
||||
}
|
||||
EXPORT_SYMBOL(dm365_vpss_set_pg_frame_size);
|
||||
|
||||
static int vpss_probe(struct platform_device *pdev)
|
||||
{
|
||||
char *platform_name;
|
||||
|
||||
if (!pdev->dev.platform_data) {
|
||||
dev_err(&pdev->dev, "no platform data\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
platform_name = pdev->dev.platform_data;
|
||||
if (!strcmp(platform_name, "dm355_vpss"))
|
||||
oper_cfg.platform = DM355;
|
||||
else if (!strcmp(platform_name, "dm365_vpss"))
|
||||
oper_cfg.platform = DM365;
|
||||
else if (!strcmp(platform_name, "dm644x_vpss"))
|
||||
oper_cfg.platform = DM644X;
|
||||
else {
|
||||
dev_err(&pdev->dev, "vpss driver not supported on this platform\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
dev_info(&pdev->dev, "%s vpss probed\n", platform_name);
|
||||
oper_cfg.vpss_regs_base0 = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(oper_cfg.vpss_regs_base0))
|
||||
return PTR_ERR(oper_cfg.vpss_regs_base0);
|
||||
|
||||
if (oper_cfg.platform == DM355 || oper_cfg.platform == DM365) {
|
||||
oper_cfg.vpss_regs_base1 = devm_platform_ioremap_resource(pdev, 1);
|
||||
if (IS_ERR(oper_cfg.vpss_regs_base1))
|
||||
return PTR_ERR(oper_cfg.vpss_regs_base1);
|
||||
}
|
||||
|
||||
if (oper_cfg.platform == DM355) {
|
||||
oper_cfg.hw_ops.enable_clock = dm355_enable_clock;
|
||||
oper_cfg.hw_ops.select_ccdc_source = dm355_select_ccdc_source;
|
||||
/* Setup vpss interrupts */
|
||||
bl_regw(DM355_VPSSBL_INTSEL_DEFAULT, DM355_VPSSBL_INTSEL);
|
||||
bl_regw(DM355_VPSSBL_EVTSEL_DEFAULT, DM355_VPSSBL_EVTSEL);
|
||||
} else if (oper_cfg.platform == DM365) {
|
||||
oper_cfg.hw_ops.enable_clock = dm365_enable_clock;
|
||||
oper_cfg.hw_ops.select_ccdc_source = dm365_select_ccdc_source;
|
||||
/* Setup vpss interrupts */
|
||||
isp5_write((isp5_read(DM365_ISP5_PCCR) |
|
||||
DM365_ISP5_PCCR_BL_CLK_ENABLE |
|
||||
DM365_ISP5_PCCR_ISIF_CLK_ENABLE |
|
||||
DM365_ISP5_PCCR_H3A_CLK_ENABLE |
|
||||
DM365_ISP5_PCCR_RSZ_CLK_ENABLE |
|
||||
DM365_ISP5_PCCR_IPIPE_CLK_ENABLE |
|
||||
DM365_ISP5_PCCR_IPIPEIF_CLK_ENABLE |
|
||||
DM365_ISP5_PCCR_RSV), DM365_ISP5_PCCR);
|
||||
isp5_write((isp5_read(DM365_ISP5_BCR) |
|
||||
DM365_ISP5_BCR_ISIF_OUT_ENABLE), DM365_ISP5_BCR);
|
||||
isp5_write(DM365_ISP5_INTSEL1_DEFAULT, DM365_ISP5_INTSEL1);
|
||||
isp5_write(DM365_ISP5_INTSEL2_DEFAULT, DM365_ISP5_INTSEL2);
|
||||
isp5_write(DM365_ISP5_INTSEL3_DEFAULT, DM365_ISP5_INTSEL3);
|
||||
} else
|
||||
oper_cfg.hw_ops.clear_wbl_overflow = dm644x_clear_wbl_overflow;
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
pm_runtime_get(&pdev->dev);
|
||||
|
||||
spin_lock_init(&oper_cfg.vpss_lock);
|
||||
dev_info(&pdev->dev, "%s vpss probe success\n", platform_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vpss_remove(struct platform_device *pdev)
|
||||
{
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vpss_suspend(struct device *dev)
|
||||
{
|
||||
pm_runtime_put(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vpss_resume(struct device *dev)
|
||||
{
|
||||
pm_runtime_get(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops vpss_pm_ops = {
|
||||
.suspend = vpss_suspend,
|
||||
.resume = vpss_resume,
|
||||
};
|
||||
|
||||
static struct platform_driver vpss_driver = {
|
||||
.driver = {
|
||||
.name = "vpss",
|
||||
.pm = &vpss_pm_ops,
|
||||
},
|
||||
.remove = vpss_remove,
|
||||
.probe = vpss_probe,
|
||||
};
|
||||
|
||||
static void vpss_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&vpss_driver);
|
||||
iounmap(oper_cfg.vpss_regs_base2);
|
||||
release_mem_region(VPSS_CLK_CTRL, 4);
|
||||
}
|
||||
|
||||
static int __init vpss_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!request_mem_region(VPSS_CLK_CTRL, 4, "vpss_clock_control"))
|
||||
return -EBUSY;
|
||||
|
||||
oper_cfg.vpss_regs_base2 = ioremap(VPSS_CLK_CTRL, 4);
|
||||
if (unlikely(!oper_cfg.vpss_regs_base2)) {
|
||||
ret = -ENOMEM;
|
||||
goto err_ioremap;
|
||||
}
|
||||
|
||||
writel(VPSS_CLK_CTRL_VENCCLKEN |
|
||||
VPSS_CLK_CTRL_DACCLKEN, oper_cfg.vpss_regs_base2);
|
||||
|
||||
ret = platform_driver_register(&vpss_driver);
|
||||
if (ret)
|
||||
goto err_pd_register;
|
||||
|
||||
return 0;
|
||||
|
||||
err_pd_register:
|
||||
iounmap(oper_cfg.vpss_regs_base2);
|
||||
err_ioremap:
|
||||
release_mem_region(VPSS_CLK_CTRL, 4);
|
||||
return ret;
|
||||
}
|
||||
subsys_initcall(vpss_init);
|
||||
module_exit(vpss_exit);
|
|
@ -1,184 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) 2010 Texas Instruments Inc
|
||||
*/
|
||||
#ifndef _VPBE_H
|
||||
#define _VPBE_H
|
||||
|
||||
#include <linux/videodev2.h>
|
||||
#include <linux/i2c.h>
|
||||
|
||||
#include <media/v4l2-dev.h>
|
||||
#include <media/v4l2-ioctl.h>
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/davinci/vpbe_osd.h>
|
||||
#include <media/davinci/vpbe_venc.h>
|
||||
#include <media/davinci/vpbe_types.h>
|
||||
|
||||
/* OSD configuration info */
|
||||
struct osd_config_info {
|
||||
char module_name[32];
|
||||
};
|
||||
|
||||
struct vpbe_output {
|
||||
struct v4l2_output output;
|
||||
/*
|
||||
* If output capabilities include dv_timings, list supported timings
|
||||
* below
|
||||
*/
|
||||
char *subdev_name;
|
||||
/*
|
||||
* default_mode identifies the default timings set at the venc or
|
||||
* external encoder.
|
||||
*/
|
||||
char *default_mode;
|
||||
/*
|
||||
* Fields below are used for supporting multiple modes. For example,
|
||||
* LCD panel might support different modes and they are listed here.
|
||||
* Similarly for supporting external encoders, lcd controller port
|
||||
* requires a set of non-standard timing values to be listed here for
|
||||
* each supported mode since venc is used in non-standard timing mode
|
||||
* for interfacing with external encoder similar to configuring lcd
|
||||
* panel timings
|
||||
*/
|
||||
unsigned int num_modes;
|
||||
struct vpbe_enc_mode_info *modes;
|
||||
/*
|
||||
* Bus configuration goes here for external encoders. Some encoders
|
||||
* may require multiple interface types for each of the output. For
|
||||
* example, SD modes would use YCC8 where as HD mode would use YCC16.
|
||||
* Not sure if this is needed on a per mode basis instead of per
|
||||
* output basis. If per mode is needed, we may have to move this to
|
||||
* mode_info structure
|
||||
*/
|
||||
u32 if_params;
|
||||
};
|
||||
|
||||
/* encoder configuration info */
|
||||
struct encoder_config_info {
|
||||
char module_name[32];
|
||||
/* Is this an i2c device ? */
|
||||
unsigned int is_i2c:1;
|
||||
/* i2c subdevice board info */
|
||||
struct i2c_board_info board_info;
|
||||
};
|
||||
|
||||
/*amplifier configuration info */
|
||||
struct amp_config_info {
|
||||
char module_name[32];
|
||||
/* Is this an i2c device ? */
|
||||
unsigned int is_i2c:1;
|
||||
/* i2c subdevice board info */
|
||||
struct i2c_board_info board_info;
|
||||
};
|
||||
|
||||
/* structure for defining vpbe display subsystem components */
|
||||
struct vpbe_config {
|
||||
char module_name[32];
|
||||
/* i2c bus adapter no */
|
||||
int i2c_adapter_id;
|
||||
struct osd_config_info osd;
|
||||
struct encoder_config_info venc;
|
||||
/* external encoder information goes here */
|
||||
int num_ext_encoders;
|
||||
struct encoder_config_info *ext_encoders;
|
||||
/* amplifier information goes here */
|
||||
struct amp_config_info *amp;
|
||||
unsigned int num_outputs;
|
||||
/* Order is venc outputs followed by LCD and then external encoders */
|
||||
struct vpbe_output *outputs;
|
||||
};
|
||||
|
||||
struct vpbe_device;
|
||||
|
||||
struct vpbe_device_ops {
|
||||
/* Enumerate the outputs */
|
||||
int (*enum_outputs)(struct vpbe_device *vpbe_dev,
|
||||
struct v4l2_output *output);
|
||||
|
||||
/* Set output to the given index */
|
||||
int (*set_output)(struct vpbe_device *vpbe_dev,
|
||||
int index);
|
||||
|
||||
/* Get current output */
|
||||
unsigned int (*get_output)(struct vpbe_device *vpbe_dev);
|
||||
|
||||
/* Set DV preset at current output */
|
||||
int (*s_dv_timings)(struct vpbe_device *vpbe_dev,
|
||||
struct v4l2_dv_timings *dv_timings);
|
||||
|
||||
/* Get DV presets supported at the output */
|
||||
int (*g_dv_timings)(struct vpbe_device *vpbe_dev,
|
||||
struct v4l2_dv_timings *dv_timings);
|
||||
|
||||
/* Enumerate the DV Presets supported at the output */
|
||||
int (*enum_dv_timings)(struct vpbe_device *vpbe_dev,
|
||||
struct v4l2_enum_dv_timings *timings_info);
|
||||
|
||||
/* Set std at the output */
|
||||
int (*s_std)(struct vpbe_device *vpbe_dev, v4l2_std_id std_id);
|
||||
|
||||
/* Get the current std at the output */
|
||||
int (*g_std)(struct vpbe_device *vpbe_dev, v4l2_std_id *std_id);
|
||||
|
||||
/* initialize the device */
|
||||
int (*initialize)(struct device *dev, struct vpbe_device *vpbe_dev);
|
||||
|
||||
/* De-initialize the device */
|
||||
void (*deinitialize)(struct device *dev, struct vpbe_device *vpbe_dev);
|
||||
|
||||
/* Get the current mode info */
|
||||
int (*get_mode_info)(struct vpbe_device *vpbe_dev,
|
||||
struct vpbe_enc_mode_info*);
|
||||
|
||||
/*
|
||||
* Set the current mode in the encoder. Alternate way of setting
|
||||
* standard or DV preset or custom timings in the encoder
|
||||
*/
|
||||
int (*set_mode)(struct vpbe_device *vpbe_dev,
|
||||
struct vpbe_enc_mode_info*);
|
||||
/* Power management operations */
|
||||
int (*suspend)(struct vpbe_device *vpbe_dev);
|
||||
int (*resume)(struct vpbe_device *vpbe_dev);
|
||||
};
|
||||
|
||||
/* struct for vpbe device */
|
||||
struct vpbe_device {
|
||||
/* V4l2 device */
|
||||
struct v4l2_device v4l2_dev;
|
||||
/* vpbe dispay controller cfg */
|
||||
struct vpbe_config *cfg;
|
||||
/* parent device */
|
||||
struct device *pdev;
|
||||
/* external encoder v4l2 sub devices */
|
||||
struct v4l2_subdev **encoders;
|
||||
/* current encoder index */
|
||||
int current_sd_index;
|
||||
/* external amplifier v4l2 subdevice */
|
||||
struct v4l2_subdev *amp;
|
||||
struct mutex lock;
|
||||
/* device initialized */
|
||||
int initialized;
|
||||
/* vpbe dac clock */
|
||||
struct clk *dac_clk;
|
||||
/* osd_device pointer */
|
||||
struct osd_state *osd_device;
|
||||
/* venc device pointer */
|
||||
struct venc_platform_data *venc_device;
|
||||
/*
|
||||
* fields below are accessed by users of vpbe_device. Not the
|
||||
* ones above
|
||||
*/
|
||||
|
||||
/* current output */
|
||||
int current_out_index;
|
||||
/* lock used by caller to do atomic operation on vpbe device */
|
||||
/* current timings set in the controller */
|
||||
struct vpbe_enc_mode_info current_timings;
|
||||
/* venc sub device */
|
||||
struct v4l2_subdev *venc;
|
||||
/* device operations below */
|
||||
struct vpbe_device_ops ops;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,122 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) 2010 Texas Instruments Incorporated - https://www.ti.com/
|
||||
*/
|
||||
#ifndef VPBE_DISPLAY_H
|
||||
#define VPBE_DISPLAY_H
|
||||
|
||||
/* Header files */
|
||||
#include <linux/videodev2.h>
|
||||
#include <media/v4l2-common.h>
|
||||
#include <media/v4l2-fh.h>
|
||||
#include <media/videobuf2-v4l2.h>
|
||||
#include <media/videobuf2-dma-contig.h>
|
||||
#include <media/davinci/vpbe_types.h>
|
||||
#include <media/davinci/vpbe_osd.h>
|
||||
#include <media/davinci/vpbe.h>
|
||||
|
||||
#define VPBE_DISPLAY_MAX_DEVICES 2
|
||||
|
||||
enum vpbe_display_device_id {
|
||||
VPBE_DISPLAY_DEVICE_0,
|
||||
VPBE_DISPLAY_DEVICE_1
|
||||
};
|
||||
|
||||
#define VPBE_DISPLAY_DRV_NAME "vpbe-display"
|
||||
|
||||
#define VPBE_DISPLAY_MAJOR_RELEASE 1
|
||||
#define VPBE_DISPLAY_MINOR_RELEASE 0
|
||||
#define VPBE_DISPLAY_BUILD 1
|
||||
#define VPBE_DISPLAY_VERSION_CODE ((VPBE_DISPLAY_MAJOR_RELEASE << 16) | \
|
||||
(VPBE_DISPLAY_MINOR_RELEASE << 8) | \
|
||||
VPBE_DISPLAY_BUILD)
|
||||
|
||||
#define VPBE_DISPLAY_VALID_FIELD(field) ((V4L2_FIELD_NONE == field) || \
|
||||
(V4L2_FIELD_ANY == field) || (V4L2_FIELD_INTERLACED == field))
|
||||
|
||||
/* Exp ratio numerator and denominator constants */
|
||||
#define VPBE_DISPLAY_H_EXP_RATIO_N 9
|
||||
#define VPBE_DISPLAY_H_EXP_RATIO_D 8
|
||||
#define VPBE_DISPLAY_V_EXP_RATIO_N 6
|
||||
#define VPBE_DISPLAY_V_EXP_RATIO_D 5
|
||||
|
||||
/* Zoom multiplication factor */
|
||||
#define VPBE_DISPLAY_ZOOM_4X 4
|
||||
#define VPBE_DISPLAY_ZOOM_2X 2
|
||||
|
||||
/* Structures */
|
||||
struct display_layer_info {
|
||||
int enable;
|
||||
/* Layer ID used by Display Manager */
|
||||
enum osd_layer id;
|
||||
struct osd_layer_config config;
|
||||
enum osd_zoom_factor h_zoom;
|
||||
enum osd_zoom_factor v_zoom;
|
||||
enum osd_h_exp_ratio h_exp;
|
||||
enum osd_v_exp_ratio v_exp;
|
||||
};
|
||||
|
||||
struct vpbe_disp_buffer {
|
||||
struct vb2_v4l2_buffer vb;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
/* vpbe display object structure */
|
||||
struct vpbe_layer {
|
||||
/* Pointer to the vpbe_display */
|
||||
struct vpbe_display *disp_dev;
|
||||
/* Pointer pointing to current v4l2_buffer */
|
||||
struct vpbe_disp_buffer *cur_frm;
|
||||
/* Pointer pointing to next v4l2_buffer */
|
||||
struct vpbe_disp_buffer *next_frm;
|
||||
/* vb2 specific parameters
|
||||
* Buffer queue used in vb2
|
||||
*/
|
||||
struct vb2_queue buffer_queue;
|
||||
/* Queue of filled frames */
|
||||
struct list_head dma_queue;
|
||||
/* Used for video buffer handling */
|
||||
spinlock_t irqlock;
|
||||
/* V4l2 specific parameters */
|
||||
/* Identifies video device for this layer */
|
||||
struct video_device video_dev;
|
||||
/* Used to store pixel format */
|
||||
struct v4l2_pix_format pix_fmt;
|
||||
enum v4l2_field buf_field;
|
||||
/* Video layer configuration params */
|
||||
struct display_layer_info layer_info;
|
||||
/* vpbe specific parameters
|
||||
* enable window for display
|
||||
*/
|
||||
unsigned char window_enable;
|
||||
/* number of open instances of the layer */
|
||||
unsigned int usrs;
|
||||
/* Indicates id of the field which is being displayed */
|
||||
unsigned int field_id;
|
||||
/* Identifies device object */
|
||||
enum vpbe_display_device_id device_id;
|
||||
/* facilitation of ioctl ops lock by v4l2*/
|
||||
struct mutex opslock;
|
||||
u8 layer_first_int;
|
||||
};
|
||||
|
||||
/* vpbe device structure */
|
||||
struct vpbe_display {
|
||||
/* layer specific parameters */
|
||||
/* lock for isr updates to buf layers*/
|
||||
spinlock_t dma_queue_lock;
|
||||
/* C-Plane offset from start of y-plane */
|
||||
unsigned int cbcr_ofst;
|
||||
struct vpbe_layer *dev[VPBE_DISPLAY_MAX_DEVICES];
|
||||
struct vpbe_device *vpbe_dev;
|
||||
struct osd_state *osd_device;
|
||||
};
|
||||
|
||||
struct buf_config_params {
|
||||
unsigned char min_numbuffers;
|
||||
unsigned char numbuffers[VPBE_DISPLAY_MAX_DEVICES];
|
||||
unsigned int min_bufsize[VPBE_DISPLAY_MAX_DEVICES];
|
||||
unsigned int layer_bufsize[VPBE_DISPLAY_MAX_DEVICES];
|
||||
};
|
||||
|
||||
#endif /* VPBE_DISPLAY_H */
|
|
@ -1,382 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) 2007-2009 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
|
||||
*/
|
||||
#ifndef _OSD_H
|
||||
#define _OSD_H
|
||||
|
||||
#include <media/davinci/vpbe_types.h>
|
||||
|
||||
#define DM644X_VPBE_OSD_SUBDEV_NAME "dm644x,vpbe-osd"
|
||||
#define DM365_VPBE_OSD_SUBDEV_NAME "dm365,vpbe-osd"
|
||||
#define DM355_VPBE_OSD_SUBDEV_NAME "dm355,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 osd_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;
|
||||
};
|
||||
|
||||
/* 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;
|
||||
|
||||
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_version vpbe_type;
|
||||
spinlock_t lock;
|
||||
struct device *dev;
|
||||
dma_addr_t osd_base_phys;
|
||||
void __iomem *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;
|
||||
};
|
||||
|
||||
struct osd_platform_data {
|
||||
int field_inv_wa_enable;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,74 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) 2010 Texas Instruments Inc
|
||||
*/
|
||||
#ifndef _VPBE_TYPES_H
|
||||
#define _VPBE_TYPES_H
|
||||
|
||||
enum vpbe_version {
|
||||
VPBE_VERSION_1 = 1,
|
||||
VPBE_VERSION_2,
|
||||
VPBE_VERSION_3,
|
||||
};
|
||||
|
||||
/* vpbe_timing_type - Timing types used in vpbe device */
|
||||
enum vpbe_enc_timings_type {
|
||||
VPBE_ENC_STD = 0x1,
|
||||
VPBE_ENC_DV_TIMINGS = 0x4,
|
||||
/* Used when set timings through FB device interface */
|
||||
VPBE_ENC_TIMINGS_INVALID = 0x8,
|
||||
};
|
||||
|
||||
/*
|
||||
* struct vpbe_enc_mode_info
|
||||
* @name: ptr to name string of the standard, "NTSC", "PAL" etc
|
||||
* @std: standard or non-standard mode. 1 - standard, 0 - nonstandard
|
||||
* @interlaced: 1 - interlaced, 0 - non interlaced/progressive
|
||||
* @xres: x or horizontal resolution of the display
|
||||
* @yres: y or vertical resolution of the display
|
||||
* @fps: frame per second
|
||||
* @left_margin: left margin of the display
|
||||
* @right_margin: right margin of the display
|
||||
* @upper_margin: upper margin of the display
|
||||
* @lower_margin: lower margin of the display
|
||||
* @hsync_len: h-sync length
|
||||
* @vsync_len: v-sync length
|
||||
* @flags: bit field: bit usage is documented below
|
||||
*
|
||||
* Description:
|
||||
* Structure holding timing and resolution information of a standard.
|
||||
* Used by vpbe_device to set required non-standard timing in the
|
||||
* venc when lcd controller output is connected to a external encoder.
|
||||
* A table of timings is maintained in vpbe device to set this in
|
||||
* venc when external encoder is connected to lcd controller output.
|
||||
* Encoder may provide a g_dv_timings() API to override these values
|
||||
* as needed.
|
||||
*
|
||||
* Notes
|
||||
* ------
|
||||
* if_type should be used only by encoder manager and encoder.
|
||||
* flags usage
|
||||
* b0 (LSB) - hsync polarity, 0 - negative, 1 - positive
|
||||
* b1 - vsync polarity, 0 - negative, 1 - positive
|
||||
* b2 - field id polarity, 0 - negative, 1 - positive
|
||||
*/
|
||||
struct vpbe_enc_mode_info {
|
||||
unsigned char *name;
|
||||
enum vpbe_enc_timings_type timings_type;
|
||||
v4l2_std_id std_id;
|
||||
struct v4l2_dv_timings dv_timings;
|
||||
unsigned int interlaced;
|
||||
unsigned int xres;
|
||||
unsigned int yres;
|
||||
struct v4l2_fract aspect;
|
||||
struct v4l2_fract fps;
|
||||
unsigned int left_margin;
|
||||
unsigned int right_margin;
|
||||
unsigned int upper_margin;
|
||||
unsigned int lower_margin;
|
||||
unsigned int hsync_len;
|
||||
unsigned int vsync_len;
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,37 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) 2010 Texas Instruments Inc
|
||||
*/
|
||||
#ifndef _VPBE_VENC_H
|
||||
#define _VPBE_VENC_H
|
||||
|
||||
#include <media/v4l2-subdev.h>
|
||||
#include <media/davinci/vpbe_types.h>
|
||||
|
||||
#define DM644X_VPBE_VENC_SUBDEV_NAME "dm644x,vpbe-venc"
|
||||
#define DM365_VPBE_VENC_SUBDEV_NAME "dm365,vpbe-venc"
|
||||
#define DM355_VPBE_VENC_SUBDEV_NAME "dm355,vpbe-venc"
|
||||
|
||||
/* venc events */
|
||||
#define VENC_END_OF_FRAME BIT(0)
|
||||
#define VENC_FIRST_FIELD BIT(1)
|
||||
#define VENC_SECOND_FIELD BIT(2)
|
||||
|
||||
struct venc_platform_data {
|
||||
int (*setup_pinmux)(u32 if_type, int field);
|
||||
int (*setup_clock)(enum vpbe_enc_timings_type type,
|
||||
unsigned int pixclock);
|
||||
int (*setup_if_config)(u32 pixcode);
|
||||
/* Number of LCD outputs supported */
|
||||
int num_lcd_outputs;
|
||||
struct vpbe_if_params *lcd_if_params;
|
||||
};
|
||||
|
||||
enum venc_ioctls {
|
||||
VENC_GET_FLD = 1,
|
||||
};
|
||||
|
||||
/* exported functions */
|
||||
struct v4l2_subdev *venc_sub_dev_init(struct v4l2_device *v4l2_dev,
|
||||
const char *venc_name);
|
||||
#endif
|
|
@ -1,111 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (C) 2009 Texas Instruments Inc
|
||||
*
|
||||
* vpss - video processing subsystem module header file.
|
||||
*
|
||||
* Include this header file if a driver needs to configure vpss system
|
||||
* module. It exports a set of library functions for video drivers to
|
||||
* configure vpss system module functions such as clock enable/disable,
|
||||
* vpss interrupt mux to arm, and other common vpss system module
|
||||
* functions.
|
||||
*/
|
||||
#ifndef _VPSS_H
|
||||
#define _VPSS_H
|
||||
|
||||
/* selector for ccdc input selection on DM355 */
|
||||
enum vpss_ccdc_source_sel {
|
||||
VPSS_CCDCIN,
|
||||
VPSS_HSSIIN,
|
||||
VPSS_PGLPBK, /* for DM365 only */
|
||||
VPSS_CCDCPG /* for DM365 only */
|
||||
};
|
||||
|
||||
struct vpss_sync_pol {
|
||||
unsigned int ccdpg_hdpol:1;
|
||||
unsigned int ccdpg_vdpol:1;
|
||||
};
|
||||
|
||||
struct vpss_pg_frame_size {
|
||||
short hlpfr;
|
||||
short pplen;
|
||||
};
|
||||
|
||||
/* Used for enable/disable VPSS Clock */
|
||||
enum vpss_clock_sel {
|
||||
/* DM355/DM365 */
|
||||
VPSS_CCDC_CLOCK,
|
||||
VPSS_IPIPE_CLOCK,
|
||||
VPSS_H3A_CLOCK,
|
||||
VPSS_CFALD_CLOCK,
|
||||
/*
|
||||
* When using VPSS_VENC_CLOCK_SEL in vpss_enable_clock() api
|
||||
* following applies:-
|
||||
* en = 0 selects ENC_CLK
|
||||
* en = 1 selects ENC_CLK/2
|
||||
*/
|
||||
VPSS_VENC_CLOCK_SEL,
|
||||
VPSS_VPBE_CLOCK,
|
||||
/* DM365 only clocks */
|
||||
VPSS_IPIPEIF_CLOCK,
|
||||
VPSS_RSZ_CLOCK,
|
||||
VPSS_BL_CLOCK,
|
||||
/*
|
||||
* When using VPSS_PCLK_INTERNAL in vpss_enable_clock() api
|
||||
* following applies:-
|
||||
* en = 0 disable internal PCLK
|
||||
* en = 1 enables internal PCLK
|
||||
*/
|
||||
VPSS_PCLK_INTERNAL,
|
||||
/*
|
||||
* When using VPSS_PSYNC_CLOCK_SEL in vpss_enable_clock() api
|
||||
* following applies:-
|
||||
* en = 0 enables MMR clock
|
||||
* en = 1 enables VPSS clock
|
||||
*/
|
||||
VPSS_PSYNC_CLOCK_SEL,
|
||||
VPSS_LDC_CLOCK_SEL,
|
||||
VPSS_OSD_CLOCK_SEL,
|
||||
VPSS_FDIF_CLOCK,
|
||||
VPSS_LDC_CLOCK
|
||||
};
|
||||
|
||||
/* select input to ccdc on dm355 */
|
||||
int vpss_select_ccdc_source(enum vpss_ccdc_source_sel src_sel);
|
||||
/* enable/disable a vpss clock, 0 - success, -1 - failure */
|
||||
int vpss_enable_clock(enum vpss_clock_sel clock_sel, int en);
|
||||
/* set sync polarity, only for DM365*/
|
||||
void dm365_vpss_set_sync_pol(struct vpss_sync_pol);
|
||||
/* set the PG_FRAME_SIZE register, only for DM365 */
|
||||
void dm365_vpss_set_pg_frame_size(struct vpss_pg_frame_size);
|
||||
|
||||
/* wbl reset for dm644x */
|
||||
enum vpss_wbl_sel {
|
||||
VPSS_PCR_AEW_WBL_0 = 16,
|
||||
VPSS_PCR_AF_WBL_0,
|
||||
VPSS_PCR_RSZ4_WBL_0,
|
||||
VPSS_PCR_RSZ3_WBL_0,
|
||||
VPSS_PCR_RSZ2_WBL_0,
|
||||
VPSS_PCR_RSZ1_WBL_0,
|
||||
VPSS_PCR_PREV_WBL_0,
|
||||
VPSS_PCR_CCDC_WBL_O,
|
||||
};
|
||||
/* clear wbl overflow flag for DM6446 */
|
||||
int vpss_clear_wbl_overflow(enum vpss_wbl_sel wbl_sel);
|
||||
|
||||
/* set sync polarity*/
|
||||
void vpss_set_sync_pol(struct vpss_sync_pol sync);
|
||||
/* set the PG_FRAME_SIZE register */
|
||||
void vpss_set_pg_frame_size(struct vpss_pg_frame_size frame_size);
|
||||
/*
|
||||
* vpss_check_and_clear_interrupt - check and clear interrupt
|
||||
* @irq - common enumerator for IRQ
|
||||
*
|
||||
* Following return values used:-
|
||||
* 0 - interrupt occurred and cleared
|
||||
* 1 - interrupt not occurred
|
||||
* 2 - interrupt status not available
|
||||
*/
|
||||
int vpss_dma_complete_interrupt(void);
|
||||
|
||||
#endif
|
Загрузка…
Ссылка в новой задаче