]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
platform: nvadsp: Add support for global TSC
authorAjay Nandakumar <anandakumarm@nvidia.com>
Tue, 30 Sep 2014 08:47:55 +0000 (14:17 +0530)
committerNitin Kumbhar <nkumbhar@nvidia.com>
Tue, 7 Oct 2014 09:29:35 +0000 (02:29 -0700)
need a global timestamp counter(TSC) to synchronize across different
modules across the system(SOC).Add API to access global timestamp
counter(TSC).

Bug 200009727

Change-Id: I69a191bcbf71457558de5b05316c336c0d52cbaa
Signed-off-by: Ajay Nandakumar <anandakumarm@nvidia.com>
Reviewed-on: http://git-master/r/551975
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Nitin Kumbhar <nkumbhar@nvidia.com>
drivers/platform/tegra/nvadsp/dev.c
include/linux/tegra_nvadsp.h

index edac98dfe9dc8d04ed6a075f2cae2e286076ab1f..0fbe01078c15372912848dda797ca1239d79fbf8 100644 (file)
 #include "ape_actmon.h"
 #include "aram_manager.h"
 
+#define ADSP_TSC       0x48
+
+static DEFINE_SPINLOCK(tsc_lock);
+static struct nvadsp_drv_data *nvadsp_drv_data;
+
 #ifdef CONFIG_DEBUG_FS
 static int __init adsp_debug_init(struct nvadsp_drv_data *drv_data)
 {
@@ -267,6 +272,37 @@ static const struct dev_pm_ops nvadsp_pm_ops = {
                           nvadsp_runtime_idle)
 };
 
+uint64_t nvadsp_get_timestamp_counter(void)
+{
+       uint32_t count_low = 0;
+       uint32_t count_high = 0;
+       uint64_t tsc = 0;
+       void * __iomem base = nvadsp_drv_data->base_regs[AMISC];
+       unsigned long flags;
+
+       spin_lock_irqsave(&tsc_lock, flags);
+read_again:
+       /* read MSB 32 bits */
+       count_high = readl(base + ADSP_TSC);
+       /* read LSB 32 bits */
+       count_low = readl(base + ADSP_TSC);
+       if (count_high != readl(base + ADSP_TSC))
+               goto read_again;
+
+       /*
+        * Additional read to make sure that the next read is the higher
+        * nibble
+        */
+       readl(base + ADSP_TSC);
+
+       tsc = count_high;
+       tsc <<= 32;
+       tsc |= count_low;
+       spin_unlock_irqrestore(&tsc_lock, flags);
+       return tsc;
+}
+EXPORT_SYMBOL(nvadsp_get_timestamp_counter);
+
 static int __init nvadsp_probe(struct platform_device *pdev)
 {
        struct nvadsp_drv_data *drv_data;
@@ -338,6 +374,8 @@ static int __init nvadsp_probe(struct platform_device *pdev)
                drv_data->dram_region[dram_iter] = res;
        }
 
+       nvadsp_drv_data = drv_data;
+
        platform_set_drvdata(pdev, drv_data);
 
        pm_runtime_enable(dev);
index dd8e695a9044bc755f8b57ec8f808f67ed573275..836438e1e1101cfd7f7c2dd4236a3162fb4d3bac 100644 (file)
@@ -188,6 +188,11 @@ int __must_check nvadsp_os_start(void);
 void nvadsp_os_stop(void);
 void nvadsp_os_suspend(void);
 
+/*
+ * ADSP TSC
+ */
+uint64_t nvadsp_get_timestamp_counter(void);
+
 /*
  * ADSP OS App
  */