platform: tegra: nvadsp: Detect simulation with DT
Ajay Nandakumar [Sun, 1 Mar 2015 06:52:59 +0000 (11:52 +0530)]
Adding ADSP DT attribute "nvidia,adsp_unit_fpga" which can be used
detect if adsp is running on Unit-FPGA or on actual silicon.

Bug 200081122

Change-Id: Ie0aa568f63df172315712421acfbf439f6417ed8
Signed-off-by: Ajay Nandakumar <anandakumarm@nvidia.com>
Reviewed-on: http://git-master/r/712313
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Nitin Kumbhar <nkumbhar@nvidia.com>
Tested-by: Nitin Kumbhar <nkumbhar@nvidia.com>

Documentation/devicetree/bindings/sound/tegra-adsp.txt
arch/arm64/boot/dts/tegra210-soc-base.dtsi
drivers/platform/tegra/nvadsp/dev.c
drivers/platform/tegra/nvadsp/dev.h
drivers/platform/tegra/nvadsp/os.c
drivers/platform/tegra/nvadsp/os.h

index 26f54ad..2925f8e 100644 (file)
@@ -4,9 +4,14 @@ Tegra ADSP bindings
 The Audio DSP (ADSP) handles audio related modules.
 
 Required properties:
- - compatible:         should be set to "nvidia,tegra210-adsp" for t210
- - reg:                        should contain ADSP registers' location and length
- - nvidia,adsp_mem:    should contain Memory address and sizes of ADSP OS, APP, ARAM
+ - compatible:                 should be set to "nvidia,tegra210-adsp" for t210
+ - reg:                                should contain ADSP registers' location and length
+ - nvidia,adsp_mem:            should contain Memory address and sizes of ADSP OS, APP, ARAM
+ - nvidia,adsp_unit_fpga:      should be added if ADSP is on Unit-FPGA
+ - nvidia,adsp_unit_fpga_reset:        should be added if ADSP is on Unit-FPGA. The first element
+                               contains the ASSERT value and the second element should
+                               contain the DEASSERT value. The ASSERT is ignored if the
+                               value is equal to 0.
 
 Example:
        adsp {
@@ -14,8 +19,10 @@ Example:
             reg = <0x0 0x702ef000 0x0 0x1000>, /* AMC */
                   <0x0 0x702ec000 0x0 0x2000>, /* AMISC */
                   <0x0 0x702ee000 0x0 0x1000>, /* ABRIDGE */
+                  <0x0 0x702dc800 0x0 0x0>, /* FPGA RESET REG */
                   <0x0 0x01000000 0x0 0x6f2c0000>, /* DRAM MAP1 */
                   <0x0 0x70300000 0x0 0x8fd00000>; /* DRAM MAP2 */
             nvidia,adsp_mem = <0x80300000 0x01000000>, /* ADSP OS */
                               <0x80B00000 0x00800000>; /* ADSP APP */
+            nvidia,adsp_unit_fpga_reset = <0x0 0x00000040>;
        };
index de9c8be..7f97e4f 100644 (file)
             reg = <0x0 0x702ef000 0x0 0x1000>, /* AMC */
                   <0x0 0x702ec000 0x0 0x2000>, /* AMISC */
                   <0x0 0x702ee000 0x0 0x1000>, /* ABRIDGE */
+                  <0x0 0x702dc800 0x0 0x0>, /* FPGA RESET REG */
                   <0x0 0x01000000 0x0 0x6f2c0000>, /* DRAM MAP1 */
                   <0x0 0x70300000 0x0 0x8fd00000>; /* DRAM MAP2 */
             iommus = <&smmu TEGRA_SWGROUP_APE>;
             nvidia,adsp_mem = <0x80300000 0x01000000>, /* ADSP OS */
                               <0x80B00000 0x00800000>, /* ADSP APP */
                               <0x00400000 0x00010000>; /* ARAM ALIAS 0 */
+            nvidia,adsp_unit_fpga_reset = <0x0 0x00000040>;
             status = "disabled";
        };
 
index 0e8b28c..0e15a45 100644 (file)
@@ -365,20 +365,37 @@ static int __init nvadsp_parse_dt(struct platform_device *pdev)
 {
        struct nvadsp_drv_data *drv_data = platform_get_drvdata(pdev);
        struct device *dev = &pdev->dev;
+       u32 *adsp_reset;
        u32 *adsp_mem;
        int iter;
 
+       adsp_reset = drv_data->unit_fpga_reset;
        adsp_mem = drv_data->adsp_mem;
 
        for (iter = 0; iter < ADSP_MEM_END; iter++) {
                if (of_property_read_u32_index(dev->of_node, "nvidia,adsp_mem",
                        iter, &adsp_mem[iter])) {
-                       dev_err(dev, "adsp mem node %d not found\n", iter);
+                       dev_err(dev, "adsp memory dt %d not found\n", iter);
                        return -EINVAL;
                }
        }
-       return 0;
 
+       drv_data->adsp_unit_fpga = of_property_read_bool(dev->of_node,
+                               "nvidia,adsp_unit_fpga");
+
+       if (drv_data->adsp_unit_fpga) {
+               for (iter = 0; iter < ADSP_UNIT_FPGA_RESET_END; iter++) {
+                       if (of_property_read_u32_index(dev->of_node,
+                               "nvidia,adsp_unit_fpga_reset", iter,
+                               &adsp_reset[iter])) {
+                               dev_err(dev, "adsp reset dt %d not found\n",
+                                       iter);
+                               return -EINVAL;
+                       }
+               }
+       }
+
+       return 0;
 }
 
 static int __init nvadsp_probe(struct platform_device *pdev)
@@ -433,10 +450,13 @@ static int __init nvadsp_probe(struct platform_device *pdev)
                        goto out;
                }
 
+               if (!drv_data->adsp_unit_fpga && iter == UNIT_FPGA_RST)
+                       continue;
+
                base = devm_ioremap_resource(dev, res);
                if (IS_ERR(base)) {
-                       dev_err(dev,
-                               "Failed to remap AMISC resource\n");
+                       dev_err(dev, "Failed to iomap resource reg[%d]\n",
+                               iter);
                        ret = PTR_ERR(base);
                        goto out;
                }
index 252f809..2d58493 100644 (file)
@@ -36,6 +36,7 @@ enum {
        AMC,
        AMISC,
        ABRIDGE,
+       UNIT_FPGA_RST,
        APE_MAX_REG
 };
 
@@ -59,6 +60,12 @@ enum adsp_mem_dt {
        ADSP_MEM_END,
 };
 
+enum adsp_unit_fpga_reset {
+       ADSP_ASSERT,
+       ADSP_DEASSERT,
+       ADSP_UNIT_FPGA_RESET_END,
+};
+
 
 #define AMISC_REGS     0x2000
 
@@ -118,6 +125,8 @@ struct nvadsp_drv_data {
        bool actmon_initialized;
 #endif
        u32 adsp_mem[ADSP_MEM_END];
+       bool adsp_unit_fpga;
+       u32 unit_fpga_reset[ADSP_UNIT_FPGA_RESET_END];
 };
 
 #define ADSP_CONFIG    0x04
index 0a8194b..b0135bf 100644 (file)
@@ -95,9 +95,7 @@ struct nvadsp_debug_log {
 };
 
 struct nvadsp_os_data {
-#if !CONFIG_SYSTEM_FPGA
-       void __iomem            *reset_reg;
-#endif
+       void __iomem            *unit_fpga_reset_reg;
        const struct firmware   *os_firmware;
        struct platform_device  *pdev;
        struct global_sym_info  *adsp_glo_sym_tbl;
@@ -726,28 +724,61 @@ end:
 }
 EXPORT_SYMBOL(nvadsp_os_load);
 
-static int __nvadsp_os_start(void)
+static int deassert_adsp(struct nvadsp_drv_data *drv_data)
 {
-       struct nvadsp_shared_mem *shared_mem;
-       struct nvadsp_drv_data *drv_data;
-       struct nvadsp_os_args *os_args;
-       struct device *dev;
-       long max_adsp_freq;
-#if !CONFIG_SYSTEM_FPGA
-       u32 val;
-#endif
-       int ret = 0;
+       struct device *dev = &priv.pdev->dev;
 
-       dev = &priv.pdev->dev;
-       drv_data = platform_get_drvdata(priv.pdev);
+       if (drv_data->adsp_unit_fpga) {
+               dev_info(dev, "De-asserting ADSP UNIT-FPGA\n");
+               writel(drv_data->unit_fpga_reset[ADSP_DEASSERT],
+                               priv.unit_fpga_reset_reg);
+               return 0;
+       }
 
-       dev_dbg(dev, "Copying EVP...\n");
-       copy_io_in_l(drv_data->state.evp_ptr,
-                    drv_data->state.evp,
-                    AMC_EVP_SIZE);
+       if (drv_data->adsp_clk) {
+               dev_dbg(dev, "deasserting adsp...\n");
+               tegra_periph_reset_deassert(drv_data->adsp_clk);
+               udelay(200);
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
+static int assert_adsp(struct nvadsp_drv_data *drv_data)
+{
+       struct device *dev = &priv.pdev->dev;
+
+       if (drv_data->adsp_unit_fpga) {
+               if (drv_data->unit_fpga_reset[ADSP_ASSERT]) {
+                       dev_info(dev, "Asserting ADSP UNIT-FPGA\n");
+                       writel(drv_data->unit_fpga_reset[ADSP_ASSERT],
+                               priv.unit_fpga_reset_reg);
+               }
+               return 0;
+       }
+
+       if (drv_data->adsp_clk) {
+               tegra_periph_reset_assert(drv_data->adsp_clk);
+               udelay(200);
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
+static int set_adsp_clks_and_timer_prescalar(struct nvadsp_drv_data *drv_data)
+{
+       struct nvadsp_shared_mem *shared_mem = drv_data->shared_adsp_os_data;
+       struct nvadsp_os_args *os_args = &shared_mem->os_args;
+       struct device *dev = &priv.pdev->dev;
+       long max_adsp_freq;
+       int ret = -EINVAL;
+
+       /* on Unit-FPGA do not set clocks, return Sucess */
+       if (drv_data->adsp_unit_fpga)
+               return 0;
 
-       shared_mem = drv_data->shared_adsp_os_data;
-       os_args = &shared_mem->os_args;
        if (drv_data->adsp_cpu_clk) {
                max_adsp_freq = clk_round_rate(drv_data->adsp_cpu_clk,
                                ULONG_MAX);
@@ -762,29 +793,42 @@ static int __nvadsp_os_start(void)
                os_args->timer_prescalar--;
                drv_data->max_adsp_freq = max_adsp_freq;
                ret = clk_set_rate(drv_data->adsp_cpu_clk, max_adsp_freq);
-               if (ret)
-                       goto end;
 
                dev_dbg(dev, "adsp cpu frequncy %lu and timer prescalar %x\n",
                        clk_get_rate(drv_data->adsp_cpu_clk),
                        os_args->timer_prescalar);
-       } else {
-               ret = -EINVAL;
-               goto end;
-       }
 
-       if (drv_data->adsp_clk) {
-               dev_dbg(dev, "deasserting adsp...\n");
-               tegra_periph_reset_deassert(drv_data->adsp_clk);
-               udelay(200);
-       } else {
-               ret = -EINVAL;
-               goto end;
        }
 
-#if !CONFIG_SYSTEM_FPGA
-       writel(APE_RESET, priv.reset_reg);
-#endif
+       return ret;
+}
+
+static int __nvadsp_os_start(void)
+{
+       struct nvadsp_drv_data *drv_data;
+       struct device *dev;
+       int ret = 0;
+
+       dev = &priv.pdev->dev;
+       drv_data = platform_get_drvdata(priv.pdev);
+
+
+       dev_dbg(dev, "ADSP is booting on %s\n",
+               drv_data->adsp_unit_fpga ? "UNIT-FPGA" : "SILICON");
+
+       assert_adsp(drv_data);
+
+       dev_dbg(dev, "Copying EVP...\n");
+       copy_io_in_l(drv_data->state.evp_ptr,
+                    drv_data->state.evp,
+                    AMC_EVP_SIZE);
+
+       ret = set_adsp_clks_and_timer_prescalar(drv_data);
+       if (ret)
+               goto end;
+       ret = deassert_adsp(drv_data);
+       if (ret)
+               goto end;
 
        dev_info(dev, "waiting for ADSP OS to boot up...\n");
        ret = wait_for_adsp_os_load_complete();
@@ -913,8 +957,7 @@ static int __nvadsp_os_suspend(void)
 
        drv_data->adsp_os_suspended = true;
 
-       tegra_periph_reset_assert(drv_data->adsp_clk);
-       udelay(200);
+       assert_adsp(drv_data);
 
        ret = pm_runtime_put_sync(&priv.pdev->dev);
        if (ret) {
@@ -957,8 +1000,7 @@ static void __nvadsp_os_stop(bool reload)
                goto end;
        }
 
-       tegra_periph_reset_assert(drv_data->adsp_clk);
-       udelay(200);
+       assert_adsp(drv_data);
 
        if (reload) {
                struct nvadsp_debug_log *logger = &priv.logger;
@@ -1092,14 +1134,16 @@ static  irqreturn_t adsp_wfi_handler(int irq, void *arg)
 static irqreturn_t adsp_wdt_handler(int irq, void *arg)
 {
        struct nvadsp_os_data *data = arg;
+       struct nvadsp_drv_data *drv_data;
        struct device *dev = &data->pdev->dev;
 
-#if CONFIG_SYSTEM_FPGA
-       dev_crit(dev, "ADSP OS Hanged or Crashed! Restarting...\n");
-       schedule_work(&data->restart_os_work);
-#else
-       dev_crit(dev, "ADSP OS Hanged or Crashed!\n");
-#endif
+       drv_data = platform_get_drvdata(data->pdev);
+       if (!drv_data->adsp_unit_fpga) {
+               dev_crit(dev, "ADSP OS Hanged or Crashed! Restarting...\n");
+               schedule_work(&data->restart_os_work);
+       } else {
+               dev_crit(dev, "ADSP OS Hanged or Crashed!\n");
+       }
        return IRQ_HANDLED;
 }
 
@@ -1111,14 +1155,7 @@ int __init nvadsp_os_probe(struct platform_device *pdev)
        struct device *dev = &pdev->dev;
        int ret = 0;
 
-#if !CONFIG_SYSTEM_FPGA
-       priv.reset_reg = ioremap(APE_FPGA_MISC_RST_DEVICES, 1);
-       if (!priv.reset_reg) {
-               dev_err(dev, "unable to map reset addr\n");
-               ret = -EINVAL;
-               goto end;
-       }
-#endif
+       priv.unit_fpga_reset_reg = drv_data->base_regs[UNIT_FPGA_RST];
        priv.misc_base = drv_data->base_regs[AMISC];
        priv.dram_region = drv_data->dram_region;
 
index 97ecfb5..048cec2 100644 (file)
 
 #define CONFIG_ADSP_DRAM_LOG_WITH_TAG  1
 #define CONFIG_USE_STATIC_APP_LOAD     0
-#define CONFIG_SYSTEM_FPGA             1
 /* enable profiling of load init start */
 #define RECORD_STATS                   0
 
 #define SYM_NAME_SZ 128
 
-#define APE_FPGA_MISC_RST_DEVICES 0x702dc800 /*1882048512*/
-#define APE_RESET (1 << 6)
-
 #define AMC_EVP_RESET_VEC_0            0x700
 #define AMC_EVP_UNDEF_VEC_0            0x704
 #define AMC_EVP_SWI_VEC_0              0x708