WAR: gr3d: limit 3d clock when camera is on
Jihoon Bang [Tue, 19 Jun 2012 23:12:00 +0000 (16:12 -0700)]
As WAR, limit 3d clock frequency and emc clock frequency
when camera is on and chip is AP37. 3d clock is set to
361MHz and 437MHz is requested for emc clock with this
change. This change allows 3d to request 1.1V in Core
instead of 1.3V in AP37.

Bug 1001262
Bug 1019309

Signed-off-by: Jihoon Bang <jbang@nvidia.com>
Change-Id: I1dbab3469a31ef603f7665fc5a6cb5c1999f89b6
Reviewed-on: http://git-master/r/120480
Reviewed-by: Varun Colbert <vcolbert@nvidia.com>
Tested-by: Varun Colbert <vcolbert@nvidia.com>

arch/arm/mach-tegra/board-cardhu.c
drivers/media/video/tegra/tegra_camera.c
drivers/video/tegra/host/gr3d/scale3d.c
include/media/tegra_camera.h

index 577d859..3f0f196 100644 (file)
@@ -45,6 +45,7 @@
 #include <sound/wm8903.h>
 #include <sound/max98095.h>
 #include <media/tegra_dtv.h>
+#include <media/tegra_camera.h>
 
 #include <mach/clk.h>
 #include <mach/iomap.h>
@@ -628,11 +629,28 @@ static void __init cardhu_uart_init(void)
                                ARRAY_SIZE(cardhu_uart_devices));
 }
 
+static struct tegra_camera_platform_data tegra_camera_pdata = {
+       .limit_3d_emc_clk = false,
+};
+
 static struct platform_device tegra_camera = {
        .name = "tegra_camera",
+       .dev = {
+               .platform_data = &tegra_camera_pdata,
+       },
        .id = -1,
 };
 
+static void tegra_camera_init(void)
+{
+       /* For AP37 platform, limit 3d and emc freq when camera is ON */
+       if (TEGRA_REVISION_A03 == tegra_get_revision() &&
+               0xA0 == tegra_sku_id())
+               tegra_camera_pdata.limit_3d_emc_clk = true;
+       else
+               tegra_camera_pdata.limit_3d_emc_clk = false;
+}
+
 static struct platform_device *cardhu_spi_devices[] __initdata = {
        &tegra_spi_device4,
 };
@@ -1440,6 +1458,7 @@ static void __init tegra_cardhu_init(void)
        cardhu_edp_init();
 #endif
        cardhu_uart_init();
+       tegra_camera_init();
        platform_add_devices(cardhu_devices, ARRAY_SIZE(cardhu_devices));
        tegra_ram_console_debug_init();
        tegra_io_dpd_init();
index 03eecf4..2b0cd00 100644 (file)
@@ -2,7 +2,7 @@
  * drivers/media/video/tegra/tegra_camera.c
  *
  * Copyright (C) 2010 Google, Inc.
- * Copyright (C) 2012 Nvidia Corp
+ * Copyright (c) 2010-2012, NVIDIA Corporation.  All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -58,6 +58,25 @@ struct tegra_camera_block {
        bool is_enabled;
 };
 
+/*
+ * Declare and define two static variables to provide hint to
+ * gr3d module
+ */
+static int tegra_camera_on;
+static struct tegra_camera_platform_data *pdata;
+
+int is_tegra_camera_on(void)
+{
+       if (pdata) {
+               if (pdata->limit_3d_emc_clk)
+                       return tegra_camera_on;
+               else
+                       return 0;
+       } else {
+               return 0;
+       }
+}
+
 static int tegra_camera_enable_clk(struct tegra_camera_dev *dev)
 {
        clk_enable(dev->vi_clk);
@@ -227,6 +246,7 @@ static int tegra_camera_power_on(struct tegra_camera_dev *dev)
                        __func__);
 #endif
        dev->power_on = 1;
+       tegra_camera_on = dev->power_on;
        return ret;
 }
 
@@ -255,6 +275,7 @@ static int tegra_camera_power_off(struct tegra_camera_dev *dev)
                }
        }
        dev->power_on = 0;
+       tegra_camera_on = dev->power_on;
        return ret;
 }
 
@@ -425,6 +446,7 @@ static int tegra_camera_probe(struct platform_device *pdev)
        mutex_unlock(&dev->tegra_camera_lock);
 
        dev->dev = &pdev->dev;
+       pdata = pdev->dev.platform_data;
 
        /* Get regulator pointer */
 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
index 9a6a8e7..fc30c22 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Tegra Graphics Host 3D clock scaling
  *
- * Copyright (c) 2010-2012, NVIDIA Corporation.
+ * Copyright (c) 2010-2012, NVIDIA Corporation.  All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -41,6 +41,7 @@
 #include <mach/hardware.h>
 #include "scale3d.h"
 #include "dev.h"
+#include <media/tegra_camera.h>
 
 static int scale3d_is_enabled(void);
 static void scale3d_enable(int enable);
@@ -48,6 +49,15 @@ static void scale3d_enable(int enable);
 #define POW2(x) ((x) * (x))
 
 /*
+ * 3D clock scaling should be treated differently when camera is on in AP37.
+ * 3D in AP37 requires 1.3V and combining it with MPE reaches to EDP limit.
+ * 3D clock really needs to be set to lower frequency which requires 1.0V.
+ * The same thing applies to 3D EMC clock.
+ */
+#define CAMERA_3D_CLK 300000000
+#define CAMERA_3D_EMC_CLK 437000000
+
+/*
  * debugfs parameters to control 3d clock scaling test
  *
  * period        - time period for clock rate evaluation
@@ -169,12 +179,26 @@ void nvhost_scale3d_suspend(struct nvhost_device *dev)
 static void reset_3d_clocks(void)
 {
        if (clk_get_rate(scale3d.clk_3d) != scale3d.max_rate_3d) {
-               clk_set_rate(scale3d.clk_3d, scale3d.max_rate_3d);
-               if (tegra_get_chipid() == TEGRA_CHIPID_TEGRA3)
-                       clk_set_rate(scale3d.clk_3d2, scale3d.max_rate_3d);
-               if (scale3d.p_scale_emc)
-                       clk_set_rate(scale3d.clk_3d_emc,
-                               clk_round_rate(scale3d.clk_3d_emc, UINT_MAX));
+               if (is_tegra_camera_on())
+                       clk_set_rate(scale3d.clk_3d, CAMERA_3D_CLK);
+               else
+                       clk_set_rate(scale3d.clk_3d, scale3d.max_rate_3d);
+               if (tegra_get_chipid() == TEGRA_CHIPID_TEGRA3) {
+                       if (is_tegra_camera_on())
+                               clk_set_rate(scale3d.clk_3d2, CAMERA_3D_CLK);
+                       else
+                               clk_set_rate(scale3d.clk_3d2,
+                                                       scale3d.max_rate_3d);
+               }
+               if (scale3d.p_scale_emc) {
+                       if (is_tegra_camera_on())
+                               clk_set_rate(scale3d.clk_3d_emc,
+                                       CAMERA_3D_EMC_CLK);
+                       else
+                               clk_set_rate(scale3d.clk_3d_emc,
+                                       clk_round_rate(scale3d.clk_3d_emc,
+                                                               UINT_MAX));
+               }
        }
 }
 
index 9dea148..3c41864 100644 (file)
@@ -2,6 +2,7 @@
  * include/linux/tegra_camera.h
  *
  * Copyright (C) 2010 Google, Inc.
+ * Copyright (c) 2010-2012, NVIDIA Corporation.  All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -48,6 +49,15 @@ enum StereoCameraMode {
        StereoCameraMode_Force32 = 0x7FFFFFFF
 };
 
+struct tegra_camera_platform_data {
+       bool limit_3d_emc_clk;
+};
+
+#if  defined(CONFIG_TEGRA_CAMERA)
+int is_tegra_camera_on(void);
+#else
+int is_tegra_camera_on(void) { return 0; }
+#endif
 
 #define TEGRA_CAMERA_IOCTL_ENABLE              _IOWR('i', 1, uint)
 #define TEGRA_CAMERA_IOCTL_DISABLE             _IOWR('i', 2, uint)