soctherm hardware after offsetting has been applied.
Offsets are disabled if one or more elements of a triplet are missing or
incorrect.
+- nvidia, thermtrips : When present, this property specifies the temperature at
+ which the soctherm hardware will assert the thermal trigger signal to the
+ Power Management IC, which can be configured to reset or shutdown the device.
+ It is an array of pairs where each pair represents a tsensor id followed by a
+ temperature in milli Celcius. In the absence of this property the critical
+ trip point will be used for thermtrip temperature.
- throttle-cfgs: A sub-node which is a container of configuration for each
hardware throttle events. These events can be set as cooling devices.
* throttle events: Sub-nodes must be named as "light", "heavy", "oc1" - "oc5".
is 0.
Note:
-- the "critical" type trip points will be set to SOC_THERM hardware as the
-shut down temperature. Once the temperature of this thermal zone is higher
-than it, the system will be shutdown or reset by hardware.
+- the "critical" type trip points will be used to set the temperature at which
+the SOC_THERM hardware will assert a thermal trigger if the thermtrips property
+is missing. When the thermtrips property is present the breach of a critical
+trip point is reported back to the thermal framework.
- the "hot" type trip points will be set to SOC_THERM hardware as the throttle
temperature. Once the the temperature of this thermal zone is higher
than it, it will trigger the HW throttle event.
return NULL;
}
+static int tsensor_group_thermtrip_get(struct tegra_soctherm *ts, int id)
+{
+ int i, temp = min_low_temp;
+ struct tsensor_group_thermtrips *tt = ts->soc->thermtrips;
+
+ if (tt) {
+ for (i = 0; i < ts->soc->num_ttgs; i++) {
+ if (tt[i].id == id)
+ return tt[i].temp;
+ }
+ }
+
+ return temp;
+}
+
static int tegra_thermctl_set_trip_temp(void *data, int trip, int temp)
{
struct tegra_thermctl_zone *zone = data;
return ret;
if (type == THERMAL_TRIP_CRITICAL) {
- return thermtrip_program(dev, sg, temp);
+ /* dont allow if soctherm has thermtrips property in DT */
+ if (min_low_temp == tsensor_group_thermtrip_get(ts, sg->id))
+ return thermtrip_program(dev, sg, temp);
+ else
+ return 0;
} else if (type == THERMAL_TRIP_HOT) {
int i;
{
struct tegra_soctherm *ts = dev_get_drvdata(dev);
struct soctherm_throt_cfg *stc;
- int i, trip, temperature;
- int ret;
+ int i, trip, temperature, ret;
- ret = tz->ops->get_crit_temp(tz, &temperature);
- if (ret) {
- dev_info(dev, "thermtrip: %s: missing critical temperature\n",
- sg->name);
- goto set_throttle;
- }
+ temperature = tsensor_group_thermtrip_get(ts, sg->id);
+ if (min_low_temp == temperature)
+ if (tz->ops->get_crit_temp(tz, &temperature))
+ temperature = max_high_temp;
+
+ dev_info(dev, "thermtrip: will shut down when %s reaches %d mC\n",
+ sg->name, temperature);
ret = thermtrip_program(dev, sg, temperature);
if (ret) {
- dev_err(dev, "thermtrip: %s: error during enable\n",
- sg->name);
+ dev_err(dev, "thermtrip: %s: error during enable\n", sg->name);
return ret;
}
- dev_info(dev,
- "thermtrip: will shut down when %s reaches %d mC\n",
- sg->name, temperature);
-
-set_throttle:
if (ts->soc->use_ccroc)
return 0;
.set_cur_state = throt_set_cdev_state,
};
+static int soctherm_thermtrips_parse(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct tegra_soctherm *ts = dev_get_drvdata(dev);
+ struct tsensor_group_thermtrips *tt = ts->soc->thermtrips;
+ const int max_num_prop = ts->soc->num_ttgs * 2;
+ int i = 0, j = 0, r, n;
+ u32 off[max_num_prop];
+
+ if (!tt)
+ return 0;
+
+ n = of_property_count_u32_elems(dev->of_node, "nvidia,thermtrips");
+ if (n <= 0) {
+ dev_err(dev, "invalid dt prop: thermtrips:%d\n", n);
+ return n;
+ }
+
+ n = min(max_num_prop, n);
+ r = of_property_read_u32_array(dev->of_node, "nvidia,thermtrips",
+ off, n);
+ if (r) {
+ dev_err(dev, "invalid num ele: thermtrips:%d\n", r);
+ return r;
+ }
+
+ for (j = 0; j < n; j = j + 2) {
+ if (off[j] >= TEGRA124_SOCTHERM_SENSOR_NUM)
+ continue;
+
+ tt[i].id = off[j];
+ tt[i].temp = off[j+1];
+ i++;
+ }
+
+ return 0;
+}
+
static int soctherm_hw_pllx_offsets_parse(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
if (!tegra->soc->use_ccroc)
soctherm_init_hw_throt_cdev(pdev);
+ soctherm_thermtrips_parse(pdev);
soctherm_hw_pllx_offsets_parse(pdev);
soctherm_init(pdev);
soctherm_debug_init(pdev);