summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRuicheng Dai <rdai@nvidia.com>2018-06-03 10:27:18 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2018-06-07 16:09:42 -0400
commitaa521a7f3b4e552c581b95e5b4c8747bc4c5b102 (patch)
treea85d221785096732955497315474c55bac9949d2
parent8af4db8e8ef8f67bc4757c54425f24511721be63 (diff)
media: tegra: camera: add framerate control
use framerate control for tpg in t19x and add module parameter for framerate Bug 200375889 Change-Id: I577c797e8ea7b886ef6b973a5e85a3f42e0c07ba Signed-off-by: Ruicheng Dai <rdai@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1740463 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Bhanu Murthy V <bmurthyv@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
-rw-r--r--drivers/media/platform/tegra/camera/nvcsi/csi5_fops.c34
-rw-r--r--drivers/media/platform/tegra/tpg/tpg_t19x.c48
2 files changed, 63 insertions, 19 deletions
diff --git a/drivers/media/platform/tegra/camera/nvcsi/csi5_fops.c b/drivers/media/platform/tegra/camera/nvcsi/csi5_fops.c
index c89786fa8..c109390c0 100644
--- a/drivers/media/platform/tegra/camera/nvcsi/csi5_fops.c
+++ b/drivers/media/platform/tegra/camera/nvcsi/csi5_fops.c
@@ -186,8 +186,10 @@ static int csi5_stream_set_config(struct tegra_csi_channel *chan, int csi_port,
186static int csi5_stream_tpg_start(struct tegra_csi_channel *chan, 186static int csi5_stream_tpg_start(struct tegra_csi_channel *chan,
187 enum tegra_csi_port_num port_num) 187 enum tegra_csi_port_num port_num)
188{ 188{
189 int err = 0;
189 struct tegra_csi_device *csi = chan->csi; 190 struct tegra_csi_device *csi = chan->csi;
190 struct tegra_csi_port *port = &chan->ports[port_num]; 191 struct tegra_csi_port *port = &chan->ports[port_num];
192 unsigned long csi_rate = 0;
191 193
192 int csi_port = chan->ports[port_num].num; 194 int csi_port = chan->ports[port_num].num;
193 195
@@ -215,7 +217,15 @@ static int csi5_stream_tpg_start(struct tegra_csi_channel *chan,
215 tpg_config->t194.virtual_channel_id = chan->virtual_channel; 217 tpg_config->t194.virtual_channel_id = chan->virtual_channel;
216 tpg_config->t194.datatype = port->core_format->img_dt; 218 tpg_config->t194.datatype = port->core_format->img_dt;
217 219
218 tpg_config->t194.lane_count = chan->numlanes; 220 /*
221 * T19x TPG is generating 64 bits per cycle
222 * it will insert (TPG_LANE_NUM-8) * nvcsi_clock cycles between
223 * two 64bit pixel_packages to reduce framerate
224 * TPG_LANE_NUM=8 means no blank insertion.
225 * 7 means insert 1 clock between two 64bit pixel packages,
226 * 6 means 2 clocks blank, …, 1 means 7 blank clocks.
227 */
228 tpg_config->t194.lane_count = 8;
219 tpg_config->t194.flags = NVCSI_TPG_FLAG_PATCH_MODE; 229 tpg_config->t194.flags = NVCSI_TPG_FLAG_PATCH_MODE;
220 230
221 tpg_config->t194.initial_frame_number = 1; 231 tpg_config->t194.initial_frame_number = 1;
@@ -236,18 +246,20 @@ static int csi5_stream_tpg_start(struct tegra_csi_channel *chan,
236 246
237 /* Enable TPG on a stream */ 247 /* Enable TPG on a stream */
238 memset(&msg, 0, sizeof(msg)); 248 memset(&msg, 0, sizeof(msg));
239 msg.header.msg_id = CAPTURE_CSI_STREAM_TPG_START_REQ; 249 msg.header.msg_id = CAPTURE_CSI_STREAM_TPG_START_RATE_REQ;
240 msg.header.channel_id = TEMP_CHANNEL_ID; 250 msg.header.channel_id = TEMP_CHANNEL_ID;
241 251
242 msg.csi_stream_tpg_start_req.stream_id = csi_port; 252 msg.csi_stream_tpg_start_req.stream_id = csi_port;
243 msg.csi_stream_tpg_start_req.virtual_channel_id = chan->virtual_channel; 253 msg.csi_stream_tpg_start_req.virtual_channel_id = chan->virtual_channel;
244 msg.csi_stream_tpg_start_req.tpg_rate_config.hblank = TPG_HBLANK; 254 msg.csi_stream_tpg_start_rate_req.frame_rate = port->framerate;
245 msg.csi_stream_tpg_start_req.tpg_rate_config.vblank = TPG_VBLANK; 255 err = nvhost_module_get_rate(csi->pdev, &csi_rate, 0);
246 msg.csi_stream_tpg_start_req.tpg_rate_config.pixel_interval = 0; 256 if (err)
257 return err;
247 258
259 msg.csi_stream_tpg_start_rate_req.csi_clk_rate = csi_rate / 1000;
248 tegra_capture_ivc_control_submit(&msg, sizeof(msg)); 260 tegra_capture_ivc_control_submit(&msg, sizeof(msg));
249 261
250 return 0; 262 return err;
251} 263}
252 264
253static void csi5_stream_tpg_stop(struct tegra_csi_channel *chan, int csi_port) 265static void csi5_stream_tpg_stop(struct tegra_csi_channel *chan, int csi_port)
@@ -272,6 +284,7 @@ static void csi5_stream_tpg_stop(struct tegra_csi_channel *chan, int csi_port)
272static int csi5_start_streaming(struct tegra_csi_channel *chan, 284static int csi5_start_streaming(struct tegra_csi_channel *chan,
273 enum tegra_csi_port_num port_num) 285 enum tegra_csi_port_num port_num)
274{ 286{
287 int err = 0;
275 struct tegra_csi_device *csi = chan->csi; 288 struct tegra_csi_device *csi = chan->csi;
276 289
277 int csi_port = chan->ports[port_num].num; 290 int csi_port = chan->ports[port_num].num;
@@ -285,10 +298,13 @@ static int csi5_start_streaming(struct tegra_csi_channel *chan,
285 298
286 csi5_stream_open(chan, csi_port); 299 csi5_stream_open(chan, csi_port);
287 300
288 if (chan->pg_mode) 301 if (chan->pg_mode) {
289 csi5_stream_tpg_start(chan, port_num); 302 err = csi5_stream_tpg_start(chan, port_num);
303 if (err)
304 return err;
305 }
290 306
291 return 0; 307 return err;
292} 308}
293 309
294static void csi5_stop_streaming(struct tegra_csi_channel *chan, 310static void csi5_stop_streaming(struct tegra_csi_channel *chan,
diff --git a/drivers/media/platform/tegra/tpg/tpg_t19x.c b/drivers/media/platform/tegra/tpg/tpg_t19x.c
index 657c0f38c..9041bcfd9 100644
--- a/drivers/media/platform/tegra/tpg/tpg_t19x.c
+++ b/drivers/media/platform/tegra/tpg/tpg_t19x.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Tegra VI test pattern generator driver 4 * Tegra VI test pattern generator driver
5 * 5 *
6 * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. 6 * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify it 8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License, 9 * under the terms and conditions of the GNU General Public License,
@@ -28,18 +28,27 @@
28#include "nvcsi/nvcsi.h" 28#include "nvcsi/nvcsi.h"
29#include "host1x/host1x.h" 29#include "host1x/host1x.h"
30 30
31static struct tpg_frmfmt *frmfmt_table;
32
33static bool override_frmfmt;
34module_param(override_frmfmt, bool, 0444);
35MODULE_PARM_DESC(override_frmfmt, "override existing format table");
36
37static int framerate = 30;
38module_param(framerate, int, 0444);
39
31/* PG generate 32 bit per nvcsi_clk: 40/* PG generate 32 bit per nvcsi_clk:
32 * clks_per_line = width * bits_per_pixel / 32 41 * clks_per_line = width * bits_per_pixel / 32
33 * ((clks_per_line + hblank) * height + vblank) * fps * lanes = nvcsi_clk_freq 42 * ((clks_per_line + hblank) * height + vblank) * fps * lanes = nvcsi_clk_freq
34 * 43 *
35 */ 44 */
36const struct tpg_frmfmt tegra19x_csi_tpg_frmfmt[] = { 45const struct tpg_frmfmt tegra19x_csi_tpg_frmfmt[] = {
37 {{1280, 720}, V4L2_PIX_FMT_SRGGB10, 120, 180, 100}, 46 {{1280, 720}, V4L2_PIX_FMT_SRGGB10, 30, 0, 0},
38 {{1920, 1080}, V4L2_PIX_FMT_SRGGB10, 60, 180, 100}, 47 {{1920, 1080}, V4L2_PIX_FMT_SRGGB10, 30, 0, 0},
39 {{3840, 2160}, V4L2_PIX_FMT_SRGGB10, 20, 90, 100}, 48 {{3840, 2160}, V4L2_PIX_FMT_SRGGB10, 30, 0, 0},
40 {{1280, 720}, V4L2_PIX_FMT_RGB32, 60, 210, 100}, 49 {{1280, 720}, V4L2_PIX_FMT_RGB32, 30, 0, 0},
41 {{1920, 1080}, V4L2_PIX_FMT_RGB32, 30, 120, 100}, 50 {{1920, 1080}, V4L2_PIX_FMT_RGB32, 30, 0, 0},
42 {{3840, 2160}, V4L2_PIX_FMT_RGB32, 8, 120, 100}, 51 {{3840, 2160}, V4L2_PIX_FMT_RGB32, 30, 0, 0},
43}; 52};
44 53
45#define TPG_PORT_IDX 0 54#define TPG_PORT_IDX 0
@@ -127,7 +136,9 @@ static int __init tpg_probe_t19x(void)
127{ 136{
128 struct tegra_csi_device *mc_csi = tegra_get_mc_csi(); 137 struct tegra_csi_device *mc_csi = tegra_get_mc_csi();
129 struct tegra_mc_vi *mc_vi = tegra_get_mc_vi(); 138 struct tegra_mc_vi *mc_vi = tegra_get_mc_vi();
130 int err; 139 int err = 0;
140 int i = 0;
141 unsigned int table_size = ARRAY_SIZE(tegra19x_csi_tpg_frmfmt);
131 142
132 if (!mc_vi || !mc_csi) 143 if (!mc_vi || !mc_csi)
133 return -EINVAL; 144 return -EINVAL;
@@ -135,8 +146,21 @@ static int __init tpg_probe_t19x(void)
135 dev_info(mc_csi->dev, "%s\n", __func__); 146 dev_info(mc_csi->dev, "%s\n", __func__);
136 mc_vi->csi = mc_csi; 147 mc_vi->csi = mc_csi;
137 /* Init CSI related media controller interface */ 148 /* Init CSI related media controller interface */
138 mc_csi->tpg_frmfmt_table = tegra19x_csi_tpg_frmfmt; 149 frmfmt_table = devm_kzalloc(mc_csi->dev,
139 mc_csi->tpg_frmfmt_table_size = ARRAY_SIZE(tegra19x_csi_tpg_frmfmt); 150 table_size * sizeof(struct tpg_frmfmt), GFP_KERNEL);
151 if (!frmfmt_table)
152 return -ENOMEM;
153
154 mc_csi->tpg_frmfmt_table_size = table_size;
155 memcpy(frmfmt_table, tegra19x_csi_tpg_frmfmt,
156 table_size * sizeof(struct tpg_frmfmt));
157
158 if (override_frmfmt) {
159 for (i = 0; i < table_size; i++)
160 frmfmt_table[i].framerate = framerate;
161 }