X-Git-Url: http://plrg.eecs.uci.edu/git/?p=firefly-linux-kernel-4.4.55.git;a=blobdiff_plain;f=drivers%2Fthermal%2Frockchip_thermal.c;h=357d967fc71fa4c679ebaddf49926d543827a062;hp=26cbda55a6ab00001f38bb9f78b50d70ab52870d;hb=83fb4e1f93adb50a1c90d1554e72a0d64ce6eb57;hpb=234718be61d6b0dbf94ac977af23e61ea3e5bfb2 diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c index 26cbda55a6ab..357d967fc71f 100644 --- a/drivers/thermal/rockchip_thermal.c +++ b/drivers/thermal/rockchip_thermal.c @@ -213,8 +213,8 @@ struct rockchip_thermal_data { #define TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT 4 #define TSADCV2_AUTO_PERIOD_TIME 250 /* 250ms */ #define TSADCV2_AUTO_PERIOD_HT_TIME 50 /* 50ms */ -#define TSADCV3_AUTO_PERIOD_TIME 187500 /* 250ms */ -#define TSADCV3_AUTO_PERIOD_HT_TIME 37500 /* 50ms */ +#define TSADCV3_AUTO_PERIOD_TIME 1875 /* 2.5ms */ +#define TSADCV3_AUTO_PERIOD_HT_TIME 1875 /* 2.5ms */ #define TSADCV2_USER_INTER_PD_SOC 0x340 /* 13 clocks */ @@ -222,10 +222,10 @@ struct rockchip_thermal_data { #define GRF_TSADC_TESTBIT_L 0x0e648 #define GRF_TSADC_TESTBIT_H 0x0e64c -#define GRF_TSADC_TSEN_PD_ON (0x30003 << 0) -#define GRF_TSADC_TSEN_PD_OFF (0x30000 << 0) #define GRF_SARADC_TESTBIT_ON (0x10001 << 2) #define GRF_TSADC_TESTBIT_H_ON (0x10001 << 2) +#define GRF_TSADC_VCM_EN_L (0x10001 << 7) +#define GRF_TSADC_VCM_EN_H (0x10001 << 7) /** * struct tsadc_table - code to temperature conversion table @@ -401,13 +401,15 @@ static u32 rk_tsadcv2_temp_to_code(struct chip_tsadc_table table, int temp) { int high, low, mid; + u32 error = table.data_mask; low = 0; high = table.length - 1; mid = (high + low) / 2; + /* Return mask code data when the temp is over table range */ if (temp < table.id[low].temp || temp > table.id[high].temp) - return 0; + goto exit; while (low <= high) { if (temp == table.id[mid].temp) @@ -419,7 +421,11 @@ static u32 rk_tsadcv2_temp_to_code(struct chip_tsadc_table table, mid = (low + high) / 2; } - return 0; +exit: + pr_err("%s: Invalid conversion table: code=%d, temperature=%d\n", + __func__, error, temp); + + return error; } static int rk_tsadcv2_code_to_temp(struct chip_tsadc_table table, u32 code, @@ -469,7 +475,8 @@ static int rk_tsadcv2_code_to_temp(struct chip_tsadc_table table, u32 code, } break; default: - pr_err("Invalid the conversion table\n"); + pr_err("%s: Invalid the conversion table mode=%d\n", + __func__, table.mode); } /* @@ -560,9 +567,10 @@ static void rk_tsadcv3_initialize(struct regmap *grf, void __iomem *regs, regs + TSADCV2_HIGHT_TSHUT_DEBOUNCE); } else { - regmap_write(grf, GRF_TSADC_TESTBIT_L, GRF_TSADC_TSEN_PD_ON); - mdelay(10); - regmap_write(grf, GRF_TSADC_TESTBIT_L, GRF_TSADC_TSEN_PD_OFF); + /* Enable the voltage common mode feature */ + regmap_write(grf, GRF_TSADC_TESTBIT_L, GRF_TSADC_VCM_EN_L); + regmap_write(grf, GRF_TSADC_TESTBIT_H, GRF_TSADC_VCM_EN_H); + udelay(100); /* The spec note says at least 15 us */ regmap_write(grf, GRF_SARADC_TESTBIT, GRF_SARADC_TESTBIT_ON); regmap_write(grf, GRF_TSADC_TESTBIT_H, GRF_TSADC_TESTBIT_H_ON); @@ -649,7 +657,11 @@ static void rk_tsadcv2_alarm_temp(struct chip_tsadc_table table, { u32 alarm_value, int_en; + /* Make sure the value is valid */ alarm_value = rk_tsadcv2_temp_to_code(table, temp); + if (alarm_value == table.data_mask) + return; + writel_relaxed(alarm_value & table.data_mask, regs + TSADCV2_COMP_INT(chn)); @@ -663,7 +675,11 @@ static void rk_tsadcv2_tshut_temp(struct chip_tsadc_table table, { u32 tshut_value, val; + /* Make sure the value is valid */ tshut_value = rk_tsadcv2_temp_to_code(table, temp); + if (tshut_value == table.data_mask) + return; + writel_relaxed(tshut_value, regs + TSADCV2_COMP_SHUT(chn)); /* TSHUT will be valid */ @@ -994,6 +1010,48 @@ static void rockchip_thermal_reset_controller(struct reset_control *reset) reset_control_deassert(reset); } +static struct platform_device *thermal_device; + +void rockchip_dump_temperature(void) +{ + struct rockchip_thermal_data *thermal; + struct platform_device *pdev; + int i; + + if (!thermal_device) + return; + + pdev = thermal_device; + thermal = platform_get_drvdata(pdev); + + for (i = 0; i < thermal->chip->chn_num; i++) { + struct rockchip_thermal_sensor *sensor = &thermal->sensors[i]; + struct thermal_zone_device *tz = sensor->tzd; + + if (tz->temperature != THERMAL_TEMP_INVALID) + dev_warn(&pdev->dev, "channal %d: temperature(%d C)\n", + i, tz->temperature / 1000); + } + + if (thermal->regs) { + pr_warn("THERMAL REGS:\n"); + print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET, + 32, 4, thermal->regs, 0x88, false); + } +} +EXPORT_SYMBOL_GPL(rockchip_dump_temperature); + +static int rockchip_thermal_panic(struct notifier_block *this, + unsigned long ev, void *ptr) +{ + rockchip_dump_temperature(); + return NOTIFY_DONE; +} + +static struct notifier_block rockchip_thermal_panic_block = { + .notifier_call = rockchip_thermal_panic, +}; + static int rockchip_thermal_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; @@ -1106,6 +1164,11 @@ static int rockchip_thermal_probe(struct platform_device *pdev) platform_set_drvdata(pdev, thermal); + thermal_device = pdev; + + atomic_notifier_chain_register(&panic_notifier_list, + &rockchip_thermal_panic_block); + return 0; err_disable_pclk: