Skip to content

Commit 6617133

Browse files
committed
sbtsi: Add support to get the SBTSI maximum HBM temperature
Add a new channel to support SBTSIx50 and SBTSIx54 for reporting maximum HBM temperature.
1 parent 3c522d7 commit 6617133

1 file changed

Lines changed: 91 additions & 25 deletions

File tree

apml_sbtsi.c

Lines changed: 91 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@
3939
#define SBTSI_REG_TEMP_DEC 0x10 /* RW */
4040
#define SBTSI_REG_TEMP_HIGH_DEC 0x13 /* RW */
4141
#define SBTSI_REG_TEMP_LOW_DEC 0x14 /* RW */
42+
#define SBTSI_REG_HBM_HIGH_INT 0x40 /* RW */
43+
#define SBTSI_REG_HBM_HIGH_DEC 0x44 /* RW */
44+
#define SBTSI_REG_HBM_LOW_INT 0x48 /* RW */
45+
#define SBTSI_REG_HBM_LOW_DEC 0x4C /* RW */
46+
#define SBTSI_REG_MAX_HBM_INT 0x50 /* RO */
47+
#define SBTSI_REG_MAX_HBM_DEC 0x54 /* RO */
4248

4349
#define SBTSI_CONFIG_READ_ORDER_SHIFT 5
4450

@@ -67,6 +73,20 @@ struct apml_sbtsi_device {
6773
u8 dev_static_addr;
6874
} __packed;
6975

76+
/*
77+
* Temperature sensor channel to the order of entries in
78+
* sbtsi_info HWMON_CHANNEL_INFO(temp, ..., ...)
79+
*/
80+
enum sbtsi_channels {
81+
CPU_CHANNEL, /* CPU temp channel */
82+
HBM_CHANNEL /* HBM temp channel */
83+
};
84+
85+
static const char *const sbtsi_temp_label[] = {
86+
"CpuTemp",
87+
"MaxMemTemp",
88+
};
89+
7090
/*
7191
* From SB-TSI spec: CPU temperature readings and limit registers encode the
7292
* temperature in increments of 0.125 from 0 to 255.875. The "high byte"
@@ -97,6 +117,23 @@ static inline void sbtsi_mc_to_reg(s32 temp, u8 *integer, u8 *decimal)
97117
*decimal = (temp & SBTSI_DEC_MASK) << SBTSI_DEC_OFFSET;
98118
}
99119

120+
static int sbtsi_read_labels(struct device *dev,
121+
enum hwmon_sensor_types type,
122+
u32 attr, int channel, const char **str)
123+
{
124+
switch (type) {
125+
case hwmon_temp:
126+
if (attr != hwmon_temp_label)
127+
return -EOPNOTSUPP;
128+
129+
*str = sbtsi_temp_label[channel];;
130+
break;
131+
default:
132+
return -EOPNOTSUPP;
133+
}
134+
return 0;
135+
}
136+
100137
static int sbtsi_read(struct device *dev, enum hwmon_sensor_types type,
101138
u32 attr, int channel, long *val)
102139
{
@@ -106,37 +143,53 @@ static int sbtsi_read(struct device *dev, enum hwmon_sensor_types type,
106143

107144
switch (attr) {
108145
case hwmon_temp_input:
109-
/*
110-
* ReadOrder bit specifies the reading order of integer and
111-
* decimal part of CPU temp for atomic reads. If bit == 0,
112-
* reading integer part triggers latching of the decimal part,
113-
* so integer part should be read first. If bit == 1, read
114-
* order should be reversed.
115-
*/
116-
ret = regmap_read(tsi_dev->regmap, SBTSI_REG_CONFIG, &cfg);
117-
if (ret < 0)
118-
return ret;
119-
120146
mutex_lock(&tsi_dev->lock);
121-
if (cfg & BIT(SBTSI_CONFIG_READ_ORDER_SHIFT)) {
122-
ret = regmap_read(tsi_dev->regmap, SBTSI_REG_TEMP_DEC, &temp_dec);
123-
ret = regmap_read(tsi_dev->regmap, SBTSI_REG_TEMP_INT, &temp_int);
147+
if (channel == HBM_CHANNEL) {
148+
ret = regmap_read(tsi_dev->regmap, SBTSI_REG_MAX_HBM_INT, &temp_int);
149+
ret = regmap_read(tsi_dev->regmap, SBTSI_REG_MAX_HBM_DEC, &temp_dec);
124150
} else {
125-
ret = regmap_read(tsi_dev->regmap, SBTSI_REG_TEMP_INT, &temp_int);
126-
ret = regmap_read(tsi_dev->regmap, SBTSI_REG_TEMP_DEC, &temp_dec);
151+
/*
152+
* ReadOrder bit specifies the reading order of integer and
153+
* decimal part of CPU temp for atomic reads. If bit == 0,
154+
* reading integer part triggers latching of the decimal part,
155+
* so integer part should be read first. If bit == 1, read
156+
* order should be reversed.
157+
*/
158+
ret = regmap_read(tsi_dev->regmap, SBTSI_REG_CONFIG, &cfg);
159+
if (ret < 0) {
160+
mutex_unlock(&tsi_dev->lock);
161+
return ret;
162+
}
163+
if (cfg & BIT(SBTSI_CONFIG_READ_ORDER_SHIFT)) {
164+
ret = regmap_read(tsi_dev->regmap, SBTSI_REG_TEMP_DEC, &temp_dec);
165+
ret = regmap_read(tsi_dev->regmap, SBTSI_REG_TEMP_INT, &temp_int);
166+
} else {
167+
ret = regmap_read(tsi_dev->regmap, SBTSI_REG_TEMP_INT, &temp_int);
168+
ret = regmap_read(tsi_dev->regmap, SBTSI_REG_TEMP_DEC, &temp_dec);
169+
}
127170
}
128171
mutex_unlock(&tsi_dev->lock);
129172
break;
130173
case hwmon_temp_max:
131174
mutex_lock(&tsi_dev->lock);
132-
ret = regmap_read(tsi_dev->regmap, SBTSI_REG_TEMP_HIGH_INT, &temp_int);
133-
ret = regmap_read(tsi_dev->regmap, SBTSI_REG_TEMP_HIGH_DEC, &temp_dec);
175+
if (channel == HBM_CHANNEL) {
176+
ret = regmap_read(tsi_dev->regmap, SBTSI_REG_HBM_HIGH_INT, &temp_int);
177+
ret = regmap_read(tsi_dev->regmap, SBTSI_REG_HBM_HIGH_DEC, &temp_dec);
178+
} else {
179+
ret = regmap_read(tsi_dev->regmap, SBTSI_REG_TEMP_HIGH_INT, &temp_int);
180+
ret = regmap_read(tsi_dev->regmap, SBTSI_REG_TEMP_HIGH_DEC, &temp_dec);
181+
}
134182
mutex_unlock(&tsi_dev->lock);
135183
break;
136184
case hwmon_temp_min:
137185
mutex_lock(&tsi_dev->lock);
138-
ret = regmap_read(tsi_dev->regmap, SBTSI_REG_TEMP_LOW_INT, &temp_int);
139-
ret = regmap_read(tsi_dev->regmap, SBTSI_REG_TEMP_LOW_DEC, &temp_dec);
186+
if (channel == HBM_CHANNEL) {
187+
ret = regmap_read(tsi_dev->regmap, SBTSI_REG_HBM_LOW_INT, &temp_int);
188+
ret = regmap_read(tsi_dev->regmap, SBTSI_REG_HBM_LOW_DEC, &temp_dec);
189+
} else {
190+
ret = regmap_read(tsi_dev->regmap, SBTSI_REG_TEMP_LOW_INT, &temp_int);
191+
ret = regmap_read(tsi_dev->regmap, SBTSI_REG_TEMP_LOW_DEC, &temp_dec);
192+
}
140193
mutex_unlock(&tsi_dev->lock);
141194
break;
142195
default:
@@ -160,12 +213,22 @@ static int sbtsi_write(struct device *dev, enum hwmon_sensor_types type,
160213

161214
switch (attr) {
162215
case hwmon_temp_max:
163-
reg_int = SBTSI_REG_TEMP_HIGH_INT;
164-
reg_dec = SBTSI_REG_TEMP_HIGH_DEC;
216+
if (channel == HBM_CHANNEL) {
217+
reg_int = SBTSI_REG_HBM_HIGH_INT;
218+
reg_dec = SBTSI_REG_HBM_HIGH_DEC;
219+
} else {
220+
reg_int = SBTSI_REG_TEMP_HIGH_INT;
221+
reg_dec = SBTSI_REG_TEMP_HIGH_DEC;
222+
}
165223
break;
166224
case hwmon_temp_min:
167-
reg_int = SBTSI_REG_TEMP_LOW_INT;
168-
reg_dec = SBTSI_REG_TEMP_LOW_DEC;
225+
if (channel == HBM_CHANNEL) {
226+
reg_int = SBTSI_REG_HBM_LOW_INT;
227+
reg_dec = SBTSI_REG_HBM_LOW_DEC;
228+
} else {
229+
reg_int = SBTSI_REG_TEMP_LOW_INT;
230+
reg_dec = SBTSI_REG_TEMP_LOW_DEC;
231+
}
169232
break;
170233
default:
171234
return -EINVAL;
@@ -193,6 +256,7 @@ static umode_t sbtsi_is_visible(const void *data,
193256
case hwmon_temp:
194257
switch (attr) {
195258
case hwmon_temp_input:
259+
case hwmon_temp_label:
196260
return 0444;
197261
case hwmon_temp_min:
198262
return 0644;
@@ -208,14 +272,16 @@ static umode_t sbtsi_is_visible(const void *data,
208272

209273
static const struct hwmon_channel_info *sbtsi_info[] = {
210274
HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),
211-
HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX),
275+
HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX | HWMON_T_LABEL,
276+
HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX | HWMON_T_LABEL),
212277
NULL
213278
};
214279

215280
static const struct hwmon_ops sbtsi_hwmon_ops = {
216281
.is_visible = sbtsi_is_visible,
217282
.read = sbtsi_read,
218283
.write = sbtsi_write,
284+
.read_string = sbtsi_read_labels,
219285
};
220286

221287
static const struct hwmon_chip_info sbtsi_chip_info = {

0 commit comments

Comments
 (0)