summaryrefslogtreecommitdiff
path: root/drivers/video/tegra/dc
diff options
context:
space:
mode:
authorIlan Aelion <iaelion@nvidia.com>2012-06-27 18:58:11 -0600
committerLokesh Pathak <lpathak@nvidia.com>2012-07-30 08:37:00 -0700
commite402db9b3737209c9981aea5970328d7c1cb06ce (patch)
tree245efed1639bfb099649c6d81263ea1a7e752cd9 /drivers/video/tegra/dc
parent8055acfa05c82997bdcfbce5093b9cd963251d2a (diff)
misc: tegra-throughput: adding throughput dev node
Creates a miscdev at /dev/tegra-throughput which gl will use to set a target frame rate. In addition it receives notifications from dc on flip events. On each notification the percentage ratio of the actual frame time to the target frame time is calculated. In subsequent changes this ratio will be reported to other modules as a throughput hint. Bug 991589 Change-Id: Ieaa2b2755b63d2d071de31e3ef819d4c3b51a956 Signed-off-by: Ilan Aelion <iaelion@nvidia.com> Reviewed-on: http://git-master/r/116865 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Diwakar Tundlam <dtundlam@nvidia.com> Reviewed-by: Jon Mayo <jmayo@nvidia.com>
Diffstat (limited to 'drivers/video/tegra/dc')
-rw-r--r--drivers/video/tegra/dc/dc_priv.h2
-rw-r--r--drivers/video/tegra/dc/ext/dev.c29
-rw-r--r--drivers/video/tegra/dc/mode.c13
3 files changed, 43 insertions, 1 deletions
diff --git a/drivers/video/tegra/dc/dc_priv.h b/drivers/video/tegra/dc/dc_priv.h
index 332c80f9cbb6..759d64da7052 100644
--- a/drivers/video/tegra/dc/dc_priv.h
+++ b/drivers/video/tegra/dc/dc_priv.h
@@ -372,7 +372,7 @@ void tegra_dc_disable_crc(struct tegra_dc *dc);
void tegra_dc_set_out_pin_polars(struct tegra_dc *dc,
const struct tegra_dc_out_pin *pins,
const unsigned int n_pins);
-/* defined in dc.c, used in bandwidth.c */
+/* defined in dc.c, used in bandwidth.c and ext/dev.c */
unsigned int tegra_dc_has_multiple_dc(void);
/* defined in dc.c, used in dsi.c */
diff --git a/drivers/video/tegra/dc/ext/dev.c b/drivers/video/tegra/dc/ext/dev.c
index f9c76f8f0d0d..92e42ce32ac2 100644
--- a/drivers/video/tegra/dc/ext/dev.c
+++ b/drivers/video/tegra/dc/ext/dev.c
@@ -274,6 +274,32 @@ static int tegra_dc_ext_set_windowattr(struct tegra_dc_ext *ext,
return 0;
}
+static struct srcu_notifier_head tegra_dc_flip_notifier_list;
+static bool init_tegra_dc_flip_notifier_list_called;
+static int __init init_tegra_dc_flip_notifier_list(void)
+{
+ srcu_init_notifier_head(&tegra_dc_flip_notifier_list);
+ init_tegra_dc_flip_notifier_list_called = true;
+ return 0;
+}
+
+pure_initcall(init_tegra_dc_flip_notifier_list);
+
+int tegra_dc_register_flip_notifier(struct notifier_block *nb)
+{
+ WARN_ON(!init_tegra_dc_flip_notifier_list_called);
+
+ return srcu_notifier_chain_register(
+ &tegra_dc_flip_notifier_list, nb);
+}
+EXPORT_SYMBOL(tegra_dc_register_flip_notifier);
+
+int tegra_dc_unregister_flip_notifier(struct notifier_block *nb)
+{
+ return srcu_notifier_chain_unregister(&tegra_dc_flip_notifier_list, nb);
+}
+EXPORT_SYMBOL(tegra_dc_unregister_flip_notifier);
+
static void tegra_dc_ext_flip_worker(struct work_struct *work)
{
struct tegra_dc_ext_flip_data *data =
@@ -327,6 +353,9 @@ static void tegra_dc_ext_flip_worker(struct work_struct *work)
tegra_dc_update_windows(wins, nr_win);
/* TODO: implement swapinterval here */
tegra_dc_sync_windows(wins, nr_win);
+ if (!tegra_dc_has_multiple_dc())
+ srcu_notifier_call_chain(&tegra_dc_flip_notifier_list,
+ 1UL, NULL);
}
for (i = 0; i < DC_N_WINDOWS; i++) {
diff --git a/drivers/video/tegra/dc/mode.c b/drivers/video/tegra/dc/mode.c
index 49cc5f5abd53..be909691b957 100644
--- a/drivers/video/tegra/dc/mode.c
+++ b/drivers/video/tegra/dc/mode.c
@@ -247,10 +247,23 @@ int tegra_dc_program_mode(struct tegra_dc *dc, struct tegra_dc_mode *mode)
return 0;
}
+static int panel_sync_rate;
+
+int tegra_dc_get_panel_sync_rate(void)
+{
+ return panel_sync_rate;
+}
+EXPORT_SYMBOL(tegra_dc_get_panel_sync_rate);
+
int tegra_dc_set_mode(struct tegra_dc *dc, const struct tegra_dc_mode *mode)
{
memcpy(&dc->mode, mode, sizeof(dc->mode));
+ if (dc->out->type == TEGRA_DC_OUT_RGB)
+ panel_sync_rate = tegra_dc_calc_refresh(mode);
+ else if (dc->out->type == TEGRA_DC_OUT_DSI)
+ panel_sync_rate = dc->out->dsi->rated_refresh_rate * 1000;
+
print_mode(dc, mode, __func__);
return 0;