From aa521a7f3b4e552c581b95e5b4c8747bc4c5b102 Mon Sep 17 00:00:00 2001 From: Ruicheng Dai Date: Sun, 3 Jun 2018 22:27:18 +0800 Subject: 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 Reviewed-on: https://git-master.nvidia.com/r/1740463 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: svc-mobile-coverity GVS: Gerrit_Virtual_Submit Reviewed-by: Bhanu Murthy V Reviewed-by: mobile promotions Tested-by: mobile promotions --- .../media/platform/tegra/camera/nvcsi/csi5_fops.c | 34 +++++++++++---- 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, static int csi5_stream_tpg_start(struct tegra_csi_channel *chan, enum tegra_csi_port_num port_num) { + int err = 0; struct tegra_csi_device *csi = chan->csi; struct tegra_csi_port *port = &chan->ports[port_num]; + unsigned long csi_rate = 0; int csi_port = chan->ports[port_num].num; @@ -215,7 +217,15 @@ static int csi5_stream_tpg_start(struct tegra_csi_channel *chan, tpg_config->t194.virtual_channel_id = chan->virtual_channel; tpg_config->t194.datatype = port->core_format->img_dt; - tpg_config->t194.lane_count = chan->numlanes; + /* + * T19x TPG is generating 64 bits per cycle + * it will insert (TPG_LANE_NUM-8) * nvcsi_clock cycles between + * two 64bit pixel_packages to reduce framerate + * TPG_LANE_NUM=8 means no blank insertion. + * 7 means insert 1 clock between two 64bit pixel packages, + * 6 means 2 clocks blank, …, 1 means 7 blank clocks. + */ + tpg_config->t194.lane_count = 8; tpg_config->t194.flags = NVCSI_TPG_FLAG_PATCH_MODE; tpg_config->t194.initial_frame_number = 1; @@ -236,18 +246,20 @@ static int csi5_stream_tpg_start(struct tegra_csi_channel *chan, /* Enable TPG on a stream */ memset(&msg, 0, sizeof(msg)); - msg.header.msg_id = CAPTURE_CSI_STREAM_TPG_START_REQ; + msg.header.msg_id = CAPTURE_CSI_STREAM_TPG_START_RATE_REQ; msg.header.channel_id = TEMP_CHANNEL_ID; msg.csi_stream_tpg_start_req.stream_id = csi_port; msg.csi_stream_tpg_start_req.virtual_channel_id = chan->virtual_channel; - msg.csi_stream_tpg_start_req.tpg_rate_config.hblank = TPG_HBLANK; - msg.csi_stream_tpg_start_req.tpg_rate_config.vblank = TPG_VBLANK; - msg.csi_stream_tpg_start_req.tpg_rate_config.pixel_interval = 0; + msg.csi_stream_tpg_start_rate_req.frame_rate = port->framerate; + err = nvhost_module_get_rate(csi->pdev, &csi_rate, 0); + if (err) + return err; + msg.csi_stream_tpg_start_rate_req.csi_clk_rate = csi_rate / 1000; tegra_capture_ivc_control_submit(&msg, sizeof(msg)); - return 0; + return err; } 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) static int csi5_start_streaming(struct tegra_csi_channel *chan, enum tegra_csi_port_num port_num) { + int err = 0; struct tegra_csi_device *csi = chan->csi; int csi_port = chan->ports[port_num].num; @@ -285,10 +298,13 @@ static int csi5_start_streaming(struct tegra_csi_channel *chan, csi5_stream_open(chan, csi_port); - if (chan->pg_mode) - csi5_stream_tpg_start(chan, port_num); + if (chan->pg_mode) { + err = csi5_stream_tpg_start(chan, port_num); + if (err) + return err; + } - return 0; + return err; } 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 @@ * * Tegra VI test pattern generator driver * - * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -28,18 +28,27 @@ #include "nvcsi/nvcsi.h" #include "host1x/host1x.h" +static struct tpg_frmfmt *frmfmt_table; + +static bool override_frmfmt; +module_param(override_frmfmt, bool, 0444); +MODULE_PARM_DESC(override_frmfmt, "override existing format table"); + +static int framerate = 30; +module_param(framerate, int, 0444); + /* PG generate 32 bit per nvcsi_clk: * clks_per_line = width * bits_per_pixel / 32 * ((clks_per_line + hblank) * height + vblank) * fps * lanes = nvcsi_clk_freq * */ const struct tpg_frmfmt tegra19x_csi_tpg_frmfmt[] = { - {{1280, 720}, V4L2_PIX_FMT_SRGGB10, 120, 180, 100}, - {{1920, 1080}, V4L2_PIX_FMT_SRGGB10, 60, 180, 100}, - {{3840, 2160}, V4L2_PIX_FMT_SRGGB10, 20, 90, 100}, - {{1280, 720}, V4L2_PIX_FMT_RGB32, 60, 210, 100}, - {{1920, 1080}, V4L2_PIX_FMT_RGB32, 30, 120, 100}, - {{3840, 2160}, V4L2_PIX_FMT_RGB32, 8, 120, 100}, + {{1280, 720}, V4L2_PIX_FMT_SRGGB10, 30, 0, 0}, + {{1920, 1080}, V4L2_PIX_FMT_SRGGB10, 30, 0, 0}, + {{3840, 2160}, V4L2_PIX_FMT_SRGGB10, 30, 0, 0}, + {{1280, 720}, V4L2_PIX_FMT_RGB32, 30, 0, 0}, + {{1920, 1080}, V4L2_PIX_FMT_RGB32, 30, 0, 0}, + {{3840, 2160}, V4L2_PIX_FMT_RGB32, 30, 0, 0}, }; #define TPG_PORT_IDX 0 @@ -127,7 +136,9 @@ static int __init tpg_probe_t19x(void) { struct tegra_csi_device *mc_csi = tegra_get_mc_csi(); struct tegra_mc_vi *mc_vi = tegra_get_mc_vi(); - int err; + int err = 0; + int i = 0; + unsigned int table_size = ARRAY_SIZE(tegra19x_csi_tpg_frmfmt); if (!mc_vi || !mc_csi) return -EINVAL; @@ -135,8 +146,21 @@ static int __init tpg_probe_t19x(void) dev_info(mc_csi->dev, "%s\n", __func__); mc_vi->csi = mc_csi; /* Init CSI related media controller interface */ - mc_csi->tpg_frmfmt_table = tegra19x_csi_tpg_frmfmt; - mc_csi->tpg_frmfmt_table_size = ARRAY_SIZE(tegra19x_csi_tpg_frmfmt); + frmfmt_table = devm_kzalloc(mc_csi->dev, + table_size * sizeof(struct tpg_frmfmt), GFP_KERNEL); + if (!frmfmt_table) + return -ENOMEM; + + mc_csi->tpg_frmfmt_table_size = table_size; + memcpy(frmfmt_table, tegra19x_csi_tpg_frmfmt, + table_size * sizeof(struct tpg_frmfmt)); + + if (override_frmfmt) { + for (i = 0; i < table_size; i++) + frmfmt_table[i].framerate = framerate; + } + mc_csi->tpg_frmfmt_table = frmfmt_table; + err = tpg_csi_media_controller_init(mc_csi, TEGRA_VI_PG_PATCH); if (err) return -EINVAL; @@ -168,6 +192,10 @@ static void __exit tpg_remove_t19x(void) tpg_remove_debugfs(mc_csi); tpg_csi_media_controller_cleanup(mc_csi); tpg_vi_media_controller_cleanup(mc_vi); + + mc_csi->tpg_frmfmt_table = NULL; + mc_csi->tpg_frmfmt_table_size = 0; + devm_kfree(mc_csi->dev, frmfmt_table); } module_init(tpg_probe_t19x); -- cgit v1.2.2