camera and ipp: modify camera driver and ipp driver, camera can work with ipp
authorddl <ddl@rock-chips.com>
Thu, 16 Dec 2010 11:00:25 +0000 (19:00 +0800)
committerddl <ddl@rock-chips.com>
Thu, 16 Dec 2010 11:00:56 +0000 (19:00 +0800)
arch/arm/mach-rk29/board-rk29sdk.c [changed mode: 0755->0644]
arch/arm/mach-rk29/devices.c [changed mode: 0755->0644]
arch/arm/mach-rk29/include/mach/rk29-ipp.h [new file with mode: 0644]
arch/arm/mach-rk29/include/mach/rk29_camera.h [changed mode: 0755->0644]
drivers/media/video/Kconfig
drivers/media/video/ov2659.c
drivers/media/video/ov5642.c
drivers/media/video/rk29_camera_oneframe.c
drivers/staging/rk29/ipp/rk29-ipp.c
drivers/staging/rk29/ipp/rk29-ipp.h [deleted file]

old mode 100755 (executable)
new mode 100644 (file)
index 2f10842..c9d1786
 #define PMEM_GPU_SIZE       SZ_64M\r
 #define PMEM_UI_SIZE        SZ_32M\r
 #define PMEM_VPU_SIZE       SZ_32M\r
-#define PMEM_CAM_SIZE       SZ_16M\r
+#define PMEM_CAM_SIZE       0x00c00000\r
+#ifdef CONFIG_VIDEO_RK29_WORK_IPP\r
+#define MEM_CAMIPP_SIZE     SZ_4M\r
+#else\r
+#define MEM_CAMIPP_SIZE     0\r
+#endif\r
 #define MEM_FB_SIZE         (3*SZ_2M)\r
 \r
 #define PMEM_GPU_BASE       ((u32)RK29_SDRAM_PHYS + SDRAM_SIZE - PMEM_GPU_SIZE)\r
 #define PMEM_UI_BASE        (PMEM_GPU_BASE - PMEM_UI_SIZE)\r
 #define PMEM_VPU_BASE       (PMEM_UI_BASE - PMEM_VPU_SIZE)\r
 #define PMEM_CAM_BASE       (PMEM_VPU_BASE - PMEM_CAM_SIZE)\r
-#define MEM_FB_BASE         (PMEM_CAM_BASE - MEM_FB_SIZE)\r
+#define MEM_CAMIPP_BASE     (PMEM_CAM_BASE - MEM_CAMIPP_SIZE)\r
+#define MEM_FB_BASE         (MEM_CAMIPP_BASE - MEM_FB_SIZE)\r
 #define LINUX_SIZE          (MEM_FB_BASE - RK29_SDRAM_PHYS)\r
 \r
 extern struct sys_timer rk29_timer;\r
@@ -541,7 +547,14 @@ struct rk29camera_platform_data rk29_camera_platform_data = {
             .gpio_flag = (SENSOR_POWERACTIVE_LEVEL_1|SENSOR_RESETACTIVE_LEVEL_1),\r
             .dev_name = SENSOR_NAME_1,\r
         }\r
-    }\r
+    },\r
+       #ifdef CONFIG_VIDEO_RK29_WORK_IPP\r
+       .meminfo = {\r
+           .name  = "camera_ipp_mem",\r
+               .start = MEM_CAMIPP_BASE,\r
+               .size   = MEM_CAMIPP_SIZE,\r
+       }\r
+       #endif\r
 };\r
 \r
 static int rk29_sensor_io_init(void)\r
@@ -701,7 +714,32 @@ struct platform_device rk29_soc_camera_pdrv_1 = {
 };\r
 \r
 \r
-extern struct platform_device rk29_device_camera;\r
+static u64 rockchip_device_camera_dmamask = 0xffffffffUL;\r
+struct resource rk29_camera_resource[] = {\r
+       [0] = {\r
+               .start = RK29_VIP_PHYS,\r
+               .end   = RK29_VIP_PHYS + RK29_VIP_SIZE - 1,\r
+               .flags = IORESOURCE_MEM,\r
+       },\r
+       [1] = {\r
+               .start = IRQ_VIP,\r
+               .end   = IRQ_VIP,\r
+               .flags = IORESOURCE_IRQ,\r
+       }\r
+};\r
+\r
+/*platform_device : */\r
+struct platform_device rk29_device_camera = {\r
+       .name             = RK29_CAM_DRV_NAME,\r
+       .id               = RK29_CAM_PLATFORM_DEV_ID,               /* This is used to put cameras on this interface */\r
+       .num_resources    = ARRAY_SIZE(rk29_camera_resource),\r
+       .resource         = rk29_camera_resource,\r
+       .dev            = {\r
+               .dma_mask = &rockchip_device_camera_dmamask,\r
+               .coherent_dma_mask = 0xffffffffUL,\r
+               .platform_data  = &rk29_camera_platform_data,\r
+       }\r
+};\r
 #endif\r
 /*****************************************************************************************\r
  * backlight  devices\r
old mode 100755 (executable)
new mode 100644 (file)
index 3761431..f9a7778
@@ -404,62 +404,6 @@ struct platform_device rk29xx_device_spi1m = {
        },
 };
 
-/* RK29 Camera :  ddl@rock-chips.com  */
-#ifdef CONFIG_VIDEO_RK29
-extern struct rk29camera_platform_data rk29_camera_platform_data;
-
-static struct resource rk29_camera_resource[] = {
-       [0] = {
-               .start = RK29_VIP_PHYS,
-               .end   = RK29_VIP_PHYS + RK29_VIP_SIZE - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_VIP,
-               .end   = IRQ_VIP,
-               .flags = IORESOURCE_IRQ,
-       }
-};
-
-static u64 rockchip_device_camera_dmamask = 0xffffffffUL;
-
-/*platform_device : */
-struct platform_device rk29_device_camera = {
-       .name             = RK29_CAM_DRV_NAME,
-       .id               = RK29_CAM_PLATFORM_DEV_ID,               /* This is used to put cameras on this interface */
-       .num_resources    = ARRAY_SIZE(rk29_camera_resource),
-       .resource         = rk29_camera_resource,
-       .dev            = {
-               .dma_mask = &rockchip_device_camera_dmamask,
-               .coherent_dma_mask = 0xffffffffUL,
-               .platform_data  = &rk29_camera_platform_data,
-       }
-};
-#endif
-
-#ifdef CONFIG_RK29_IPP
-/* rk29 ipp resource */
-static struct resource rk29_ipp_resource[] = {
-       [0] = {
-               .start = RK29_IPP_PHYS,
-               .end   = RK29_IPP_PHYS + RK29_IPP_SIZE - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_IPP,
-               .end   = IRQ_IPP,
-               .flags = IORESOURCE_IRQ,
-       },
-};
-
-/*platform_device*/
-struct platform_device rk29_device_ipp = {
-       .name             = "rk29-ipp",
-       .id               = -1,
-       .num_resources    = ARRAY_SIZE(rk29_ipp_resource),
-       .resource         = rk29_ipp_resource,
-};
-#endif
 #if defined(CONFIG_MTD_NAND_RK29XX)  
 static struct resource rk29xxnand_resources[] = {
        {
@@ -564,6 +508,31 @@ struct platform_device rk29_device_iis_8ch = {
         .resource       = rk29_iis_8ch_resource,
 };
 #endif
+#ifdef CONFIG_RK29_IPP
+/* rk29 ipp resource */
+static struct resource rk29_ipp_resource[] = {
+       [0] = {
+               .start = RK29_IPP_PHYS,
+               .end   = RK29_IPP_PHYS + RK29_IPP_SIZE - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_IPP,
+               .end   = IRQ_IPP,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+/*platform_device*/
+//extern struct rk29ipp_info rk29_ipp_info;
+struct platform_device rk29_device_ipp = {
+       .name             = "rk29-ipp",
+       .id               = -1,
+       .num_resources    = ARRAY_SIZE(rk29_ipp_resource),
+       .resource         = rk29_ipp_resource,
+};
+#endif
+
 #ifdef CONFIG_DWC_OTG
 /*DWC_OTG*/
 static struct resource dwc_otg_resource[] = {
diff --git a/arch/arm/mach-rk29/include/mach/rk29-ipp.h b/arch/arm/mach-rk29/include/mach/rk29-ipp.h
new file mode 100644 (file)
index 0000000..ebbc888
--- /dev/null
@@ -0,0 +1,103 @@
+#ifndef _RK29_IPP_DRIVER_H_\r
+#define _RK29_IPP_DRIVER_H_\r
+\r
+/* Image data */\r
+struct rk29_ipp_image\r
+{\r
+       uint32_t        YrgbMst;        // image Y/rgb address\r
+       uint32_t    CbrMst;     // image CbCr address\r
+       uint32_t        w;      // image full width\r
+       uint32_t        h;      // image full height\r
+       uint32_t        fmt;    // color format\r
+};\r
+\r
+struct rk29_ipp_req {\r
+       struct rk29_ipp_image src0; // source0 image\r
+       struct rk29_ipp_image dst0; // destination0 image\r
+       struct rk29_ipp_image src1; // source1 image\r
+       struct rk29_ipp_image dst1; // destination1 image\r
+       uint32_t src_vir_w;\r
+       uint32_t dst_vir_w;\r
+       uint32_t timeout;\r
+       uint32_t flag; //rotate\r
+};\r
+\r
+//uint32_t format Ã¶¾ÙÀàÐÍ\r
+enum\r
+{\r
+       IPP_XRGB_8888 = 0,\r
+       IPP_RGB_565 =1 ,\r
+       IPP_Y_CBCR_H2V1 = 2,  //yuv 422sp\r
+       IPP_Y_CBCR_H2V2 = 3, //yuv 420sp\r
+       IPP_Y_CBCR_H1V1 =6, //yuv 444sp\r
+       IPP_IMGTYPE_LIMIT\r
+};\r
+\r
+typedef enum\r
+ {\r
+     IPP_ROT_90,\r
+     IPP_ROT_180,\r
+     IPP_ROT_270,\r
+     IPP_ROT_X_FLIP,\r
+     IPP_ROT_Y_FLIP,\r
+     IPP_ROT_0,\r
+     IPP_ROT_LIMIT\r
+ } ROT_DEG;\r
+\r
+ struct ipp_regs {\r
+       uint32_t ipp_config;\r
+       uint32_t ipp_src_img_info;\r
+       uint32_t ipp_dst_img_info;\r
+       uint32_t ipp_img_vir;\r
+       uint32_t ipp_int;\r
+       uint32_t ipp_src0_y_mst;\r
+       uint32_t ipp_src0_Cbr_mst;\r
+       uint32_t ipp_src1_y_mst;\r
+       uint32_t ipp_src1_Cbr_mst;\r
+       uint32_t ipp_dst0_y_mst;\r
+       uint32_t ipp_dst0_Cbr_mst;\r
+       uint32_t ipp_dst1_y_mst;\r
+       uint32_t ipp_dst1_Cbr_mst;\r
+       uint32_t ipp_pre_scl_para;\r
+       uint32_t ipp_post_scl_para;\r
+       uint32_t ipp_swap_ctrl;\r
+       uint32_t ipp_pre_img_info;\r
+       uint32_t ipp_axi_id;\r
+       uint32_t ipp_process_st;\r
+};\r
+\r
+#define IPP_CONFIG                             (0x00)\r
+#define IPP_SRC_IMG_INFO                       (0x04)\r
+#define IPP_DST_IMG_INFO                       (0x08)\r
+#define IPP_IMG_VIR                            (0x0c)\r
+#define IPP_INT                                        (0x10)\r
+#define IPP_SRC0_Y_MST                 (0x14)\r
+#define IPP_SRC0_CBR_MST                       (0x18)\r
+#define IPP_SRC1_Y_MST                 (0x1c)\r
+#define IPP_SRC1_CBR_MST                       (0x20)\r
+#define IPP_DST0_Y_MST                 (0x24)\r
+#define IPP_DST0_CBR_MST                       (0x28)\r
+#define IPP_DST1_Y_MST                 (0x2c)\r
+#define IPP_DST1_CBR_MST                       (0x30)\r
+#define IPP_PRE_SCL_PARA                       (0x34)\r
+#define IPP_POST_SCL_PARA                      (0x38)\r
+#define IPP_SWAP_CTRL                          (0x3c)\r
+#define IPP_PRE_IMG_INFO                       (0x40)\r
+#define IPP_AXI_ID                             (0x44)\r
+#define IPP_SRESET                             (0x48)\r
+#define IPP_PROCESS_ST                 (0x50)\r
+\r
+/*ipp config*/\r
+#define ROT_ENABLE                             (1<<8)\r
+#define PRE_SCALE                                      (1<<4)\r
+#define POST_SCALE                             (1<<3)\r
+\r
+\r
+#define IS_YCRCB(img) ((img == IPP_Y_CBCR_H2V1) | (img == IPP_Y_CBCR_H2V2) | \\r
+                      (img == IPP_Y_CBCR_H1V1) )\r
+#define IS_RGB(img) ((img == IPP_RGB_565) | (img == IPP_ARGB_8888) | \\r
+                    (img == IPP_XRGB_8888) ))\r
+#define HAS_ALPHA(img) (img == IPP_ARGB_8888)\r
+\r
+int ipp_do_blit(struct rk29_ipp_req *req);\r
+#endif /*_RK29_IPP_DRIVER_H_*/
\ No newline at end of file
old mode 100755 (executable)
new mode 100644 (file)
index ae542c9..c033e25
@@ -53,10 +53,16 @@ struct rk29camera_gpio_res {
     const char *dev_name;
 };
 
+struct rk29camera_mem_res {
+       const char *name;
+       unsigned int start;
+       unsigned int size;
+};
 struct rk29camera_platform_data {
     int (*io_init)(void);
     int (*io_deinit)(void);
     struct rk29camera_gpio_res gpio_res[2];
+       struct rk29camera_mem_res meminfo;
 };
 
 #endif /* __ASM_ARCH_CAMERA_H_ */
index e0dafb85d85493b9dd973daa4f1966603db7d34c..394cb0b745fc702ef5f8127d0f38c43d3aac2a12 100644 (file)
@@ -975,6 +975,19 @@ config VIDEO_RK29_WORK_ONEFRAME
 config VIDEO_RK29_WORK_PINGPONG
        bool "VIP PingPong Mode"
 endchoice
+choice
+       prompt "RK29XX camera sensor interface work with IPP "
+       depends on VIDEO_RK29 && RK29_IPP
+       default VIDEO_RK29_WORK_IPP
+       ---help---
+               RK29 Camera Sensor Interface(VIP) can work with IPP or not IPP
+config VIDEO_RK29_WORK_IPP
+       bool "VIP work with IPP"
+
+config VIDEO_RK29_WORK_NOT_IPP
+       bool "VIP don't work with IPP"
+endchoice
+
 #
 # USB Multimedia device configuration
 #
index e85a8bdbf95491274a1c68ec9f9c263d05c7af4c..59f3cafb4dd134dd704e622a5f56dd581f3ddaa6 100644 (file)
@@ -1411,7 +1411,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
     struct sensor *sensor = to_sensor(client);
     struct v4l2_pix_format *pix = &f->fmt.pix;
     struct reginfo *winseqe_set_addr=NULL;
-    int ret, set_w,set_h;
+    int ret=0, set_w,set_h;
 
        if (sensor->info_priv.pixfmt != pix->pixelformat) {
                switch (pix->pixelformat)
@@ -1489,21 +1489,21 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
         winseqe_set_addr = SENSOR_INIT_WINSEQADR;               /* ddl@rock-chips.com : Sensor output smallest size if  isn't support app  */
         set_w = SENSOR_INIT_WIDTH;
         set_h = SENSOR_INIT_HEIGHT;
-
+               ret = -1;
                SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,pix->width,pix->height);
     }
 
     if ((int)winseqe_set_addr  != sensor->info_priv.winseqe_cur_addr)
     {
-        ret = sensor_write_array(client, winseqe_set_addr);
-        if (ret != 0)
-        {
+        ret |= sensor_write_array(client, winseqe_set_addr);
+        if (ret != 0) {
             SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING());
-            return ret;
+            goto sensor_s_fmt_end;
         }
 
         sensor->info_priv.winseqe_cur_addr  = (int)winseqe_set_addr;
 
+
         SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h);
     }
     else
@@ -1511,7 +1511,11 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
         SENSOR_TR("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h);
     }
 
-    return 0;
+       pix->width = set_w;
+    pix->height = set_h;
+
+sensor_s_fmt_end:
+    return ret;
 }
 
 static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
index 7a830987610c9071f6f5083153bb46901ec3bfdc..d38d3af218e9c62388ed037139d739295b52902a 100644 (file)
@@ -476,8 +476,8 @@ static struct reginfo sensor_init_data[] =
     {0x370b , 0x40},
     {0x370d , 0x02},
     {0x3620 , 0x52},
-
-    {0X0000, 0X00}
+    {0x3c00 , 0x04},
+    {0X0000 , 0x00}
 
 };
 /* 2592X1944 QSXGA */
@@ -1819,7 +1819,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
     struct sensor *sensor = to_sensor(client);
     struct v4l2_pix_format *pix = &f->fmt.pix;
     struct reginfo *winseqe_set_addr=NULL;
-    int ret, set_w,set_h;
+    int ret = 0, set_w,set_h;
 
        if (sensor->info_priv.pixfmt != pix->pixelformat) {
                switch (pix->pixelformat)
@@ -1904,31 +1904,29 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
         set_w = 2592;
         set_h = 1944;
     }
-    else if (sensor_qvga[0].reg)
+    else
     {
-        winseqe_set_addr = sensor_qvga;               /* ddl@rock-chips.com : Sensor output smallest size if  isn't support app  */
-        set_w = 320;
-        set_h = 240;
-    }
-       else
-       {
+        winseqe_set_addr = SENSOR_INIT_WINSEQADR;               /* ddl@rock-chips.com : Sensor output smallest size if  isn't support app  */
+        set_w = SENSOR_INIT_WIDTH;
+        set_h = SENSOR_INIT_HEIGHT;
+               ret = -1;
                SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,pix->width,pix->height);
-               return -EINVAL;
-       }
+    }
 
     if ((int)winseqe_set_addr  != sensor->info_priv.winseqe_cur_addr)
     {
-        ret = sensor_write_array(client, winseqe_set_addr);
-        if (ret != 0)
-        {
+        ret |= sensor_write_array(client, winseqe_set_addr);
+        if (ret != 0) {
             SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING());
-            return ret;
+            goto sensor_s_fmt_end;
         }
 
         sensor->info_priv.winseqe_cur_addr  = (int)winseqe_set_addr;
         #if CONFIG_SENSOR_Focus
                sensor_af_zoneupdate(client);
                #endif
+
+
         SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h);
     }
     else
@@ -1936,7 +1934,10 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
         SENSOR_TR("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h);
     }
 
-    return 0;
+       pix->width = set_w;
+       pix->height = set_h;
+sensor_s_fmt_end:
+    return ret;
 }
 
 static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
index 4593b8e5ffe42fa2d93b33ea9d2185a684b498c7..14e2821490acc3d20babe7a3e220e52afd91b8bc 100644 (file)
@@ -39,6 +39,8 @@
 #include <media/videobuf-dma-contig.h>
 #include <media/soc_camera.h>
 
+#include <mach/rk29-ipp.h>
+
 // VIP Reg Offset
 #define RK29_VIP_AHBR_CTRL                0x00
 #define RK29_VIP_INT_MASK                 0x04
@@ -188,6 +190,12 @@ struct rk29_camera_reg
        unsigned int VipCrm;
        enum rk29_camera_reg_state Inval;
 };
+struct rk29_camera_work
+{
+       struct videobuf_buffer *vb;
+       struct rk29_camera_dev *pcdev;
+       struct work_struct work;
+};
 struct rk29_camera_dev
 {
     struct soc_camera_host     soc_host;
@@ -201,6 +209,12 @@ struct rk29_camera_dev
        void __iomem *grf_base;
     int frame_inval;           /* ddl@rock-chips.com : The first frames is invalidate  */
     unsigned int irq;
+       unsigned int pixfmt;
+       unsigned int vipmem_phybase;
+       unsigned int vipmem_size;
+       unsigned int vipmem_bsize;
+       int host_width;
+       int host_height;
 
     struct rk29camera_platform_data *pdata;
     struct resource            *res;
@@ -212,6 +226,8 @@ struct rk29_camera_dev
     struct videobuf_buffer     *active;
        struct videobuf_queue *vb_vidq_ptr;
        struct rk29_camera_reg reginfo_suspend;
+       struct workqueue_struct *camera_wq;
+       struct rk29_camera_work *camera_work;
 };
 static DEFINE_MUTEX(camera_lock);
 static const char *rk29_cam_driver_description = "RK29_Camera";
@@ -227,14 +243,26 @@ static int rk29_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
                                unsigned int *size)
 {
     struct soc_camera_device *icd = vq->priv_data;
+       struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+    struct rk29_camera_dev *pcdev = ici->priv;
     int bytes_per_pixel = (icd->current_fmt->depth + 7) >> 3;
 
     dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);
 
+       if (pcdev->camera_work == NULL) {
+               pcdev->camera_work = kmalloc(sizeof(struct rk29_camera_work)*(*count), GFP_KERNEL);
+               if (pcdev->camera_work == NULL)
+                       RK29CAMERA_TR("\n %s kmalloc fail\n", __FUNCTION__);
+       }
+
     /* planar capture requires Y, U and V buffers to be page aligned */
-    *size = PAGE_ALIGN( icd->user_width * icd->user_height * bytes_per_pixel);                               /* Y pages UV pages, yuv422*/
+    *size = PAGE_ALIGN(icd->user_width* icd->user_height * bytes_per_pixel);                               /* Y pages UV pages, yuv422*/
+       pcdev->vipmem_bsize = PAGE_ALIGN(pcdev->host_width * pcdev->host_height * bytes_per_pixel);
 
-    RK29CAMERA_DG("\n%s..%d.. size = %d\n",__FUNCTION__,__LINE__, *size);
+       if ((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height))
+               BUG_ON(pcdev->vipmem_bsize*(*count) > pcdev->vipmem_size);
+
+    RK29CAMERA_DG("\n%s..%d.. videobuf size:%d, vipmem_buf size:%d \n",__FUNCTION__,__LINE__, *size,pcdev->vipmem_bsize);
 
     return 0;
 }
@@ -260,6 +288,7 @@ static void rk29_videobuf_free(struct videobuf_queue *vq, struct rk29_buffer *bu
 static int rk29_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field)
 {
     struct soc_camera_device *icd = vq->priv_data;
+       struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
     struct rk29_buffer *buf;
     int ret;
 
@@ -290,7 +319,7 @@ static int rk29_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buff
         vb->state   = VIDEOBUF_NEEDS_INIT;
     }
 
-    vb->size = vb->width * vb->height * ((buf->fmt->depth + 7) >> 3) ;          /* ddl@rock-chips.com : fmt->depth is coorect */
+    vb->size = (((vb->width * vb->height *buf->fmt->depth) + 7) >> 3) ;          /* ddl@rock-chips.com : fmt->depth is coorect */
     if (0 != vb->baddr && vb->bsize < vb->size) {
         ret = -EINVAL;
         goto out;
@@ -313,14 +342,21 @@ out:
 
 static inline void rk29_videobuf_capture(struct videobuf_buffer *vb)
 {
-    unsigned int size;
+       unsigned int y_addr,uv_addr;
+       struct rk29_camera_dev *pcdev = rk29_camdev_info_ptr;
 
     if (vb) {
-        size = vb->width * vb->height; /* Y pages UV pages, yuv422*/
-        write_vip_reg(RK29_VIP_CAPTURE_F1SA_Y, vb->boff);
-        write_vip_reg(RK29_VIP_CAPTURE_F1SA_UV, vb->boff + size);
-        write_vip_reg(RK29_VIP_CAPTURE_F2SA_Y, vb->boff);
-        write_vip_reg(RK29_VIP_CAPTURE_F2SA_UV, vb->boff + size);
+               if ((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height)) {
+                       y_addr = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
+                       uv_addr = y_addr + pcdev->host_width*pcdev->host_height;
+               } else {
+                       y_addr = vb->boff;
+                       uv_addr = y_addr + vb->width * vb->height;
+               }
+        write_vip_reg(RK29_VIP_CAPTURE_F1SA_Y, y_addr);
+        write_vip_reg(RK29_VIP_CAPTURE_F1SA_UV, uv_addr);
+        write_vip_reg(RK29_VIP_CAPTURE_F2SA_Y, y_addr);
+        write_vip_reg(RK29_VIP_CAPTURE_F2SA_UV, uv_addr);
         write_vip_reg(RK29_VIP_FB_SR,  0x00000002);//frame1 has been ready to receive data,frame 2 is not used
     }
 }
@@ -337,7 +373,7 @@ static void rk29_videobuf_queue(struct videobuf_queue *vq,
 
     vb->state = VIDEOBUF_QUEUED;
 
-       if (!list_empty(&pcdev->capture)) {
+       if (list_empty(&pcdev->capture)) {
                list_add_tail(&vb->queue, &pcdev->capture);
        } else {
                if (list_entry(pcdev->capture.next, struct videobuf_buffer, queue) != vb)
@@ -351,10 +387,76 @@ static void rk29_videobuf_queue(struct videobuf_queue *vq,
         rk29_videobuf_capture(vb);
     }
 }
+static int rk29_pixfmt2ippfmt(unsigned int pixfmt, int *ippfmt)
+{
+       switch (pixfmt)
+       {
+               case V4L2_PIX_FMT_YUV422P:
+               {
+                       *ippfmt = IPP_Y_CBCR_H2V1;
+                       break;
+               }
+               case V4L2_PIX_FMT_YUV420:
+               {
+                       *ippfmt = IPP_Y_CBCR_H2V2;
+                       break;
+               }
+               default:
+                       goto rk29_pixfmt2ippfmt_err;
+       }
+
+       return 0;
+rk29_pixfmt2ippfmt_err:
+       return -1;
+}
+static void rk29_camera_capture_process(struct work_struct *work)
+{
+       struct rk29_camera_work *camera_work = container_of(work, struct rk29_camera_work, work);
+       struct videobuf_buffer *vb = camera_work->vb;
+       struct rk29_camera_dev *pcdev = camera_work->pcdev;
+       struct rk29_ipp_req ipp_req;
+       unsigned int flags;
+
+       ipp_req.src0.YrgbMst = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
+       ipp_req.src0.CbrMst= ipp_req.src0.YrgbMst + pcdev->host_width*pcdev->host_height;
+       ipp_req.src0.w = pcdev->host_width;
+       ipp_req.src0.h = pcdev->host_height;
+       rk29_pixfmt2ippfmt(pcdev->pixfmt, &ipp_req.src0.fmt);
+
+       ipp_req.dst0.YrgbMst = vb->boff;
+       ipp_req.dst0.CbrMst= vb->boff+vb->width * vb->height;
+       ipp_req.dst0.w = pcdev->icd->user_width;
+       ipp_req.dst0.h = pcdev->icd->user_height;
+       rk29_pixfmt2ippfmt(pcdev->pixfmt, &ipp_req.dst0.fmt);
+
+       ipp_req.src_vir_w = ipp_req.src0.w;
+       ipp_req.dst_vir_w = ipp_req.dst0.w;
+       ipp_req.timeout = 100;
+       ipp_req.flag = IPP_ROT_0;
+
+       if (ipp_do_blit(&ipp_req)) {
+               spin_lock_irqsave(&pcdev->lock, flags);
+               vb->state = VIDEOBUF_ERROR;
+               spin_unlock_irqrestore(&pcdev->lock, flags);
+               RK29CAMERA_TR("Capture image(vb->i:0x%x) which IPP operated is error!\n", vb->i);
+               RK29CAMERA_TR("ipp_req.src0.YrgbMst:0x%x ipp_req.src0.CbrMst:0x%x \n", ipp_req.src0.YrgbMst,ipp_req.src0.CbrMst);
+               RK29CAMERA_TR("ipp_req.src0.w:0x%x ipp_req.src0.h:0x%x \n",ipp_req.src0.w,ipp_req.src0.h);
+               RK29CAMERA_TR("ipp_req.src0.fmt:0x%x\n",ipp_req.src0.fmt);
+               RK29CAMERA_TR("ipp_req.dst0.YrgbMst:0x%x ipp_req.dst0.CbrMst:0x%x \n",ipp_req.dst0.YrgbMst,ipp_req.dst0.CbrMst);
+               RK29CAMERA_TR("ipp_req.dst0.w:0x%x ipp_req.dst0.h:0x%x \n",ipp_req.dst0.w ,ipp_req.dst0.h);
+               RK29CAMERA_TR("ipp_req.dst0.fmt:0x%x\n",ipp_req.dst0.fmt);
+               RK29CAMERA_TR("ipp_req.src_vir_w:0x%x ipp_req.dst_vir_w :0x%x\n",ipp_req.src_vir_w ,ipp_req.dst_vir_w);
+           RK29CAMERA_TR("ipp_req.timeout:0x%x ipp_req.flag :0x%x\n",ipp_req.timeout,ipp_req.flag);
+       }
+
+       wake_up(&(camera_work->vb->done));
+}
+
 static irqreturn_t rk29_camera_irq(int irq, void *data)
 {
     struct rk29_camera_dev *pcdev = data;
     struct videobuf_buffer *vb;
+       struct rk29_camera_work *wk;
 
     read_vip_reg(RK29_VIP_INT_STS);    /* clear vip interrupte single  */
 
@@ -397,7 +499,15 @@ static irqreturn_t rk29_camera_irq(int irq, void *data)
                vb->field_count++;
                }
 
-        wake_up(&vb->done);
+               if ((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height)) {
+                       wk = pcdev->camera_work + vb->i;
+                       INIT_WORK(&(wk->work), rk29_camera_capture_process);
+                       wk->vb = vb;
+                       wk->pcdev = pcdev;
+                       queue_work(pcdev->camera_wq, &(wk->work));
+               } else {
+                       wake_up(&vb->done);
+               }
     }
 
 RK29_CAMERA_IRQ_END:
@@ -596,6 +706,11 @@ static void rk29_camera_remove_device(struct soc_camera_device *icd)
                pcdev->vb_vidq_ptr = NULL;
        }
 
+       if (pcdev->camera_work) {
+               kfree(pcdev->camera_work);
+               pcdev->camera_work = NULL;
+       }
+
        pcdev->active = NULL;
     pcdev->icd = NULL;
        pcdev->reginfo_suspend.Inval = Reg_Invalidate;
@@ -717,15 +832,18 @@ static void rk29_camera_setup_format(struct soc_camera_device *icd, __u32 host_p
         case V4L2_PIX_FMT_YUV422P:
             vip_ctrl_val |= VIPREGYUV422;
                        pcdev->frame_inval = RK29_CAM_FRAME_INVAL_DC;
+                       pcdev->pixfmt = host_pixfmt;
             break;
         case V4L2_PIX_FMT_YUV420:
             vip_ctrl_val |= VIPREGYUV420;
                        if (pcdev->frame_inval != RK29_CAM_FRAME_INVAL_INIT)
                                pcdev->frame_inval = RK29_CAM_FRAME_INVAL_INIT;
+                       pcdev->pixfmt = host_pixfmt;
             break;
                case V4L2_PIX_FMT_SGRBG10:
                        vip_ctrl_val |= (VIP_RAW | VIP_SENSOR | VIP_DATA_LITTLEEND);
                        pcdev->frame_inval = RK29_CAM_FRAME_INVAL_DC;
+                       pcdev->pixfmt = host_pixfmt;
                        break;
         default:                                                                                /* ddl@rock-chips.com : vip output format is hold when pixfmt is invalidate */
             vip_ctrl_val |= (read_vip_reg(RK29_VIP_CTRL) & VIPREGYUV422);
@@ -753,12 +871,7 @@ static void rk29_camera_setup_format(struct soc_camera_device *icd, __u32 host_p
         vip_crop = ((rect->left<<16) + rect->top);
         vip_fs  = (((rect->width + rect->left)<<16) + (rect->height+rect->top));
     } else if (vip_ctrl_val & PING_PONG) {
-        if (rect->left ||rect->top ) {
-                       RK29CAMERA_DG("\n %s..PingPang not support Crop \n",__FUNCTION__);
-                       BUG();
-        }
-               vip_crop = 0;
-        vip_fs  = (((rect->width + rect->left)<<16) + (rect->height+rect->top));
+        BUG();
     }
 
     write_vip_reg(RK29_VIP_CROP, vip_crop);
@@ -766,6 +879,9 @@ static void rk29_camera_setup_format(struct soc_camera_device *icd, __u32 host_p
 
     write_vip_reg(RK29_VIP_FB_SR,  0x00000003);
 
+       pcdev->host_width = rect->width;
+       pcdev->host_height = rect->height;
+
     RK29CAMERA_DG("\n%s.. crop:0x%x fs:0x%x ctrl:0x%x CtrlReg:0x%x\n",__FUNCTION__,vip_crop,vip_fs,vip_ctrl_val,read_vip_reg(RK29_VIP_CTRL));
        return;
 }
@@ -874,12 +990,16 @@ static int rk29_camera_set_fmt(struct soc_camera_device *icd,
     struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
     const struct soc_camera_data_format *cam_fmt = NULL;
     const struct soc_camera_format_xlate *xlate = NULL;
+       struct soc_camera_host *ici =to_soc_camera_host(icd->dev.parent);
+    struct rk29_camera_dev *pcdev = ici->priv;
     struct v4l2_pix_format *pix = &f->fmt.pix;
     struct v4l2_format cam_f = *f;
     struct v4l2_rect rect;
-    int ret;
+    int ret,usr_w,usr_h;
 
-    RK29CAMERA_DG("\n%s..%d..  \n",__FUNCTION__,__LINE__);
+       usr_w = pix->width;
+       usr_h = pix->height;
+    RK29CAMERA_DG("\n%s enter width:%d  height:%d\n",__FUNCTION__,usr_w,usr_h);
 
     xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
     if (!xlate) {
@@ -894,20 +1014,29 @@ static int rk29_camera_set_fmt(struct soc_camera_device *icd,
     ret = v4l2_subdev_call(sd, video, s_fmt, &cam_f);
     cam_f.fmt.pix.pixelformat = pix->pixelformat;
     *pix = cam_f.fmt.pix;
-
+       #ifdef CONFIG_VIDEO_RK29_WORK_IPP
+       if ((pix->width != usr_w) || (pix->height != usr_h)) {
+               pix->width = usr_w;
+               pix->height = usr_h;
+       }
+       #endif
     icd->sense = NULL;
 
     if (!ret) {
         rect.left = 0;
         rect.top = 0;
-        rect.width = pix->width;
-        rect.height = pix->height;
+        rect.width = cam_f.fmt.pix.width;
+        rect.height = cam_f.fmt.pix.height;
 
-        RK29CAMERA_DG("\n%s..%s..%s \n",__FUNCTION__,xlate->host_fmt->name, cam_fmt->name);
+        RK29CAMERA_DG("\n%s..%s..%s icd width:%d  host width:%d \n",__FUNCTION__,xlate->host_fmt->name, cam_fmt->name,
+                                  rect.width, pix->width);
         rk29_camera_setup_format(icd, pix->pixelformat, cam_fmt->fourcc, &rect);
-
         icd->buswidth = xlate->buswidth;
         icd->current_fmt = xlate->host_fmt;
+
+               if (((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height))) {
+                       BUG_ON(pcdev->vipmem_phybase == 0);
+               }
     }
 
 RK29_CAMERA_SET_FMT_END:
@@ -925,9 +1054,11 @@ static int rk29_camera_try_fmt(struct soc_camera_device *icd,
     struct v4l2_pix_format *pix = &f->fmt.pix;
     __u32 pixfmt = pix->pixelformat;
     enum v4l2_field field;
-    int ret;
+    int ret,usr_w,usr_h;
 
-    RK29CAMERA_DG("\n%s..%d.. \n",__FUNCTION__,__LINE__);
+       usr_w = pix->width;
+       usr_h = pix->height;
+       RK29CAMERA_DG("\n%s enter width:%d  height:%d\n",__FUNCTION__,usr_w,usr_h);
 
     xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
     if (!xlate) {
@@ -948,6 +1079,12 @@ static int rk29_camera_try_fmt(struct soc_camera_device *icd,
     /* limit to sensor capabilities */
     ret = v4l2_subdev_call(sd, video, try_fmt, f);
     pix->pixelformat = pixfmt;
+       #ifdef CONFIG_VIDEO_RK29_WORK_IPP
+       if ((pix->width != usr_w) || (pix->height != usr_h)) {
+               pix->width = usr_w;
+               pix->height = usr_h;
+       }
+       #endif
 
     field = pix->field;
 
@@ -1150,7 +1287,17 @@ static int rk29_camera_probe(struct platform_device *pdev)
     if (pcdev->pdata && pcdev->pdata->io_init) {
         pcdev->pdata->io_init();
     }
-
+       #ifdef CONFIG_VIDEO_RK29_WORK_IPP
+       if (pcdev->pdata && (strcmp(pcdev->pdata->meminfo.name,"camera_ipp_mem")==0)) {
+               pcdev->vipmem_phybase = pcdev->pdata->meminfo.start;
+               pcdev->vipmem_size = pcdev->pdata->meminfo.size;
+               RK29CAMERA_TR("\n%s Memory(start:0x%x size:0x%x) for IPP obtain \n",__FUNCTION__, pcdev->pdata->meminfo.start,pcdev->pdata->meminfo.size);
+       } else {
+               RK29CAMERA_TR("\n%s Memory for IPP have not obtain! IPP Function is fail\n",__FUNCTION__);
+               pcdev->vipmem_phybase = 0;
+               pcdev->vipmem_size = 0;
+       }
+       #endif
     INIT_LIST_HEAD(&pcdev->capture);
     spin_lock_init(&pcdev->lock);
 
@@ -1182,6 +1329,10 @@ static int rk29_camera_probe(struct platform_device *pdev)
         goto exit_reqirq;
     }
 
+       pcdev->camera_wq = create_workqueue("camera wq");
+       if (pcdev->camera_wq == NULL)
+               goto exit_free_irq;
+
     pcdev->soc_host.drv_name   = RK29_CAM_DRV_NAME;
     pcdev->soc_host.ops                = &rk29_soc_camera_host_ops;
     pcdev->soc_host.priv               = pcdev;
index 411be71ce93ff40105735b44b23816337059f139..f30e0f11205e63ce280b1d0d7686442e58965ef8 100644 (file)
@@ -38,7 +38,7 @@
 #include <linux/wait.h>\r
 #include <linux/syscalls.h>\r
 #include <linux/timer.h>\r
-#include "rk29-ipp.h"\r
+#include <mach/rk29-ipp.h>\r
 \r
 \r
 struct ipp_drvdata {\r
@@ -123,7 +123,7 @@ static void ipp_soft_reset(void)
                ERR("soft reset timeout.\n");\r
 }\r
 \r
-static int ipp_do_blit(struct rk29_ipp_req *req)\r
+int ipp_do_blit(struct rk29_ipp_req *req)\r
 {\r
        uint32_t rotate;\r
        uint32_t pre_scale      = 0;\r
@@ -131,9 +131,9 @@ static int ipp_do_blit(struct rk29_ipp_req *req)
        uint32_t pre_scale_w, pre_scale_h;\r
        uint32_t post_scale_w = 0x1000;\r
        uint32_t post_scale_h = 0x1000;\r
-       uint32_t pre_scale_target_w, pre_scale_target_h;\r
+       uint32_t pre_scale_target_w=0, pre_scale_target_h=0;\r
        uint32_t post_scale_target_w, post_scale_target_h;\r
-       uint32_t dst0_YrgbMst,dst0_CbrMst;\r
+       uint32_t dst0_YrgbMst=0,dst0_CbrMst=0;\r
        uint32_t ret = 0;\r
        rotate = req->flag;\r
        switch (rotate) {\r
@@ -620,7 +620,7 @@ static int ipp_do_blit(struct rk29_ipp_req *req)
 \r
        if(!wait_event_timeout(wait_queue, wq_condition, msecs_to_jiffies(req->timeout)))\r
        {\r
-               printk("wait_event_timeout \n");\r
+               printk("%s wait_event_timeout \n",__FUNCTION__);\r
                wq_condition = 0;\r
                if(!drvdata)\r
                {\r
diff --git a/drivers/staging/rk29/ipp/rk29-ipp.h b/drivers/staging/rk29/ipp/rk29-ipp.h
deleted file mode 100644 (file)
index d9c5338..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-#ifndef _RK29_IPP_DRIVER_H_\r
-#define _RK29_IPP_DRIVER_H_\r
-\r
-/* Image data */\r
-struct rk29_ipp_image\r
-{\r
-       uint32_t        YrgbMst;        // image Y/rgb address\r
-       uint32_t    CbrMst;     // image CbCr address\r
-       uint32_t        w;      // image full width\r
-       uint32_t        h;      // image full height\r
-       uint32_t        fmt;    // color format\r
-};\r
-\r
-struct rk29_ipp_req {\r
-       struct rk29_ipp_image src0; // source0 image\r
-       struct rk29_ipp_image dst0; // destination0 image\r
-       struct rk29_ipp_image src1; // source1 image\r
-       struct rk29_ipp_image dst1; // destination1 image\r
-       uint32_t src_vir_w;\r
-       uint32_t dst_vir_w;\r
-       uint32_t timeout;\r
-       uint32_t flag; //rotate\r
-};\r
-\r
-//uint32_t format Ã¶¾ÙÀàÐÍ\r
-enum\r
-{\r
-       IPP_XRGB_8888 = 0,\r
-       IPP_RGB_565 =1 ,\r
-       IPP_Y_CBCR_H2V1 = 2,  //yuv 422sp\r
-       IPP_Y_CBCR_H2V2 = 3, //yuv 420sp\r
-       IPP_Y_CBCR_H1V1 =6, //yuv 444sp\r
-       IPP_IMGTYPE_LIMIT\r
-};\r
-\r
-typedef enum\r
- {\r
-     IPP_ROT_90,\r
-     IPP_ROT_180,\r
-     IPP_ROT_270,\r
-     IPP_ROT_X_FLIP,\r
-     IPP_ROT_Y_FLIP,\r
-     IPP_ROT_0,\r
-     IPP_ROT_LIMIT\r
- } ROT_DEG;\r
-\r
- struct ipp_regs {\r
-       uint32_t ipp_config;\r
-       uint32_t ipp_src_img_info;\r
-       uint32_t ipp_dst_img_info;\r
-       uint32_t ipp_img_vir;\r
-       uint32_t ipp_int;\r
-       uint32_t ipp_src0_y_mst;\r
-       uint32_t ipp_src0_Cbr_mst;\r
-       uint32_t ipp_src1_y_mst;\r
-       uint32_t ipp_src1_Cbr_mst;\r
-       uint32_t ipp_dst0_y_mst;\r
-       uint32_t ipp_dst0_Cbr_mst;\r
-       uint32_t ipp_dst1_y_mst;\r
-       uint32_t ipp_dst1_Cbr_mst;\r
-       uint32_t ipp_pre_scl_para;\r
-       uint32_t ipp_post_scl_para;\r
-       uint32_t ipp_swap_ctrl;\r
-       uint32_t ipp_pre_img_info;\r
-       uint32_t ipp_axi_id;\r
-       uint32_t ipp_process_st;\r
-};\r
-\r
-#define IPP_CONFIG                             (0x00)\r
-#define IPP_SRC_IMG_INFO                       (0x04)\r
-#define IPP_DST_IMG_INFO                       (0x08)\r
-#define IPP_IMG_VIR                            (0x0c)\r
-#define IPP_INT                                        (0x10)\r
-#define IPP_SRC0_Y_MST                 (0x14)\r
-#define IPP_SRC0_CBR_MST                       (0x18)\r
-#define IPP_SRC1_Y_MST                 (0x1c)\r
-#define IPP_SRC1_CBR_MST                       (0x20)\r
-#define IPP_DST0_Y_MST                 (0x24)\r
-#define IPP_DST0_CBR_MST                       (0x28)\r
-#define IPP_DST1_Y_MST                 (0x2c)\r
-#define IPP_DST1_CBR_MST                       (0x30)\r
-#define IPP_PRE_SCL_PARA                       (0x34)\r
-#define IPP_POST_SCL_PARA                      (0x38)\r
-#define IPP_SWAP_CTRL                          (0x3c)\r
-#define IPP_PRE_IMG_INFO                       (0x40)\r
-#define IPP_AXI_ID                             (0x44)\r
-#define IPP_SRESET                             (0x48)\r
-#define IPP_PROCESS_ST                 (0x50)\r
-\r
-/*ipp config*/\r
-#define ROT_ENABLE                             (1<<8)\r
-#define PRE_SCALE                                      (1<<4)\r
-#define POST_SCALE                             (1<<3)\r
-\r
-\r
-#define IS_YCRCB(img) ((img == IPP_Y_CBCR_H2V1) | (img == IPP_Y_CBCR_H2V2) | \\r
-                      (img == IPP_Y_CBCR_H1V1) )\r
-#define IS_RGB(img) ((img == IPP_RGB_565) | (img == IPP_ARGB_8888) | \\r
-                    (img == IPP_XRGB_8888) ))\r
-#define HAS_ALPHA(img) (img == IPP_ARGB_8888)\r
-\r
-#endif /*_RK29_IPP_DRIVER_H_*/
\ No newline at end of file