summaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorPekka Pessi <ppessi@nvidia.com>2017-07-09 14:13:55 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2017-07-12 16:24:50 -0400
commit5a48f5db2a18a5bae491ff98b1fc0c23fe3780b7 (patch)
tree3f38372e4c8e49cd2a842082ad86861307acefda /drivers/media
parent9547278fccaefa009356207312dd368d607cae6c (diff)
media: tegra: camera: slvs: variable syncgen clock
While the syncgen clock is constant in silicon, the simulation can use much slower clock speeds. Make syngen clock as a variable with default value of 72 MHz on VDK or linsim. Jira CAMC-382 Change-Id: Id2f8ebc4cffc440297f930e7bdafedce1cc15910 Signed-off-by: Pekka Pessi <ppessi@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1515907 GVS: Gerrit_Virtual_Submit Reviewed-by: Aki Niemi <aniemi@nvidia.com> Reviewed-by: Jihoon Bang <jbang@nvidia.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/platform/tegra/camera/slvs/slvs.c37
1 files changed, 30 insertions, 7 deletions
diff --git a/drivers/media/platform/tegra/camera/slvs/slvs.c b/drivers/media/platform/tegra/camera/slvs/slvs.c
index a81c46bf9..5b7b7d98f 100644
--- a/drivers/media/platform/tegra/camera/slvs/slvs.c
+++ b/drivers/media/platform/tegra/camera/slvs/slvs.c
@@ -25,13 +25,15 @@
25#include <media/mc_common.h> 25#include <media/mc_common.h>
26#include <media/slvs.h> 26#include <media/slvs.h>
27 27
28#include <soc/tegra/chip-id.h>
29
28#include "dev.h" 30#include "dev.h"
29#include "linux/nvhost.h" 31#include "linux/nvhost.h"
30#include <linux/version.h> 32#include <linux/version.h>
31 33
32#define SLVSEC_NUM_LANES 8 34#define SLVSEC_NUM_LANES 8
33 35
34#define SYCNGEN_CLOCK U64_C(408000) 36#define SYNCGEN_CLOCK U32_C(408000)
35#define XSYNC_WIDTH 4 37#define XSYNC_WIDTH 4
36#define VI_NUM_VGP 6 38#define VI_NUM_VGP 6
37#define VI_NUM_SYNCGEN 3 39#define VI_NUM_SYNCGEN 3
@@ -107,6 +109,8 @@ struct tegra_mc_slvs {
107 void __iomem *slvs_base; 109 void __iomem *slvs_base;
108 void __iomem *vi_base; 110 void __iomem *vi_base;
109 111
112 u32 syncgen_clock;
113
110 atomic_t power_ref; 114 atomic_t power_ref;
111 atomic_t sensor_active; 115 atomic_t sensor_active;
112 116
@@ -386,9 +390,11 @@ static inline void slvs_vi_syncgen_stop(struct tegra_mc_slvs *slvs,
386} 390}
387 391
388static int slvs_get_syncgen_config( 392static int slvs_get_syncgen_config(
393 struct tegra_mc_slvs *slvs,
389 const struct camera_common_framesync *fs, 394 const struct camera_common_framesync *fs,
390 struct slvsec_syncgen_config *cfg) 395 struct slvsec_syncgen_config *cfg)
391{ 396{
397 u64 syncgen_clock = slvs->syncgen_clock;
392 /* HS per 1000 second. */ 398 /* HS per 1000 second. */
393 u64 hs_per_1000sec = (u64)fs->xvs * fs->fps; 399 u64 hs_per_1000sec = (u64)fs->xvs * fs->fps;
394 u64 xhs; 400 u64 xhs;
@@ -398,7 +404,7 @@ static int slvs_get_syncgen_config(
398 if (hs_per_1000sec == 0) 404 if (hs_per_1000sec == 0)
399 return -EINVAL; 405 return -EINVAL;
400 406
401 xhs = ((10 * 1000 * SYCNGEN_CLOCK) << 32) / hs_per_1000sec * 100; 407 xhs = ((10 * 1000 * syncgen_clock) << 32) / hs_per_1000sec * 100;
402 408
403 for (frac = 0; (xhs >> (frac + 32)) != 0; frac++) 409 for (frac = 0; (xhs >> (frac + 32)) != 0; frac++)
404 ; 410 ;
@@ -407,7 +413,9 @@ static int slvs_get_syncgen_config(
407 cfg->hclk_div_fmt = 31 - frac; 413 cfg->hclk_div_fmt = 31 - frac;
408 414
409 /* At least XSYNC_WIDTH iclk cycles */ 415 /* At least XSYNC_WIDTH iclk cycles */
410 width = (XSYNC_WIDTH * SYCNGEN_CLOCK + fs->inck - 1) / fs->inck; 416 width = (XSYNC_WIDTH * syncgen_clock + fs->inck - 1) / fs->inck;
417 if (width < XSYNC_WIDTH)
418 width = XSYNC_WIDTH;
411 419
412 cfg->xhs_width = width; 420 cfg->xhs_width = width;
413 cfg->xvs_width = width; 421 cfg->xvs_width = width;
@@ -426,7 +434,8 @@ static int tegra_slvs_syncgen_start(struct tegra_slvs_stream *stream)
426 struct slvsec_syncgen_config config; 434 struct slvsec_syncgen_config config;
427 int err; 435 int err;
428 436
429 err = slvs_get_syncgen_config(&stream->framesync, &config); 437 err = slvs_get_syncgen_config(slvs,
438 &stream->framesync, &config);
430 if (err) 439 if (err)
431 return err; 440 return err;
432 441
@@ -474,12 +483,14 @@ static void fractional_binary(char buffer[35], u32 value, u32 fraction)
474static int slvs_debugfs_syncgen_config_read(struct seq_file *s, void *data) 483static int slvs_debugfs_syncgen_config_read(struct seq_file *s, void *data)
475{ 484{
476 struct tegra_slvs_stream *stream = s->private; 485 struct tegra_slvs_stream *stream = s->private;
486 struct tegra_mc_slvs *slvs = stream->slvs;
487 u64 syncgen_clock = slvs->syncgen_clock;
477 int err; 488 int err;
478 struct slvsec_syncgen_config config; 489 struct slvsec_syncgen_config config;
479 char buffer[35]; 490 char buffer[35];
480 u64 framerate; 491 u64 framerate;
481 492
482 err = slvs_get_syncgen_config(&stream->framesync, &config); 493 err = slvs_get_syncgen_config(slvs, &stream->framesync, &config);
483 if (err < 0) 494 if (err < 0)
484 return err; 495 return err;
485 496
@@ -488,7 +499,7 @@ static int slvs_debugfs_syncgen_config_read(struct seq_file *s, void *data)
488 499
489 fractional_binary(buffer, config.hclk_div, config.hclk_div_fmt); 500 fractional_binary(buffer, config.hclk_div, config.hclk_div_fmt);
490 501
491 framerate = (1000 * SYCNGEN_CLOCK) << 32; 502 framerate = (1000 * syncgen_clock) << 32;
492 framerate /= config.hclk_div; 503 framerate /= config.hclk_div;
493 framerate /= config.xvs_interval; 504 framerate /= config.xvs_interval;
494 /* Multiply framerate by 2000 followed by right shift by 32 */ 505 /* Multiply framerate by 2000 followed by right shift by 32 */
@@ -498,7 +509,7 @@ static int slvs_debugfs_syncgen_config_read(struct seq_file *s, void *data)
498 else 509 else
499 framerate >>= (32 - 3) - config.hclk_div_fmt; 510 framerate >>= (32 - 3) - config.hclk_div_fmt;
500 511
501 seq_printf(s, "clk = %llu\n", 1000ULL * SYCNGEN_CLOCK); 512 seq_printf(s, "clk = %llu\n", 1000ULL * syncgen_clock);
502 seq_printf(s, "hclk_div = %u >> %u (%s)\n", 513 seq_printf(s, "hclk_div = %u >> %u (%s)\n",
503 config.hclk_div, config.hclk_div_fmt, buffer); 514 config.hclk_div, config.hclk_div_fmt, buffer);
504 seq_printf(s, "xvs = %u\n", config.xvs_interval); 515 seq_printf(s, "xvs = %u\n", config.xvs_interval);
@@ -601,6 +612,9 @@ static void tegra_slvs_init_debugfs(struct tegra_mc_slvs *slvs)
601 char name[32]; 612 char name[32];
602 struct dentry *dir; 613 struct dentry *dir;
603 614
615 debugfs_create_u32("syncgen-clock", S_IRUGO | S_IWUSR, info->debugfs,
616 &slvs->syncgen_clock);
617
604 for (i = 0; i < slvs->num_streams; i++) { 618 for (i = 0; i < slvs->num_streams; i++) {
605 snprintf(name, sizeof(name), "mc@%d", i); 619 snprintf(name, sizeof(name), "mc@%d", i);
606 dir = debugfs_create_dir(name, info->debugfs); 620 dir = debugfs_create_dir(name, info->debugfs);
@@ -1009,6 +1023,9 @@ static int tegra_slvs_parse_dt(struct tegra_mc_slvs *slvs)
1009 struct tegra_slvs_stream *stream; 1023 struct tegra_slvs_stream *stream;
1010 int i; 1024 int i;
1011 1025
1026 (void)of_property_read_u32(node, "nvidia,syncgen-clock",
1027 &slvs->syncgen_clock);
1028
1012 if (num_streams <= 0) { 1029 if (num_streams <= 0) {
1013 dev_info(slvs->dev, "no streams defined"); 1030 dev_info(slvs->dev, "no streams defined");
1014 return -ENODEV; 1031 return -ENODEV;
@@ -1076,6 +1093,12 @@ struct tegra_mc_slvs *tegra_slvs_media_controller_init(
1076 slvs->slvs_base = pdata->aperture[0]; 1093 slvs->slvs_base = pdata->aperture[0];
1077 slvs->vi_base = pdata->aperture[1]; 1094 slvs->vi_base = pdata->aperture[1];
1078 1095
1096 slvs->syncgen_clock = SYNCGEN_CLOCK;
1097
1098 if (tegra_platform_is_linsim() || tegra_platform_is_vdk()) {
1099 slvs->syncgen_clock = 72000; /* 72 MHz */
1100 }
1101
1079 atomic_set(&slvs->power_ref, 0); 1102 atomic_set(&slvs->power_ref, 0);
1080 1103
1081 err = tegra_slvs_parse_dt(slvs); 1104 err = tegra_slvs_parse_dt(slvs);