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