xref: /linux/drivers/iio/adc/versal-sysmon.h (revision 3a2c4d55e32ad65efebdb6de44eef3bfa08bb49d)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * AMD Versal SysMon driver
4  *
5  * Copyright (C) 2019 - 2022, Xilinx, Inc.
6  * Copyright (C) 2022 - 2026, Advanced Micro Devices, Inc.
7  */
8 
9 #ifndef _VERSAL_SYSMON_H_
10 #define _VERSAL_SYSMON_H_
11 
12 #include <linux/bits.h>
13 #include <linux/mutex.h>
14 #include <linux/spinlock_types.h>
15 #include <linux/workqueue.h>
16 
17 struct device;
18 struct regmap;
19 
20 /* Register offsets (sorted by address) */
21 #define SYSMON_NPI_LOCK			0x000C
22 #define SYSMON_ISR			0x0044
23 #define SYSMON_IMR			0x0048
24 #define SYSMON_IER			0x004C
25 #define SYSMON_IDR			0x0050
26 #define SYSMON_CONFIG			0x0100
27 #define SYSMON_TEMP_MAX			0x1030
28 #define SYSMON_TEMP_MIN			0x1034
29 #define SYSMON_SUPPLY_BASE		0x1040
30 #define SYSMON_ALARM_FLAG		0x1018
31 #define SYSMON_ALARM_REG		0x1940
32 #define SYSMON_SUPPLY_EN_AVG_BASE	0x1958
33 #define SYSMON_TEMP_TH_LOW		0x1970
34 #define SYSMON_TEMP_TH_UP		0x1974
35 #define SYSMON_SUPPLY_TH_LOW		0x1980
36 #define SYSMON_SUPPLY_TH_UP		0x1C80
37 #define SYSMON_TEMP_EV_CFG		0x1F84
38 #define SYSMON_TEMP_MIN_MIN		0x1F8C
39 #define SYSMON_TEMP_MAX_MAX		0x1F90
40 #define SYSMON_STATUS_RESET		0x1F94
41 #define SYSMON_TEMP_SAT_BASE		0x1FAC
42 #define SYSMON_TEMP_EN_AVG_BASE		0x24B4
43 #define SYSMON_MAX_REG			0x24C0
44 
45 /* NPI unlock value written to SYSMON_NPI_LOCK */
46 #define SYSMON_NPI_UNLOCK_CODE		0xF9E8D7C6
47 
48 /* Register stride: 4 bytes per 32-bit register */
49 #define SYSMON_REG_STRIDE		4
50 
51 #define SYSMON_SUPPLY_IDX_MAX		159
52 #define SYSMON_TEMP_SAT_MAX		64
53 #define SYSMON_NO_OF_EVENTS		32
54 #define SYSMON_INTR_ALL_MASK		GENMASK(31, 0)
55 
56 /* ISR/IMR temperature alarm mask (bit 9) */
57 #define SYSMON_TEMP_INTR_MASK		BIT(9)
58 
59 /* SYSMON_CONFIG: supply oversampling ratio */
60 #define SYSMON_CONFIG_SUPPLY_OSR	GENMASK(17, 14)
61 
62 /* SYSMON_CONFIG: temperature satellite oversampling ratio */
63 #define SYSMON_CONFIG_TEMP_SAT_OSR	GENMASK(27, 24)
64 
65 /* Per-channel averaging enable register counts */
66 #define SYSMON_SUPPLY_EN_AVG_COUNT	5
67 #define SYSMON_TEMP_EN_AVG_COUNT	2
68 
69 /* Supply voltage conversion register fields */
70 #define SYSMON_MANTISSA_MASK		GENMASK(15, 0)
71 #define SYSMON_FMT_MASK			BIT(16)
72 #define SYSMON_MODE_MASK		GENMASK(18, 17)
73 
74 /* Q8.7 fractional shift */
75 #define SYSMON_FRACTIONAL_SHIFT		7U
76 #define SYSMON_SUPPLY_MANTISSA_BITS	16
77 
78 /* Bits per alarm register */
79 #define SYSMON_ALARM_BITS_PER_REG	32
80 
81 #define SYSMON_UNMASK_WORK_DELAY_MS	500
82 
83 /**
84  * struct sysmon - Driver data for Versal SysMon
85  * @regmap: register map for hardware access
86  * @lock: protects read-modify-write sequences on threshold registers
87  *        and cached state that spans multiple regmap calls
88  * @irq_lock: protects interrupt mask register updates (MMIO path only)
89  * @masked_temp: currently masked temperature alarm bits
90  * @temp_mask: temperature interrupt configuration mask
91  * @temp_hysteresis: cached DEVICE_TEMP hysteresis in millicelsius
92  * @sysmon_unmask_work: re-enables events after alarm condition clears
93  * @temp_oversampling: current temp oversampling ratio
94  * @supply_oversampling: current supply oversampling ratio
95  */
96 struct sysmon {
97 	struct regmap *regmap;
98 	/*
99 	 * Protects read-modify-write sequences on threshold registers
100 	 * and cached state (oversampling ratios, hysteresis values)
101 	 * that spans multiple regmap calls.
102 	 */
103 	struct mutex lock;
104 	/*
105 	 * Protects interrupt mask register updates.  Only used on the
106 	 * MMIO path (fast_io regmap); I2C has no IRQ and never reaches
107 	 * the event code that takes this lock.
108 	 */
109 	spinlock_t irq_lock;
110 	unsigned int masked_temp;
111 	unsigned int temp_mask;
112 	int temp_hysteresis;
113 	struct delayed_work sysmon_unmask_work;
114 	unsigned int temp_oversampling;
115 	unsigned int supply_oversampling;
116 };
117 
118 int devm_versal_sysmon_core_probe(struct device *dev, struct regmap *regmap);
119 
120 #endif /* _VERSAL_SYSMON_H_ */
121