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

1 // SPDX-License-Identifier: GPL-2.0-only
74 struct armada_thermal_data *data; member
87 /* Formula coeficients: temp = (b - m * reg) / div */
124 } data; member
128 * struct armada_thermal_sensor - hold the information of one thermal sensor
141 struct armada_thermal_data *data = priv->data; in armadaxp_init() local
142 u32 reg; in armadaxp_init() local
144 regmap_read(priv->syscon, data->syscon_control1_off, &reg); in armadaxp_init()
145 reg |= PMU_TDC0_OTF_CAL_MASK; in armadaxp_init()
148 reg &= ~PMU_TDC0_REF_CAL_CNT_MASK; in armadaxp_init()
149 reg |= (0xf1 << PMU_TDC0_REF_CAL_CNT_OFFS); in armadaxp_init()
152 reg |= PMU_TDC0_SW_RST_MASK; in armadaxp_init()
154 regmap_write(priv->syscon, data->syscon_control1_off, reg); in armadaxp_init()
156 reg &= ~PMU_TDC0_SW_RST_MASK; in armadaxp_init()
157 regmap_write(priv->syscon, data->syscon_control1_off, reg); in armadaxp_init()
160 regmap_read(priv->syscon, data->syscon_status_off, &reg); in armadaxp_init()
161 reg &= ~PMU_TM_DISABLE_MASK; in armadaxp_init()
162 regmap_write(priv->syscon, data->syscon_status_off, reg); in armadaxp_init()
168 struct armada_thermal_data *data = priv->data; in armada370_init() local
169 u32 reg; in armada370_init() local
171 regmap_read(priv->syscon, data->syscon_control1_off, &reg); in armada370_init()
172 reg |= PMU_TDC0_OTF_CAL_MASK; in armada370_init()
175 reg &= ~PMU_TDC0_REF_CAL_CNT_MASK; in armada370_init()
176 reg |= (0xf1 << PMU_TDC0_REF_CAL_CNT_OFFS); in armada370_init()
179 reg &= ~PMU_TDC0_START_CAL_MASK; in armada370_init()
181 regmap_write(priv->syscon, data->syscon_control1_off, reg); in armada370_init()
189 struct armada_thermal_data *data = priv->data; in armada375_init() local
190 u32 reg; in armada375_init() local
192 regmap_read(priv->syscon, data->syscon_control1_off, &reg); in armada375_init()
193 reg &= ~(A375_UNIT_CONTROL_MASK << A375_UNIT_CONTROL_SHIFT); in armada375_init()
194 reg &= ~A375_READOUT_INVERT; in armada375_init()
195 reg &= ~A375_HW_RESETn; in armada375_init()
196 regmap_write(priv->syscon, data->syscon_control1_off, reg); in armada375_init()
200 reg |= A375_HW_RESETn; in armada375_init()
201 regmap_write(priv->syscon, data->syscon_control1_off, reg); in armada375_init()
208 u32 reg; in armada_wait_sensor_validity() local
210 return regmap_read_poll_timeout(priv->syscon, in armada_wait_sensor_validity()
211 priv->data->syscon_status_off, reg, in armada_wait_sensor_validity()
212 reg & priv->data->is_valid_bit, in armada_wait_sensor_validity()
220 struct armada_thermal_data *data = priv->data; in armada380_init() local
221 u32 reg; in armada380_init() local
224 regmap_read(priv->syscon, data->syscon_control1_off, &reg); in armada380_init()
225 reg |= CONTROL1_EXT_TSEN_HW_RESETn; in armada380_init()
226 reg &= ~CONTROL1_EXT_TSEN_SW_RESET; in armada380_init()
227 regmap_write(priv->syscon, data->syscon_control1_off, reg); in armada380_init()
230 regmap_read(priv->syscon, data->syscon_control0_off, &reg); in armada380_init()
231 reg &= ~CONTROL0_TSEN_TC_TRIM_MASK; in armada380_init()
232 reg |= CONTROL0_TSEN_TC_TRIM_VAL; in armada380_init()
233 regmap_write(priv->syscon, data->syscon_control0_off, reg); in armada380_init()
239 struct armada_thermal_data *data = priv->data; in armada_ap806_init() local
240 u32 reg; in armada_ap806_init() local
242 regmap_read(priv->syscon, data->syscon_control0_off, &reg); in armada_ap806_init()
243 reg &= ~CONTROL0_TSEN_RESET; in armada_ap806_init()
244 reg |= CONTROL0_TSEN_START | CONTROL0_TSEN_ENABLE; in armada_ap806_init()
247 reg |= CONTROL0_TSEN_OSR_MAX << CONTROL0_TSEN_OSR_SHIFT; in armada_ap806_init()
250 reg &= ~CONTROL0_TSEN_AVG_BYPASS; in armada_ap806_init()
252 regmap_write(priv->syscon, data->syscon_control0_off, reg); in armada_ap806_init()
258 struct armada_thermal_data *data = priv->data; in armada_cp110_init() local
259 u32 reg; in armada_cp110_init() local
264 regmap_read(priv->syscon, data->syscon_control0_off, &reg); in armada_cp110_init()
265 reg |= CONTROL0_TSEN_OSR_MAX << CONTROL0_TSEN_OSR_SHIFT; in armada_cp110_init()
266 regmap_write(priv->syscon, data->syscon_control0_off, reg); in armada_cp110_init()
269 regmap_read(priv->syscon, data->syscon_control1_off, &reg); in armada_cp110_init()
270 reg &= ~CONTROL1_TSEN_AVG_MASK; in armada_cp110_init()
271 reg |= 1; in armada_cp110_init()
272 regmap_write(priv->syscon, data->syscon_control1_off, reg); in armada_cp110_init()
277 u32 reg; in armada_is_valid() local
279 if (!priv->data->is_valid_bit) in armada_is_valid()
282 regmap_read(priv->syscon, priv->data->syscon_status_off, &reg); in armada_is_valid()
284 return reg & priv->data->is_valid_bit; in armada_is_valid()
289 struct armada_thermal_data *data = priv->data; in armada_enable_overheat_interrupt() local
290 u32 reg; in armada_enable_overheat_interrupt() local
293 regmap_read(priv->syscon, data->dfx_irq_cause_off, &reg); in armada_enable_overheat_interrupt()
296 regmap_read(priv->syscon, data->dfx_irq_mask_off, &reg); in armada_enable_overheat_interrupt()
297 reg |= data->dfx_overheat_irq; in armada_enable_overheat_interrupt()
298 regmap_write(priv->syscon, data->dfx_irq_mask_off, reg); in armada_enable_overheat_interrupt()
301 regmap_read(priv->syscon, data->dfx_server_irq_mask_off, &reg); in armada_enable_overheat_interrupt()
302 reg |= data->dfx_server_irq_en; in armada_enable_overheat_interrupt()
303 regmap_write(priv->syscon, data->dfx_server_irq_mask_off, reg); in armada_enable_overheat_interrupt()
306 regmap_read(priv->syscon, data->syscon_control1_off, &reg); in armada_enable_overheat_interrupt()
307 reg |= CONTROL1_TSEN_INT_EN; in armada_enable_overheat_interrupt()
308 regmap_write(priv->syscon, data->syscon_control1_off, reg); in armada_enable_overheat_interrupt()
314 struct armada_thermal_data *data = priv->data; in armada_disable_overheat_interrupt() local
315 u32 reg; in armada_disable_overheat_interrupt() local
317 regmap_read(priv->syscon, data->syscon_control1_off, &reg); in armada_disable_overheat_interrupt()
318 reg &= ~CONTROL1_TSEN_INT_EN; in armada_disable_overheat_interrupt()
319 regmap_write(priv->syscon, data->syscon_control1_off, reg); in armada_disable_overheat_interrupt()
325 struct armada_thermal_data *data = priv->data; in armada_select_channel() local
328 if (channel < 0 || channel > priv->data->cpu_nr) in armada_select_channel()
329 return -EINVAL; in armada_select_channel()
331 if (priv->current_channel == channel) in armada_select_channel()
335 regmap_read(priv->syscon, data->syscon_control0_off, &ctrl0); in armada_select_channel()
337 regmap_write(priv->syscon, data->syscon_control0_off, ctrl0); in armada_select_channel()
349 ctrl0 |= (channel - 1) << CONTROL0_TSEN_CHAN_SHIFT; in armada_select_channel()
353 regmap_write(priv->syscon, data->syscon_control0_off, ctrl0); in armada_select_channel()
354 priv->current_channel = channel; in armada_select_channel()
356 /* Re-start the measurements */ in armada_select_channel()
358 regmap_write(priv->syscon, data->syscon_control0_off, ctrl0); in armada_select_channel()
363 * actual data. in armada_select_channel()
366 dev_err(priv->dev, in armada_select_channel()
368 return -EIO; in armada_select_channel()
376 u32 reg, div; in armada_read_sensor() local
379 regmap_read(priv->syscon, priv->data->syscon_status_off, &reg); in armada_read_sensor()
380 reg = (reg >> priv->data->temp_shift) & priv->data->temp_mask; in armada_read_sensor()
381 if (priv->data->signed_sample) in armada_read_sensor()
383 sample = sign_extend32(reg, fls(priv->data->temp_mask) - 1); in armada_read_sensor()
385 sample = reg; in armada_read_sensor()
388 b = priv->data->coef_b; in armada_read_sensor()
389 m = priv->data->coef_m; in armada_read_sensor()
390 div = priv->data->coef_div; in armada_read_sensor()
392 if (priv->data->inverted) in armada_read_sensor()
393 *temp = div_s64((m * sample) - b, div); in armada_read_sensor()
395 *temp = div_s64(b - (m * sample), div); in armada_read_sensor()
403 struct armada_thermal_priv *priv = thermal->devdata; in armada_get_temp_legacy()
408 dev_err(priv->dev, in armada_get_temp_legacy()
410 return -EIO; in armada_get_temp_legacy()
425 struct armada_thermal_sensor *sensor = tz->devdata; in armada_get_temp()
426 struct armada_thermal_priv *priv = sensor->priv; in armada_get_temp()
429 mutex_lock(&priv->update_lock); in armada_get_temp()
432 ret = armada_select_channel(priv, sensor->id); in armada_get_temp()
445 ret = armada_select_channel(priv, priv->interrupt_source); in armada_get_temp()
448 mutex_unlock(&priv->update_lock); in armada_get_temp()
457 static unsigned int armada_mc_to_reg_temp(struct armada_thermal_data *data, in armada_mc_to_reg_temp() argument
460 s64 b = data->coef_b; in armada_mc_to_reg_temp()
461 s64 m = data->coef_m; in armada_mc_to_reg_temp()
462 s64 div = data->coef_div; in armada_mc_to_reg_temp()
465 if (data->inverted) in armada_mc_to_reg_temp()
468 sample = div_s64((b - (temp_mc * div)), m); in armada_mc_to_reg_temp()
470 return sample & data->temp_mask; in armada_mc_to_reg_temp()
475 * high/low watermark = threshold +/- 0.4761 * 2^(hysteresis + 2)
481 static unsigned int armada_mc_to_reg_hyst(struct armada_thermal_data *data, in armada_mc_to_reg_hyst() argument
491 for (i = ARRAY_SIZE(hyst_levels_mc) - 1; i > 0; i--) in armada_mc_to_reg_hyst()
495 return i & data->hyst_mask; in armada_mc_to_reg_hyst()
501 struct armada_thermal_data *data = priv->data; in armada_set_overheat_thresholds() local
502 unsigned int threshold = armada_mc_to_reg_temp(data, thresh_mc); in armada_set_overheat_thresholds()
503 unsigned int hysteresis = armada_mc_to_reg_hyst(data, hyst_mc); in armada_set_overheat_thresholds()
506 regmap_read(priv->syscon, data->syscon_control1_off, &ctrl1); in armada_set_overheat_thresholds()
510 ctrl1 &= ~(data->temp_mask << data->thresh_shift); in armada_set_overheat_thresholds()
511 ctrl1 |= threshold << data->thresh_shift; in armada_set_overheat_thresholds()
512 priv->current_threshold = thresh_mc; in armada_set_overheat_thresholds()
517 ctrl1 &= ~(data->hyst_mask << data->hyst_shift); in armada_set_overheat_thresholds()
518 ctrl1 |= hysteresis << data->hyst_shift; in armada_set_overheat_thresholds()
519 priv->current_hysteresis = hyst_mc; in armada_set_overheat_thresholds()
522 regmap_write(priv->syscon, data->syscon_control1_off, ctrl1); in armada_set_overheat_thresholds()
539 int low_threshold = priv->current_threshold - priv->current_hysteresis; in armada_overheat_isr_thread()
545 thermal_zone_device_update(priv->overheat_sensor, in armada_overheat_isr_thread()
555 mutex_lock(&priv->update_lock); in armada_overheat_isr_thread()
557 mutex_unlock(&priv->update_lock); in armada_overheat_isr_thread()
562 regmap_read(priv->syscon, priv->data->dfx_irq_cause_off, &dummy); in armada_overheat_isr_thread()
565 thermal_zone_device_update(priv->overheat_sensor, in armada_overheat_isr_thread()
632 .coef_b = -150000LL,
672 .compatible = "marvell,armadaxp-thermal",
673 .data = &armadaxp_data,
676 .compatible = "marvell,armada370-thermal",
677 .data = &armada370_data,
680 .compatible = "marvell,armada375-thermal",
681 .data = &armada375_data,
684 .compatible = "marvell,armada380-thermal",
685 .data = &armada380_data,
688 .compatible = "marvell,armada-ap806-thermal",
689 .data = &armada_ap806_data,
692 .compatible = "marvell,armada-cp110-thermal",
693 .data = &armada_cp110_data,
711 struct armada_thermal_data *data = priv->data; in armada_thermal_probe_legacy() local
717 base = devm_ioremap_resource(&pdev->dev, res); in armada_thermal_probe_legacy()
728 if (((unsigned long)base & ~PAGE_MASK) < data->syscon_status_off) in armada_thermal_probe_legacy()
729 return -EINVAL; in armada_thermal_probe_legacy()
730 base -= data->syscon_status_off; in armada_thermal_probe_legacy()
732 priv->syscon = devm_regmap_init_mmio(&pdev->dev, base, in armada_thermal_probe_legacy()
734 return PTR_ERR_OR_ZERO(priv->syscon); in armada_thermal_probe_legacy()
740 priv->syscon = syscon_node_to_regmap(pdev->dev.parent->of_node); in armada_thermal_probe_syscon()
741 return PTR_ERR_OR_ZERO(priv->syscon); in armada_thermal_probe_syscon()
747 const char *name = dev_name(&pdev->dev); in armada_set_sane_name()
753 * form: f06f8000.system-controller:ap-thermal so stripping in armada_set_sane_name()
764 strncpy(priv->zone_name, name, THERMAL_NAME_LENGTH - 1); in armada_set_sane_name()
765 priv->zone_name[THERMAL_NAME_LENGTH - 1] = '\0'; in armada_set_sane_name()
767 /* Then check there are no '-' or hwmon core will complain */ in armada_set_sane_name()
769 insane_char = strpbrk(priv->zone_name, "-"); in armada_set_sane_name()
793 return -EINVAL; in armada_configure_overheat_int()
800 return -EINVAL; in armada_configure_overheat_int()
809 priv->overheat_sensor = tz; in armada_configure_overheat_int()
810 priv->interrupt_source = sensor_id; in armada_configure_overheat_int()
827 match = of_match_device(armada_thermal_id_table, &pdev->dev); in armada_thermal_probe()
829 return -ENODEV; in armada_thermal_probe()
831 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); in armada_thermal_probe()
833 return -ENOMEM; in armada_thermal_probe()
835 drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); in armada_thermal_probe()
837 return -ENOMEM; in armada_thermal_probe()
839 priv->dev = &pdev->dev; in armada_thermal_probe()
840 priv->data = (struct armada_thermal_data *)match->data; in armada_thermal_probe()
842 mutex_init(&priv->update_lock); in armada_thermal_probe()
856 if (IS_ERR(syscon_node_to_regmap(pdev->dev.parent->of_node))) { in armada_thermal_probe()
864 priv->data->init(pdev, priv); in armada_thermal_probe()
869 tz = thermal_zone_device_register(priv->zone_name, 0, 0, priv, in armada_thermal_probe()
872 dev_err(&pdev->dev, in armada_thermal_probe()
883 drvdata->type = LEGACY; in armada_thermal_probe()
884 drvdata->data.tz = tz; in armada_thermal_probe()
894 priv->current_channel = -1; in armada_thermal_probe()
895 priv->data->init(pdev, priv); in armada_thermal_probe()
896 drvdata->type = SYSCON; in armada_thermal_probe()
897 drvdata->data.priv = priv; in armada_thermal_probe()
901 if (irq == -EPROBE_DEFER) in armada_thermal_probe()
906 ret = devm_request_threaded_irq(&pdev->dev, irq, in armada_thermal_probe()
911 dev_err(&pdev->dev, "Cannot request threaded IRQ %d\n", in armada_thermal_probe()
921 for (sensor_id = 0; sensor_id <= priv->data->cpu_nr; sensor_id++) { in armada_thermal_probe()
922 sensor = devm_kzalloc(&pdev->dev, in armada_thermal_probe()
926 return -ENOMEM; in armada_thermal_probe()
929 sensor->priv = priv; in armada_thermal_probe()
930 sensor->id = sensor_id; in armada_thermal_probe()
931 tz = devm_thermal_of_zone_register(&pdev->dev, in armada_thermal_probe()
932 sensor->id, sensor, in armada_thermal_probe()
935 dev_info(&pdev->dev, "Thermal sensor %d unavailable\n", in armada_thermal_probe()
937 devm_kfree(&pdev->dev, sensor); in armada_thermal_probe()
946 if (irq > 0 && !priv->overheat_sensor) in armada_thermal_probe()
947 armada_configure_overheat_int(priv, tz, sensor->id); in armada_thermal_probe()
951 if (!priv->overheat_sensor) in armada_thermal_probe()
952 dev_warn(&pdev->dev, "Overheat interrupt not available\n"); in armada_thermal_probe()
961 if (drvdata->type == LEGACY) in armada_thermal_exit()
962 thermal_zone_device_unregister(drvdata->data.tz); in armada_thermal_exit()
978 MODULE_AUTHOR("Ezequiel Garcia <ezequiel.garcia@free-electrons.com>");