Lines Matching +full:reg +full:- +full:data

1 // SPDX-License-Identifier: GPL-2.0-only
72 struct armada_thermal_data *data; member
85 /* Formula coeficients: temp = (b - m * reg) / div */
122 } data; member
126 * struct armada_thermal_sensor - hold the information of one thermal sensor
139 struct armada_thermal_data *data = priv->data; in armadaxp_init() local
140 u32 reg; in armadaxp_init() local
142 regmap_read(priv->syscon, data->syscon_control1_off, &reg); in armadaxp_init()
143 reg |= PMU_TDC0_OTF_CAL_MASK; in armadaxp_init()
146 reg &= ~PMU_TDC0_REF_CAL_CNT_MASK; in armadaxp_init()
147 reg |= (0xf1 << PMU_TDC0_REF_CAL_CNT_OFFS); in armadaxp_init()
150 reg |= PMU_TDC0_SW_RST_MASK; in armadaxp_init()
152 regmap_write(priv->syscon, data->syscon_control1_off, reg); in armadaxp_init()
154 reg &= ~PMU_TDC0_SW_RST_MASK; in armadaxp_init()
155 regmap_write(priv->syscon, data->syscon_control1_off, reg); in armadaxp_init()
158 regmap_read(priv->syscon, data->syscon_status_off, &reg); in armadaxp_init()
159 reg &= ~PMU_TM_DISABLE_MASK; in armadaxp_init()
160 regmap_write(priv->syscon, data->syscon_status_off, reg); in armadaxp_init()
166 struct armada_thermal_data *data = priv->data; in armada370_init() local
167 u32 reg; in armada370_init() local
169 regmap_read(priv->syscon, data->syscon_control1_off, &reg); in armada370_init()
170 reg |= PMU_TDC0_OTF_CAL_MASK; in armada370_init()
173 reg &= ~PMU_TDC0_REF_CAL_CNT_MASK; in armada370_init()
174 reg |= (0xf1 << PMU_TDC0_REF_CAL_CNT_OFFS); in armada370_init()
177 reg &= ~PMU_TDC0_START_CAL_MASK; in armada370_init()
179 regmap_write(priv->syscon, data->syscon_control1_off, reg); in armada370_init()
187 struct armada_thermal_data *data = priv->data; in armada375_init() local
188 u32 reg; in armada375_init() local
190 regmap_read(priv->syscon, data->syscon_control1_off, &reg); in armada375_init()
191 reg &= ~(A375_UNIT_CONTROL_MASK << A375_UNIT_CONTROL_SHIFT); in armada375_init()
192 reg &= ~A375_READOUT_INVERT; in armada375_init()
193 reg &= ~A375_HW_RESETn; in armada375_init()
194 regmap_write(priv->syscon, data->syscon_control1_off, reg); in armada375_init()
198 reg |= A375_HW_RESETn; in armada375_init()
199 regmap_write(priv->syscon, data->syscon_control1_off, reg); in armada375_init()
206 u32 reg; in armada_wait_sensor_validity() local
208 return regmap_read_poll_timeout(priv->syscon, in armada_wait_sensor_validity()
209 priv->data->syscon_status_off, reg, in armada_wait_sensor_validity()
210 reg & priv->data->is_valid_bit, in armada_wait_sensor_validity()
218 struct armada_thermal_data *data = priv->data; in armada380_init() local
219 u32 reg; in armada380_init() local
222 regmap_read(priv->syscon, data->syscon_control1_off, &reg); in armada380_init()
223 reg |= CONTROL1_EXT_TSEN_HW_RESETn; in armada380_init()
224 reg &= ~CONTROL1_EXT_TSEN_SW_RESET; in armada380_init()
225 regmap_write(priv->syscon, data->syscon_control1_off, reg); in armada380_init()
228 regmap_read(priv->syscon, data->syscon_control0_off, &reg); in armada380_init()
229 reg &= ~CONTROL0_TSEN_TC_TRIM_MASK; in armada380_init()
230 reg |= CONTROL0_TSEN_TC_TRIM_VAL; in armada380_init()
231 regmap_write(priv->syscon, data->syscon_control0_off, reg); in armada380_init()
237 struct armada_thermal_data *data = priv->data; in armada_ap80x_init() local
238 u32 reg; in armada_ap80x_init() local
240 regmap_read(priv->syscon, data->syscon_control0_off, &reg); in armada_ap80x_init()
241 reg &= ~CONTROL0_TSEN_RESET; in armada_ap80x_init()
242 reg |= CONTROL0_TSEN_START | CONTROL0_TSEN_ENABLE; in armada_ap80x_init()
245 reg |= CONTROL0_TSEN_OSR_MAX << CONTROL0_TSEN_OSR_SHIFT; in armada_ap80x_init()
248 reg &= ~CONTROL0_TSEN_AVG_BYPASS; in armada_ap80x_init()
250 regmap_write(priv->syscon, data->syscon_control0_off, reg); in armada_ap80x_init()
256 struct armada_thermal_data *data = priv->data; in armada_cp110_init() local
257 u32 reg; in armada_cp110_init() local
262 regmap_read(priv->syscon, data->syscon_control0_off, &reg); in armada_cp110_init()
263 reg |= CONTROL0_TSEN_OSR_MAX << CONTROL0_TSEN_OSR_SHIFT; in armada_cp110_init()
264 regmap_write(priv->syscon, data->syscon_control0_off, reg); in armada_cp110_init()
267 regmap_read(priv->syscon, data->syscon_control1_off, &reg); in armada_cp110_init()
268 reg &= ~CONTROL1_TSEN_AVG_MASK; in armada_cp110_init()
269 reg |= 1; in armada_cp110_init()
270 regmap_write(priv->syscon, data->syscon_control1_off, reg); in armada_cp110_init()
275 u32 reg; in armada_is_valid() local
277 if (!priv->data->is_valid_bit) in armada_is_valid()
280 regmap_read(priv->syscon, priv->data->syscon_status_off, &reg); in armada_is_valid()
282 return reg & priv->data->is_valid_bit; in armada_is_valid()
287 struct armada_thermal_data *data = priv->data; in armada_enable_overheat_interrupt() local
288 u32 reg; in armada_enable_overheat_interrupt() local
291 regmap_read(priv->syscon, data->dfx_irq_cause_off, &reg); in armada_enable_overheat_interrupt()
294 regmap_read(priv->syscon, data->dfx_irq_mask_off, &reg); in armada_enable_overheat_interrupt()
295 reg |= data->dfx_overheat_irq; in armada_enable_overheat_interrupt()
296 regmap_write(priv->syscon, data->dfx_irq_mask_off, reg); in armada_enable_overheat_interrupt()
299 regmap_read(priv->syscon, data->dfx_server_irq_mask_off, &reg); in armada_enable_overheat_interrupt()
300 reg |= data->dfx_server_irq_en; in armada_enable_overheat_interrupt()
301 regmap_write(priv->syscon, data->dfx_server_irq_mask_off, reg); in armada_enable_overheat_interrupt()
304 regmap_read(priv->syscon, data->syscon_control1_off, &reg); in armada_enable_overheat_interrupt()
305 reg |= CONTROL1_TSEN_INT_EN; in armada_enable_overheat_interrupt()
306 regmap_write(priv->syscon, data->syscon_control1_off, reg); in armada_enable_overheat_interrupt()
312 struct armada_thermal_data *data = priv->data; in armada_disable_overheat_interrupt() local
313 u32 reg; in armada_disable_overheat_interrupt() local
315 regmap_read(priv->syscon, data->syscon_control1_off, &reg); in armada_disable_overheat_interrupt()
316 reg &= ~CONTROL1_TSEN_INT_EN; in armada_disable_overheat_interrupt()
317 regmap_write(priv->syscon, data->syscon_control1_off, reg); in armada_disable_overheat_interrupt()
323 struct armada_thermal_data *data = priv->data; in armada_select_channel() local
326 if (channel < 0 || channel > priv->data->cpu_nr) in armada_select_channel()
327 return -EINVAL; in armada_select_channel()
329 if (priv->current_channel == channel) in armada_select_channel()
333 regmap_read(priv->syscon, data->syscon_control0_off, &ctrl0); in armada_select_channel()
335 regmap_write(priv->syscon, data->syscon_control0_off, ctrl0); in armada_select_channel()
347 ctrl0 |= (channel - 1) << CONTROL0_TSEN_CHAN_SHIFT; in armada_select_channel()
351 regmap_write(priv->syscon, data->syscon_control0_off, ctrl0); in armada_select_channel()
352 priv->current_channel = channel; in armada_select_channel()
354 /* Re-start the measurements */ in armada_select_channel()
356 regmap_write(priv->syscon, data->syscon_control0_off, ctrl0); in armada_select_channel()
361 * actual data. in armada_select_channel()
364 return -EIO; in armada_select_channel()
371 u32 reg, div; in armada_read_sensor() local
374 regmap_read(priv->syscon, priv->data->syscon_status_off, &reg); in armada_read_sensor()
375 reg = (reg >> priv->data->temp_shift) & priv->data->temp_mask; in armada_read_sensor()
376 if (priv->data->signed_sample) in armada_read_sensor()
378 sample = sign_extend32(reg, fls(priv->data->temp_mask) - 1); in armada_read_sensor()
380 sample = reg; in armada_read_sensor()
383 b = priv->data->coef_b; in armada_read_sensor()
384 m = priv->data->coef_m; in armada_read_sensor()
385 div = priv->data->coef_div; in armada_read_sensor()
387 if (priv->data->inverted) in armada_read_sensor()
388 *temp = div_s64((m * sample) - b, div); in armada_read_sensor()
390 *temp = div_s64(b - (m * sample), div); in armada_read_sensor()
403 return -EIO; in armada_get_temp_legacy()
418 struct armada_thermal_priv *priv = sensor->priv; in armada_get_temp()
421 mutex_lock(&priv->update_lock); in armada_get_temp()
424 ret = armada_select_channel(priv, sensor->id); in armada_get_temp()
437 ret = armada_select_channel(priv, priv->interrupt_source); in armada_get_temp()
440 mutex_unlock(&priv->update_lock); in armada_get_temp()
449 static unsigned int armada_mc_to_reg_temp(struct armada_thermal_data *data, in armada_mc_to_reg_temp() argument
452 s64 b = data->coef_b; in armada_mc_to_reg_temp()
453 s64 m = data->coef_m; in armada_mc_to_reg_temp()
454 s64 div = data->coef_div; in armada_mc_to_reg_temp()
457 if (data->inverted) in armada_mc_to_reg_temp()
460 sample = div_s64((b - (temp_mc * div)), m); in armada_mc_to_reg_temp()
462 return sample & data->temp_mask; in armada_mc_to_reg_temp()
467 * high/low watermark = threshold +/- 0.4761 * 2^(hysteresis + 2)
473 static unsigned int armada_mc_to_reg_hyst(struct armada_thermal_data *data, in armada_mc_to_reg_hyst() argument
483 for (i = ARRAY_SIZE(hyst_levels_mc) - 1; i > 0; i--) in armada_mc_to_reg_hyst()
487 return i & data->hyst_mask; in armada_mc_to_reg_hyst()
493 struct armada_thermal_data *data = priv->data; in armada_set_overheat_thresholds() local
494 unsigned int threshold = armada_mc_to_reg_temp(data, thresh_mc); in armada_set_overheat_thresholds()
495 unsigned int hysteresis = armada_mc_to_reg_hyst(data, hyst_mc); in armada_set_overheat_thresholds()
498 regmap_read(priv->syscon, data->syscon_control1_off, &ctrl1); in armada_set_overheat_thresholds()
502 ctrl1 &= ~(data->temp_mask << data->thresh_shift); in armada_set_overheat_thresholds()
503 ctrl1 |= threshold << data->thresh_shift; in armada_set_overheat_thresholds()
504 priv->current_threshold = thresh_mc; in armada_set_overheat_thresholds()
509 ctrl1 &= ~(data->hyst_mask << data->hyst_shift); in armada_set_overheat_thresholds()
510 ctrl1 |= hysteresis << data->hyst_shift; in armada_set_overheat_thresholds()
511 priv->current_hysteresis = hyst_mc; in armada_set_overheat_thresholds()
514 regmap_write(priv->syscon, data->syscon_control1_off, ctrl1); in armada_set_overheat_thresholds()
531 int low_threshold = priv->current_threshold - priv->current_hysteresis; in armada_overheat_isr_thread()
537 thermal_zone_device_update(priv->overheat_sensor, in armada_overheat_isr_thread()
547 mutex_lock(&priv->update_lock); in armada_overheat_isr_thread()
549 mutex_unlock(&priv->update_lock); in armada_overheat_isr_thread()
554 regmap_read(priv->syscon, priv->data->dfx_irq_cause_off, &dummy); in armada_overheat_isr_thread()
557 thermal_zone_device_update(priv->overheat_sensor, in armada_overheat_isr_thread()
624 .coef_b = -150000LL,
648 .coef_b = -128900LL,
688 .compatible = "marvell,armadaxp-thermal",
689 .data = &armadaxp_data,
692 .compatible = "marvell,armada370-thermal",
693 .data = &armada370_data,
696 .compatible = "marvell,armada375-thermal",
697 .data = &armada375_data,
700 .compatible = "marvell,armada380-thermal",
701 .data = &armada380_data,
704 .compatible = "marvell,armada-ap806-thermal",
705 .data = &armada_ap806_data,
708 .compatible = "marvell,armada-ap807-thermal",
709 .data = &armada_ap807_data,
712 .compatible = "marvell,armada-cp110-thermal",
713 .data = &armada_cp110_data,
731 struct armada_thermal_data *data = priv->data; in armada_thermal_probe_legacy() local
746 if (((unsigned long)base & ~PAGE_MASK) < data->syscon_status_off) in armada_thermal_probe_legacy()
747 return -EINVAL; in armada_thermal_probe_legacy()
748 base -= data->syscon_status_off; in armada_thermal_probe_legacy()
750 priv->syscon = devm_regmap_init_mmio(&pdev->dev, base, in armada_thermal_probe_legacy()
752 return PTR_ERR_OR_ZERO(priv->syscon); in armada_thermal_probe_legacy()
758 priv->syscon = syscon_node_to_regmap(pdev->dev.parent->of_node); in armada_thermal_probe_syscon()
759 return PTR_ERR_OR_ZERO(priv->syscon); in armada_thermal_probe_syscon()
765 const char *name = dev_name(&pdev->dev); in armada_set_sane_name()
771 * form: f06f8000.system-controller:ap-thermal so stripping in armada_set_sane_name()
782 strscpy(priv->zone_name, name, THERMAL_NAME_LENGTH); in armada_set_sane_name()
784 /* Then check there are no '-' or hwmon core will complain */ in armada_set_sane_name()
786 insane_char = strpbrk(priv->zone_name, "-"); in armada_set_sane_name()
820 priv->overheat_sensor = tz; in armada_configure_overheat_int()
821 priv->interrupt_source = sensor_id; in armada_configure_overheat_int()
837 match = of_match_device(armada_thermal_id_table, &pdev->dev); in armada_thermal_probe()
839 return -ENODEV; in armada_thermal_probe()
841 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); in armada_thermal_probe()
843 return -ENOMEM; in armada_thermal_probe()
845 drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); in armada_thermal_probe()
847 return -ENOMEM; in armada_thermal_probe()
849 priv->dev = &pdev->dev; in armada_thermal_probe()
850 priv->data = (struct armada_thermal_data *)match->data; in armada_thermal_probe()
852 mutex_init(&priv->update_lock); in armada_thermal_probe()
866 if (IS_ERR(syscon_node_to_regmap(pdev->dev.parent->of_node))) { in armada_thermal_probe()
874 priv->data->init(pdev, priv); in armada_thermal_probe()
879 tz = thermal_tripless_zone_device_register(priv->zone_name, in armada_thermal_probe()
883 dev_err(&pdev->dev, in armada_thermal_probe()
894 drvdata->type = LEGACY; in armada_thermal_probe()
895 drvdata->data.tz = tz; in armada_thermal_probe()
905 priv->current_channel = -1; in armada_thermal_probe()
906 priv->data->init(pdev, priv); in armada_thermal_probe()
907 drvdata->type = SYSCON; in armada_thermal_probe()
908 drvdata->data.priv = priv; in armada_thermal_probe()
912 if (irq == -EPROBE_DEFER) in armada_thermal_probe()
917 ret = devm_request_threaded_irq(&pdev->dev, irq, in armada_thermal_probe()
922 dev_err(&pdev->dev, "Cannot request threaded IRQ %d\n", in armada_thermal_probe()
932 for (sensor_id = 0; sensor_id <= priv->data->cpu_nr; sensor_id++) { in armada_thermal_probe()
933 sensor = devm_kzalloc(&pdev->dev, in armada_thermal_probe()
937 return -ENOMEM; in armada_thermal_probe()
940 sensor->priv = priv; in armada_thermal_probe()
941 sensor->id = sensor_id; in armada_thermal_probe()
942 tz = devm_thermal_of_zone_register(&pdev->dev, in armada_thermal_probe()
943 sensor->id, sensor, in armada_thermal_probe()
946 dev_info(&pdev->dev, "Thermal sensor %d unavailable\n", in armada_thermal_probe()
948 devm_kfree(&pdev->dev, sensor); in armada_thermal_probe()
957 if (irq > 0 && !priv->overheat_sensor) in armada_thermal_probe()
958 armada_configure_overheat_int(priv, tz, sensor->id); in armada_thermal_probe()
962 if (!priv->overheat_sensor) in armada_thermal_probe()
963 dev_warn(&pdev->dev, "Overheat interrupt not available\n"); in armada_thermal_probe()
972 if (drvdata->type == LEGACY) in armada_thermal_exit()
973 thermal_zone_device_unregister(drvdata->data.tz); in armada_thermal_exit()
989 MODULE_AUTHOR("Ezequiel Garcia <ezequiel.garcia@free-electrons.com>");