]> rtime.felk.cvut.cz Git - hercules2020/nv-tegra/linux-4.4.git/commitdiff
drivers: media: camera: Add sync op support
authorBhanu Murthy V <bmurthyv@nvidia.com>
Fri, 10 Jun 2016 23:17:52 +0000 (16:17 -0700)
committermobile promotions <svcmobile_promotions@nvidia.com>
Wed, 14 Jun 2017 11:31:19 +0000 (04:31 -0700)
Add sync file op support in VI driver.
Sub devices will be synchronized when the MFI interrupt
arrives to VI driver. At present this interrupt is
configured when the ROI of focus area ends during the
current frame capture.

Fix vi2 and vi4 differences using fops in addition to
the original commit.
Cleanup MFI code in the active isr flow.

Bug 1754305

Change-Id: I7e96d413e79dbab17c7c4349cef9ef6b78ab983d
Signed-off-by: Bhanu Murthy V <bmurthyv@nvidia.com>
Reviewed-on: http://git-master/r/1162764
(cherry picked from commit 8c7c212927f1b1703fe0bf95086605fef48ff89d)
Reviewed-on: http://git-master/r/1327223
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
drivers/media/platform/tegra/camera/vi/channel.c
drivers/media/platform/tegra/camera/vi/mc_common.c
drivers/media/platform/tegra/camera/vi/mc_common.h
drivers/media/platform/tegra/camera/vi/vi2_fops.c
drivers/media/platform/tegra/camera/vi/vi2_fops.h
drivers/media/platform/tegra/camera/vi/vi4_fops.c
drivers/media/platform/tegra/camera/vi/vi4_fops.h
drivers/media/platform/tegra/vi/vi.c

index cb67429a65f2dae4bb799c8ab67291e6a3ad4e74..64591fcf87e88755c87948668f522e0727b99b8b 100644 (file)
@@ -1586,6 +1586,15 @@ void tegra_vi_channels_unregister(struct tegra_mc_vi *vi)
        }
 }
 
+int tegra_vi_mfi_work(struct tegra_mc_vi *vi, int channel)
+{
+       if (vi->fops)
+               return vi->fops->vi_mfi_work(vi, channel);
+
+       return 0;
+}
+EXPORT_SYMBOL(tegra_vi_mfi_work);
+
 int tegra_vi_channels_init(struct tegra_mc_vi *vi)
 {
        int ret = 0;
index 7d130596991d0f0985bad266b2175159bb36227f..96a08c127aa5008a9b520dcaa086d47730ad619f 100644 (file)
 #include "host1x/host1x.h"
 #include "camera/vi/registers.h"
 
+static struct tegra_mc_vi *tegra_mcvi;
+
+struct tegra_mc_vi *tegra_get_mc_vi(void)
+{
+       return tegra_mcvi;
+}
+EXPORT_SYMBOL(tegra_get_mc_vi);
+
 /* In TPG mode, VI only support 2 formats */
 static void vi_tpg_fmts_bitmap_init(struct tegra_channel *chan)
 {
@@ -321,6 +329,8 @@ int tegra_vi_media_controller_init(struct tegra_mc_vi *mc_vi,
        if (err < 0)
                goto register_error;
 
+       tegra_mcvi = mc_vi;
+
        return 0;
 
 register_error:
@@ -341,5 +351,6 @@ void tegra_vi_media_controller_cleanup(struct tegra_mc_vi *mc_vi)
        tegra_vi_graph_cleanup(mc_vi);
        tegra_vi_channels_cleanup(mc_vi);
        tegra_vi_v4l2_cleanup(mc_vi);
+       tegra_mcvi = NULL;
 }
 EXPORT_SYMBOL(tegra_vi_media_controller_cleanup);
index eab79bb22ea1b5079666c98685b1a11ab9e76111..ea566b0d18dbc501bf58bf2729262d693c8979b6 100644 (file)
@@ -299,8 +299,10 @@ void tegra_vi_media_controller_cleanup(struct tegra_mc_vi *mc_vi);
 void tegra_channel_ec_close(struct tegra_mc_vi *mc_vi);
 void tegra_channel_query_hdmiin_unplug(struct tegra_channel *chan,
                struct v4l2_event *event);
+int tegra_vi_mfi_work(struct tegra_mc_vi *mc_vi, int csiport);
 int tpg_vi_media_controller_init(struct tegra_mc_vi *mc_vi, int pg_mode);
 void tpg_vi_media_controller_cleanup(struct tegra_mc_vi *mc_vi);
+struct tegra_mc_vi *tegra_get_mc_vi(void);
 
 u32 tegra_core_get_fourcc_by_idx(struct tegra_channel *chan,
                unsigned int index);
@@ -321,6 +323,7 @@ struct tegra_vi_fops {
        int (*vi_stop_streaming)(struct vb2_queue *vq);
        int (*vi_add_ctrls)(struct tegra_channel *chan);
        void (*vi_init_video_formats)(struct tegra_channel *chan);
+       int (*vi_mfi_work)(struct tegra_mc_vi *vi, int port);
 };
 
 struct tegra_csi_fops {
index 271209a06018eca35445ed4b7df1dbdfb9c007ca..8008c1991e9a745447cb6ae08a05f66c4f0812c4 100644 (file)
@@ -718,6 +718,28 @@ void vi2_channel_stop_streaming(struct vb2_queue *vq)
        vi_channel_syncpt_free(chan);
 }
 
+int vi2_mfi_work(struct tegra_mc_vi *vi, int csiport)
+{
+       struct tegra_channel *it;
+       int ret = 0;
+
+       /* for vi2, the input argument is the actual CSI port itself */
+       /* search the list and match the port */
+       list_for_each_entry(it, &vi->vi_chans, list) {
+               if (csiport == it->port[0]) {
+                       ret = v4l2_subdev_call(it->subdev_on_csi, core,
+                                       sync, V4L2_SYNC_EVENT_FOCUS_POS);
+                       if (ret < 0 && ret != -ENOIOCTLCMD) {
+                               dev_err(vi->dev,
+                                       "%s:channel failed\n", __func__);
+                               return ret;
+                       }
+               }
+       }
+
+       return ret;
+}
+
 int tegra_vi2_power_on(struct tegra_mc_vi *vi)
 {
        int ret;
index 66c59879c44deca521623dd04c08a7276d35d4a9..4153e4c1af619acfbbf8b7dc0a55e2f22a97f886 100644 (file)
@@ -21,6 +21,7 @@ int vi2_channel_start_streaming(struct vb2_queue *vq, u32 count);
 int vi2_channel_stop_streaming(struct vb2_queue *vq);
 int vi2_add_ctrls(struct tegra_channel *chan);
 void vi2_init_video_formats(struct tegra_channel *chan);
+int vi2_mfi_work(struct tegra_mc_vi *vi, int csiport);
 
 struct tegra_vi_fops vi2_fops = {
        .vi_power_on = vi2_power_on,
@@ -29,6 +30,7 @@ struct tegra_vi_fops vi2_fops = {
        .vi_stop_streaming = vi2_channel_stop_streaming,
        .vi_add_ctrls = vi2_add_ctrls,
        .vi_init_video_formats = vi2_init_video_formats,
+       .vi_mfi_work = vi2_mfi_work,
 };
 
 #endif
index 5d75923945a1dfd413901d763ab03692ace024c0..1809b429d50bb9a40b41900c156f2ad029574ddd 100644 (file)
@@ -903,6 +903,28 @@ int vi4_channel_stop_streaming(struct vb2_queue *vq)
        return 0;
 }
 
+int vi4_mfi_work(struct tegra_mc_vi *vi, int channel)
+{
+       struct tegra_channel *it = NULL;
+       int ret = 0;
+
+       /* for vi4, the input argument is the hw channel id*/
+       /* search the list and match the hw id */
+       list_for_each_entry(it, &vi->vi_chans, list) {
+               if (channel == it->vnc_id[0]) {
+                       ret = v4l2_subdev_call(it->subdev_on_csi, core,
+                                       sync, V4L2_SYNC_EVENT_FOCUS_POS);
+                       if (ret < 0 && ret != -ENOIOCTLCMD) {
+                               dev_err(vi->dev,
+                                       "%s:channel failed\n", __func__);
+                               return ret;
+                       }
+               }
+       }
+
+       return ret;
+}
+
 int tegra_vi4_power_on(struct tegra_mc_vi *vi)
 {
        int ret;
index c8f3c506bbda8d4c592b1f69cabb3f8e6c81975c..d8e77d57ca79070656f1e850cb61f340bf3f8921 100644 (file)
@@ -21,6 +21,7 @@ int vi4_channel_start_streaming(struct vb2_queue *vq, u32 count);
 int vi4_channel_stop_streaming(struct vb2_queue *vq);
 int vi4_add_ctrls(struct tegra_channel *chan);
 void vi4_init_video_formats(struct tegra_channel *chan);
+int vi4_mfi_work(struct tegra_mc_vi *vi, int channel);
 
 struct tegra_vi_fops vi4_fops = {
        .vi_power_on = vi4_power_on,
@@ -29,6 +30,7 @@ struct tegra_vi_fops vi4_fops = {
        .vi_stop_streaming = vi4_channel_stop_streaming,
        .vi_add_ctrls = vi4_add_ctrls,
        .vi_init_video_formats = vi4_init_video_formats,
+       .vi_mfi_work = vi4_mfi_work,
 };
 
 #endif
index da86ee4725679e6c0fda26f706e97d3a177145b1..aca75a20cbb0dcc81327c6f61f1cf4b650575de0 100644 (file)
@@ -106,6 +106,7 @@ struct tegra_mfi_chan {
        struct work_struct mfi_cb_work;
        struct rcu_head rcu;
        u8 channel;
+       void *priv;
 };
 
 struct tegra_vi_mfi_ctx {
@@ -118,16 +119,10 @@ static void vi_mfi_worker(struct work_struct *vi_work)
 {
        struct tegra_mfi_chan *mfi_chan =
                container_of(vi_work, struct tegra_mfi_chan, mfi_cb_work);
+       struct tegra_mc_vi *vi = tegra_get_mc_vi();
 
        mutex_lock(&vi_isr_lock);
-       if (mfi_callback == NULL) {
-               pr_debug("NULL callback\n");
-               mutex_unlock(&vi_isr_lock);
-               return;
-       }
-       if (mfi_callback_arg)
-               mfi_callback_arg->vi_chan = mfi_chan->channel;
-       mfi_callback(mfi_callback_arg);
+       tegra_vi_mfi_work(vi, mfi_chan->channel);
        mutex_unlock(&vi_isr_lock);
 }