diff options
| author | Ruicheng Dai <rdai@nvidia.com> | 2018-06-03 10:27:18 -0400 |
|---|---|---|
| committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2018-06-07 16:09:42 -0400 |
| commit | aa521a7f3b4e552c581b95e5b4c8747bc4c5b102 (patch) | |
| tree | a85d221785096732955497315474c55bac9949d2 | |
| parent | 8af4db8e8ef8f67bc4757c54425f24511721be63 (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.c | 34 | ||||
| -rw-r--r-- | drivers/media/platform/tegra/tpg/tpg_t19x.c | 48 |
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, | |||
| 186 | static int csi5_stream_tpg_start(struct tegra_csi_channel *chan, | 186 | static 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 | ||
| 253 | static void csi5_stream_tpg_stop(struct tegra_csi_channel *chan, int csi_port) | 265 | static 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) | |||
| 272 | static int csi5_start_streaming(struct tegra_csi_channel *chan, | 284 | static 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 | ||
| 294 | static void csi5_stop_streaming(struct tegra_csi_channel *chan, | 310 | static 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 | ||
| 31 | static struct tpg_frmfmt *frmfmt_table; | ||
| 32 | |||
| 33 | static bool override_frmfmt; | ||
| 34 | module_param(override_frmfmt, bool, 0444); | ||
| 35 | MODULE_PARM_DESC(override_frmfmt, "override existing format table"); | ||
| 36 | |||
| 37 | static int framerate = 30; | ||
| 38 | module_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 | */ |
| 36 | const struct tpg_frmfmt tegra19x_csi_tpg_frmfmt[] = { | 45 | const 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 | } | ||
