Commit 7267c925b3817478c9ccd0c4a1286ff81f7859f9
Committed by
Stefano Babic
1 parent
3d99fcbc15
Exists in
v2017.01-smarct4x
and in
37 other branches
thermal: imx_thermal: Do not display calibration data
Printing the calibration data on every boot does not provide really useful information: U-Boot 2015.01-rc1-18266-ge7eb277 (Nov 24 2014 - 11:29:51) CPU: Freescale i.MX6Q rev1.2 at 792 MHz CPU: Thermal calibration data: 0x5d85067d CPU: Temperature 33 C Reset cause: POR Board: MX6-SabreSD Do not display the calibration data in order to have a cleaner boot log. Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
Showing 1 changed file with 0 additions and 2 deletions Inline Diff
drivers/thermal/imx_thermal.c
1 | /* | 1 | /* |
2 | * (C) Copyright 2014 Freescale Semiconductor, Inc. | 2 | * (C) Copyright 2014 Freescale Semiconductor, Inc. |
3 | * Author: Nitin Garg <nitin.garg@freescale.com> | 3 | * Author: Nitin Garg <nitin.garg@freescale.com> |
4 | * Ye Li <Ye.Li@freescale.com> | 4 | * Ye Li <Ye.Li@freescale.com> |
5 | * | 5 | * |
6 | * SPDX-License-Identifier: GPL-2.0+ | 6 | * SPDX-License-Identifier: GPL-2.0+ |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <config.h> | 9 | #include <config.h> |
10 | #include <common.h> | 10 | #include <common.h> |
11 | #include <div64.h> | 11 | #include <div64.h> |
12 | #include <fuse.h> | 12 | #include <fuse.h> |
13 | #include <asm/io.h> | 13 | #include <asm/io.h> |
14 | #include <asm/arch/clock.h> | 14 | #include <asm/arch/clock.h> |
15 | #include <dm.h> | 15 | #include <dm.h> |
16 | #include <errno.h> | 16 | #include <errno.h> |
17 | #include <malloc.h> | 17 | #include <malloc.h> |
18 | #include <thermal.h> | 18 | #include <thermal.h> |
19 | #include <imx_thermal.h> | 19 | #include <imx_thermal.h> |
20 | 20 | ||
21 | #define TEMPERATURE_MIN -40 | 21 | #define TEMPERATURE_MIN -40 |
22 | #define TEMPERATURE_HOT 80 | 22 | #define TEMPERATURE_HOT 80 |
23 | #define TEMPERATURE_MAX 125 | 23 | #define TEMPERATURE_MAX 125 |
24 | #define FACTOR0 10000000 | 24 | #define FACTOR0 10000000 |
25 | #define FACTOR1 15976 | 25 | #define FACTOR1 15976 |
26 | #define FACTOR2 4297157 | 26 | #define FACTOR2 4297157 |
27 | #define MEASURE_FREQ 327 | 27 | #define MEASURE_FREQ 327 |
28 | 28 | ||
29 | #define TEMPSENSE0_TEMP_CNT_SHIFT 8 | 29 | #define TEMPSENSE0_TEMP_CNT_SHIFT 8 |
30 | #define TEMPSENSE0_TEMP_CNT_MASK (0xfff << TEMPSENSE0_TEMP_CNT_SHIFT) | 30 | #define TEMPSENSE0_TEMP_CNT_MASK (0xfff << TEMPSENSE0_TEMP_CNT_SHIFT) |
31 | #define TEMPSENSE0_FINISHED (1 << 2) | 31 | #define TEMPSENSE0_FINISHED (1 << 2) |
32 | #define TEMPSENSE0_MEASURE_TEMP (1 << 1) | 32 | #define TEMPSENSE0_MEASURE_TEMP (1 << 1) |
33 | #define TEMPSENSE0_POWER_DOWN (1 << 0) | 33 | #define TEMPSENSE0_POWER_DOWN (1 << 0) |
34 | #define MISC0_REFTOP_SELBIASOFF (1 << 3) | 34 | #define MISC0_REFTOP_SELBIASOFF (1 << 3) |
35 | #define TEMPSENSE1_MEASURE_FREQ 0xffff | 35 | #define TEMPSENSE1_MEASURE_FREQ 0xffff |
36 | 36 | ||
37 | static int read_cpu_temperature(struct udevice *dev) | 37 | static int read_cpu_temperature(struct udevice *dev) |
38 | { | 38 | { |
39 | int temperature; | 39 | int temperature; |
40 | unsigned int reg, n_meas; | 40 | unsigned int reg, n_meas; |
41 | const struct imx_thermal_plat *pdata = dev_get_platdata(dev); | 41 | const struct imx_thermal_plat *pdata = dev_get_platdata(dev); |
42 | struct anatop_regs *anatop = (struct anatop_regs *)pdata->regs; | 42 | struct anatop_regs *anatop = (struct anatop_regs *)pdata->regs; |
43 | unsigned int *priv = dev_get_priv(dev); | 43 | unsigned int *priv = dev_get_priv(dev); |
44 | u32 fuse = *priv; | 44 | u32 fuse = *priv; |
45 | int t1, n1; | 45 | int t1, n1; |
46 | u32 c1, c2; | 46 | u32 c1, c2; |
47 | u64 temp64; | 47 | u64 temp64; |
48 | 48 | ||
49 | /* | 49 | /* |
50 | * Sensor data layout: | 50 | * Sensor data layout: |
51 | * [31:20] - sensor value @ 25C | 51 | * [31:20] - sensor value @ 25C |
52 | * We use universal formula now and only need sensor value @ 25C | 52 | * We use universal formula now and only need sensor value @ 25C |
53 | * slope = 0.4297157 - (0.0015976 * 25C fuse) | 53 | * slope = 0.4297157 - (0.0015976 * 25C fuse) |
54 | */ | 54 | */ |
55 | n1 = fuse >> 20; | 55 | n1 = fuse >> 20; |
56 | t1 = 25; /* t1 always 25C */ | 56 | t1 = 25; /* t1 always 25C */ |
57 | 57 | ||
58 | /* | 58 | /* |
59 | * Derived from linear interpolation: | 59 | * Derived from linear interpolation: |
60 | * slope = 0.4297157 - (0.0015976 * 25C fuse) | 60 | * slope = 0.4297157 - (0.0015976 * 25C fuse) |
61 | * slope = (FACTOR2 - FACTOR1 * n1) / FACTOR0 | 61 | * slope = (FACTOR2 - FACTOR1 * n1) / FACTOR0 |
62 | * (Nmeas - n1) / (Tmeas - t1) = slope | 62 | * (Nmeas - n1) / (Tmeas - t1) = slope |
63 | * We want to reduce this down to the minimum computation necessary | 63 | * We want to reduce this down to the minimum computation necessary |
64 | * for each temperature read. Also, we want Tmeas in millicelsius | 64 | * for each temperature read. Also, we want Tmeas in millicelsius |
65 | * and we don't want to lose precision from integer division. So... | 65 | * and we don't want to lose precision from integer division. So... |
66 | * Tmeas = (Nmeas - n1) / slope + t1 | 66 | * Tmeas = (Nmeas - n1) / slope + t1 |
67 | * milli_Tmeas = 1000 * (Nmeas - n1) / slope + 1000 * t1 | 67 | * milli_Tmeas = 1000 * (Nmeas - n1) / slope + 1000 * t1 |
68 | * milli_Tmeas = -1000 * (n1 - Nmeas) / slope + 1000 * t1 | 68 | * milli_Tmeas = -1000 * (n1 - Nmeas) / slope + 1000 * t1 |
69 | * Let constant c1 = (-1000 / slope) | 69 | * Let constant c1 = (-1000 / slope) |
70 | * milli_Tmeas = (n1 - Nmeas) * c1 + 1000 * t1 | 70 | * milli_Tmeas = (n1 - Nmeas) * c1 + 1000 * t1 |
71 | * Let constant c2 = n1 *c1 + 1000 * t1 | 71 | * Let constant c2 = n1 *c1 + 1000 * t1 |
72 | * milli_Tmeas = c2 - Nmeas * c1 | 72 | * milli_Tmeas = c2 - Nmeas * c1 |
73 | */ | 73 | */ |
74 | temp64 = FACTOR0; | 74 | temp64 = FACTOR0; |
75 | temp64 *= 1000; | 75 | temp64 *= 1000; |
76 | do_div(temp64, FACTOR1 * n1 - FACTOR2); | 76 | do_div(temp64, FACTOR1 * n1 - FACTOR2); |
77 | c1 = temp64; | 77 | c1 = temp64; |
78 | c2 = n1 * c1 + 1000 * t1; | 78 | c2 = n1 * c1 + 1000 * t1; |
79 | 79 | ||
80 | /* | 80 | /* |
81 | * now we only use single measure, every time we read | 81 | * now we only use single measure, every time we read |
82 | * the temperature, we will power on/down anadig thermal | 82 | * the temperature, we will power on/down anadig thermal |
83 | * module | 83 | * module |
84 | */ | 84 | */ |
85 | writel(TEMPSENSE0_POWER_DOWN, &anatop->tempsense0_clr); | 85 | writel(TEMPSENSE0_POWER_DOWN, &anatop->tempsense0_clr); |
86 | writel(MISC0_REFTOP_SELBIASOFF, &anatop->ana_misc0_set); | 86 | writel(MISC0_REFTOP_SELBIASOFF, &anatop->ana_misc0_set); |
87 | 87 | ||
88 | /* setup measure freq */ | 88 | /* setup measure freq */ |
89 | reg = readl(&anatop->tempsense1); | 89 | reg = readl(&anatop->tempsense1); |
90 | reg &= ~TEMPSENSE1_MEASURE_FREQ; | 90 | reg &= ~TEMPSENSE1_MEASURE_FREQ; |
91 | reg |= MEASURE_FREQ; | 91 | reg |= MEASURE_FREQ; |
92 | writel(reg, &anatop->tempsense1); | 92 | writel(reg, &anatop->tempsense1); |
93 | 93 | ||
94 | /* start the measurement process */ | 94 | /* start the measurement process */ |
95 | writel(TEMPSENSE0_MEASURE_TEMP, &anatop->tempsense0_clr); | 95 | writel(TEMPSENSE0_MEASURE_TEMP, &anatop->tempsense0_clr); |
96 | writel(TEMPSENSE0_FINISHED, &anatop->tempsense0_clr); | 96 | writel(TEMPSENSE0_FINISHED, &anatop->tempsense0_clr); |
97 | writel(TEMPSENSE0_MEASURE_TEMP, &anatop->tempsense0_set); | 97 | writel(TEMPSENSE0_MEASURE_TEMP, &anatop->tempsense0_set); |
98 | 98 | ||
99 | /* make sure that the latest temp is valid */ | 99 | /* make sure that the latest temp is valid */ |
100 | while ((readl(&anatop->tempsense0) & | 100 | while ((readl(&anatop->tempsense0) & |
101 | TEMPSENSE0_FINISHED) == 0) | 101 | TEMPSENSE0_FINISHED) == 0) |
102 | udelay(10000); | 102 | udelay(10000); |
103 | 103 | ||
104 | /* read temperature count */ | 104 | /* read temperature count */ |
105 | reg = readl(&anatop->tempsense0); | 105 | reg = readl(&anatop->tempsense0); |
106 | n_meas = (reg & TEMPSENSE0_TEMP_CNT_MASK) | 106 | n_meas = (reg & TEMPSENSE0_TEMP_CNT_MASK) |
107 | >> TEMPSENSE0_TEMP_CNT_SHIFT; | 107 | >> TEMPSENSE0_TEMP_CNT_SHIFT; |
108 | writel(TEMPSENSE0_FINISHED, &anatop->tempsense0_clr); | 108 | writel(TEMPSENSE0_FINISHED, &anatop->tempsense0_clr); |
109 | 109 | ||
110 | /* milli_Tmeas = c2 - Nmeas * c1 */ | 110 | /* milli_Tmeas = c2 - Nmeas * c1 */ |
111 | temperature = (c2 - n_meas * c1)/1000; | 111 | temperature = (c2 - n_meas * c1)/1000; |
112 | 112 | ||
113 | /* power down anatop thermal sensor */ | 113 | /* power down anatop thermal sensor */ |
114 | writel(TEMPSENSE0_POWER_DOWN, &anatop->tempsense0_set); | 114 | writel(TEMPSENSE0_POWER_DOWN, &anatop->tempsense0_set); |
115 | writel(MISC0_REFTOP_SELBIASOFF, &anatop->ana_misc0_clr); | 115 | writel(MISC0_REFTOP_SELBIASOFF, &anatop->ana_misc0_clr); |
116 | 116 | ||
117 | return temperature; | 117 | return temperature; |
118 | } | 118 | } |
119 | 119 | ||
120 | int imx_thermal_get_temp(struct udevice *dev, int *temp) | 120 | int imx_thermal_get_temp(struct udevice *dev, int *temp) |
121 | { | 121 | { |
122 | int cpu_tmp = 0; | 122 | int cpu_tmp = 0; |
123 | 123 | ||
124 | cpu_tmp = read_cpu_temperature(dev); | 124 | cpu_tmp = read_cpu_temperature(dev); |
125 | while (cpu_tmp > TEMPERATURE_MIN && cpu_tmp < TEMPERATURE_MAX) { | 125 | while (cpu_tmp > TEMPERATURE_MIN && cpu_tmp < TEMPERATURE_MAX) { |
126 | if (cpu_tmp >= TEMPERATURE_HOT) { | 126 | if (cpu_tmp >= TEMPERATURE_HOT) { |
127 | printf("CPU Temperature is %d C, too hot to boot, waiting...\n", | 127 | printf("CPU Temperature is %d C, too hot to boot, waiting...\n", |
128 | cpu_tmp); | 128 | cpu_tmp); |
129 | udelay(5000000); | 129 | udelay(5000000); |
130 | cpu_tmp = read_cpu_temperature(dev); | 130 | cpu_tmp = read_cpu_temperature(dev); |
131 | } else { | 131 | } else { |
132 | break; | 132 | break; |
133 | } | 133 | } |
134 | } | 134 | } |
135 | 135 | ||
136 | *temp = cpu_tmp; | 136 | *temp = cpu_tmp; |
137 | 137 | ||
138 | return 0; | 138 | return 0; |
139 | } | 139 | } |
140 | 140 | ||
141 | static const struct dm_thermal_ops imx_thermal_ops = { | 141 | static const struct dm_thermal_ops imx_thermal_ops = { |
142 | .get_temp = imx_thermal_get_temp, | 142 | .get_temp = imx_thermal_get_temp, |
143 | }; | 143 | }; |
144 | 144 | ||
145 | static int imx_thermal_probe(struct udevice *dev) | 145 | static int imx_thermal_probe(struct udevice *dev) |
146 | { | 146 | { |
147 | unsigned int fuse = ~0; | 147 | unsigned int fuse = ~0; |
148 | 148 | ||
149 | const struct imx_thermal_plat *pdata = dev_get_platdata(dev); | 149 | const struct imx_thermal_plat *pdata = dev_get_platdata(dev); |
150 | unsigned int *priv = dev_get_priv(dev); | 150 | unsigned int *priv = dev_get_priv(dev); |
151 | 151 | ||
152 | /* Read Temperature calibration data fuse */ | 152 | /* Read Temperature calibration data fuse */ |
153 | fuse_read(pdata->fuse_bank, pdata->fuse_word, &fuse); | 153 | fuse_read(pdata->fuse_bank, pdata->fuse_word, &fuse); |
154 | 154 | ||
155 | /* Check for valid fuse */ | 155 | /* Check for valid fuse */ |
156 | if (fuse == 0 || fuse == ~0) { | 156 | if (fuse == 0 || fuse == ~0) { |
157 | printf("CPU: Thermal invalid data, fuse: 0x%x\n", fuse); | 157 | printf("CPU: Thermal invalid data, fuse: 0x%x\n", fuse); |
158 | return -EPERM; | 158 | return -EPERM; |
159 | } else { | ||
160 | printf("CPU: Thermal calibration data: 0x%x\n", fuse); | ||
161 | } | 159 | } |
162 | 160 | ||
163 | *priv = fuse; | 161 | *priv = fuse; |
164 | 162 | ||
165 | enable_thermal_clk(); | 163 | enable_thermal_clk(); |
166 | 164 | ||
167 | return 0; | 165 | return 0; |
168 | } | 166 | } |
169 | 167 | ||
170 | U_BOOT_DRIVER(imx_thermal) = { | 168 | U_BOOT_DRIVER(imx_thermal) = { |
171 | .name = "imx_thermal", | 169 | .name = "imx_thermal", |
172 | .id = UCLASS_THERMAL, | 170 | .id = UCLASS_THERMAL, |
173 | .ops = &imx_thermal_ops, | 171 | .ops = &imx_thermal_ops, |
174 | .probe = imx_thermal_probe, | 172 | .probe = imx_thermal_probe, |
175 | .priv_auto_alloc_size = sizeof(unsigned int), | 173 | .priv_auto_alloc_size = sizeof(unsigned int), |
176 | .flags = DM_FLAG_PRE_RELOC, | 174 | .flags = DM_FLAG_PRE_RELOC, |
177 | }; | 175 | }; |
178 | 176 |