]> rtime.felk.cvut.cz Git - hercules2020/nv-tegra/linux-4.4.git/commitdiff
driver:media:platform: Add v4l2 vi bw and clk ctrl
authorWenjia Zhou <wenjiaz@nvidia.com>
Wed, 7 Sep 2016 04:16:48 +0000 (21:16 -0700)
committermobile promotions <svcmobile_promotions@nvidia.com>
Tue, 20 Sep 2016 01:24:28 +0000 (18:24 -0700)
-- Register each channel as vi nvhost module client.
-- Utilize nvhost APIs to set VI clock with aggregation logic
-- Updated T186 iso bw request function

Jira CHWI-385

Change-Id: Id6171db7d0499eb6bde38c7737900ff308aaa263
Signed-off-by: Wenjia Zhou <wenjiaz@nvidia.com>
Reviewed-on: http://git-master/r/1217429
(cherry picked from commit 219aa762e3a28e7c90445a5e43543cb93012a9e0)
Reviewed-on: http://git-master/r/1215916
GVS: Gerrit_Virtual_Submit
Reviewed-by: Jihoon Bang <jbang@nvidia.com>
Reviewed-by: Frank Chen <frankc@nvidia.com>
Tested-by: Frank Chen <frankc@nvidia.com>
drivers/media/platform/tegra/camera/vi/Makefile
drivers/media/platform/tegra/camera/vi/vi4_fops.c

index cb8d08cb76af66d781b57917fc0bbe15c06317ea..c53c068032087496a508c787726bc5922a3f1dce 100644 (file)
@@ -8,6 +8,7 @@ ccflags-y += -Werror
 ifeq ($(CONFIG_ARCH_TEGRA_18x_SOC),y)
 ccflags-y += -I../nvhost-t18x/drivers/video/tegra/host/
 ccflags-y += -I../t18x/drivers/video/tegra/host/
+ccflags-y += -I../nvhost/include
 endif
 
 obj-y += mc_common.o core.o channel.o graph.o vi2_fops.o vi4_fops.o
index feb81c6f6429ff8d8d66c1f311131606b5e27744..1dc2994345e26a319eb130a50a7f36cf6ef65423 100644 (file)
@@ -16,7 +16,8 @@
 #include <linux/freezer.h>
 #include <media/tegra_camera_platform.h>
 #include "nvhost_acm.h"
-#include "vi/vi.h"
+#include "linux/nvhost_ioctl.h"
+#include "vi/vi4.h"
 #include "mc_common.h"
 #include "mipical/mipi_cal.h"
 #include "t18x_registers.h"
@@ -367,24 +368,28 @@ static void tegra_channel_stop_kthreads(struct tegra_channel *chan)
        mutex_unlock(&chan->stop_kthread_lock);
 }
 
-static void tegra_channel_update_clknbw(struct tegra_channel *chan, u8 on)
+static int tegra_channel_update_clknbw(struct tegra_channel *chan, u8 on)
 {
-#if 0
+       int ret = 0;
+
        /* width * height * fps * KBytes write to memory
         * WAR: Using fix fps until we have a way to set it
         */
-       chan->requested_kbyteps = (on > 0 ? 1 : -1) * ((chan->format.width
-                               * chan->format.height
-                               * FRAMERATE * BPP_MEM) / 1000);
-       chan->requested_hz = on > 0 ? chan->format.width * chan->format.height
-                               * FRAMERATE : 0;
+       chan->requested_kbyteps = (on > 0 ? 1 : -1) *
+               ((long long)(chan->format.width * chan->format.height
+               * FRAMERATE * BPP_MEM) * 115 / 100) / 1000;
        mutex_lock(&chan->vi->bw_update_lock);
        chan->vi->aggregated_kbyteps += chan->requested_kbyteps;
-       vi_v4l2_update_isobw(chan->vi->aggregated_kbyteps, 0);
-       vi_v4l2_set_la(tegra_vi_get(), 0, 0);
-       update_clk(chan->vi);
+       ret = vi_v4l2_update_isobw(chan->vi->aggregated_kbyteps, 0);
        mutex_unlock(&chan->vi->bw_update_lock);
-#endif
+       if (ret)
+               dev_info(chan->vi->dev,
+               "WAR:Calculation not precise.Ignore BW request failure\n");
+       ret = vi4_v4l2_set_la(chan->vi->ndev, 0, 0);
+       if (ret)
+               dev_info(chan->vi->dev,
+               "WAR:Calculation not precise.Ignore LA failure\n");
+       return 0;
 }
 
 int vi4_channel_start_streaming(struct vb2_queue *vq, u32 count)
@@ -392,9 +397,9 @@ int vi4_channel_start_streaming(struct vb2_queue *vq, u32 count)
        struct tegra_channel *chan = vb2_get_drv_priv(vq);
        struct media_pipeline *pipe = chan->video.entity.pipe;
        int ret = 0, i;
+       unsigned long request_pixelrate;
 
        vi4_init(chan);
-
        if (!chan->vi->pg_mode) {
                /* Start the pipeline. */
                ret = media_entity_pipeline_start(&chan->video.entity, pipe);
@@ -430,8 +435,17 @@ int vi4_channel_start_streaming(struct vb2_queue *vq, u32 count)
        tegra_channel_init_ring_buffer(chan);
 
        /* Update clock and bandwidth based on the format */
-       tegra_channel_update_clknbw(chan, 1);
-
+       mutex_lock(&chan->vi->bw_update_lock);
+       request_pixelrate = (long long)(chan->format.width * chan->format.height
+                        * FRAMERATE / 100) * 115;
+       ret = nvhost_module_set_rate(chan->vi->ndev, &chan->video,
+                       request_pixelrate, 0, NVHOST_PIXELRATE);
+       mutex_unlock(&chan->vi->bw_update_lock);
+       if (ret)
+               goto error_capture_setup;
+       ret = tegra_channel_update_clknbw(chan, 1);
+       if (ret)
+               goto error_capture_setup;
        /* Start kthread to capture data to buffer */
        chan->kthread_capture_start = kthread_run(
                                        tegra_channel_kthread_capture_start,
@@ -524,6 +538,12 @@ int vi4_power_on(struct tegra_channel *chan)
        vi = chan->vi;
        csi = vi->csi;
 
+       /* Use chan->video as identifier of vi4 nvhost_module client
+        * since they are unique per channel
+        */
+       ret = nvhost_module_add_client(vi->ndev, &chan->video);
+       if (ret)
+               return ret;
        tegra_vi4_power_on(vi);
 
        if (!vi->pg_mode &&
@@ -551,4 +571,5 @@ void vi4_power_off(struct tegra_channel *chan)
        }
 
        tegra_vi4_power_off(vi);
+       nvhost_module_remove_client(vi->ndev, &chan->video);
 }