mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
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:
committed by
mobile promotions
parent
33f74c0dd8
commit
b66b703f0e
@@ -2,7 +2,7 @@
|
|||||||
/*
|
/*
|
||||||
* NVIDIA Tegra Video Input Device
|
* 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>
|
#include <linux/atomic.h>
|
||||||
@@ -45,6 +45,8 @@
|
|||||||
|
|
||||||
#define TPG_CSI_GROUP_ID 10
|
#define TPG_CSI_GROUP_ID 10
|
||||||
#define HDMI_IN_RATE 550000000
|
#define HDMI_IN_RATE 550000000
|
||||||
|
/* number of lanes per brick */
|
||||||
|
#define NUM_LANES_PER_BRICK 4
|
||||||
|
|
||||||
static s64 queue_init_ts;
|
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;
|
int i = 0;
|
||||||
u64 val = 0, pixelclock = 0;
|
u64 val = 0;
|
||||||
|
|
||||||
struct v4l2_subdev *sd = chan->subdev_on_csi;
|
struct v4l2_subdev *sd = chan->subdev_on_csi;
|
||||||
struct camera_common_data *s_data =
|
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;
|
struct sensor_mode_properties *sensor_mode;
|
||||||
|
|
||||||
if (!s_data)
|
if (!s_data)
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < s_data->sensor_props.num_modes; i++) {
|
for (i = 0; i < s_data->sensor_props.num_modes; i++) {
|
||||||
sensor_mode = &s_data->sensor_props.sensor_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;
|
val = sensor_mode->signal_properties.serdes_pixel_clock.val;
|
||||||
else
|
else
|
||||||
val = sensor_mode->signal_properties.pixel_clock.val;
|
val = sensor_mode->signal_properties.pixel_clock.val;
|
||||||
/* Select the mode with largest pixel rate */
|
|
||||||
if (pixelclock < val)
|
/* Select the value from the mode with largest pixel rate and lane numbers */
|
||||||
pixelclock = val;
|
if (*pixelclock < val)
|
||||||
|
*pixelclock = val;
|
||||||
|
|
||||||
|
if (*num_lanes < sensor_mode->signal_properties.num_lanes)
|
||||||
|
*num_lanes = sensor_mode->signal_properties.num_lanes;
|
||||||
}
|
}
|
||||||
spec_bar();
|
spec_bar();
|
||||||
|
|
||||||
return pixelclock;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static u32 tegra_channel_get_num_lanes(struct tegra_channel *chan)
|
static u32 tegra_channel_get_num_lanes(struct tegra_channel *chan)
|
||||||
{
|
{
|
||||||
u32 num_lanes = 0;
|
u32 num_lanes = 0;
|
||||||
|
|
||||||
struct v4l2_subdev *sd = chan->subdev_on_csi;
|
struct v4l2_subdev *sd = chan->subdev_on_csi;
|
||||||
|
|
||||||
struct camera_common_data *s_data =
|
struct camera_common_data *s_data =
|
||||||
to_camera_common_data(sd->dev);
|
to_camera_common_data(sd->dev);
|
||||||
struct sensor_mode_properties *sensor_mode;
|
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)
|
struct tegra_channel *chan)
|
||||||
{
|
{
|
||||||
u64 pixelclock = 0;
|
u64 pixelclock = 0;
|
||||||
|
u32 max_num_lanes = 0;
|
||||||
struct camera_common_data *s_data =
|
struct camera_common_data *s_data =
|
||||||
to_camera_common_data(chan->subdev_on_csi->dev);
|
to_camera_common_data(chan->subdev_on_csi->dev);
|
||||||
|
|
||||||
if (s_data != NULL) {
|
if (s_data != NULL) {
|
||||||
/* camera sensors */
|
/* camera sensors */
|
||||||
cdev->sensor_type = tegra_channel_get_sensor_type(chan);
|
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. */
|
/* Multiply by CPHY symbols to pixels factor. */
|
||||||
if (cdev->sensor_type == SENSORTYPE_CPHY)
|
if (cdev->sensor_type == SENSORTYPE_CPHY)
|
||||||
pixelclock *= 16/7;
|
pixelclock *= 16/7;
|
||||||
@@ -1840,7 +1847,13 @@ static void tegra_channel_populate_dev_info(struct tegra_camera_dev_info *cdev,
|
|||||||
return;
|
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_rate = pixelclock;
|
||||||
cdev->pixel_bit_depth = chan->fmtinfo->width;
|
cdev->pixel_bit_depth = chan->fmtinfo->width;
|
||||||
cdev->bpp = chan->fmtinfo->bpp.numerator;
|
cdev->bpp = chan->fmtinfo->bpp.numerator;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
/*
|
/*
|
||||||
* VI5 driver
|
* 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>
|
#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");
|
"No platform data, fall back to default policy\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!pixelrate || clk_index != 0)
|
|
||||||
|
if (clk_index != 0)
|
||||||
return 0;
|
return 0;
|
||||||
/* SCF send request using NVHOST_CLK, which is calculated
|
/*
|
||||||
* in floor_rate, so we need to aggregate its request
|
* SCF and V4l2 send request using NVHOST_CLK through tegra_camera_platform,
|
||||||
* with V4L2 pixelrate request
|
* which is calculated in floor_rate.
|
||||||
*/
|
*/
|
||||||
return floor_rate + (pixelrate / pdata->num_ppc);
|
return floor_rate + (pixelrate / pdata->num_ppc);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user