Arm: Tegra: Tsensor: Added guardbanding to temperatures
Diwakar Tundlam [Tue, 12 Jul 2011 07:51:11 +0000 (00:51 -0700)]
Bug 844025

- Guardband to account for hotspot offset and sensor accuracy.
- Throttling point specified independent of EDP, but constrained to be
  one of the specified EDP points.

Original-Change-Id: Ic9231ad6887ca282bb520ea23229526ac7a243be
Reviewed-on: http://git-master/r/40566
Reviewed-by: Diwakar Tundlam <dtundlam@nvidia.com>
Tested-by: Diwakar Tundlam <dtundlam@nvidia.com>
Reviewed-by: Bitan Biswas <bbiswas@nvidia.com>

Rebase-Id: Rb582312d40da8f1cc753666bdef6068138358cd0

arch/arm/mach-tegra/board-cardhu-sensors.c
drivers/misc/nct1008.c

index 1170645..ab673a8 100644 (file)
@@ -516,10 +516,14 @@ static struct nct1008_platform_data cardhu_nct1008_pdata = {
        .supported_hwrev = true,
        .ext_range = false,
        .conv_rate = 0x08,
-       .offset = 0,
+/*
+ * BugID 844025 requires 11C guardband (9.7C for hotspot offset + 1.5C
+ * for sensor accuracy). FIXME: Move sensor accuracy to sensor driver.
+ */
+       .offset = 11,
        .hysteresis = 5,
-       .shutdown_ext_limit = 75,
-       .shutdown_local_limit = 75,
+       .shutdown_ext_limit = 90,
+       .shutdown_local_limit = 90,
        .throttling_ext_limit = 90,
        .alarm_fn = tegra_throttling_enable,
 };
@@ -556,6 +560,7 @@ static int cardhu_nct1008_init(void)
        struct tegra_edp_limits *z;
        int zones_sz;
        int i;
+       bool throttle_ok = false;
 #endif
 
        if ((board_info.board_id == BOARD_E1198) ||
@@ -585,8 +590,21 @@ static int cardhu_nct1008_init(void)
 #ifdef CONFIG_TEGRA_EDP_LIMITS
        cardhu_thermal_zones_info(&z, &zones_sz);
        zones_sz = min(zones_sz, MAX_ZONES);
-       for (i = 0; i < zones_sz; i++)
+       for (i = 0; i < zones_sz; i++) {
                cardhu_nct1008_pdata.thermal_zones[i] = z[i].temperature;
+               if (cardhu_nct1008_pdata.thermal_zones[i] ==
+                   cardhu_nct1008_pdata.throttling_ext_limit) {
+                       throttle_ok = true;
+               }
+       }
+
+       if (throttle_ok != true)
+               pr_warn("%s: WARNING! Throttling limit %dC would be inaccurate"
+                       " as it is NOT one of the EDP points\n",
+                       __func__, cardhu_nct1008_pdata.throttling_ext_limit);
+       else
+               pr_info("%s: Throttling limit %dC OK\n",
+                       __func__, cardhu_nct1008_pdata.throttling_ext_limit);
 
        cardhu_nct1008_pdata.thermal_zones_sz = zones_sz;
 #endif
index d4a8c1c..748697a 100644 (file)
@@ -441,7 +441,6 @@ static void nct1008_work_func(struct work_struct *work)
        int nentries = data->limits_sz;
        int lo_limit = 0, hi_limit = 0;
        int intr_status = i2c_smbus_read_byte_data(data->client, STATUS_RD);
-       bool throttle = false;
 
        err = nct1008_get_temp(&data->client->dev, &temperature);
        if (err) {
@@ -461,7 +460,6 @@ static void nct1008_work_func(struct work_struct *work)
        } else if (temperature >= data->limits[nentries-1]) {
                lo_limit = data->limits[nentries-1] - ALERT_HYSTERESIS;
                hi_limit = data->plat_data.shutdown_ext_limit;
-               throttle = true;
        } else {
                for (i = 0; (i + 1) < nentries; i++) {
                        if (temperature >= data->limits[i] &&
@@ -473,6 +471,15 @@ static void nct1008_work_func(struct work_struct *work)
                }
        }
 
+       if (temperature >= data->plat_data.throttling_ext_limit) {
+               /* start throttling */
+               therm_throttle(data, true);
+       } else if (temperature <
+                  (data->plat_data.throttling_ext_limit - ALERT_HYSTERESIS)) {
+               /* switch off throttling */
+               therm_throttle(data, false);
+       }
+
        if (lo_limit == hi_limit) {
                err = -ENODATA;
                goto out;
@@ -503,19 +510,12 @@ static void nct1008_work_func(struct work_struct *work)
                current_hi_limit = hi_limit;
        }
 
-       if (throttle) {
-               /* start throttling */
-               therm_throttle(data, true);
-               goto out;
-       } else {
-               /* switch off throttling */
-               therm_throttle(data, false);
-       }
-
        /* inform edp governor */
        if (edp_thermal_zone_val != temperature)
-               // FIXME: Move this direct tegra_ function call to be called via
-               //        a pointer in 'struct nct1008_data' (like 'alarm_fn')
+               /*
+                * FIXME: Move this direct tegra_ function call to be called
+                * via a pointer in 'struct nct1008_data' (like 'alarm_fn')
+                */
                tegra_edp_update_thermal_zone(temperature);
 
        edp_thermal_zone_val = temperature;
@@ -629,7 +629,10 @@ static int __devinit nct1008_configure_sensor(struct nct1008_data* data)
                if (err)
                        goto error;
        } else {
-               /* External Temperature Throttling limit */
+               /*
+                * External Temperature Throttling limit:
+                *   Applies when 'Thermal Zones' are not specified.
+                */
                hi_limit = pdata->throttling_ext_limit;
        }