@@ -522,6 +522,12 @@ config VIDEO_DM355_AEW
the control loops for Auto Exposure and Auto White Balance. It collects
metrics about the image or video data
+config VIDEO_DM355_IPIPE
+ depends on ARCH_DAVINCI_DM355
+ tristate "DM355 IPIPE"
+ help
+ DM355 IPIPE driver
+
source "drivers/media/video/bt8xx/Kconfig"
config VIDEO_PMS
@@ -2,3 +2,5 @@ dm355_af_driver-objs += dm355_af.o dm355_af_hw.o
obj-$(CONFIG_VIDEO_DM355_AF) += dm355_af_driver.o
dm355_aew_driver-objs += dm355_aew.o dm355_aew_hw.o
obj-$(CONFIG_VIDEO_DM355_AEW) += dm355_aew_driver.o
+dm355_ipipe_driver-objs += dm355_ipipe.o dm355_ipipe_hw.o
+obj-$(CONFIG_VIDEO_DM355_IPIPE) += dm355_ipipe_driver.o
new file mode 100644
@@ -0,0 +1,1632 @@
+/*
+ * Copyright (C) 2009 Texas Instruments Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/cdev.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/uaccess.h>
+#include <linux/platform_device.h>
+#include <linux/semaphore.h>
+#include <media/davinci/dm355_ipipe_hw.h>
+#include <linux/major.h>
+#include <media/davinci/dm355_ipipe.h>
+
+#include "ipipe_para.h"
+
+/* Keeps track of how many times the device driver has been opened */
+static atomic_t reference_count = ATOMIC_INIT(0);
+
+static struct class *ipipe_class;
+struct device *ipipe_dev;
+
+static irqreturn_t ipipe_isr(int irq, void *device_id)
+{
+
+ struct ipipe_device *ipipedevice = (struct ipipe_device *)device_id;
+ dev_dbg(ipipe_dev, "IPIPE isr returned.\n");
+ /* indicate the completion ofr frame processing */
+ if (ipipedevice)
+ complete(&(ipipedevice->wfc));
+
+ return IRQ_HANDLED;
+}
+
+#define DRIVERNAME "DM355IPIPE"
+
+/* global object of ipipe_device structure */
+struct ipipe_device ipipedevice = { 0 };
+
+/* inline function to free reserver pages */
+inline void ipipe_free_pages(unsigned long addr, unsigned long bufsize)
+{
+ unsigned long size, ad = addr;
+ size = PAGE_SIZE << (get_order(bufsize));
+ if (!addr)
+ return;
+ while (size > 0) {
+ ClearPageReserved(virt_to_page(addr));
+ addr += PAGE_SIZE;
+ size -= PAGE_SIZE;
+ }
+ free_pages(ad, get_order(bufsize));
+}
+
+/* This function is used to free memory allocated to buffers */
+int free_buffers(struct ipipe_device *device)
+{
+ int i;
+ unsigned long adr;
+ if (!device) {
+ dev_err(ipipe_dev, "\nfree_buffers:error in argument");
+ return -EINVAL;
+ }
+ /* free memory allocated to in buffers */
+ for (i = 0; i < device->in_numbuffers; i++) {
+ if (device->in_buff[i]) {
+ adr = device->in_buff[i]->offset;
+ if (adr)
+ ipipe_free_pages((unsigned long)
+ phys_to_virt(adr),
+ device->in_buff[i]->size);
+
+ kfree(device->in_buff[i]);
+
+ device->in_buff[i] = NULL;
+ }
+ }
+ device->in_numbuffers = 0;
+ /* free memory allocated to out buffers */
+ for (i = 0; i < device->out_numbuffers; i++) {
+ if (device->out_buff[i]) {
+ adr = device->out_buff[i]->offset;
+ if (adr)
+ ipipe_free_pages((unsigned long)
+ phys_to_virt(adr),
+ device->out_buff[i]->size);
+
+ kfree(device->out_buff[i]);
+
+ device->out_buff[i] = NULL;
+ }
+ }
+
+ device->out_numbuffers = 0;
+ return 0;
+}
+
+/*
+ * This function will query the buffer's physical address
+ * whose index is passed in ipipe_buffer.
+ * It will store that address in ipipe_buffer.
+ */
+int query_buffer(struct ipipe_device *device, struct ipipe_buffer *buffer)
+{
+
+ if (!buffer || !device) {
+ dev_err(ipipe_dev, "query_buffer: error in argument\n");
+ return -EINVAL;
+ }
+
+ if (buffer->index < 0) {
+ dev_err(ipipe_dev, "query_buffer: invalid index %d\n",
+ buffer->index);
+ return -EINVAL;
+ }
+
+ if ((buffer->buf_type != IPIPE_BUF_IN)
+ && (buffer->buf_type != IPIPE_BUF_OUT)) {
+ dev_err(ipipe_dev, "request_buffer: invalid buffer type\n");
+ return -EINVAL;
+ }
+ /* if buf_type is input buffer then get offset of input buffer */
+ if (buffer->buf_type == IPIPE_BUF_IN) {
+ /* error checking for wrong index number */
+ if (buffer->index >= device->in_numbuffers) {
+ dev_err(ipipe_dev, "query_buffer: invalid index");
+
+ return -EINVAL;
+ }
+
+ /* get the offset and size of the buffer and store
+ it in buffer */
+ buffer->offset = device->in_buff[buffer->index]->offset;
+ buffer->size = device->in_buff[buffer->index]->size;
+ }
+ /* if buf_type is output buffer then get offset of output buffer */
+ else if (buffer->buf_type == IPIPE_BUF_OUT) {
+ /* error checking for wrong index number */
+ if (buffer->index >= device->out_numbuffers) {
+ dev_err(ipipe_dev, "query_buffer: invalid index\n");
+
+ return -EINVAL;
+ }
+ /* get the offset and size of the buffer and store
+ it in buffer */
+ buffer->offset = device->out_buff[buffer->index]->offset;
+ buffer->size = device->out_buff[buffer->index]->size;
+ } else {
+ dev_err(ipipe_dev, "query_buffer: invalid buffer type\n");
+
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int request_buffer(struct ipipe_device *device, struct ipipe_reqbufs *reqbufs)
+{
+ struct ipipe_buffer *buffer = NULL;
+ int count = 0;
+ unsigned long adr;
+ u32 size;
+
+ if (!reqbufs || !device) {
+ dev_err(ipipe_dev, "request_buffer: error in argument\n");
+ return -EINVAL;
+ }
+
+ /* if number of buffers requested is more then support return error */
+ if (reqbufs->count > MAX_BUFFER) {
+ dev_err(ipipe_dev, "request_buffer: invalid buffer count\n");
+ return -EINVAL;
+ }
+
+ if ((reqbufs->buf_type != IPIPE_BUF_IN)
+ && (reqbufs->buf_type != IPIPE_BUF_OUT)) {
+ dev_err(ipipe_dev, "request_buffer: invalid buffer type %d\n",
+ reqbufs->buf_type);
+ return -EINVAL;
+ }
+ if (reqbufs->count < 0) {
+ dev_err(ipipe_dev, "request_buffer: invalid buffer count %d\n",
+ reqbufs->count);
+ return -EINVAL;
+ }
+ /* if buf_type is input then allocate buffers for input */
+ if (reqbufs->buf_type == IPIPE_BUF_IN) {
+ /*if buffer count is zero, free all the buffers */
+ if (reqbufs->count == 0) {
+ /* free all the buffers */
+ for (count = 0; count < device->in_numbuffers;
+ count++) {
+ /* free memory allocate for the image */
+ if (device->in_buff[count]) {
+ adr =
+ (unsigned long)device->
+ in_buff[count]->offset;
+ if (adr)
+ ipipe_free_pages(
+ (unsigned long)
+ phys_to_virt(adr),
+ device->in_buff
+ [count]->size);
+
+ /*
+ * free the memory allocated
+ * to ipipe_buffer
+ */
+ kfree(device->in_buff[count]);
+
+ device->in_buff[count] = NULL;
+ }
+ }
+ device->in_numbuffers = 0;
+ return 0;
+ }
+
+ /* free the extra buffers */
+ if (device->in_numbuffers > reqbufs->count &&
+ reqbufs->size == device->in_buff[0]->size) {
+ for (count = reqbufs->count;
+ count < device->in_numbuffers; count++) {
+ /* free memory allocate for the image */
+ if (device->in_buff[count]) {
+ adr = device->in_buff[count]->offset;
+ if (adr)
+ ipipe_free_pages((unsigned long)
+ phys_to_virt
+ (adr),
+ device->in_buff
+ [count]->size);
+
+ /* free the memory allocated
+ to ipipe_buffer */
+ kfree(device->in_buff[count]);
+
+ device->in_buff[count] = NULL;
+ }
+ }
+ device->in_numbuffers = reqbufs->count;
+ return 0;
+ }
+ /* if size requested is different from already allocated,
+ free memory of all already allocated buffers */
+ if (device->in_numbuffers) {
+ if (reqbufs->size != device->in_buff[0]->size) {
+ for (count = 0;
+ count < device->in_numbuffers; count++) {
+ if (device->in_buff[count]) {
+ adr =
+ device->
+ in_buff[count]->offset;
+ if (adr)
+ ipipe_free_pages(
+ (unsigned long)
+ phys_to_virt
+ (adr),
+ device->
+ in_buff
+ [count]->
+ size);
+
+ kfree(device->in_buff[count]);
+
+ device->in_buff[count] = NULL;
+ }
+ }
+ device->in_numbuffers = 0;
+ }
+ }
+
+ /* allocate the buffer */
+ for (count = device->in_numbuffers; count < reqbufs->count;
+ count++) {
+ /* Allocate memory for struct ipipe_buffer */
+ buffer =
+ kmalloc(sizeof(struct ipipe_buffer), GFP_KERNEL);
+
+ /* if memory allocation fails then return error */
+ if (!buffer) {
+ /* free all the buffers */
+ while (--count >= device->in_numbuffers) {
+ adr = device->in_buff[count]->offset;
+ if (adr)
+ ipipe_free_pages((unsigned long)
+ phys_to_virt
+ (adr),
+ device->in_buff
+ [count]->size);
+ kfree(device->in_buff[count]);
+ device->in_buff[count] = NULL;
+ }
+ dev_err(ipipe_dev, "1.request_buffer:not \
+ enough memory\n");
+ return -ENOMEM;
+ }
+
+ /* assign buffer's address in configuration */
+ device->in_buff[count] = buffer;
+
+ /* set buffers index and buf_type,size parameters */
+ buffer->index = count;
+ buffer->buf_type = IPIPE_BUF_IN;
+ buffer->size = reqbufs->size;
+ /* allocate memory for buffer of size passed
+ in reqbufs */
+ buffer->offset =
+ (unsigned long)__get_free_pages(GFP_KERNEL |
+ GFP_DMA,
+ get_order
+ (reqbufs->size));
+
+ /* if memory allocation fails, return error */
+ if (!(buffer->offset)) {
+ /* free all the buffer's space */
+ kfree(buffer);
+ device->in_buff[count] = NULL;
+ while (--count >= device->in_numbuffers) {
+ adr = device->in_buff[count]->offset;
+ if (adr)
+ ipipe_free_pages((unsigned long)
+ phys_to_virt
+ (adr),
+ device->in_buff
+ [count]->size);
+ kfree(device->in_buff[count]);
+ device->in_buff[count] = NULL;
+ }
+ dev_err(ipipe_dev, "2.request_buffer:not \
+ enough memory\n");
+
+ return -ENOMEM;
+ }
+
+ adr = (unsigned long)buffer->offset;
+ size = PAGE_SIZE << (get_order(reqbufs->size));
+ while (size > 0) {
+ /* make sure the frame buffers
+ are never swapped out of memory */
+ SetPageReserved(virt_to_page(adr));
+ adr += PAGE_SIZE;
+ size -= PAGE_SIZE;
+ }
+ /* convert vertual address to physical */
+ buffer->offset = (unsigned long)
+ virt_to_phys((void *)(buffer->offset));
+ }
+ device->in_numbuffers = reqbufs->count;
+ }
+
+ /* if buf_type is output then allocate buffers for output */
+ else if (reqbufs->buf_type == IPIPE_BUF_OUT) {
+ if (reqbufs->count == 0) {
+ /* free all the buffers */
+ for (count = 0; count < device->out_numbuffers;
+ count++) {
+ /* free memory allocate for the image */
+ if (device->out_buff[count]) {
+ adr = device->out_buff[count]->offset;
+ if (adr)
+ ipipe_free_pages(
+ (unsigned long)
+ phys_to_virt
+ (adr),
+ device->out_buff
+ [count]->size);
+
+ /*
+ * Free the memory allocated to
+ * ipipe_buffer
+ */
+ kfree(device->out_buff[count]);
+
+ device->out_buff[count] = NULL;
+ }
+ }
+ device->out_numbuffers = 0;
+
+ return 0;
+ }
+ /* free the buffers */
+ if (device->out_numbuffers > reqbufs->count &&
+ reqbufs->size == device->out_buff[0]->size) {
+ for (count = reqbufs->count;
+ count < device->out_numbuffers; count++) {
+ /* free memory allocate for the image */
+ if (device->out_buff[count]) {
+ adr = device->out_buff[count]->offset;
+ if (adr)
+ ipipe_free_pages((unsigned long)
+ phys_to_virt
+ (adr),
+ device->
+ out_buff
+ [count]->size);
+
+ /*
+ * free the memory allocated to
+ * ipipe_buffer
+ */
+ kfree(device->out_buff[count]);
+
+ device->out_buff[count] = NULL;
+ }
+ }
+ device->out_numbuffers = reqbufs->count;
+
+ return 0;
+ }
+ /*
+ * if size requested is different from already allocated,
+ * free memory of all already allocated buffers
+ */
+ if (device->out_numbuffers) {
+ if (reqbufs->size != device->out_buff[0]->size) {
+ for (count = 0;
+ count < device->out_numbuffers; count++) {
+ if (device->out_buff[count]) {
+ adr =
+ device->
+ out_buff[count]->offset;
+
+ if (adr)
+ ipipe_free_pages(
+ (unsigned long)
+ phys_to_virt
+ (adr),
+ device->
+ out_buff
+ [count]->size);
+
+ kfree(device->out_buff[count]);
+
+ device->out_buff[count] = NULL;
+ }
+ }
+ device->out_numbuffers = 0;
+ }
+ }
+
+ /* allocate the buffer */
+ for (count = device->out_numbuffers;
+ count < reqbufs->count; count++) {
+ /* Allocate memory for struct ipipe_buffer */
+ buffer =
+ kmalloc(sizeof(struct ipipe_buffer), GFP_KERNEL);
+
+ /* if memory allocation fails then return error */
+ if (!buffer) {
+ /* free all the buffers */
+ while (--count >= device->out_numbuffers) {
+ adr = device->out_buff[count]->offset;
+ if (adr)
+ ipipe_free_pages((unsigned long)
+ phys_to_virt
+ (adr),
+ device->
+ out_buff
+ [count]->size);
+ kfree(device->out_buff[count]);
+ device->out_buff[count] = NULL;
+ }
+
+ dev_err(ipipe_dev,
+ "3.request_buffer:not enough \
+ memory\n");
+
+ return -ENOMEM;
+ }
+
+ /* assign buffer's address out configuration */
+ device->out_buff[count] = buffer;
+
+ /* set buffers outdex and buf_type,size parameters */
+ buffer->index = count;
+ buffer->buf_type = IPIPE_BUF_OUT;
+ buffer->size = reqbufs->size;
+ /* allocate memory for buffer of size passed
+ in reqbufs */
+ buffer->offset =
+ (unsigned long)__get_free_pages(GFP_KERNEL |
+ GFP_DMA,
+ get_order
+ (reqbufs->size));
+
+ /* if memory allocation fails, return error */
+ if (!(buffer->offset)) {
+ /* free all the buffer's space */
+ kfree(buffer);
+ device->out_buff[count] = NULL;
+ while (--count >= device->out_numbuffers) {
+ adr = device->out_buff[count]->offset;
+ if (adr)
+ ipipe_free_pages((unsigned long)
+ phys_to_virt
+ (adr),
+ device->
+ out_buff
+ [count]->size);
+ kfree(device->out_buff[count]);
+ device->out_buff[count] = NULL;
+ }
+ dev_err(ipipe_dev, "4.request_buffer:not \
+ enough memory\n");
+
+ return -ENOMEM;
+ }
+
+ adr = (unsigned long)buffer->offset;
+ size = PAGE_SIZE << (get_order(reqbufs->size));
+ while (size > 0) {
+ /* make sure the frame buffers
+ are never swapped out of memory */
+ SetPageReserved(virt_to_page(adr));
+ adr += PAGE_SIZE;
+ size -= PAGE_SIZE;
+ }
+ /* convert vertual address to physical */
+ buffer->offset = (unsigned long)
+ virt_to_phys((void *)(buffer->offset));
+ }
+ device->out_numbuffers = reqbufs->count;
+ } else {
+ dev_err(ipipe_dev, "request_buffer: invalid buffer type\n");
+
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* Functions */
+int ipipe_open(struct inode *inode, struct file *filp)
+{
+ struct ipipe_params *config = NULL;
+
+ if (atomic_inc_return(&reference_count) != 1) {
+ dev_err(ipipe_dev, "ipipe_open: device is already openend\n");
+ return -EBUSY;
+ }
+
+ /* allocate memory for a new configuration */
+ config = kmalloc(sizeof(struct ipipe_params), GFP_KERNEL);
+ if (config == NULL)
+ return -ENOMEM;
+
+ /* store the pointer of ipipe_params in private_data member of file
+ and params member of ipipe_device */
+ filp->private_data = config;
+
+ /* initialize mutex to 0 */
+ ipipedevice.params = config;
+ ipipedevice.opened = 1;
+ ipipedevice.in_numbuffers = 0;
+ ipipedevice.out_numbuffers = 0;
+ init_completion(&(ipipedevice.wfc));
+ ipipedevice.wfc.done = 0;
+ init_MUTEX(&(ipipedevice.sem));
+
+ return 0;
+}
+int write_out_addr(int resize_no, unsigned int address)
+{
+ unsigned int utemp;
+ unsigned int rsz_start_add;
+ if ((resize_no == 0) || (resize_no == 1)) {
+ if (resize_no)
+ rsz_start_add = RSZ_EN_1;
+ else
+ rsz_start_add = RSZ_EN_0;
+ } else
+ return -EINVAL;
+
+ utemp = address & SET_LOW_ADD;
+ regw_ip(utemp, rsz_start_add + RSZ_SDR_BAD_L);
+ regw_ip(utemp, rsz_start_add + RSZ_SDR_SAD_L);
+
+ utemp = (address & SET_HIGH_ADD) >> 16;
+ regw_ip(utemp, rsz_start_add + RSZ_SDR_BAD_H);
+ regw_ip(utemp, rsz_start_add + RSZ_SDR_SAD_H);
+ return 0;
+}
+int validate_params(struct ipipe_params *params)
+{
+
+ u32 data_format;
+
+ if ((params->ipipeif_param.source == SDRAM_RAW) &&
+ (params->ipipe_dpaths_fmt == YUV2YUV)) {
+
+ dev_err(ipipe_dev,
+ "validate:input source and"
+ " data format does not match\n");
+ return -EINVAL;
+ }
+
+ if ((params->ipipeif_param.source == SDRAM_YUV) &&
+ (params->ipipe_dpaths_fmt == RAW2YUV)) {
+
+ dev_err(ipipe_dev,
+ "validate:input source and"
+ " data format does not match\n");
+ return -EINVAL;
+ }
+
+ if ((params->ipipeif_param.source < CCDC) ||
+ (params->ipipeif_param.source > SDRAM_YUV)) {
+
+ dev_err(ipipe_dev,
+ "validate:invalidate input source of ipipeif\n");
+ return -EINVAL;
+ }
+
+ if (params->ipipeif_param.source == CCDC_DARKFM) {
+ if (!(params->ipipeif_param.glob_ver_size)) {
+
+ dev_err(ipipe_dev, "validate:glob_ver_size is 0\n");
+ return -EINVAL;
+ }
+ /*
+ * Data should be read from SDRAM with CFG.ALAW set to .0 and
+ * CFG.PACK8IN set to 1
+ */
+ if ((params->ipipeif_param.ialaw)
+ || (!(params->ipipeif_param.pack_mode))) {
+
+ dev_err(ipipe_dev,
+ "validate: error in either"
+ " ialaw or ipipeif pack mode\n");
+ return -EINVAL;
+ }
+ }
+
+ if ((params->ipipeif_param.source == CCDC_DARKFM)
+ || (params->ipipeif_param.source == CCDC)) {
+ if (params->ipipeif_param.clock_select) {
+ dev_err(ipipe_dev, "validate:error in clock select\n");
+ return -EINVAL;
+ }
+ }
+
+ if (params->ipipeif_param.decimation) {
+ if ((params->ipipeif_param.rsz < ONE) ||
+ (params->ipipeif_param.rsz > ONE_SEVENTH)) {
+ dev_err(ipipe_dev,
+ "validate:error in resize"
+ " factor for decimation \n");
+ return -EINVAL;
+ }
+ }
+
+ if (params->ipipeif_param.clock_select) {
+ if ((params->ipipeif_param.clk_div < DIVIDE_HALF) ||
+ (params->ipipeif_param.clk_div > DIVIDE_THIRTY)) {
+ dev_err(ipipe_dev,
+ "validate:error in clock"
+ " divisor factor value\n");
+ return -EINVAL;
+ }
+ }
+
+ if ((params->ipipeif_param.data_shift < BITS15_2)
+ || (params->ipipeif_param.data_shift > BITS9_0)) {
+
+ dev_err(ipipe_dev, "validate:error in data shift value\n");
+ return -EINVAL;
+ }
+
+ if ((params->ipipeif_param.clock_select != SDRAM_CLK)
+ && (params->ipipeif_param.clock_select != PIXCEL_CLK)) {
+
+ dev_err(ipipe_dev, "validate:error in clock select value\n");
+ return -EINVAL;
+ }
+ if ((params->ipipeif_param.ialaw != ALAW_OFF)
+ && (params->ipipeif_param.ialaw != ALAW_ON)) {
+
+ dev_err(ipipe_dev, "validate:error in ialaw value\n");
+ return -EINVAL;
+ }
+ if ((params->ipipeif_param.pack_mode != SIXTEEN_BIT)
+ && (params->ipipeif_param.pack_mode != EIGHT_BIT)) {
+
+ dev_err(ipipe_dev, "validate:error in pack mode value\n");
+ return -EINVAL;
+ }
+
+ if ((params->ipipeif_param.avg_filter != AVG_OFF)
+ && (params->ipipeif_param.avg_filter != AVG_ON)) {
+
+ dev_err(ipipe_dev, "validate:error in average filter value\n");
+ return -EINVAL;
+ }
+
+ if ((params->ipipeif_param.decimation != DECIMATION_OFF)
+ && (params->ipipeif_param.decimation != DECIMATION_ON)) {
+
+ dev_err(ipipe_dev, "validate:error in decimation value\n");
+ return -EINVAL;
+ }
+
+ if ((params->ipipeif_param.mode != CONTINUOUS)
+ && (params->ipipeif_param.mode != ONE_SHOT)) {
+
+ dev_err(ipipe_dev, "validate:error in ipipeif mode value\n");
+ return -EINVAL;
+ }
+
+ data_format =
+ (params->ipipe_dpaths_fmt | (params->ipipe_dpaths_bypass) << 2);
+ /*in raw pass through mode data can be < 4096 */
+ if (data_format == RAW2RAW_BYPASS) {
+ if (params->ipipe_hsz > MAX_SIZE_RAW_BY_PASS) {
+
+ dev_err(ipipe_dev,
+ "validate:invalid ipipe horizontal size\n");
+ return -EINVAL;
+ }
+ }
+ if (data_format != RAW2RAW_BYPASS) {
+ if (params->ipipe_hsz > MAX_SIZE) {
+
+ dev_err(ipipe_dev,
+ "validate:invalid ipipe horizontal size\n");
+ return -EINVAL;
+ }
+ }
+
+ if ((params->ipipe_mode != 0) && (params->ipipe_mode != 1)) {
+
+ dev_err(ipipe_dev, "validate:invalid ipipe mode\n");
+ return -EINVAL;
+ }
+ if ((params->ipipe_dpaths_bypass != RAW_MODE_OFF) &&
+ (params->ipipe_dpaths_bypass != RAW_MODE_ON)) {
+
+ dev_err(ipipe_dev, "validate:invalid ipipe datapath\n");
+ return -EINVAL;
+
+ }
+ if ((params->ipipe_colpat_elep < RED)
+ || (params->ipipe_colpat_elep > BLUE)) {
+
+ dev_err(ipipe_dev, "validate:invalid elep value\n");
+ return -EINVAL;
+ }
+ if ((params->ipipe_colpat_elop < RED)
+ || (params->ipipe_colpat_elop > BLUE)) {
+
+ dev_err(ipipe_dev, "validate:invalid elop value\n");
+ return -EINVAL;
+ }
+ if ((params->ipipe_colpat_olep < RED)
+ || (params->ipipe_colpat_olep > BLUE)) {
+
+ dev_err(ipipe_dev, "validate:invalid olep value\n");
+ return -EINVAL;
+ }
+ if ((params->ipipe_colpat_olop < RED)
+ || (params->ipipe_colpat_olop > BLUE)) {
+
+ dev_err(ipipe_dev, "validate:invalid olop value\n");
+ return -EINVAL;
+ }
+
+ if (params->def_cor.dfc_en) {
+ if ((params->def_cor.dfc_sel != FROMTOP)
+ && (params->def_cor.dfc_sel != FROMBOTTON)) {
+
+ dev_err(ipipe_dev,
+ "validate:invalid copy method"
+ " in defect correction\n");
+ return -EINVAL;
+ }
+ if (params->def_cor.dfc_siz > 1024) {
+
+ dev_err(ipipe_dev,
+ "validate:invalid defect"
+ " correction table size\n");
+ return -EINVAL;
+ }
+ }
+
+ if (params->prog_nf.noise_fil_en) {
+ if ((params->prog_nf.type != BOX)
+ && (params->prog_nf.type != DIAMOND)) {
+
+ dev_err(ipipe_dev,
+ "validate:invalid noise filter type\n");
+ return -EINVAL;
+ }
+
+ }
+ if (params->prefilter.pre_en) {
+
+ if ((params->prefilter.sel_0 != AVG2MEDPIX)
+ && (params->prefilter.sel_0 != AVG4PIX)) {
+
+ dev_err(ipipe_dev,
+ "validate:invalid averaging"
+ " method(sel0) in prefilter\n");
+ return -EINVAL;
+ }
+
+ if ((params->prefilter.sel_1 != AVG2MEDPIX)
+ && (params->prefilter.sel_1 != AVG4PIX)) {
+
+ dev_err(ipipe_dev,
+ "validate:invalid averaging"
+ " method(sel1) in prefilter\n");
+ return -EINVAL;
+ }
+
+ if ((params->prefilter.typ_adaptive != DISABLE) &&
+ (params->prefilter.typ_adaptive != ENABLE)) {
+
+ dev_err(ipipe_dev,
+ "validate:invalid adaptive filter"
+ " value(en0) in pre filter\n");
+ return -EINVAL;
+ }
+ if ((params->prefilter.typ_adaptive_dotred != DISABLE) &&
+ (params->prefilter.typ_adaptive_dotred != ENABLE)) {
+
+ dev_err(ipipe_dev,
+ "validate:invalid adaptive dot"
+ " reduction value(en1) in pre filter\n");
+ return -EINVAL;
+ }
+ }
+
+ if ((params->rgb2rgb.gmm_cfg_bypr != GC_ENABLE) &&
+ (params->rgb2rgb.gmm_cfg_bypr != GC_BYPASS)) {
+
+ dev_err(ipipe_dev,
+ "validate:invalid gamma correction"
+ " enable/bypass value\n");
+ return -EINVAL;
+ }
+ if ((params->rgb2rgb.gmm_cfg_bypr == GC_ENABLE)
+ && params->rgb2rgb.gmm_cfg_tbl == IPIPE_RAM
+ && (params->rgb2rgb.gmm_tbl_r == NULL)) {
+ dev_err(ipipe_dev,
+ "validate:gamma red enabled but"
+ " table field is NULL\n");
+ return -EINVAL;
+ }
+
+ if ((params->rgb2rgb.gmm_cfg_bypg != GC_ENABLE)
+ && params->rgb2rgb.gmm_cfg_tbl == IPIPE_RAM
+ && (params->rgb2rgb.gmm_cfg_bypg != GC_BYPASS)) {
+
+ dev_err(ipipe_dev,
+ "validate:invalid gamma green"
+ " correction enable/bypass value\n");
+ return -EINVAL;
+ }
+
+ if ((params->rgb2rgb.gmm_cfg_bypg == GC_ENABLE)
+ && params->rgb2rgb.gmm_cfg_tbl == IPIPE_RAM
+ && (params->rgb2rgb.gmm_tbl_g == NULL)) {
+ dev_err(ipipe_dev,
+ "validate:gamma green enabled but"
+ " table field is NULL\n");
+ return -EINVAL;
+ }
+
+ if ((params->rgb2rgb.gmm_cfg_bypb != GC_ENABLE)
+ && (params->rgb2rgb.gmm_cfg_bypb != GC_BYPASS)) {
+
+ dev_err(ipipe_dev,
+ "validate:invalid gamma blue"
+ " correction enable/bypass value\n");
+ return -EINVAL;
+ }
+ if ((params->rgb2rgb.gmm_cfg_bypb == GC_ENABLE)
+ && params->rgb2rgb.gmm_cfg_tbl == IPIPE_RAM
+ && (params->rgb2rgb.gmm_tbl_b == NULL)) {
+ dev_err(ipipe_dev,
+ "validate:gamma blue enabled"
+ " but table field is NULL\n");
+ return -EINVAL;
+ }
+ if ((params->rgb2rgb.gmm_cfg_tbl != IPIPE_RAM)
+ && (params->rgb2rgb.gmm_cfg_tbl != IPIPE_ROM)) {
+
+ dev_err(ipipe_dev, "invlid gamma table source\n");
+ return -EINVAL;
+ }
+
+ if ((params->rgb2rgb.gmm_cfg_siz < IPIPE_128)
+ || (params->rgb2rgb.gmm_cfg_siz > IPIPE_512)) {
+
+ dev_err(ipipe_dev, "invalid gamma table size\n");
+ return -EINVAL;
+ }
+
+ if ((params->rgb2yuv.yuv_phs_position != COSITING)
+ && (params->rgb2yuv.yuv_phs_position != CENTERING)) {
+
+ dev_err(ipipe_dev, "invalid phase position\n");
+ return -EINVAL;
+ }
+ if ((params->rgb2yuv.yuv_phs_lpf != ENABLE)
+ && (params->rgb2yuv.yuv_phs_lpf != DISABLE)) {
+
+ dev_err(ipipe_dev, "invalid phase position\n");
+ return -EINVAL;
+ }
+
+ if ((params->edge_enhancer.yee_en != ENABLE)
+ && (params->edge_enhancer.yee_en != DISABLE)) {
+
+ dev_err(ipipe_dev,
+ "invalid value in edge enhancement enable field\n");
+ return -EINVAL;
+ }
+
+ if ((params->edge_enhancer.yee_emf != ENABLE)
+ && (params->edge_enhancer.yee_emf != DISABLE)) {
+
+ dev_err(ipipe_dev, "invalid value in"
+ " median NR enable field\n");
+ return -EINVAL;
+ }
+
+ if (params->false_color_suppresion.fcs_en) {
+ if ((params->false_color_suppresion.fcs_typ_typ < Y) ||
+ (params->false_color_suppresion.fcs_typ_typ > HPF_2D_YEE)) {
+
+ dev_err(ipipe_dev,
+ "invalid value in color"
+ " suppresion enable field\n");
+ return -EINVAL;
+ }
+ }
+
+ if ((params->rsz_seq_seq != ENABLE) &&
+ (params->rsz_seq_seq != DISABLE)) {
+
+ dev_err(ipipe_dev, "invalid value"
+ " of operation mode field\n");
+ return -EINVAL;
+ }
+
+ if ((params->rsz_seq_tmm != ENABLE) &&
+ (params->rsz_seq_tmm != DISABLE)) {
+
+ dev_err(ipipe_dev, "invalid value of"
+ " terminal condition enable field\n");
+ return -EINVAL;
+ }
+
+ if ((params->rsz_seq_hrv != ENABLE) &&
+ (params->rsz_seq_hrv != DISABLE)) {
+
+ dev_err(ipipe_dev, "invalid value of"
+ " horizontal reversal field\n");
+ return -EINVAL;
+ }
+
+ if ((params->rsz_seq_vrv != ENABLE) &&
+ (params->rsz_seq_vrv != DISABLE)) {
+
+ dev_err(ipipe_dev, "invalid value of"
+ " vertical reversal field\n");
+ return -EINVAL;
+ }
+
+ if ((params->rsz_seq_crv != ENABLE) &&
+ (params->rsz_seq_crv != DISABLE)) {
+
+ dev_err(ipipe_dev, "invalid value of"
+ " chroma sampling point field\n");
+ return -EINVAL;
+ }
+
+ if ((params->rsz_aal != ENABLE) &&
+ (params->rsz_aal != DISABLE)) {
+
+ dev_err(ipipe_dev, "invalid value of"
+ " anti aliasing filter field\n");
+ return -EINVAL;
+ }
+
+ if (params->rsz_en[0]) {
+ if ((params->rsz_rsc_param[0].rsz_h_typ != CUBIC)
+ && (params->rsz_rsc_param[0].rsz_h_typ != LINEAR)) {
+
+ dev_err(ipipe_dev,
+ "invalid low pass filter type in RZA\n");
+ return -EINVAL;
+ }
+
+ if ((params->rsz_rsc_param[0].rsz_v_dif < MIN_DIF_VAL) ||
+ (params->rsz_rsc_param[0].rsz_v_dif > MAX_DIF_VAL)) {
+ dev_err(ipipe_dev,
+ "invalid vertical resize factor for RZA\n");
+ return -EINVAL;
+ }
+
+ if ((params->rsz_rsc_param[0].rsz_h_dif < MIN_DIF_VAL) ||
+ (params->rsz_rsc_param[0].rsz_h_dif > MAX_DIF_VAL)) {
+ dev_err(ipipe_dev,
+ "invalid horizontal resize factor for RZA\n");
+ return -EINVAL;
+ }
+
+ if ((params->rsz_rsc_param[0].rsz_h_lse_sel != INTERNAL_VALUE)
+ && (params->rsz_rsc_param[0].rsz_h_lse_sel !=
+ PROGRAMMED_VALUE)) {
+
+ dev_err(ipipe_dev,
+ "invalid intensity value of LPF in RZA\n");
+ return -EINVAL;
+ }
+
+ if ((params->rsz2rgb[0].rsz_rgb_typ != OUTPUT_16BIT) &&
+ (params->rsz2rgb[0].rsz_rgb_typ != OUTPUT_32BIT)) {
+
+ dev_err(ipipe_dev, "invalid RGB output type in RZA\n");
+ return -EINVAL;
+ }
+
+ if ((params->rsz2rgb[0].rsz_rgb_msk0 != MASKLAST2)
+ && (params->rsz2rgb[0].rsz_rgb_msk0 != NOMASK)) {
+
+ dev_err(ipipe_dev,
+ "invalid value of mask0 field in RZA\n");
+ return -EINVAL;
+ }
+
+ if ((params->rsz2rgb[0].rsz_rgb_msk1 != MASKLAST2)
+ && (params->rsz2rgb[0].rsz_rgb_msk1 != NOMASK)) {
+
+ dev_err(ipipe_dev,
+ "invalid value of mask1 field in RZA\n");
+ return -EINVAL;
+ }
+
+ /*
+ * Check that mode selected by user
+ * in all modules should be same
+ */
+ if (!(params->ipipeif_param.mode == params->ipipe_mode) &&
+ (params->ipipeif_param.mode ==
+ params->rsz_rsc_param[0].rsz_mode)
+ && (params->ipipe_mode ==
+ params->rsz_rsc_param[0].rsz_mode)) {
+
+ dev_err(ipipe_dev, "mode does not match in RZA\n");
+ return -EINVAL;
+ }
+
+ if (params->rsz_rsc_param[0].rsz_o_hsz > MAX_SIZE_RSZ0) {
+
+ dev_err(ipipe_dev,
+ "invalid output horizontal size in RZA\n");
+ return -EINVAL;
+ }
+
+ }
+
+ if (params->rsz_en[1]) {
+ if ((params->rsz_rsc_param[1].rsz_h_typ != CUBIC)
+ && (params->rsz_rsc_param[1].rsz_h_typ != LINEAR)) {
+
+ dev_err(ipipe_dev,
+ "invalid low pass filter type in RZB\n");
+ return -EINVAL;
+ }
+
+ if ((params->rsz_rsc_param[1].rsz_v_dif < MIN_DIF_VAL) ||
+ (params->rsz_rsc_param[1].rsz_v_dif > MAX_DIF_VAL)) {
+ dev_err(ipipe_dev,
+ "invalid vertical resize factor for RZB\n");
+ return -EINVAL;
+ }
+
+ if ((params->rsz_rsc_param[1].rsz_h_dif < MIN_DIF_VAL) ||
+ (params->rsz_rsc_param[1].rsz_h_dif > MAX_DIF_VAL)) {
+ dev_err(ipipe_dev,
+ "invalid horizontal resize factor for RZB\n");
+ return -EINVAL;
+ }
+
+ if ((params->rsz_rsc_param[1].rsz_h_lse_sel != INTERNAL_VALUE)
+ && (params->rsz_rsc_param[1].rsz_h_lse_sel !=
+ PROGRAMMED_VALUE)) {
+
+ dev_err(ipipe_dev,
+ "invalid intensity value of LPF in RZB\n");
+ return -EINVAL;
+ }
+
+ if ((params->rsz2rgb[1].rsz_rgb_typ != OUTPUT_16BIT) &&
+ (params->rsz2rgb[1].rsz_rgb_typ != OUTPUT_32BIT)) {
+
+ dev_err(ipipe_dev, "invalid RGB output type in RZB\n");
+ return -EINVAL;
+ }
+
+ if ((params->rsz2rgb[1].rsz_rgb_msk0 != MASKLAST2)
+ && (params->rsz2rgb[1].rsz_rgb_msk0 != NOMASK)) {
+
+ dev_err(ipipe_dev,
+ "invalid value of mask0 field in RZB\n");
+ return -EINVAL;
+ }
+
+ if ((params->rsz2rgb[1].rsz_rgb_msk1 != MASKLAST2)
+ && (params->rsz2rgb[1].rsz_rgb_msk1 != NOMASK)) {
+
+ dev_err(ipipe_dev,
+ "invalid value of mask1 field in RZB\n");
+ return -EINVAL;
+ }
+
+ /*
+ * Check that mode selected by user
+ * in all modules should be same
+ */
+ if (!(params->ipipeif_param.mode == params->ipipe_mode) &&
+ (params->ipipeif_param.mode ==
+ params->rsz_rsc_param[1].rsz_mode)
+ && (params->ipipe_mode ==
+ params->rsz_rsc_param[1].rsz_mode)) {
+
+ dev_err(ipipe_dev, "mode does not match in RZB\n");
+ return -EINVAL;
+ }
+
+ if (params->rsz_rsc_param[1].rsz_o_hsz > MAX_SIZE_RSZ1) {
+
+ dev_err(ipipe_dev,
+ "invalid output horizontal size in RZB\n");
+ return -EINVAL;
+ }
+ }
+ /*both resizers can not be enabled simultaniously in one shot mode */
+
+ if ((params->ipipe_dpaths_fmt > YUV2YUV)
+ || (params->ipipe_dpaths_fmt < RAW2YUV)) {
+
+ dev_err(ipipe_dev, "invalid data format\n");
+ return -EINVAL;
+ }
+
+ if (params->def_cor.dfc_en)
+ if (params->def_cor.dfc_siz > MAX_SIZE_DFC) {
+
+ dev_err(ipipe_dev, "DFC table size exceeds limit\n");
+ return -EINVAL;
+ }
+ return 0;
+}
+
+int ipipe(struct ipipe_device *device, struct ipipe_convert *arg)
+{
+ unsigned int utemp, utemp_h, utemp_l;
+ int resizer_no_0, resizer_no_1;
+
+ resizer_no_0 = device->params->rsz_en[0];
+ resizer_no_1 = device->params->rsz_en[1];
+
+ /*set ipipe clock */
+ regw_vpss(0x79, VPSS_CLK); /*!FIXME */
+ if (device->params->ipipeif_param.source != 0) {
+ regw_if(((device->params->ipipeif_param.adofs) >> 5),
+ IPIPEIF_ADOFS);
+
+ if (arg->in_buff.index < 0) {
+ /*check if adress is 32 bit alligned */
+ if (arg->in_buff.offset % 32) {
+ dev_dbg(ipipe_dev,
+ "address offset not alligned\n");
+ return -EINVAL;
+ }
+ /*lower sixteen bit */
+ utemp = arg->in_buff.offset;
+ utemp_l = utemp >> 5;
+ regw_if(utemp_l, IPIPEIF_ADDRL);
+ /*upper next seven bit */
+ utemp_h = utemp >> 21;
+ regw_if(utemp_h, IPIPEIF_ADDRU);
+ } else if (arg->in_buff.index > 7) {
+ dev_dbg(ipipe_dev, "Invalid buffer index\n");
+ return -EINVAL;
+ } else {
+ /*lower sixteen bit */
+ utemp = device->in_buff[arg->in_buff.index]->offset;
+ utemp_l = utemp >> 5;
+ regw_if(utemp_l, IPIPEIF_ADDRL);
+ utemp_h = utemp >> 21;
+
+ regw_if(utemp_h, IPIPEIF_ADDRU);
+ }
+ }
+ if (resizer_no_0)
+ regw_ip(device->params->ext_mem_param[0].rsz_sdr_oft,
+ RSZ_EN_0 + RSZ_SDR_OFT);
+ regw_ip(device->params->rsz_en[0], RSZ_EN_0);
+ if (resizer_no_1)
+ regw_ip(device->params->ext_mem_param[1].rsz_sdr_oft,
+ RSZ_EN_1 + RSZ_SDR_OFT);
+ regw_ip(device->params->rsz_en[1], RSZ_EN_1);
+
+ if (arg->out_buff.index < 0) {
+ if (arg->out_buff.offset % 32)
+ return -EINVAL;
+ else {
+ /* CHECK this statems */
+ if (resizer_no_0 == 1 && resizer_no_1 == 1) {
+ printk
+ ("If both the resizer enable then user can \
+ not provide output address\n");
+ return -EINVAL;
+ }
+ if (resizer_no_0)
+ write_out_addr(0, arg->out_buff.offset);
+ if (resizer_no_1)
+ write_out_addr(1, arg->out_buff.offset);
+ }
+ } else if (arg->in_buff.index > 7) {
+ return -EINVAL;
+ } else {
+ if (resizer_no_0)
+ write_out_addr(0,
+ device->out_buff[arg->out_buff.index]->
+ offset);
+ if (resizer_no_1 && resizer_no_0)
+ write_out_addr(1,
+ device->out_buff[arg->out_buff.index +
+ 1]->offset);
+ if (resizer_no_1 && !resizer_no_0)
+ write_out_addr(1,
+ device->out_buff[arg->out_buff.index]->
+ offset);
+
+ }
+
+ regw_ip(0xff, IRQ_EN);
+ while (1) {
+ utemp = regr_ip(IPIPE_EN);
+ if (utemp == 0)
+ break;
+ }
+ regw_ip(1, IPIPE_EN);
+ while (1) {
+ utemp = regr_if(IPIPEIF_ENABLE);
+ if (utemp == 0)
+ break;
+ };
+
+ regw_if(1, IPIPEIF_ENABLE);
+ dev_dbg(ipipe_dev, "ipipe started\n");
+ wait_for_completion_interruptible(&device->wfc);
+ return 0;
+
+}
+int ipipe_release(struct inode *inode, struct file *filp)
+{
+ /* get the configuratin from private_date member of file */
+ struct ipipe_params *config = filp->private_data;
+ struct ipipe_device *device = &ipipedevice;
+ /* call free_buffers to free memory allocated to buffers */
+ if (atomic_dec_and_test(&reference_count)) {
+ free_buffers(device);
+ /* change the device status to available */
+ device->opened = 0;
+ }
+
+ /* free the memory allocated to configuration */
+ kfree(config);
+
+ /* Assign null to private_data member of file and params
+ member of device */
+ filp->private_data = device->params = NULL;
+
+ return 0;
+}
+
+int ipipe_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ /* get the address of global object of ipipe_device structure */
+ struct ipipe_device *device = &ipipedevice;
+ int i, flag = 0, shift;
+ /* get the page offset */
+ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+ shift = PAGE_SHIFT;
+ for (i = 0; i < device->in_numbuffers; i++) {
+ if (device->in_buff[i]->offset == offset) {
+ flag = 1;
+ break;
+ }
+ }
+
+ /* page offset passed in mmap should one from output buffers */
+ if (flag == 0) {
+ for (i = 0; i < device->out_numbuffers; i++) {
+ if (device->out_buff[i]->offset == offset) {
+ flag = 1;
+ break;
+ }
+ }
+ }
+ /* map buffers address space from kernel space to user space */
+ if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+ vma->vm_end - vma->vm_start, vma->vm_page_prot))
+ return -EAGAIN;
+
+ return 0;
+}
+int ipipe_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct ipipe_params params_t;
+ /* struct ipipe_reg_dump reg_addr; */
+ int ret = 0;
+ /* get the address of global object of ipipe_device structure */
+ struct ipipe_device *device = &ipipedevice;
+ struct ipipe_params *params = ¶ms_t;
+ struct ipipe_convert addr_struct;
+ /* struct ipipe_cropsize *crop_struct = NULL; */
+ /* Before decoding check for correctness of cmd */
+ dev_dbg(ipipe_dev, "ipipe ioctl\n");
+ if (_IOC_TYPE(cmd) != IPIPE_IOC_BASE) {
+ dev_dbg(ipipe_dev, "Bad command Value \n");
+ return -1;
+ }
+ if (_IOC_NR(cmd) > IPIPE_IOC_MAXNR) {
+ dev_dbg(ipipe_dev, "Bad command Value\n");
+ return -1;
+ }
+
+ /* Verify accesses */
+ if (_IOC_DIR(cmd) & _IOC_READ)
+ ret = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd));
+ else if (_IOC_DIR(cmd) & _IOC_WRITE)
+ ret = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd));
+ if (ret) {
+ dev_err(ipipe_dev, "access denied\n");
+ return -1; /*error in access */
+ }
+ /* switch according value of cmd */
+ switch (cmd) {
+
+ case IPIPE_QUERYBUF:
+ /* call query buffer which will return buffer address */
+ down_interruptible(&(device->sem));
+ ret = query_buffer(device, (struct ipipe_buffer *)arg);
+ if (ret != 0) {
+ up(&(device->sem));
+ return ret;
+ }
+ up(&(device->sem));
+ break;
+ case IPIPE_REQBUF:
+ /* call request buffer to allocate buffers */
+ down_interruptible(&(device->sem));
+ ret = request_buffer(device, (struct ipipe_reqbufs *)arg);
+ if (ret != 0) {
+ up(&(device->sem));
+ return ret;
+ }
+
+ up(&(device->sem));
+ break;
+ case IPIPE_SET_PARAM:
+ /*set the parametres */
+ down_interruptible(&(device->sem));
+ /*default parameters */
+ if ((void *)arg == NULL) {
+ params = ¶m_def;
+ dev_dbg(ipipe_dev, "NULL parameters.\n");
+ } else {
+ /* copy the parameters to the configuration */
+ if (copy_from_user
+ (params, (struct ipipe_params *)arg,
+ sizeof(struct ipipe_params))) {
+ /* if it fails return error */
+ up(&(device->sem));
+ return -EFAULT;
+ }
+ }
+
+ /* test for register write OK */
+ ret = validate_params(params);
+ if (ret != 0) {
+ dev_dbg(ipipe_dev, "Error in validate \n");
+ up(&(device->sem));
+ return ret;
+ }
+ dev_dbg(ipipe_dev, "Pass validation.\n");
+
+ /* copy the values to device params */
+ if (device->params)
+ memcpy(device->params, params,
+ sizeof(struct ipipe_params));
+ else {
+ up(&(device->sem));
+ dev_dbg(ipipe_dev,
+ "invalid device parameter buffer.\n");
+ return -EINVAL;
+ }
+
+ ret = ipipe_hw_setup(device->params);
+ if (ret != 0) {
+ dev_dbg(ipipe_dev, "Error in hardware set up\n");
+ up(&(device->sem));
+ return ret;
+ }
+ up(&(device->sem));
+ break;
+
+ case IPIPE_GET_PARAM:
+ down_interruptible(&(device->sem));
+ /* copy the parameters from the configuration */
+ if (copy_to_user((struct ipipe_params *)arg, (device->params),
+ sizeof(struct ipipe_params))) {
+ /* if copying fails return error */
+
+ ret = -EFAULT;
+ }
+ up(&(device->sem));
+ break;
+
+ case IPIPE_START:
+ down_interruptible(&(device->sem));
+ dev_dbg(ipipe_dev, "ipipe startioctl\n");
+ /* copy the parameters to the configuration */
+ if (copy_from_user
+ (&addr_struct, (struct ipipe_convert *)arg,
+ sizeof(struct ipipe_convert)))
+ /* if it fails return error */
+ {
+ up(&(device->sem));
+ return -EFAULT;
+ }
+ ret = ipipe(device, &addr_struct);
+ if (ret != 0) {
+ up(&(device->sem));
+ return ret;
+ }
+ up(&(device->sem));
+
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+
+}
+static void ipipe_platform_release(struct device *device)
+{
+ /* This is called when the reference count goes to zero */
+}
+
+static int ipipe_probe(struct device *device)
+{
+ ipipe_dev = device;
+ return 0;
+}
+
+static int ipipe_remove(struct device *device)
+{
+ return 0;
+}
+
+/*
+ * Global variable of type file_operations containing function
+ * pointers of file operations
+ */
+static const struct file_operations ipipe_fops = {
+ .owner = THIS_MODULE,
+ .open = ipipe_open,
+ .release = ipipe_release,
+ .mmap = ipipe_mmap,
+ .ioctl = ipipe_ioctl,
+};
+
+/* global variable of type cdev to register driver to the kernel */
+static struct cdev cdev;
+
+/* global variable which keeps major and minor number of the driver in it */
+static dev_t dev;
+
+static struct device_driver ipipe_driver = {
+ .name = "dm355_ipipe",
+ .bus = &platform_bus_type,
+ .probe = ipipe_probe,
+ .remove = ipipe_remove,
+};
+static struct platform_device ipipe_pt_device = {
+ .name = "dm355_ipipe",
+ .id = 2,
+ .dev = {
+ .release = ipipe_platform_release,
+ }
+};
+int __init ipipe_init(void)
+{
+ int result = 0;
+
+ /* Register the driver in the kernel */
+ /* dynmically get the major number for the driver using
+ alloc_chrdev_region function */
+ result = alloc_chrdev_region(&dev, 0, 1, DRIVERNAME);
+
+ /* if it fails return error */
+ if (result < 0) {
+ dev_dbg(ipipe_dev, "DM355IPIPE: Module intialization"
+ "failed. could not register character device\n");
+ return -ENODEV;
+ }
+ printk(KERN_INFO "ipipe major#: %d, minor# %d\n", MAJOR(dev),
+ MINOR(dev));
+
+ /* initialize cdev with file operations */
+ cdev_init(&cdev, &ipipe_fops);
+
+ cdev.owner = THIS_MODULE;
+ cdev.ops = &ipipe_fops;
+
+ /* add cdev to the kernel */
+ result = cdev_add(&cdev, dev, 1);
+
+ if (result) {
+ unregister_chrdev_region(dev, 1);
+ dev_dbg(ipipe_dev, "DM355 IPIPE: Error adding \
+ DM355 IPIPE .. error no:%d\n", result);
+ return -EINVAL;
+ }
+
+ /* register driver as a platform driver */
+ if (driver_register(&ipipe_driver) != 0) {
+ unregister_chrdev_region(dev, 1);
+ cdev_del(&cdev);
+ return -EINVAL;
+ }
+
+ /* Register the drive as a platform device */
+ if (platform_device_register(&ipipe_pt_device) != 0) {
+ driver_unregister(&ipipe_driver);
+ unregister_chrdev_region(dev, 1);
+ cdev_del(&cdev);
+ return -EINVAL;
+ }
+
+ ipipe_class = class_create(THIS_MODULE, "dm355_ipipe");
+ if (!ipipe_class) {
+ printk(KERN_ERR "error in creating device class\n");
+ driver_unregister(&ipipe_driver);
+ platform_device_unregister(&ipipe_pt_device);
+ unregister_chrdev_region(dev, 1);
+ unregister_chrdev(MAJOR(dev), DRIVERNAME);
+ cdev_del(&cdev);
+ return -EINVAL;
+ }
+
+ device_create(ipipe_class, NULL, dev, NULL, "dm355_ipipe");
+
+ /* Set up the Interrupt handler for PRVINT interrupt */
+ /*request irq 8(sdr) intt */
+ result = request_irq(5, ipipe_isr, IRQF_DISABLED,
+ "dm355_ipipe", (void *)&ipipedevice);
+
+ if (result < 0) {
+ dev_dbg(ipipe_dev, "ipipe_init:cannot get irq\n");
+
+ unregister_chrdev_region(dev, 1);
+ device_destroy(ipipe_class, dev);
+ class_destroy(ipipe_class);
+ driver_unregister(&ipipe_driver);
+ platform_device_unregister(&ipipe_pt_device);
+ cdev_del(&cdev);
+ return -EINVAL;
+ }
+
+ ipipedevice.opened = 0;
+ printk(KERN_INFO "ipipe driver registered\n");
+
+ return 0;
+}
+
+void __exit ipipe_cleanup(void)
+{
+ /* remove major number allocated to this driver */
+ unregister_chrdev_region(dev, 1);
+
+ /* Remove platform driver */
+ driver_unregister(&ipipe_driver);
+
+ device_destroy(ipipe_class, dev);
+
+ class_destroy(ipipe_class);
+
+ platform_device_unregister(&ipipe_pt_device);
+
+ /* disable interrupt */
+ free_irq(5, &ipipedevice);
+ cdev_del(&cdev);
+
+ /* unregistering the driver from the kernel */
+ unregister_chrdev(MAJOR(dev), DRIVERNAME);
+}
+
+module_init(ipipe_init);
+module_exit(ipipe_cleanup);
+MODULE_LICENSE("GPL");
new file mode 100644
@@ -0,0 +1,710 @@
+/*
+ * Copyright (C) 2009 Texas Instruments Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <media/davinci/dm355_ipipe_hw.h>
+#include <media/davinci/dm355_ipipe.h>
+#include <mach/hardware.h>
+#include <linux/device.h>
+#ifdef __KERNEL__
+
+/* ipipe_hw_setup:It is used for Hardware Setup */
+int ipipe_hw_setup(struct ipipe_params *config)
+{
+ u32 utemp = 0;
+ u32 data_format;
+ ipipeif_decimation decimation_en;
+ ipipeif_input_source input_source = config->ipipeif_param.source;
+ if (!config)
+ return -EINVAL;
+
+ utemp = config->ipipeif_param.mode << 0;
+ utemp |= config->ipipeif_param.decimation << 1;
+ utemp |= config->ipipeif_param.source << 2;
+ utemp |= config->ipipeif_param.clk_div << 4;
+ utemp |= config->ipipeif_param.avg_filter << 7;
+ utemp |= config->ipipeif_param.pack_mode << 8;
+ utemp |= config->ipipeif_param.ialaw << 9;
+ utemp |= config->ipipeif_param.clock_select << 10;
+ utemp |= config->ipipeif_param.data_shift << 11;
+ regw_if(utemp, IPIPEIF_GFG);
+ switch (input_source) {
+ case CCDC:
+ regw_if(config->ipipeif_param.gain, IPIPEIF_GAIN);
+
+ break;
+
+ case SDRAM_RAW:
+
+ case CCDC_DARKFM:
+ regw_if(config->ipipeif_param.gain, IPIPEIF_GAIN);
+
+ case SDRAM_YUV:
+ regw_if(config->ipipeif_param.glob_hor_size, IPIPEIF_PPLN);
+ regw_if(config->ipipeif_param.glob_ver_size, IPIPEIF_LPFR);
+ regw_if(config->ipipeif_param.hnum, IPIPEIF_HNUM);
+ regw_if(config->ipipeif_param.vnum, IPIPEIF_VNUM);
+ utemp = regr_vpss(VPSS_PCR);
+ RESETBIT(utemp, 4);
+ RESETBIT(utemp, 5);
+ regw_vpss(utemp, VPSS_PCR);
+
+ break;
+
+ }
+ /* check if decimation is enable or not */
+ decimation_en = config->ipipeif_param.decimation;
+ if (decimation_en) {
+ regw_if(config->ipipeif_param.rsz, IPIPEIF_RSZ);
+ /* Enable Aneraging filter PRATIK */
+ }
+
+ /*
+ * Hardware set up of IPIPE Module
+ * set GCL_ARM reg before writting to ipipe registers
+ */
+ regw_ip(1, GCL_ARM);
+ /* enable the clock wb,cfa,dfc,d2f,pre modules */
+ regw_ip(0x06, GCL_CCD);
+ data_format =
+ (config->ipipe_dpaths_fmt | (config->ipipe_dpaths_bypass) << 2);
+
+ utemp = regr_vpss(VPSS_PCR);
+ RESETBIT(utemp, 6);
+ regw_vpss(utemp, VPSS_PCR);
+ /*enable ipipe mode to either one shot or continuous */
+ utemp = regr_ip(IPIPE_MODE);
+ RESETBIT(utemp, 0);
+
+ utemp |= config->ipipe_mode;
+ regw_ip(utemp, IPIPE_MODE);
+ regw_ip(data_format, IPIPE_DPATHS);
+ /*set size */
+ regw_ip(config->ipipe_vst, IPIPE_VST);
+ regw_ip(config->ipipe_hst, IPIPE_HST);
+ regw_ip(config->ipipe_vsz, IPIPE_VSZ);
+ regw_ip(config->ipipe_hsz, IPIPE_HSZ);
+ switch (data_format) {
+ case RAW2YUV:
+
+ /*Combine all the fields to make COLPAT register of IPIPE */
+ utemp = (config->ipipe_colpat_elep << 0);
+ utemp |= (config->ipipe_colpat_elop << 2);
+ utemp |= (config->ipipe_colpat_olep << 4);
+ utemp |= (config->ipipe_colpat_olop << 6);
+
+ regw_ip(utemp, IPIPE_COLPAT);
+
+ set_d2f_regs(&(config->prog_nf)); /*noise filter */
+ set_pre_regs(&(config->prefilter)); /*prefilter */
+ /*histogram configuration may come here */
+ set_wb_regs(&(config->wb));
+
+ /*
+ * Diff data_format value needs diff regs to be
+ * configured so passing the value of data_format
+ */
+ set_rgb_2_yuv_regs(config->ipipe_dpaths_fmt,
+ &(config->rgb2yuv));
+
+ set_rgb_to_rgb_regs(&(config->rgb2rgb));
+
+ set_ee_regs(&(config->edge_enhancer));
+ set_fcs_regs(&(config->false_color_suppresion));
+ set_rsz_regs(config); /*set RSZ_SEQ registers */
+ set_aal_regs(config); /*set RSZ_AAL registers */
+ /*set the registers of either RSZ0 or RSZ1 */
+ set_rsz_structs(config);
+
+ break;
+
+ case RAW2RAW:
+ set_d2f_regs(&(config->prog_nf)); /*noise filter */
+ set_pre_regs(&(config->prefilter)); /*prefilter */
+ set_wb_regs(&(config->wb)); /* .................CHECK */
+ set_aal_regs(config); /*set RSZ_AAL registers */
+ /*set the registers of RSZ0 and RSZ1 */
+ set_rsz_structs(config); /*...................CHECK */
+ default_for_raw2raw(config);
+ break;
+
+ case RAW2BOX:
+ printk(KERN_INFO "boxcar mode is not supported by driver\n");
+
+ break;
+
+ case YUV2YUV:
+ set_ee_regs(&(config->edge_enhancer));
+ set_fcs_regs(&(config->false_color_suppresion));
+ set_rsz_regs(config); /*set RSZ_SEQ registers */
+ set_aal_regs(config); /*set RSZ_AAL registers */
+ /*set the registers of either RSZ0 or RSZ1 */
+ set_rsz_structs(config);
+ break;
+
+ case RAW2RAW_BYPASS:
+ set_d2f_regs(&(config->prog_nf)); /*noise filter */
+ set_pre_regs(&(config->prefilter)); /*prefilter */
+ set_wb_regs(&(config->wb));
+ /*
+ * Diff data_format value needs diff regs
+ * to be configured so passing the value of data_format
+ */
+ set_rgb_2_yuv_regs(config->ipipe_dpaths_fmt,
+ &(config->rgb2yuv));
+ default_for_raw2raw(config);
+ default_for_bypass(config);
+ set_aal_regs(config); /*set RSZ_AAL registers */
+ /*set the registers of either RSZ0 or RSZ1 */
+ set_rsz_structs(config);
+ break;
+
+ }
+ return 0;
+
+}
+
+/*default configuratins for RAW2RAW mode*/
+int default_for_raw2raw(struct ipipe_params *parameter)
+{
+ u32 utemp;
+ u32 bright = 0;
+ u32 contrast = 16;
+
+ int seq_tmm = 0;
+ utemp = regr_vpss(VPSS_MEMCTL);
+ RESETBIT(utemp, 1);
+ RESETBIT(utemp, 0);
+ SETBIT(utemp, 2);
+ regw_vpss(utemp, VPSS_MEMCTL);
+
+ regw_ip(1, GCL_SDR);
+
+ /*set this to 0 for dafault config */
+ utemp =
+ (parameter->rsz_seq_seq << 0) | (seq_tmm << 1) | (parameter->
+ rsz_seq_hrv << 2)
+ | (parameter->rsz_seq_vrv << 3) | (parameter->rsz_seq_crv << 4);
+ regw_ip(utemp, RSZ_SEQ);
+ /*set this to 0 for dafault config */
+ regw_ip(0, FCS_EN);
+ /*set this to 0 for dafault config */
+ regw_ip(0, YEE_EN);
+ /*set default brightness and contrast */
+ utemp = ((contrast << 0) | (bright << 8));
+ regw_ip(utemp, YUV_ADJ);
+
+ /*set default luminance */
+ regw_ip(0, YUV_Y_MIN);
+ regw_ip(255, YUV_Y_MAX);
+
+ /*set default chrominance */
+ regw_ip(0, YUV_C_MIN);
+ regw_ip(255, YUV_C_MAX);
+ /*default config for resizer 1 registers */
+ regw_ip(1, RSZ_EN_0);
+ regw_ip(0, RSZ_EN_0 + RSZ_I_HST);
+ regw_ip(0, RSZ_EN_0 + RSZ_I_VST);
+ regw_ip(0, RSZ_EN_0 + RSZ_O_HST);
+ regw_ip(0, RSZ_EN_0 + RSZ_V_PHS);
+ regw_ip(256, RSZ_EN_0 + RSZ_V_DIF);
+ regw_ip(256, RSZ_EN_0 + RSZ_H_DIF);
+ regw_ip(0, RSZ_EN_0 + RSZ_H_PHS);
+ regw_ip(0, RSZ_EN_0 + RSZ_H_TYP);
+ regw_ip(0, RSZ_EN_0 + RSZ_H_LSE);
+ regw_ip(0, RSZ_EN_0 + RSZ_H_LPF);
+ regw_ip(0, RSZ_EN_0 + RSZ_RGB_EN);
+ /*disable resizer 0 in default mode */
+ regw_ip(0, RSZ_EN_1);
+/*
+for debugging
+*/
+ return 0;
+}
+
+/*default configuratins for RAW2RAW_bypass mode*/
+int default_for_bypass(struct ipipe_params *parameter)
+{
+ /*disable noise filter in default config */
+ regw_ip(0, D2F_EN);
+ /*disable defect coorection in default config */
+ regw_ip(0, DFC_EN);
+ /*disable prefilter filter in default config */
+ regw_ip(0, PRE_EN);
+ /*set default config for white balance */
+ regw_ip(256, WB2_DGN);
+ regw_ip(128, WB2_WG_R);
+ regw_ip(128, WB2_WG_GR);
+ regw_ip(128, WB2_WG_GB);
+ regw_ip(128, WB2_WG_B);
+ return 0;
+}
+
+/*IPIPE Register write function definition */
+int set_dfc_regs(struct ipipe_def_cor *dfc)
+{
+ u32 utemp;
+ unsigned int horizontal_pos[MAX_SIZE_DFC];
+ unsigned int vertical_pos_method[MAX_SIZE_DFC];
+ unsigned int count;
+ regw_ip(dfc->dfc_en, DFC_EN); /*writting to enable register */
+
+ if (1 == dfc->dfc_en) {
+ regw_ip(dfc->dfc_sel, DFC_SEL);
+ regw_ip(DEF_COR_START_ADDR, DFC_ADR);
+ regw_ip(dfc->dfc_siz, DFC_SIZE);
+ utemp = regr_vpss(VPSS_MEMCTL);
+ RESETBIT(utemp, 0);
+ regw_vpss(utemp, VPSS_MEMCTL);
+ /*set the auto increment,write only,dfc mode in RAM_MODE */
+ regw_ip(0x0034, RAM_MODE);
+ regw_ip(0x00, RAM_ADR);
+ regw_ip(dfc->dfc_adr, DFC_ADR);
+ /*regw_ip(0x00,DFC_ADR);*/
+ if (dfc->dfc_table != NULL) {
+ for (count = 0; count < dfc->dfc_siz; count++) {
+ horizontal_pos[count] =
+ dfc->dfc_table[count] & 0x00000FFF;
+ vertical_pos_method[count] =
+ dfc->dfc_table[count] & 0x07FFF000;
+ }
+
+ /*write first twelve bit */
+ count = 0;
+
+ while (count < dfc->dfc_siz) {
+ regw_ip(horizontal_pos[count], RAM_WDT);
+ printk(KERN_INFO "###RAM_WDT[%d] = %x\n", count,
+ regr_ip(RAM_WDT));
+ /*write next fifteen bit */
+ regw_ip(vertical_pos_method[count], RAM_WDT);
+ printk(KERN_INFO "RAM_WDT[%d] = %x\n", count,
+ regr_ip(RAM_WDT));
+
+ count++;
+ }
+
+ } else {
+
+ }
+
+ }
+ return 0;
+
+}
+
+int set_d2f_regs(struct ipipe_prog_nf *noise_filter)
+{
+ u32 utemp;
+ int count = 0;
+ regw_ip(noise_filter->noise_fil_en, D2F_EN);
+ if (1 == noise_filter->noise_fil_en) {
+ /*Combine all the fields to make D2F_CFG register of IPIPE */
+ utemp =
+ (noise_filter->d2f_cfg_spr << 0) | (noise_filter->
+ d2f_cfg_shf << 2) |
+ (noise_filter->type << 4);
+ regw_ip(utemp, D2F_CFG);
+ if (noise_filter->d2f_str != NULL) {
+ count = 0;
+ while (count < 32) {
+ regw_ip(noise_filter->d2f_str[count],
+ D2F_STR + count * 4);
+ count++;
+ }
+ } else {
+ }
+ if (noise_filter->d2f_thr != NULL) {
+ count = 0;
+ while (count < 32) {
+ regw_ip(noise_filter->d2f_thr[count],
+ DFC_THR + count * 4);
+ count++;
+ }
+ } else {
+ }
+ }
+ return 0;
+}
+
+int set_pre_regs(struct ipipe_prefilter *pre_filter)
+{
+
+ u32 utemp;
+ regw_ip(pre_filter->pre_en, PRE_EN);
+ if (1 == pre_filter->pre_en) {
+ /*Combine all the fields to make PRE_EN register of IPIPE */
+ utemp = ((pre_filter->sel_0 << 0) | (pre_filter->sel_1 << 1) |
+ (pre_filter->typ_adaptive << 2) | (pre_filter->
+ typ_adaptive_dotred)
+ << 3);
+ regw_ip(utemp, PRE_TYP);
+ regw_ip(pre_filter->pre_shf, PRE_SHF);
+ regw_ip(pre_filter->pre_gain, PRE_GAIN);
+ regw_ip(pre_filter->pre_thr_g, PRE_THR_G);
+ regw_ip(pre_filter->pre_thr_b, PRE_THR_B);
+ regw_ip(pre_filter->pre_thr_1, PRE_THR_1);
+ }
+ return 0;
+
+}
+int set_wb_regs(struct ipipe_wb *white_balance)
+{
+ regw_ip(white_balance->wb2_dgn, WB2_DGN);
+ regw_ip(white_balance->wb2_wg_r, WB2_WG_R);
+ regw_ip(white_balance->wb2_wg_gr, WB2_WG_GR);
+ regw_ip(white_balance->wb2_wg_gb, WB2_WG_GB);
+ regw_ip(white_balance->wb2_wg_b, WB2_WG_B);
+ return 0;
+}
+
+int set_rgb_2_yuv_regs(int data_format, struct ipipe_rgb2yuv *y_cr_cb)
+{
+ u32 utemp;
+ if (data_format < 2) {
+ /*combine fields of YUV_ADJ to set brightness and contrast */
+ utemp =
+ ((y_cr_cb->yuv_adj_ctr << 0) | (y_cr_cb->yuv_adj_brt << 8));
+ regw_ip(utemp, YUV_ADJ);
+ regw_ip(y_cr_cb->yuv_y_min, YUV_Y_MIN);
+ regw_ip(y_cr_cb->yuv_y_max, YUV_Y_MAX);
+ regw_ip(y_cr_cb->yuv_c_min, YUV_C_MIN);
+ regw_ip(y_cr_cb->yuv_c_max, YUV_C_MAX);
+
+ }
+ if (data_format == 0) {
+
+ regw_ip(y_cr_cb->yuv_mul_ry, YUV_MUL_RY);
+ regw_ip(y_cr_cb->yuv_mul_gy, YUV_MUL_GY);
+ regw_ip(y_cr_cb->yuv_mul_by, YUV_MUL_BY);
+ regw_ip(y_cr_cb->yuv_mul_rcb, YUV_MUL_RCB);
+ regw_ip(y_cr_cb->yuv_mul_gcb, YUV_MUL_GCB);
+ regw_ip(y_cr_cb->yuv_mul_bcb, YUV_MUL_BCB);
+ regw_ip(y_cr_cb->yuv_mul_rcr, YUV_MUL_RCR);
+ regw_ip(y_cr_cb->yuv_mul_gcr, YUV_MUL_GCR);
+ regw_ip(y_cr_cb->yuv_mul_bcr, YUV_MUL_BCR);
+ regw_ip(y_cr_cb->yuv_oft_y, YUV_OFT_Y);
+ regw_ip(y_cr_cb->yuv_oft_cb, YUV_OFT_CB);
+ regw_ip(y_cr_cb->yuv_oft_cr, YUV_OFT_CR);
+ /*Combine all the fields to make YUV_PHS register of IPIPE */
+ utemp =
+ ((y_cr_cb->yuv_phs_position << 0) | (y_cr_cb->
+ yuv_phs_lpf << 1));
+ regw_ip(utemp, YUV_PHS);
+
+ }
+ return 0;
+}
+int set_rgb_to_rgb_regs(struct ipipe_rgb2rgb *rgb)
+{
+ u32 utemp;
+ int count, table_size = 0;
+
+ regw_ip(rgb->rgb_mul_rr, RGB_MUL_RR);
+ regw_ip(rgb->rgb_mul_gr, RGB_MUL_GR);
+ regw_ip(rgb->rgb_mul_br, RGB_MUL_BR);
+ regw_ip(rgb->rgb_mul_rg, RGB_MUL_RG);
+ regw_ip(rgb->rgb_mul_gg, RGB_MUL_GG);
+ regw_ip(rgb->rgb_mul_bg, RGB_MUL_BG);
+ regw_ip(rgb->rgb_mul_rb, RGB_MUL_RB);
+ regw_ip(rgb->rgb_mul_gb, RGB_MUL_GB);
+ regw_ip(rgb->rgb_mul_bb, RGB_MUL_BB);
+ regw_ip(rgb->rgb_oft_or, RGB_MUL_OR);
+ regw_ip(rgb->rgb_oft_og, RGB_MUL_OG);
+ regw_ip(rgb->rgb_oft_ob, RGB_MUL_OB);
+
+ utemp =
+ ((rgb->gmm_cfg_bypr << 0) | (rgb->gmm_cfg_bypg << 1) | (rgb->
+ gmm_cfg_bypb
+ << 2)
+ | (rgb->gmm_cfg_tbl << 4) | (rgb->gmm_cfg_siz << 5));
+
+ regw_ip(utemp, GMM_CFG);
+ /*testing -- for register write */
+ utemp = regr_ip(GMM_CFG);
+
+ if (rgb->gmm_cfg_siz == IPIPE_128)
+ table_size = 128 * 2;
+ else if (rgb->gmm_cfg_siz == IPIPE_256)
+ table_size = 256 * 2;
+ else if (rgb->gmm_cfg_siz == IPIPE_512)
+ table_size = 512 * 2;
+
+ if (!(rgb->gmm_cfg_bypr)) {
+ if (rgb->gmm_tbl_r != NULL) {
+ /*set the auto increment,write only, gamma
+ red mode in RAM_MODE */
+ regw_ip(0x0035, RAM_MODE);
+ /*set the starting address of gamma table */
+ regw_ip(0x00, RAM_ADR);
+
+ for (count = 0; count < table_size; count++)
+ regw_ip(rgb->gmm_tbl_r[count], RAM_WDT);
+ }
+ }
+ if (!(rgb->gmm_cfg_bypb)) {
+ if (rgb->gmm_tbl_b != NULL) {
+ /*set the auto increment,write only, gamma red mode
+ in RAM_MODE */
+ regw_ip(0x0036, RAM_MODE);
+ /*set the starting address of gamma table */
+ regw_ip(0x00, RAM_ADR);
+ for (count = 0; count < table_size; count++)
+ regw_ip(rgb->gmm_tbl_b[count], RAM_WDT);
+ }
+ }
+ if (!(rgb->gmm_cfg_bypg)) {
+ if (rgb->gmm_tbl_g != NULL) {
+ /*set the auto increment,write only, gamma red
+ mode in RAM_MODE */
+ regw_ip(0x0037, RAM_MODE);
+ /*set the starting address of gamma table */
+ regw_ip(0x00, RAM_ADR);
+ for (count = 0; count < table_size; count++)
+ regw_ip(rgb->gmm_tbl_g[count], RAM_WDT);
+ }
+ }
+ /*set the auto increment,write only, gamma red mode in RAM_MODE */
+ regw_ip(0x0038, RAM_MODE);
+ /*set the starting address of gamma table */
+ regw_ip(0x00, RAM_ADR);
+ if (rgb->gmm_tbl_all != NULL) {
+ printk(KERN_INFO "gamma table not null\n");
+ for (count = 0; count < table_size; count++)
+ regw_ip(rgb->gmm_tbl_all[count], RAM_WDT);
+ } else {
+ }
+ regw_ip(0x00, RAM_MODE);
+ return 0;
+}
+
+int set_ee_regs(struct ipipe_edge_enhancer *edge_enhance)
+{
+ unsigned int count;
+ regw_ip(edge_enhance->yee_en, YEE_EN);
+ if (1 == edge_enhance->yee_en) {
+ regw_ip(edge_enhance->yee_emf, YEE_EMF);
+ regw_ip(edge_enhance->yee_shf, YEE_SHF);
+ regw_ip(edge_enhance->yee_mul_00, YEE_MUL_00);
+ regw_ip(edge_enhance->yee_mul_01, YEE_MUL_01);
+ regw_ip(edge_enhance->yee_mul_02, YEE_MUL_02);
+ regw_ip(edge_enhance->yee_mul_10, YEE_MUL_10);
+ regw_ip(edge_enhance->yee_mul_11, YEE_MUL_11);
+ regw_ip(edge_enhance->yee_mul_12, YEE_MUL_12);
+ regw_ip(edge_enhance->yee_mul_20, YEE_MUL_20);
+ regw_ip(edge_enhance->yee_mul_21, YEE_MUL_21);
+ regw_ip(edge_enhance->yee_mul_22, YEE_MUL_22);
+ /*set the auto increment,write only,ee mode in RAM_MODE */
+ regw_ip(0x0039, RAM_MODE);
+ regw_ip(-512 /*0x1FF */ , RAM_ADR);
+ if (edge_enhance->ee_table != NULL) {
+ for (count = 0; count < MAX_SIZE_EEC; count++)
+ regw_ip(edge_enhance->ee_table[count], RAM_WDT);
+
+ regw_ip(0x0, RAM_MODE);
+ regw_ip(0x0019, RAM_MODE);
+ regw_ip(-512, RAM_ADR);
+ for (count = 0; count < MAX_SIZE_EEC; count++)
+ regw_ip(0xFF, RAM_WDT);
+ }
+ }
+ return 0;
+}
+
+int set_fcs_regs(struct ipipe_false_color_suppresion *color_supress)
+{
+ regw_ip(color_supress->fcs_en, FCS_EN);
+ if (1 == color_supress->fcs_en) {
+ regw_ip(color_supress->fcs_typ_typ, FCS_TYP);
+ regw_ip(color_supress->fcs_shf_y, FCS_SHF_Y);
+ regw_ip(color_supress->fcs_shf_c, FCS_SHF_C);
+ regw_ip(color_supress->fcs_thr, FCS_THR);
+ regw_ip(color_supress->fcs_sgn, FCS_SGN);
+ regw_ip(color_supress->fcs_lth, FCS_LTH);
+ }
+ return 0;
+}
+
+int set_rsz_regs(struct ipipe_params *param_resize)
+{
+ u32 utemp;
+ /*Combine all the fields to make RSZ_SEQ register of IPIPE */
+ utemp =
+ (param_resize->rsz_seq_seq << 0) | (param_resize->
+ rsz_seq_tmm << 1) |
+ (param_resize->rsz_seq_hrv << 2)
+ | (param_resize->rsz_seq_vrv << 3) | (param_resize->
+ rsz_seq_crv << 4);
+ regw_ip(utemp, RSZ_SEQ);
+
+ return 0;
+}
+
+int set_aal_regs(struct ipipe_params *param_resize)
+{
+ regw_ip(param_resize->rsz_aal, RSZ_AAL);
+ return 0;
+}
+
+int set_rsz_structs(struct ipipe_params *params)
+{ /*set the registers of either RSZ0 or RSZ1 */
+ u32 utemp;
+ u32 rsz_seq, rsz_tmm;
+ utemp = regr_vpss(VPSS_MEMCTL);
+ RESETBIT(utemp, 1);
+ RESETBIT(utemp, 0);
+ SETBIT(utemp, 2);
+ regw_vpss(utemp, VPSS_MEMCTL);
+ regw_ip(params->rsz_en[0], RSZ_EN_0);
+ if (params->rsz_en[0]) {
+ /*testing--- for register write */
+ utemp = regr_ip(RSZ_EN_0);
+ /*enable RSZ clock */
+ regw_ip(1, GCL_SDR);
+ /*setting rescale parameters */
+ regw_ip(params->rsz_rsc_param[0].rsz_mode, RSZ_EN_0 + RSZ_MODE);
+ regw_ip(params->rsz_rsc_param[0].rsz_i_vst,
+ RSZ_EN_0 + RSZ_I_VST);
+ regw_ip(params->rsz_rsc_param[0].rsz_i_hst,
+ RSZ_EN_0 + RSZ_I_HST);
+ regw_ip(params->rsz_rsc_param[0].rsz_o_vsz,
+ RSZ_EN_0 + RSZ_O_VSZ);
+ regw_ip(params->rsz_rsc_param[0].rsz_o_hsz,
+ RSZ_EN_0 + RSZ_O_HSZ);
+ regw_ip(params->rsz_rsc_param[0].rsz_o_hst,
+ RSZ_EN_0 + RSZ_O_HST);
+ regw_ip(params->rsz_rsc_param[0].rsz_v_phs,
+ RSZ_EN_0 + RSZ_V_PHS);
+ regw_ip(params->rsz_rsc_param[0].rsz_v_dif,
+ RSZ_EN_0 + RSZ_V_DIF);
+ regw_ip(params->rsz_rsc_param[0].rsz_h_phs,
+ RSZ_EN_0 + RSZ_H_PHS);
+ regw_ip(params->rsz_rsc_param[0].rsz_h_dif,
+ RSZ_EN_0 + RSZ_H_DIF);
+ regw_ip(params->rsz_rsc_param[0].rsz_h_typ,
+ RSZ_EN_0 + RSZ_H_TYP);
+ regw_ip(params->rsz_rsc_param[0].rsz_h_lse_sel,
+ RSZ_EN_0 + RSZ_H_LSE);
+ regw_ip(params->rsz_rsc_param[0].rsz_h_lpf,
+ RSZ_EN_0 + RSZ_H_LPF);
+
+ /*seting rgb conversion parameters */
+ regw_ip(params->rsz2rgb[0].rsz_rgb_en, RSZ_EN_0 + RSZ_RGB_EN);
+ regw_ip(params->rsz2rgb[0].rsz_rgb_en, RSZ_EN_0 + RSZ_RGB_EN);
+ utemp =
+ ((params->rsz2rgb[0].rsz_rgb_typ << 0) | (params->
+ rsz2rgb[0].
+ rsz_rgb_msk0 << 1)
+ | (params->rsz2rgb[0].rsz_rgb_msk1) << 2);
+ regw_ip(utemp, RSZ_RGB_TYP);
+ regw_ip(params->rsz2rgb[0].rsz_rgb_alpha_val,
+ RSZ_EN_0 + RSZ_RGB_BLD);
+
+ /*setting external memory parameters */
+ regw_ip(params->ext_mem_param[0].rsz_sdr_oft,
+ RSZ_EN_0 + RSZ_SDR_OFT);
+ regw_ip(params->ext_mem_param[0].rsz_sdr_ptr_s,
+ RSZ_EN_0 + RSZ_SDR_PTR_S);
+ regw_ip(params->ext_mem_param[0].rsz_sdr_ptr_e,
+ RSZ_EN_0 + RSZ_SDR_PTR_E);
+ }
+
+ regw_ip(params->rsz_en[1], RSZ_EN_1);
+ if (params->rsz_en[1]) {
+ /*testing---- for register write */
+ utemp = regr_ip(RSZ_EN_1);
+
+ /*enable RSZ clock */
+ regw_ip(1, GCL_SDR);
+ /*setting rescale parameters */
+ regw_ip(params->rsz_rsc_param[1].rsz_mode, RSZ_EN_1 + RSZ_MODE);
+ regw_ip(params->rsz_rsc_param[1].rsz_i_vst,
+ RSZ_EN_1 + RSZ_I_VST);
+ /*regw_ip(rez_rescale_para->rsz_i_vsz,
+ RSZ_EN_0 + RSZ_I_VSZ); */
+ regw_ip(params->rsz_rsc_param[1].rsz_i_hst,
+ RSZ_EN_1 + RSZ_I_HST);
+ regw_ip(params->rsz_rsc_param[1].rsz_o_vsz,
+ RSZ_EN_1 + RSZ_O_VSZ);
+ regw_ip(params->rsz_rsc_param[1].rsz_o_hsz,
+ RSZ_EN_1 + RSZ_O_HSZ);
+ regw_ip(params->rsz_rsc_param[1].rsz_o_hst,
+ RSZ_EN_1 + RSZ_O_HST);
+ regw_ip(params->rsz_rsc_param[1].rsz_v_phs,
+ RSZ_EN_1 + RSZ_V_PHS);
+ regw_ip(params->rsz_rsc_param[1].rsz_v_dif,
+ RSZ_EN_1 + RSZ_V_DIF);
+ regw_ip(params->rsz_rsc_param[1].rsz_h_phs,
+ RSZ_EN_1 + RSZ_H_PHS);
+ regw_ip(params->rsz_rsc_param[1].rsz_h_dif,
+ RSZ_EN_1 + RSZ_H_DIF);
+ regw_ip(params->rsz_rsc_param[1].rsz_h_typ,
+ RSZ_EN_1 + RSZ_H_TYP);
+ regw_ip(params->rsz_rsc_param[1].rsz_h_lse_sel,
+ RSZ_EN_1 + RSZ_H_LSE);
+ regw_ip(params->rsz_rsc_param[1].rsz_h_lpf,
+ RSZ_EN_1 + RSZ_H_LPF);
+
+ /*seting rgb conversion parameters */
+ regw_ip(params->rsz2rgb[1].rsz_rgb_en, RSZ_EN_1 + RSZ_RGB_EN);
+ regw_ip(params->rsz2rgb[1].rsz_rgb_en, RSZ_EN_1 + RSZ_RGB_EN);
+ utemp =
+ ((params->rsz2rgb[1].rsz_rgb_typ << 0) | (params->
+ rsz2rgb[1].
+ rsz_rgb_msk0 << 1)
+ | (params->rsz2rgb[1].rsz_rgb_msk1) << 2);
+ regw_ip(utemp, RSZ_RGB_TYP);
+ regw_ip(params->rsz2rgb[1].rsz_rgb_alpha_val,
+ RSZ_EN_1 + RSZ_RGB_BLD);
+
+ /*setting external memory parameters */
+ regw_ip(params->ext_mem_param[1].rsz_sdr_oft,
+ RSZ_EN_1 + RSZ_SDR_OFT);
+ regw_ip(params->ext_mem_param[1].rsz_sdr_ptr_s,
+ RSZ_EN_1 + RSZ_SDR_PTR_S);
+ regw_ip(params->ext_mem_param[1].rsz_sdr_ptr_e,
+ RSZ_EN_1 + RSZ_SDR_PTR_E);
+
+ } else {
+ }
+
+ if (!params->rsz_en[0] && !params->rsz_en[1]) { /*resizer bypass mode */
+ rsz_tmm = 0;
+ rsz_seq = 0;
+ utemp =
+ (params->rsz_seq_seq << 0) | (params->
+ rsz_seq_tmm << 1) | (params->
+ rsz_seq_hrv << 2)
+ | (params->rsz_seq_vrv << 3) | (params->rsz_seq_crv << 4);
+ regw_ip(0, RSZ_AAL);
+ regw_ip(0, RSZ_EN_0 + RSZ_O_HST);
+ regw_ip(0, RSZ_EN_0 + RSZ_V_PHS);
+ regw_ip(256, RSZ_EN_0 + RSZ_V_DIF);
+ regw_ip(256, RSZ_EN_0 + RSZ_H_DIF);
+ regw_ip(0, RSZ_EN_0 + RSZ_H_LSE);
+ regw_ip(0, RSZ_EN_0 + RSZ_H_PHS);
+ regw_ip(0, RSZ_EN_1);
+ /*disable resizer clock, necessary to bypass resizer */
+ regw_ip(0, GCL_SDR);
+
+ }
+ return 0;
+}
+
+#endif /* End of #ifdef __KERNEL__ */
new file mode 100644
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2009 Texas Instruments Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define WIDTH_I 640
+#define HEIGHT_I 480
+#define WIDTH_O 640
+#define HEIGHT_O 480
+
+struct ipipe_params param_def = {
+ .ipipeif_param = {
+ /*IPPEIF config register */
+ .data_shift = BITS9_0,
+ .clock_select = SDRAM_CLK,
+
+ .ialaw = ALAW_OFF,
+ .pack_mode = SIXTEEN_BIT,
+ .avg_filter = AVG_OFF,
+ .clk_div = DIVIDE_SIXTH,
+ .source = SDRAM_RAW,
+ .decimation = DECIMATION_OFF,
+ .mode = ONE_SHOT,
+
+ .glob_hor_size = WIDTH_I + 8, /*632,*/
+ .glob_ver_size = HEIGHT_I + 10, /*466,*/
+ .hnum = WIDTH_I, /* 624,*/
+ .vnum = HEIGHT_I, /* 456, */
+ .adofs = WIDTH_I * 2, /* 1248, to make it
+ 32 alligned */
+ .rsz = 16, /* resize ratio = 16/rsz:
+ valid range (16-112) */
+ .gain = 0x200 /* (precision is U10Q9) */
+ },
+ .ipipe_mode = ONE_SHOT,
+ /*input/output datapath register */
+ .ipipe_dpaths_fmt = RAW2YUV,
+ .ipipe_dpaths_bypass = RAW_MODE_OFF, /*...check */
+
+ /*color pattern register */
+ .ipipe_colpat_olop = GREEN_BLUE,
+ .ipipe_colpat_olep = BLUE,
+ .ipipe_colpat_elop = RED,
+ .ipipe_colpat_elep = GREEN_RED,
+
+ /*horizontal/vertical start, horizontal/vertical size */
+ .ipipe_vst = 0,
+ .ipipe_vsz = HEIGHT_I - 1, /*456 - 1,*/
+ .ipipe_hst = 0, /*check*/
+ .ipipe_hsz = WIDTH_I - 1, /*624 - 1,*/
+ /*interupt generation after lines */
+
+ .def_cor = {.dfc_en = DISABLE,
+ .dfc_sel = 0,
+ /*.dfc_adr = 0,*/
+ .dfc_siz = 4,
+ .dfc_table = NULL /*(unsigned int*) yeeTable*/
+ },
+ .prog_nf = {
+ .noise_fil_en = DISABLE,
+ .d2f_cfg_spr = 0,
+ .d2f_cfg_shf = 0,
+ .type = 0,
+ .d2f_thr = NULL, /*(unsigned int *)NoiseFilterTHR ,*/
+ .d2f_str = NULL /*(unsigned int *)NoiseFilterSTR */
+ },
+ .prefilter = {
+ .pre_en = ENABLE,
+ .sel_0 = 1, /*AVG2MEDPIX,*/
+ .sel_1 = 1,
+ .typ_adaptive = ENABLE,
+ .typ_adaptive_dotred = DISABLE,
+ .pre_shf = 9,
+ .pre_gain = 128,
+ .pre_thr_g = 500,
+ .pre_thr_b = 4096,
+ .pre_thr_1 = 800},
+ .wb = {
+ .wb2_dgn = 0x200, /*512,512,1023,256, */
+ .wb2_wg_r = 0x40, /*444,*/
+ .wb2_wg_gr = 0x45, /*256,*/
+ .wb2_wg_gb = 0x60, /*256,*/
+ .wb2_wg_b = 0x45, /*568,428*/
+ },
+ .rgb2rgb = {
+ .rgb_mul_rr = 0x1a1, /*0x016c,*/
+ .rgb_mul_gr = 0xf8a, /*0x0FA4,*/
+ .rgb_mul_br = 0xfd5, /*0x0FF1,*/
+ .rgb_mul_rg = 0xfa1, /*0x0FD2,*/
+ .rgb_mul_gg = 0x1c4, /*0x013D,*/
+ .rgb_mul_bg = 0xf9b, /*0x0FF1,*/
+ .rgb_mul_rb = 0xfbd, /*0x0FD2,*/
+ .rgb_mul_gb = 0xfb1, /*0x0FA4,*/
+ .rgb_mul_bb = 0x192, /*0x018A,*/
+ .rgb_oft_or = 0x0000,
+ .rgb_oft_og = 0x0000,
+ .rgb_oft_ob = 0x0000,
+ .gmm_cfg_bypr = GC_BYPASS,
+ .gmm_cfg_bypg = GC_BYPASS,
+ .gmm_cfg_bypb = GC_BYPASS,
+ .gmm_cfg_tbl = IPIPE_RAM,
+ .gmm_cfg_siz = IPIPE_512,
+ .gmm_tbl_r = NULL,
+ .gmm_tbl_b = NULL,
+ .gmm_tbl_g = NULL,
+ .gmm_tbl_all = NULL /*(unsigned int *)GammaTableall */
+ },
+ .rgb2yuv = {
+ /* RDRV_IPIPE__SAT_LOW */
+ .yuv_adj_ctr = 0x10,
+ .yuv_adj_brt = 0x00,
+
+ .yuv_mul_ry = 0x004d,
+ .yuv_mul_gy = 0x0096,
+ .yuv_mul_by = 0x001d,
+ .yuv_mul_rcb = 0x03d4,
+ .yuv_mul_gcb = 0x03ac,
+ .yuv_mul_bcb = 0x0080,
+ .yuv_mul_rcr = 0x0080,
+ .yuv_mul_gcr = 0x0395,
+ .yuv_mul_bcr = 0x03eb,
+ .yuv_oft_y = 0x00,
+ .yuv_oft_cb = 0x80,
+ .yuv_oft_cr = 0x80,
+ .yuv_y_min = 0,
+ .yuv_y_max = 0xFF,
+ .yuv_c_min = 0,
+ .yuv_c_max = 0xFF,
+ .yuv_phs_lpf = DISABLE,
+ .yuv_phs_position = 1,
+
+ },
+ .edge_enhancer = {
+
+ .yee_en = DISABLE,
+ .yee_emf = ENABLE,
+ .yee_shf = 4, /* HPF Down Shift
+ Value: valid range (0-15) */
+ .yee_mul_00 = 48,
+ .yee_mul_01 = 12,
+ .yee_mul_02 = 1014,
+ .yee_mul_10 = 12,
+ .yee_mul_11 = 0,
+ .yee_mul_12 = 1018,
+ .yee_mul_20 = 1014,
+ .yee_mul_21 = 1018,
+ .yee_mul_22 = 1022,
+ .ee_table = NULL /*(unsigned int*) yeeTable*/
+ },
+ .false_color_suppresion = {
+ .fcs_en = ENABLE, /* Uint8 csupEnable*/
+ .fcs_typ_typ = 0,
+ .fcs_shf_y = 0,
+ .fcs_shf_c = 7,
+ .fcs_thr = 235,
+ .fcs_sgn = 0,
+ .fcs_lth = 0},
+ .rsz_seq_seq = DISABLE,
+ .rsz_seq_tmm = DISABLE, /* output confined mode (normal mode) */
+ .rsz_seq_hrv = DISABLE,
+ .rsz_seq_vrv = DISABLE,
+ .rsz_seq_crv = DISABLE,
+
+ .rsz_aal = DISABLE,
+
+ .rsz_rsc_param = {
+ {
+ .rsz_mode = ONE_SHOT,
+ .rsz_i_vst = 0,
+ .rsz_i_vsz = 0,
+ .rsz_i_hst = 0,
+ .rsz_o_vsz = HEIGHT_O - 1,
+ .rsz_o_hsz = WIDTH_O - 1,
+ .rsz_o_hst = 0,
+ .rsz_v_phs = 0,
+ /*unsigned int rsz_v_phs_o;*/
+ .rsz_v_dif = 243,
+ /*unsigned int rsz_v_siz_o;*/
+ .rsz_h_phs = 0,
+ .rsz_h_dif = 243,
+ .rsz_h_typ = CUBIC,
+ .rsz_h_lse_sel = INTERNAL_VALUE,
+ .rsz_h_lpf = 0},
+ {
+ ONE_SHOT,
+ 0,
+ 0,
+ 0,
+ 239,
+ 319,
+ 0,
+ 0,
+ 256,
+ 0,
+ 256,
+ CUBIC,
+ INTERNAL_VALUE,
+ 0}
+ },
+ .rsz2rgb = {
+ {
+ .rsz_rgb_en = DISABLE, /*....check*/
+ /* .rsz_rgb_typ = 0,
+ .rsz_rgb_msk0 = 0,
+ .rsz_rgb_msk1 = 0,
+ .rsz_rgb_alpha_val = 0 */
+ },
+ {
+ DISABLE,
+ }
+ },
+
+ .ext_mem_param = {
+ {
+ .rsz_sdr_bad_h = 0,
+ .rsz_sdr_bad_l = 0,
+ .rsz_sdr_sad_h = 0,
+ .rsz_sdr_sad_l = 0,
+ .rsz_sdr_oft = WIDTH_O * 2,
+ .rsz_sdr_ptr_s = 0,
+ .rsz_sdr_ptr_e = WIDTH_O},
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ WIDTH_O * 2,
+ 0,
+ 8191}
+ },
+ .rsz_en[0] = ENABLE,
+ .rsz_en[1] = DISABLE
+};
new file mode 100644
@@ -0,0 +1,529 @@
+/*
+ * Copyright (C) 2009 Texas Instruments Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef DM355_IPIPE_H
+#define DM355_IPIPE_H
+
+#include <linux/ioctl.h>
+
+
+#ifdef __KERNEL__
+
+/* include linux specific header files */
+#include <linux/completion.h>
+#include <linux/interrupt.h>
+#include <linux/semaphore.h>
+#include <mach/hardware.h>
+
+#endif /* End of #ifdef __KERNEL__ */
+
+#define MAX_SIZE_DFC 1024
+#define MAX_SIZE_EEC 1024
+#define MAX_SIZE_GAMMA 512
+
+#define MAX_SIZE_RAW_BY_PASS 4096
+#define MAX_SIZE 1344
+#define MAX_SIZE_RSZ0 1344
+#define MAX_SIZE_RSZ1 640
+#define MAX_DIF_VAL 4096
+#define MIN_DIF_VAL 32
+
+#define WB_GAIN_MAX 4
+#define RGB_MAX 3
+
+#define MAX_BUFFER 8
+#define SET_LOW_ADD 0x0000FFFF
+#define SET_HIGH_ADD 0xFFFF0000
+
+#define IPIPE_BUF_IN 0 /* input buffer */
+#define IPIPE_BUF_OUT 1 /* output buffer */
+
+#define IPIPE_INWIDTH_8BIT 0 /* pixel width of 8 bitS */
+#define IPIPE_INWIDTH_10BIT 1 /* pixel width of 10 bits */
+
+/*
+ * list of enums
+ */
+enum copy_method {
+ FROMTOP = 0,
+ FROMBOTTON = 1
+};
+
+enum sampling_type {
+ BOX = 0,
+ DIAMOND = 1
+};
+
+enum pre_filter_type {
+ AVG4PIX = 0,
+ AVG2MEDPIX = 1
+};
+
+enum enable_disable {
+ DISABLE = 0,
+ ENABLE = 1
+};
+
+enum gamma_cor_t {
+ GC_ENABLE = 0,
+ GC_BYPASS = 1
+};
+
+enum gamma_tbl_t {
+ IPIPE_RAM = 0,
+ IPIPE_ROM = 1
+};
+
+enum gamma_siz_t {
+ IPIPE_128 = 0,
+ IPIPE_256 = 1,
+ IPIPE_RESV = 2,
+ IPIPE_512 = 3
+};
+
+enum _ipipe_dpaths_fmt {
+ RAW2YUV = 0,
+ RAW2RAW = 1,
+ RAW2BOX = 2,
+ YUV2YUV = 3,
+ RAW2RAW_BYPASS = 4
+};
+
+enum _ipipe_dpaths_bypass {
+ RAW_MODE_OFF = 0,
+ RAW_MODE_ON = 1
+};
+
+enum _ipipe_colpat {
+ RED = 0,
+ GREEN_RED = 1,
+ GREEN_BLUE = 2,
+ BLUE = 3
+};
+
+enum fcs_typ {
+ Y = 0,
+ HPF_HORZ = 1,
+ HPF_VERT = 2,
+ HPF_2D = 3,
+ HPF_2D_YEE = 4
+};
+
+/* Resizer */
+enum resz_h_typ {
+ CUBIC = 0,
+ LINEAR = 1
+};
+
+enum resz_h_lse {
+ INTERNAL_VALUE = 0,
+ PROGRAMMED_VALUE = 1
+};
+
+enum ipipe_rsz_rgb_typ_t {
+ OUTPUT_32BIT = 0,
+ OUTPUT_16BIT = 1,
+};
+
+enum ipipe_rsz_rgb_msk_t {
+ NOMASK = 0,
+ MASKLAST2 = 1,
+};
+
+enum ipipeif_data_shift {
+ BITS15_2 = 0,
+ BITS14_1 = 1,
+ BITS13_0 = 2,
+ BITS12_0 = 3,
+ BITS11_0 = 4,
+ BITS10_0 = 5,
+ BITS9_0 = 6
+};
+
+enum ipipeif_clock {
+ PIXCEL_CLK = 0,
+ SDRAM_CLK = 1
+};
+
+enum ipipeif_ialaw {
+ ALAW_OFF = 0,
+ ALAW_ON = 1
+};
+
+enum ipipeif_pack_mode {
+ SIXTEEN_BIT = 0,
+ EIGHT_BIT = 1
+};
+
+enum ipipeif_avg_filter {
+ AVG_OFF = 0,
+ AVG_ON = 1
+};
+
+enum ipipeif_clkdiv {
+ DIVIDE_HALF = 0,
+ DIVIDE_THIRD = 1,
+ DIVIDE_FOURTH = 2,
+ DIVIDE_FIFTH = 3,
+ DIVIDE_SIXTH = 4,
+ DIVIDE_EIGHTH = 5,
+ DIVIDE_SIXTEENTH = 6,
+ DIVIDE_THIRTY = 7
+
+};
+
+enum ipipeif_input_source {
+ CCDC = 0,
+ SDRAM_RAW = 1,
+ CCDC_DARKFM = 2,
+ SDRAM_YUV = 3
+};
+
+enum ipipeif_decimation {
+ DECIMATION_OFF = 0,
+ DECIMATION_ON = 1
+};
+
+enum operation_mode {
+ CONTINUOUS = 0,
+ ONE_SHOT = 1
+};
+
+enum ipipeif_rsz_ratio {
+ ONE = 16,
+ ONE_HALF = 32,
+ ONE_THIRD = 48,
+ ONE_FOURTH = 64,
+ ONE_FIFTH = 80,
+ ONE_SIXTH = 96,
+ ONE_SEVENTH = 112
+
+};
+
+/* Defect Correction */
+struct ipipe_def_cor {
+ enum enable_disable dfc_en;
+ enum copy_method dfc_sel;
+
+ unsigned int dfc_siz;
+ unsigned int dfc_adr;
+ unsigned int *dfc_table;
+};
+
+struct ipipe_reqbufs {
+ int buf_type; /* type of frame buffer */
+ unsigned int size;
+ int count; /* number of frame buffer to be allocated */
+};
+/* structure buffer */
+struct ipipe_buffer {
+ int index; /* index number, 0 -> N-1 */
+ int buf_type; /* buffer type, input or output */
+ unsigned int offset;
+ unsigned int size; /* size of the buffer */
+};
+
+
+/* Programmable Noise Filter */
+struct ipipe_prog_nf {
+ enum enable_disable noise_fil_en;
+ unsigned int d2f_cfg_spr;
+ unsigned int d2f_cfg_shf;
+ enum sampling_type type;
+ unsigned int *d2f_thr;
+ unsigned int *d2f_str;
+};
+
+/* Prefilter */
+struct ipipe_prefilter {
+ enum enable_disable pre_en;
+ enum pre_filter_type sel_0;
+ enum pre_filter_type sel_1;
+
+ enum enable_disable typ_adaptive;
+ enum enable_disable typ_adaptive_dotred;
+ unsigned int pre_shf;
+ unsigned int pre_gain;
+ unsigned int pre_thr_g;
+ unsigned int pre_thr_b;
+ unsigned int pre_thr_1;
+};
+
+/* White Balance */
+struct ipipe_wb {
+ unsigned int wb2_dgn;
+ unsigned int wb2_wg_r;
+ unsigned int wb2_wg_gr;
+ unsigned int wb2_wg_gb;
+ unsigned int wb2_wg_b;
+};
+
+/* RGB to RGB conversion (include GAMMA correction) */
+struct ipipe_rgb2rgb {
+ unsigned int rgb_mul_rr;
+ unsigned int rgb_mul_gr;
+ unsigned int rgb_mul_br;
+ unsigned int rgb_mul_rg;
+ unsigned int rgb_mul_gg;
+ unsigned int rgb_mul_bg;
+ unsigned int rgb_mul_rb;
+ unsigned int rgb_mul_gb;
+ unsigned int rgb_mul_bb;
+ unsigned int rgb_oft_or;
+ unsigned int rgb_oft_og;
+ unsigned int rgb_oft_ob;
+ enum gamma_cor_t gmm_cfg_bypr;
+ enum gamma_cor_t gmm_cfg_bypg;
+ enum gamma_cor_t gmm_cfg_bypb;
+ enum gamma_tbl_t gmm_cfg_tbl;
+ enum gamma_siz_t gmm_cfg_siz;
+ unsigned int *gmm_tbl_r;
+ unsigned int *gmm_tbl_b;
+ unsigned int *gmm_tbl_g;
+ unsigned int *gmm_tbl_all;
+};
+
+enum yuv_phs_pos_t {
+ COSITING = 0,
+ CENTERING = 1
+};
+
+/* RGB to YUV(YCbCr) conversion */
+struct ipipe_rgb2yuv {
+ unsigned int yuv_adj_ctr;
+ unsigned int yuv_adj_brt;
+
+ unsigned int yuv_mul_ry;
+ unsigned int yuv_mul_gy;
+ unsigned int yuv_mul_by;
+ unsigned int yuv_mul_rcb;
+ unsigned int yuv_mul_gcb;
+ unsigned int yuv_mul_bcb;
+ unsigned int yuv_mul_rcr;
+ unsigned int yuv_mul_gcr;
+ unsigned int yuv_mul_bcr;
+ unsigned int yuv_oft_y;
+ unsigned int yuv_oft_cb;
+ unsigned int yuv_oft_cr;
+ unsigned int yuv_y_min;
+ unsigned int yuv_y_max;
+ unsigned int yuv_c_min;
+ unsigned int yuv_c_max;
+ enum enable_disable yuv_phs_lpf;
+ enum yuv_phs_pos_t yuv_phs_position;
+};
+
+/* Edge Enhancer */
+struct ipipe_edge_enhancer {
+ enum enable_disable yee_en;
+ enum enable_disable yee_emf;
+ unsigned int yee_shf;
+ unsigned int yee_mul_00;
+ unsigned int yee_mul_01;
+ unsigned int yee_mul_02;
+ unsigned int yee_mul_10;
+ unsigned int yee_mul_11;
+ unsigned int yee_mul_12;
+ unsigned int yee_mul_20;
+ unsigned int yee_mul_21;
+ unsigned int yee_mul_22;
+ unsigned int *ee_table;
+};
+
+/* False Color Suppression */
+struct ipipe_false_color_suppresion {
+ enum enable_disable fcs_en;
+ enum fcs_typ fcs_typ_typ;
+ unsigned int fcs_shf_y;
+ unsigned int fcs_shf_c;
+ unsigned int fcs_thr;
+ unsigned int fcs_sgn;
+ unsigned int fcs_lth;
+};
+
+/* Resizer Rescale Parameters*/
+struct ipipe_resizer_rescale_param {
+ unsigned int rsz_mode;
+ unsigned int rsz_i_vst;
+ unsigned int rsz_i_vsz;
+ unsigned int rsz_i_hst;
+ unsigned int rsz_o_vsz;
+ unsigned int rsz_o_hsz;
+ unsigned int rsz_o_hst;
+ unsigned int rsz_v_phs;
+ unsigned int rsz_v_dif;
+ unsigned int rsz_h_phs;
+ unsigned int rsz_h_dif;
+ enum resz_h_typ rsz_h_typ;
+ enum resz_h_lse rsz_h_lse_sel;
+ unsigned int rsz_h_lpf;
+};
+
+/* Resizer RGB Conversion Parameters */
+struct ipipe_resize2rgb {
+ enum enable_disable rsz_rgb_en;
+ enum ipipe_rsz_rgb_typ_t rsz_rgb_typ;
+ enum ipipe_rsz_rgb_msk_t rsz_rgb_msk0;
+ enum ipipe_rsz_rgb_msk_t rsz_rgb_msk1;
+ unsigned int rsz_rgb_alpha_val;
+};
+
+/* Resizer External Memory Parameters */
+struct ipipe_ext_mem_param {
+ unsigned int rsz_sdr_bad_h;
+ unsigned int rsz_sdr_bad_l;
+ unsigned int rsz_sdr_sad_h;
+ unsigned int rsz_sdr_sad_l;
+ unsigned int rsz_sdr_oft;
+ unsigned int rsz_sdr_ptr_s;
+ unsigned int rsz_sdr_ptr_e;
+};
+/*ipipeif structures*/
+struct ipipeif {
+ /*IPPEIF config register*/
+ enum ipipeif_data_shift data_shift;
+ enum ipipeif_clock clock_select;
+
+ enum ipipeif_ialaw ialaw;
+ enum ipipeif_pack_mode pack_mode;
+ enum ipipeif_avg_filter avg_filter;
+ enum ipipeif_clkdiv clk_div;
+ enum ipipeif_input_source source;
+ enum ipipeif_decimation decimation;
+ enum operation_mode mode;
+
+ unsigned int glob_hor_size;
+ unsigned int glob_ver_size;
+ unsigned int hnum;
+ unsigned int vnum;
+ unsigned int adofs;
+ enum ipipeif_rsz_ratio rsz;
+ unsigned int gain;
+};
+/* structure for all configurations */
+struct ipipe_params {
+ struct ipipeif ipipeif_param;
+
+ enum operation_mode ipipe_mode;
+ /*input/output datapath register*/
+ enum _ipipe_dpaths_fmt ipipe_dpaths_fmt;
+ enum _ipipe_dpaths_bypass ipipe_dpaths_bypass;
+
+ /*color pattern register*/
+ enum _ipipe_colpat ipipe_colpat_elep;
+ enum _ipipe_colpat ipipe_colpat_elop;
+ enum _ipipe_colpat ipipe_colpat_olep;
+ enum _ipipe_colpat ipipe_colpat_olop;
+
+ /*horizontal/vertical start, horizontal/vertical size*/
+ unsigned int ipipe_vst;
+ unsigned int ipipe_vsz;
+ unsigned int ipipe_hst;
+ unsigned int ipipe_hsz;
+ /*interupt generation after lines*/
+
+ struct ipipe_def_cor def_cor;
+ struct ipipe_prog_nf prog_nf;
+ struct ipipe_prefilter prefilter;
+ struct ipipe_wb wb;
+ struct ipipe_rgb2rgb rgb2rgb;
+ struct ipipe_rgb2yuv rgb2yuv;
+ struct ipipe_edge_enhancer edge_enhancer;
+ struct ipipe_false_color_suppresion false_color_suppresion;
+
+ enum enable_disable rsz_seq_seq;
+ enum enable_disable rsz_seq_tmm;
+ enum enable_disable rsz_seq_hrv;
+ enum enable_disable rsz_seq_vrv;
+ enum enable_disable rsz_seq_crv;
+
+ enum enable_disable rsz_aal;
+
+ struct ipipe_resizer_rescale_param rsz_rsc_param[2];
+ struct ipipe_resize2rgb rsz2rgb[2];
+ struct ipipe_ext_mem_param ext_mem_param[2];
+
+ enum enable_disable rsz_en[2];
+};
+struct ipipe_convert {
+ struct ipipe_buffer in_buff;
+ struct ipipe_buffer out_buff;
+};
+#ifdef __KERNEL__
+/* device structure keeps track of global information */
+struct ipipe_device {
+ struct ipipe_params *params;
+ unsigned char opened; /* state of the device */
+ unsigned char in_numbuffers; /* number of input buffers */
+ unsigned char out_numbuffers; /* number of output buffers */
+ struct ipipe_buffer *in_buff[MAX_BUFFER];
+ struct ipipe_buffer *out_buff[MAX_BUFFER];
+ struct completion wfc;
+ struct semaphore sem;
+};
+
+int ipipe_hw_setup(struct ipipe_params *config);
+int default_for_raw2raw(struct ipipe_params *parameter);
+int default_for_bypass(struct ipipe_params *parameter);
+int set_dfc_regs(struct ipipe_def_cor *dfc);
+int set_d2f_regs(struct ipipe_prog_nf *noise_filter);
+int set_pre_regs(struct ipipe_prefilter *pre_amplifier);
+int set_wb_regs(struct ipipe_wb *white_balance);
+int set_rgb_2_yuv_regs(int data_format, struct ipipe_rgb2yuv *y_cr_cb);
+int set_rgb_to_rgb_regs(struct ipipe_rgb2rgb *rgb);
+int set_ee_regs(struct ipipe_edge_enhancer *edge_enhance);
+int set_fcs_regs(struct ipipe_false_color_suppresion *color_supress);
+int set_rsz_regs(struct ipipe_params *param_resize);
+int set_aal_regs(struct ipipe_params *param_resize);
+int set_rsz_structs(struct ipipe_params *params);
+int write_out_addr(int resize_no, unsigned int address);
+
+int ipipe(struct ipipe_device *device, struct ipipe_convert *);
+int request_buffer(struct ipipe_device *, struct ipipe_reqbufs *);
+int query_buffer(struct ipipe_device *, struct ipipe_buffer *);
+int free_buffers(struct ipipe_device *);
+int validate_params(struct ipipe_params *);
+#endif /* End of #ifdef __KERNEL__ */
+/* ioctls definition */
+#define IPIPE_IOC_BASE 'P'
+#define IPIPE_REQBUF _IOW(IPIPE_IOC_BASE, 1, struct ipipe_reqbufs)
+#define IPIPE_QUERYBUF _IOR(IPIPE_IOC_BASE, 2, struct ipipe_buffer)
+#define IPIPE_SET_PARAM _IOWR(IPIPE_IOC_BASE, 3, struct ipipe_params*)
+#define IPIPE_GET_PARAM _IOWR(IPIPE_IOC_BASE, 4, struct ipipe_params*)
+#define IPIPE_START _IOWR(IPIPE_IOC_BASE, 5, char)
+/*
+*/
+#define IPIPE_IOC_MAXNR 5
+/* End of ioctls */
+
+#ifdef __KERNEL__
+struct vm_struct_area;
+struct inode;
+struct file;
+/* function definition for character driver interface functions */
+int ipipe_init(void);
+void ipipe_cleanup(void);
+int ipipe_open(struct inode *inode, struct file *);
+int ipipe_release(struct inode *inode, struct file *);
+int ipipe_ioctl(struct inode *inode, struct file *, unsigned int,
+ unsigned long);
+int ipipe_mmap(struct file *, struct vm_area_struct *);
+
+#endif /* End of #ifdef __KERNEL__ */
+
+#endif /* End of DM355_IPIPE_H */
new file mode 100644
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 2009 Texas Instruments Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef DAVINCI_IPIPE_HW_H
+#define DAVINCI_IPIPE_HW_H
+
+#include <linux/kernel.h>
+#include <mach/hardware.h>
+#include <linux/io.h>
+
+#ifdef __KERNEL__
+
+extern struct device *ipipe_dev;
+
+#define IPIPE_IOBASE_VADDR IO_ADDRESS(0x01C71000)
+#define IPIPEIF_IOBASE_VADDR IO_ADDRESS(0x01C70100)
+#define VPSS_BL_BASE IO_ADDRESS(0x01C70000)
+
+/* Register read/write */
+#define regw_ip(val, reg) __raw_writel(val, (reg + IPIPE_IOBASE_VADDR))
+#define regr_ip(reg) __raw_readl((reg) + IPIPE_IOBASE_VADDR)
+#define regw_if(val, reg) __raw_writel(val, (reg + IPIPEIF_IOBASE_VADDR))
+#define regr_if(reg) __raw_readl((reg) + IPIPEIF_IOBASE_VADDR)
+#define regw_vpss(val, reg) __raw_writel(val, (reg + VPSS_BL_BASE))
+#define regr_vpss(reg) __raw_readl((reg) + VPSS_BL_BASE)
+
+/* macro for bit set and clear */
+#define SETBIT(reg, bit) (reg = ((reg) | ((0x00000001)<<(bit))))
+#define RESETBIT(reg, bit) (reg = ((reg) & (~(0x00000001<<(bit)))))
+/* -to set vpss reg for ipipe- */
+#define VPSS_PCR 0x0804
+#define VPSS_MEMCTL 0x0818
+#define VPSS_CLK 0x0004
+
+#define SDR_ENABLE 2/*int number for IRQ_EN*/
+/* Internal RAM table addresses for defect correction */
+#define DEF_COR_START_ADDR 0x0000
+#define DEF_COR_END_ADDR 0x07FF
+#define DEF_COR_SIZE 1024
+
+/* Internal RAM table addresses for gamma correction */
+#define GAMMA_START_ADDR 0x0000
+#define GAMMA_END_ADDR 0x03FF
+
+/*Internal RAM table addresses for edge enhancement correction*/
+#define EDGE_ENHANCE_START_ADDR 0x0200
+#define EDGE_ENHANCE_END_ADDR 0x01FF
+/* -- */
+
+
+
+/* IPIPE Register Offsets from the base address */
+
+#define IPIPE_EN 0x0000
+#define IPIPE_MODE 0x0004
+#define IPIPE_DPATHS 0x0008
+#define IPIPE_COLPAT 0x000C
+#define IPIPE_VST 0x0010
+#define IPIPE_VSZ 0x0014
+#define IPIPE_HST 0x0018
+#define IPIPE_HSZ 0x001C
+/*gated clock enable*/
+#define GCL_ARM 0x0024
+#define GCL_CCD 0x0028
+#define GCL_SDR 0x002C
+/* Internal Memory Access */
+#define RAM_MODE 0x0030
+#define RAM_ADR 0x0034
+#define RAM_WDT 0x0038
+#define RAM_RDT 0x003C
+/* Interrupts */
+#define IRQ_EN 0x0040
+#define IRQ_RZA 0x0044
+#define IRQ_RZB 0x0048
+/* Defect Correction */
+#define DFC_EN 0x004C
+#define DFC_SEL 0x0050
+#define DFC_ADR 0x0054
+#define DFC_SIZE 0x0058
+/* Programmable Noise Filter */
+#define D2F_EN 0x005C
+#define D2F_CFG 0x0060
+#define DFC_THR 0x0064
+#define D2F_STR 0x00E4
+/* PreFilter */
+#define PRE_EN 0x0164
+#define PRE_TYP 0x0168
+#define PRE_SHF 0x016C
+#define PRE_GAIN 0x0170
+#define PRE_THR_G 0x0174
+#define PRE_THR_B 0x0178
+#define PRE_THR_1 0x017C
+/* White Balance */
+#define WB2_DGN 0x0180
+#define WB2_WG_R 0x0184
+#define WB2_WG_GR 0x0188
+#define WB2_WG_GB 0x018C
+#define WB2_WG_B 0x0190
+
+/* RGB to RGB conversion (include GAMMA correction) */
+#define RGB_MUL_RR 0x01F4
+
+/* Defect Correction */
+#define DFC_EN 0x004C
+#define DFC_SEL 0x0050
+#define DFC_ADR 0x0054
+#define DFC_SIZ 0x0058
+/* Programmable Noise Filter */
+#define D2F_EN 0x005C
+#define D2F_CFG 0x0060
+#define DFC_THR 0x0064
+#define D2F_STR 0x00E4
+/* PreFilter */
+#define PRE_EN 0x0164
+#define PRE_TYP 0x0168
+#define PRE_SHF 0x016C
+#define PRE_GAIN 0x0170
+#define PRE_THR_G 0x0174
+#define PRE_THR_B 0x0178
+#define PRE_THR_1 0x017C
+/* White Balance */
+#define WB2_DGN 0x0180
+#define WB2_WG_R 0x0184
+#define WB2_WG_GR 0x0188
+#define WB2_WG_GB 0x018C
+#define WB2_WG_B 0x0190
+
+/* RGB to RGB conversion (include GAMMA correction) */
+#define RGB_MUL_RR 0x01F4
+#define RGB_MUL_GR 0x01F8
+#define RGB_MUL_BR 0x01FC
+#define RGB_MUL_RG 0x0200
+#define RGB_MUL_GG 0x0204
+#define RGB_MUL_BG 0x0208
+#define RGB_MUL_RB 0x020C
+
+#define RGB_MUL_GB 0x0210
+#define RGB_MUL_BB 0x0214
+#define RGB_MUL_OR 0x0218
+#define RGB_MUL_OG 0x021C
+#define RGB_MUL_OB 0x0220
+#define GMM_CFG 0x0224
+
+/* RGB to YUV(YCbCr) conversion */
+#define YUV_ADJ 0x0228
+#define YUV_MUL_RY 0x022C
+#define YUV_MUL_GY 0x0230
+#define YUV_MUL_BY 0x0234
+#define YUV_MUL_RCB 0x0238
+#define YUV_MUL_GCB 0x023C
+#define YUV_MUL_BCB 0x0240
+#define YUV_MUL_RCR 0x0244
+#define YUV_MUL_GCR 0x0248
+#define YUV_MUL_BCR 0x024C
+#define YUV_OFT_Y 0x0250
+#define YUV_OFT_CB 0x0254
+#define YUV_OFT_CR 0x0258
+#define YUV_Y_MIN 0x025C
+#define YUV_Y_MAX 0x0260
+#define YUV_C_MIN 0x0264
+#define YUV_C_MAX 0x0268
+#define YUV_PHS 0x026C
+
+/* Edge Enhancer */
+#define YEE_EN 0x0270
+#define YEE_EMF 0x0274
+#define YEE_SHF 0x0278
+#define YEE_MUL_00 0x027C
+#define YEE_MUL_01 0x0280
+#define YEE_MUL_02 0x0284
+#define YEE_MUL_10 0x0288
+#define YEE_MUL_11 0x028C
+#define YEE_MUL_12 0x0290
+#define YEE_MUL_20 0x0294
+#define YEE_MUL_21 0x0298
+#define YEE_MUL_22 0x029C
+
+/* False Color Suppression */
+#define FCS_EN 0x02A0
+#define FCS_TYP 0x02A4
+#define FCS_SHF_Y 0x02A8
+#define FCS_SHF_C 0x02AC
+#define FCS_THR 0x02B0
+#define FCS_SGN 0x02B4
+#define FCS_LTH 0x02B8
+
+/* Resizer */
+#define RSZ_SEQ 0x02BC
+#define RSZ_AAL 0x02C0
+
+/* Resizer Rescale Parameters */
+#define RSZ_EN_0 0x02C4
+#define RSZ_EN_1 0x0334
+/*
+ * Offset of the registers to be added with
+ * base register of either RSZ0 or RSZ1
+ */
+#define RSZ_MODE 0x4
+#define RSZ_I_VST 0x8
+#define RSZ_I_VSZ 0xC
+#define RSZ_I_HST 0x10
+#define RSZ_O_VSZ 0x14
+#define RSZ_O_HST 0x18
+#define RSZ_O_HSZ 0x1C
+#define RSZ_V_PHS 0x20
+#define RSZ_V_PHS_O 0x24
+#define RSZ_V_DIF 0x28
+#define RSZ_V_SIZ_O 0x2C
+#define RSZ_H_PHS 0x30
+#define RSZ_H_DIF 0x34
+#define RSZ_H_TYP 0x38
+#define RSZ_H_LSE 0x3C
+#define RSZ_H_LPF 0x40
+
+/* Resizer RGB Conversion Parameters */
+#define RSZ_RGB_EN 0x44
+#define RSZ_RGB_TYP 0x48
+#define RSZ_RGB_BLD 0x4C
+
+/* Resizer External Memory Parameters */
+#define RSZ_SDR_BAD_H 0x50
+#define RSZ_SDR_BAD_L 0x54
+#define RSZ_SDR_SAD_H 0x58
+#define RSZ_SDR_SAD_L 0x5C
+#define RSZ_SDR_OFT 0x60
+#define RSZ_SDR_PTR_S 0x64
+#define RSZ_SDR_PTR_E 0x68
+#define RSZ_SDR_PTR_O 0x6C
+
+
+/* Macro for resizer */
+#define IPIPE_RESIZER_0(i) (IPIPE_IOBASE_VADDR + RSZ_EN_0 + i)
+#define IPIPE_RESIZER_1(i) (IPIPE_IOBASE_VADDR + RSZ_EN_1 + i)
+/* --*/
+
+/* Masking fields */
+#define IPIPE_MODE_WRT (1 << 1)
+#define IPIPE_DPATHS_FMT (3 << 0)
+#define IPIPE_DPATHS_BYPASS (1 << 2)
+#define IPIPE_COLPAT_ELEP (3 << 0)
+#define IPIPE_COLPAT_ELOP (3 << 2)
+#define IPIPE_COLPAT_OLEP (3 << 4)
+#define IPIPE_COLPAT_OLOP (3 << 6)
+#define IPIPE_D2F_CFG_SPR (3 << 0)
+#define IPIPE_D2F_CFG_SHF (3 << 2)
+#define IPIPE_D2F_CFG_TYP (1 << 4)
+#define IPIPE_PRE_TYP_SEL1 (1 << 1)
+#define IPIPE_PRE_TYP_EN0 (1 << 2)
+#define IPIPE_PRE_TYP_EN1 (1 << 3)
+#define IPIPE_GMM_CFG_BYPG (1 << 1)
+#define IPIPE_GMM_CFG_BYPB (1 << 2)
+#define IPIPE_GMM_CFG_TBL (1 << 4)
+#define IPIPE_GMM_CFG_SIZ (3 << 5)
+#define IPIPE_YUV_ADJ_CTR (0Xff << 0)
+#define IPIPE_YUV_ADJ_BRT (0Xff << 8)
+#define IPIPE_YUV_PHS_LPF (1 << 1)
+#define IPIPE_RSZ_SEQ_TMM (1 << 1)
+#define IPIPE_RSZ_SEQ_HRV (1 << 2)
+#define IPIPE_RSZ_SEQ_VRV (1 << 3)
+#define IPIPE_RSZ_SEQ_CRV (1 << 3)
+#define IPIPE_RSZ_RGB_TYP_MSK0 (1 << 1)
+#define IPIPE_RSZ_RGB_TYP_MSK1 (1 << 2)
+
+/* BIT FIELDS */
+
+#define IPIPE_DPATHS_BYPASS_SHIFT 2
+#define IPIPE_COLPAT_ELOP_SHIFT 2
+#define IPIPE_COLPAT_OLEP_SHIFT 4
+#define IPIPE_COLPAT_OLOP_SHIFT 6
+#define IPIPE_D2F_CFG_SHF_SHIFT 2
+#define IPIPE_D2F_CFG_TYP_SHIFT 4
+#define IPIPE_PRE_TYP_SEL1_SHIFT 1
+#define IPIPE_PRE_TYP_EN0_SHIFT 2
+#define IPIPE_PRE_TYP_EN1_SHIFT 3
+#define IPIPE_GMM_CFG_BYPG_SHIFT 1
+#define IPIPE_GMM_CFG_BYPB_SHIFT 2
+#define IPIPE_GMM_CFG_TBL_SHIFT 4
+#define IPIPE_GMM_CFG_SIZ_SHIFT 5
+#define IPIPE_YUV_ADJ_BRT_SHIFT 8
+#define IPIPE_YUV_PHS_LPF_SHIFT 1
+#define IPIPE_RSZ_SEQ_TMM_SHIFT 1
+#define IPIPE_RSZ_SEQ_HRV_SHIFT 2
+#define IPIPE_RSZ_SEQ_VRV_SHIFT 3
+#define IPIPE_RSZ_SEQ_CRV_SHIFT 3
+#define IPIPE_RSZ_RGB_TYP_MSK0_SHIFT 1
+#define IPIPE_RSZ_RGB_TYP_MSK1_SHIFT 2
+
+
+
+/* IPIPEIF Register Offsets from the base address */
+#define IPIPEIF_ENABLE 0x00
+#define IPIPEIF_GFG 0x04
+#define IPIPEIF_PPLN 0x08
+#define IPIPEIF_LPFR 0x0C
+#define IPIPEIF_HNUM 0x10
+#define IPIPEIF_VNUM 0x14
+#define IPIPEIF_ADDRU 0x18
+#define IPIPEIF_ADDRL 0x1C
+#define IPIPEIF_ADOFS 0x20
+#define IPIPEIF_RSZ 0x24
+#define IPIPEIF_GAIN 0x28
+
+#endif /* End of #ifdef __KERNEL__ */
+#endif /* End of #ifdef DAVINCI_IPIPE_HW_H */