fimc-is: Add setting of vendorSpecific2[0] metadata structure field
authorSylwester Nawrocki <s.nawrocki@samsung.com>
Fri, 26 Feb 2016 16:33:50 +0000 (17:33 +0100)
committerMarek Szyprowski <m.szyprowski@samsung.com>
Fri, 27 Apr 2018 08:25:07 +0000 (10:25 +0200)
vendorSpecific2[0] value pattern depends on the fimc-is firmware
revision. Move setting up of this field to the kernel as there is
all information required for this.
The driver will update the field accordingly only if user space
leaves it cleared.

Change-Id: Ib77d7be7081a2239a19912757392522d044d58f9
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
drivers/media/platform/exynos/fimc-is/fimc-is-device-ischain.c
drivers/media/platform/exynos/fimc-is/fimc-is-device-ischain.h

index be0de25d28ea91e263eb794f05ee8dc3e33a816d..03864545b4e1397595f2f7235ddff0036b313360 100644 (file)
@@ -757,6 +757,19 @@ static void fimc_is_ischain_version(struct fimc_is_device_ischain *this, char *n
                pinfo = &this->pinfo;
                memcpy(pinfo->header_ver, &version_str[32], 11);
                pinfo->header_ver[11] = '\0';
+
+               if (strnstr(&load_bin[size - FIMC_IS_VERSION_SIZE],
+                           "9745-2014/08/27", FIMC_IS_VERSION_SIZE)) {
+                       /* TM2E (reverse engineered values) */
+                       this->isp_vs2_offset = 0x003f8be0;
+                       this->isp_vs2_step = 0x8308;
+               } else {
+                       /* TM2 */
+                       this->isp_vs2_offset = 0x003f8ce4;
+                       this->isp_vs2_step = 0x8350;
+               }
+               info("vendorSpecific2[0]: offset: %#x, step: %#x\n",
+                    this->isp_vs2_offset, this->isp_vs2_step);
        } else {
                memcpy(version_str, &load_bin[size - FIMC_IS_SETFILE_VER_OFFSET],
                        FIMC_IS_SETFILE_VER_SIZE);
@@ -5214,6 +5227,26 @@ int fimc_is_ischain_isp_buffer_queue(struct fimc_is_device_ischain *device,
        groupmgr = device->groupmgr;
        group = &device->group_isp;
 
+       /*
+        * Set the (all undocumented) shot->udm.internal.vendorSpecific2[0]
+        * field if it is cleared.
+        */
+       if (groupmgr && queue && group && group->instance < FIMC_IS_MAX_NODES
+           && group->id < GROUP_ID_MAX && index < FRAMEMGR_MAX_REQUEST) {
+               struct fimc_is_framemgr *framemgr = &queue->framemgr;
+               struct fimc_is_frame *frame = &framemgr->frame[index];
+               struct camera2_shot *shot = frame->shot;
+               int fcount;
+
+               if (shot->udm.internal.vendorSpecific2[0] == 0) {
+                       fcount = shot->dm.request.frameCount;
+
+                       shot->udm.internal.vendorSpecific2[0] =
+                               (device->isp_vs2_offset + ((fcount - 1) % 40)
+                               * device->isp_vs2_step);
+               }
+       }
+
        ret = fimc_is_group_buffer_queue(groupmgr, group, queue, index);
        if (ret) {
                merr("fimc_is_group_buffer_queue is fail(%d)", device, ret);
index a84b0703c75a8c98207c0eaf1d16021a086d77c5..f704913588376fb2d441a2a281d80c64eda7ac5d 100644 (file)
@@ -260,6 +260,9 @@ struct fimc_is_device_ischain {
 
        void *                                  private_data;
        struct fimc_is_device_sensor            *sensor;
+
+       unsigned int                            isp_vs2_offset;
+       unsigned int                            isp_vs2_step;
 };
 
 /*global function*/