camera: vi: Fix VI clk scaling for gangmode

gangmode uses single VI channel to stream simultaneously
from 2 CSI bricks. The VI clk should be scaled accordingly
to accommodate this bandwidth

bug 3814565

Signed-off-by: Anubhav rai <arai@nvidia.com>
Change-Id: I6912f1aeb878e53e63e3a04c7132219f030973d1
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2791338
(cherry picked from commit 7a95f84f1eb4f60a8e9740876db53b23c95f865e)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2866932
Reviewed-by: svcacv <svcacv@nvidia.com>
Reviewed-by: Ankur Pawar <ankurp@nvidia.com>
Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
Tested-by: Ankur Pawar <ankurp@nvidia.com>
GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
Anubhav rai
2022-10-13 08:09:48 +00:00
committed by mobile promotions
parent 33f74c0dd8
commit b66b703f0e
2 changed files with 32 additions and 18 deletions

View File

@@ -2,7 +2,7 @@
/*
* NVIDIA Tegra Video Input Device
*
* Copyright (c) 2015-2023, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2015-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*/
#include <linux/atomic.h>
@@ -45,6 +45,8 @@
#define TPG_CSI_GROUP_ID 10
#define HDMI_IN_RATE 550000000
/* number of lanes per brick */
#define NUM_LANES_PER_BRICK 4
static s64 queue_init_ts;
@@ -1737,10 +1739,11 @@ static int map_to_sensor_type(u32 phy_mode)
}
}
static u64 tegra_channel_get_max_pixelclock(struct tegra_channel *chan)
static void tegra_channel_get_sensor_peak_vals(struct tegra_channel *chan,
u64 *pixelclock, u32 *num_lanes)
{
int i = 0;
u64 val = 0, pixelclock = 0;
u64 val = 0;
struct v4l2_subdev *sd = chan->subdev_on_csi;
struct camera_common_data *s_data =
@@ -1748,7 +1751,7 @@ static u64 tegra_channel_get_max_pixelclock(struct tegra_channel *chan)
struct sensor_mode_properties *sensor_mode;
if (!s_data)
return 0;
return;
for (i = 0; i < s_data->sensor_props.num_modes; i++) {
sensor_mode = &s_data->sensor_props.sensor_modes[i];
@@ -1756,20 +1759,23 @@ static u64 tegra_channel_get_max_pixelclock(struct tegra_channel *chan)
val = sensor_mode->signal_properties.serdes_pixel_clock.val;
else
val = sensor_mode->signal_properties.pixel_clock.val;
/* Select the mode with largest pixel rate */
if (pixelclock < val)
pixelclock = val;
/* Select the value from the mode with largest pixel rate and lane numbers */
if (*pixelclock < val)
*pixelclock = val;
if (*num_lanes < sensor_mode->signal_properties.num_lanes)
*num_lanes = sensor_mode->signal_properties.num_lanes;
}
spec_bar();
return pixelclock;
}
static u32 tegra_channel_get_num_lanes(struct tegra_channel *chan)
{
u32 num_lanes = 0;
struct v4l2_subdev *sd = chan->subdev_on_csi;
struct camera_common_data *s_data =
to_camera_common_data(sd->dev);
struct sensor_mode_properties *sensor_mode;
@@ -1815,13 +1821,14 @@ static void tegra_channel_populate_dev_info(struct tegra_camera_dev_info *cdev,
struct tegra_channel *chan)
{
u64 pixelclock = 0;
u32 max_num_lanes = 0;
struct camera_common_data *s_data =
to_camera_common_data(chan->subdev_on_csi->dev);
if (s_data != NULL) {
/* camera sensors */
cdev->sensor_type = tegra_channel_get_sensor_type(chan);
pixelclock = tegra_channel_get_max_pixelclock(chan);
tegra_channel_get_sensor_peak_vals(chan, &pixelclock, &max_num_lanes);
/* Multiply by CPHY symbols to pixels factor. */
if (cdev->sensor_type == SENSORTYPE_CPHY)
pixelclock *= 16/7;
@@ -1840,7 +1847,13 @@ static void tegra_channel_populate_dev_info(struct tegra_camera_dev_info *cdev,
return;
}
}
/*
* VI clk scaling for gang mode usecase where 2 CSI bricks
* stream through a single VI channel.
*/
if (max_num_lanes > NUM_LANES_PER_BRICK)
cdev->pixel_rate = pixelclock * (max_num_lanes / NUM_LANES_PER_BRICK);
else
cdev->pixel_rate = pixelclock;
cdev->pixel_bit_depth = chan->fmtinfo->width;
cdev->bpp = chan->fmtinfo->bpp.numerator;

View File

@@ -2,7 +2,7 @@
/*
* VI5 driver
*
* Copyright (c) 2017-2023, NVIDIA Corporation. All rights reserved.
* Copyright (c) 2017-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*/
#include <asm/ioctls.h>
@@ -86,11 +86,12 @@ int nvhost_vi5_aggregate_constraints(struct platform_device *dev,
"No platform data, fall back to default policy\n");
return 0;
}
if (!pixelrate || clk_index != 0)
if (clk_index != 0)
return 0;
/* SCF send request using NVHOST_CLK, which is calculated
* in floor_rate, so we need to aggregate its request
* with V4L2 pixelrate request
/*
* SCF and V4l2 send request using NVHOST_CLK through tegra_camera_platform,
* which is calculated in floor_rate.
*/
return floor_rate + (pixelrate / pdata->num_ppc);
}