diff options
Diffstat (limited to 'drivers/thermal/armada_thermal.c')
-rw-r--r-- | drivers/thermal/armada_thermal.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c index f84d9f077fe2..e65c5e442ed5 100644 --- a/drivers/thermal/armada_thermal.c +++ b/drivers/thermal/armada_thermal.c | |||
@@ -35,6 +35,15 @@ | |||
35 | #define PMU_TDC0_OTF_CAL_MASK (0x1 << 30) | 35 | #define PMU_TDC0_OTF_CAL_MASK (0x1 << 30) |
36 | #define PMU_TDC0_START_CAL_MASK (0x1 << 25) | 36 | #define PMU_TDC0_START_CAL_MASK (0x1 << 25) |
37 | 37 | ||
38 | #define A375_Z1_CAL_RESET_LSB 0x8011e214 | ||
39 | #define A375_Z1_CAL_RESET_MSB 0x30a88019 | ||
40 | #define A375_Z1_WORKAROUND_BIT BIT(9) | ||
41 | |||
42 | #define A375_UNIT_CONTROL_SHIFT 27 | ||
43 | #define A375_UNIT_CONTROL_MASK 0x7 | ||
44 | #define A375_READOUT_INVERT BIT(15) | ||
45 | #define A375_HW_RESETn BIT(8) | ||
46 | |||
38 | struct armada_thermal_data; | 47 | struct armada_thermal_data; |
39 | 48 | ||
40 | /* Marvell EBU Thermal Sensor Dev Structure */ | 49 | /* Marvell EBU Thermal Sensor Dev Structure */ |
@@ -110,6 +119,36 @@ static void armada370_init_sensor(struct platform_device *pdev, | |||
110 | mdelay(10); | 119 | mdelay(10); |
111 | } | 120 | } |
112 | 121 | ||
122 | static void armada375_init_sensor(struct platform_device *pdev, | ||
123 | struct armada_thermal_priv *priv) | ||
124 | { | ||
125 | unsigned long reg; | ||
126 | bool quirk_needed = | ||
127 | !!of_device_is_compatible(pdev->dev.of_node, | ||
128 | "marvell,armada375-z1-thermal"); | ||
129 | |||
130 | if (quirk_needed) { | ||
131 | /* Ensure these registers have the default (reset) values */ | ||
132 | writel(A375_Z1_CAL_RESET_LSB, priv->control); | ||
133 | writel(A375_Z1_CAL_RESET_MSB, priv->control + 0x4); | ||
134 | } | ||
135 | |||
136 | reg = readl(priv->control + 4); | ||
137 | reg &= ~(A375_UNIT_CONTROL_MASK << A375_UNIT_CONTROL_SHIFT); | ||
138 | reg &= ~A375_READOUT_INVERT; | ||
139 | reg &= ~A375_HW_RESETn; | ||
140 | |||
141 | if (quirk_needed) | ||
142 | reg |= A375_Z1_WORKAROUND_BIT; | ||
143 | |||
144 | writel(reg, priv->control + 4); | ||
145 | mdelay(20); | ||
146 | |||
147 | reg |= A375_HW_RESETn; | ||
148 | writel(reg, priv->control + 4); | ||
149 | mdelay(50); | ||
150 | } | ||
151 | |||
113 | static bool armada_is_valid(struct armada_thermal_priv *priv) | 152 | static bool armada_is_valid(struct armada_thermal_priv *priv) |
114 | { | 153 | { |
115 | unsigned long reg = readl_relaxed(priv->sensor); | 154 | unsigned long reg = readl_relaxed(priv->sensor); |
@@ -170,6 +209,17 @@ static const struct armada_thermal_data armada370_data = { | |||
170 | .coef_div = 13825, | 209 | .coef_div = 13825, |
171 | }; | 210 | }; |
172 | 211 | ||
212 | static const struct armada_thermal_data armada375_data = { | ||
213 | .is_valid = armada_is_valid, | ||
214 | .init_sensor = armada375_init_sensor, | ||
215 | .is_valid_shift = 10, | ||
216 | .temp_shift = 0, | ||
217 | .temp_mask = 0x1ff, | ||
218 | .coef_b = 3171900000UL, | ||
219 | .coef_m = 10000000UL, | ||
220 | .coef_div = 13616, | ||
221 | }; | ||
222 | |||
173 | static const struct of_device_id armada_thermal_id_table[] = { | 223 | static const struct of_device_id armada_thermal_id_table[] = { |
174 | { | 224 | { |
175 | .compatible = "marvell,armadaxp-thermal", | 225 | .compatible = "marvell,armadaxp-thermal", |
@@ -180,6 +230,14 @@ static const struct of_device_id armada_thermal_id_table[] = { | |||
180 | .data = &armada370_data, | 230 | .data = &armada370_data, |
181 | }, | 231 | }, |
182 | { | 232 | { |
233 | .compatible = "marvell,armada375-thermal", | ||
234 | .data = &armada375_data, | ||
235 | }, | ||
236 | { | ||
237 | .compatible = "marvell,armada375-z1-thermal", | ||
238 | .data = &armada375_data, | ||
239 | }, | ||
240 | { | ||
183 | /* sentinel */ | 241 | /* sentinel */ |
184 | }, | 242 | }, |
185 | }; | 243 | }; |