Skip to content

Commit 32963da

Browse files
authored
[Mellanox] Add new patches come along with hw-mgmt V.7.0000.3020 (#129)
Add new patches which required by new hw-mgmt package V.7.0000.3020 Including: - support for VID protocol detection per page bases - Increase i2c-mlxcpld transaction pooling - mlxreg-hotplug: Use capability register for attribute creation - Add support for attributes composed from few registers - Add config for sensor xdpe122 and modify mlx_wdt to m
1 parent 97c6686 commit 32963da

6 files changed

+840
-0
lines changed
Lines changed: 386 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,386 @@
1+
From 482c5a7b46fd39c2df42c47f96a817c2d50b9c75 Mon Sep 17 00:00:00 2001
2+
From: Vadim Pasternak <[email protected]>
3+
Date: Tue, 3 Mar 2020 14:33:59 +0200
4+
Subject: [hwmon v1] hwmon: (pmbus/core) Add support for vid mode detection per
5+
page bases
6+
7+
Add support for VID protocol detection per page bases, instead of
8+
detecting it based on PMBU_VOUT readout from page 0.
9+
The reason that some devices allows to configure different VID modes
10+
per page within the same device.
11+
12+
Extend "vrm_version" with the type for Intel IMVP9 and AMD 6.25mV VID
13+
modes.
14+
Add calculation for those types.
15+
16+
Add support for devices XDPE12254, XDPE12284.
17+
All these device support two pages.
18+
The below lists of VOUT_MODE command readout with their related VID
19+
protocols, Digital to Analog Converter steps, supported by these
20+
devices:
21+
VR12.0 mode, 5-mV DAC - 0x01;
22+
VR12.5 mode, 10-mV DAC - 0x02;
23+
IMVP9 mode, 5-mV DAC - 0x03;
24+
AMD mode 6.25mV - 0x10.
25+
26+
Signed-off-by: Vadim Pasternak <[email protected]>
27+
---
28+
drivers/hwmon/pmbus/Kconfig | 9 +++
29+
drivers/hwmon/pmbus/Makefile | 1 +
30+
drivers/hwmon/pmbus/max20751.c | 2 +-
31+
drivers/hwmon/pmbus/pmbus.c | 5 +-
32+
drivers/hwmon/pmbus/pmbus.h | 4 +-
33+
drivers/hwmon/pmbus/pmbus_core.c | 10 ++-
34+
drivers/hwmon/pmbus/tps53679.c | 44 +++++-----
35+
drivers/hwmon/pmbus/xdpe12284.c | 171 +++++++++++++++++++++++++++++++++++++++
36+
8 files changed, 219 insertions(+), 27 deletions(-)
37+
create mode 100644 drivers/hwmon/pmbus/xdpe12284.c
38+
39+
diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig
40+
index 61938ea22208..79fd67e0c940 100644
41+
--- a/drivers/hwmon/pmbus/Kconfig
42+
+++ b/drivers/hwmon/pmbus/Kconfig
43+
@@ -156,6 +156,15 @@ config SENSORS_UCD9200
44+
This driver can also be built as a module. If so, the module will
45+
be called ucd9200.
46+
47+
+config SENSORS_XDPE122
48+
+ tristate "Infineon XDPE122 family"
49+
+ help
50+
+ If you say yes here you get hardware monitoring support for Infineon
51+
+ XDPE12254, XDPE12284, device.
52+
+
53+
+ This driver can also be built as a module. If so, the module will
54+
+ be called xdpe12284.
55+
+
56+
config SENSORS_ZL6100
57+
tristate "Intersil ZL6100 and compatibles"
58+
default n
59+
diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile
60+
index b912fec9876d..e0fe17121afb 100644
61+
--- a/drivers/hwmon/pmbus/Makefile
62+
+++ b/drivers/hwmon/pmbus/Makefile
63+
@@ -16,4 +16,5 @@ obj-$(CONFIG_SENSORS_TPS40422) += tps40422.o
64+
obj-$(CONFIG_SENSORS_TPS53679) += tps53679.o
65+
obj-$(CONFIG_SENSORS_UCD9000) += ucd9000.o
66+
obj-$(CONFIG_SENSORS_UCD9200) += ucd9200.o
67+
+obj-$(CONFIG_SENSORS_XDPE122) += xdpe12284.o
68+
obj-$(CONFIG_SENSORS_ZL6100) += zl6100.o
69+
diff --git a/drivers/hwmon/pmbus/max20751.c b/drivers/hwmon/pmbus/max20751.c
70+
index ab74aeae8cf2..394c662c811b 100644
71+
--- a/drivers/hwmon/pmbus/max20751.c
72+
+++ b/drivers/hwmon/pmbus/max20751.c
73+
@@ -25,7 +25,7 @@ static struct pmbus_driver_info max20751_info = {
74+
.pages = 1,
75+
.format[PSC_VOLTAGE_IN] = linear,
76+
.format[PSC_VOLTAGE_OUT] = vid,
77+
- .vrm_version = vr12,
78+
+ .vrm_version[0] = vr12,
79+
.format[PSC_TEMPERATURE] = linear,
80+
.format[PSC_CURRENT_OUT] = linear,
81+
.format[PSC_POWER] = linear,
82+
diff --git a/drivers/hwmon/pmbus/pmbus.c b/drivers/hwmon/pmbus/pmbus.c
83+
index 44ca8a94873d..ad360a88a53a 100644
84+
--- a/drivers/hwmon/pmbus/pmbus.c
85+
+++ b/drivers/hwmon/pmbus/pmbus.c
86+
@@ -121,7 +121,7 @@ static int pmbus_identify(struct i2c_client *client,
87+
}
88+
89+
if (pmbus_check_byte_register(client, 0, PMBUS_VOUT_MODE)) {
90+
- int vout_mode;
91+
+ int vout_mode, i;
92+
93+
vout_mode = pmbus_read_byte_data(client, 0, PMBUS_VOUT_MODE);
94+
if (vout_mode >= 0 && vout_mode != 0xff) {
95+
@@ -130,7 +130,8 @@ static int pmbus_identify(struct i2c_client *client,
96+
break;
97+
case 1:
98+
info->format[PSC_VOLTAGE_OUT] = vid;
99+
- info->vrm_version = vr11;
100+
+ for (i = 0; i < info->pages; i++)
101+
+ info->vrm_version[i] = vr11;
102+
break;
103+
case 2:
104+
info->format[PSC_VOLTAGE_OUT] = direct;
105+
diff --git a/drivers/hwmon/pmbus/pmbus.h b/drivers/hwmon/pmbus/pmbus.h
106+
index 4efa2bd4f6d8..881156491581 100644
107+
--- a/drivers/hwmon/pmbus/pmbus.h
108+
+++ b/drivers/hwmon/pmbus/pmbus.h
109+
@@ -341,12 +341,12 @@ enum pmbus_sensor_classes {
110+
#define PMBUS_HAVE_STATUS_VMON BIT(19)
111+
112+
enum pmbus_data_format { linear = 0, direct, vid };
113+
-enum vrm_version { vr11 = 0, vr12, vr13 };
114+
+enum vrm_version { vr11 = 0, vr12, vr13, imvp9, amd625mv };
115+
116+
struct pmbus_driver_info {
117+
int pages; /* Total number of pages */
118+
enum pmbus_data_format format[PSC_NUM_CLASSES];
119+
- enum vrm_version vrm_version;
120+
+ enum vrm_version vrm_version[PMBUS_PAGES]; /* vrm version per page */
121+
/*
122+
* Support one set of coefficients for each sensor type
123+
* Used for chips providing data in direct mode.
124+
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
125+
index 682b01624908..764a28105831 100644
126+
--- a/drivers/hwmon/pmbus/pmbus_core.c
127+
+++ b/drivers/hwmon/pmbus/pmbus_core.c
128+
@@ -522,7 +522,7 @@ static long pmbus_reg2data_vid(struct pmbus_data *data,
129+
long val = sensor->data;
130+
long rv = 0;
131+
132+
- switch (data->info->vrm_version) {
133+
+ switch (data->info->vrm_version[sensor->page]) {
134+
case vr11:
135+
if (val >= 0x02 && val <= 0xb2)
136+
rv = DIV_ROUND_CLOSEST(160000 - (val - 2) * 625, 100);
137+
@@ -535,6 +535,14 @@ static long pmbus_reg2data_vid(struct pmbus_data *data,
138+
if (val >= 0x01)
139+
rv = 500 + (val - 1) * 10;
140+
break;
141+
+ case imvp9:
142+
+ if (val >= 0x01)
143+
+ rv = 200 + (val - 1) * 10;
144+
+ break;
145+
+ case amd625mv:
146+
+ if (val >= 0x0 && val <= 0xd8)
147+
+ rv = DIV_ROUND_CLOSEST(155000 - val * 625, 100);
148+
+ break;
149+
}
150+
return rv;
151+
}
152+
diff --git a/drivers/hwmon/pmbus/tps53679.c b/drivers/hwmon/pmbus/tps53679.c
153+
index 45eacc504e2f..28d3de029b91 100644
154+
--- a/drivers/hwmon/pmbus/tps53679.c
155+
+++ b/drivers/hwmon/pmbus/tps53679.c
156+
@@ -33,27 +33,29 @@ static int tps53679_identify(struct i2c_client *client,
157+
struct pmbus_driver_info *info)
158+
{
159+
u8 vout_params;
160+
- int ret;
161+
-
162+
- /* Read the register with VOUT scaling value.*/
163+
- ret = pmbus_read_byte_data(client, 0, PMBUS_VOUT_MODE);
164+
- if (ret < 0)
165+
- return ret;
166+
-
167+
- vout_params = ret & GENMASK(4, 0);
168+
-
169+
- switch (vout_params) {
170+
- case TPS53679_PROT_VR13_10MV:
171+
- case TPS53679_PROT_VR12_5_10MV:
172+
- info->vrm_version = vr13;
173+
- break;
174+
- case TPS53679_PROT_VR13_5MV:
175+
- case TPS53679_PROT_VR12_5MV:
176+
- case TPS53679_PROT_IMVP8_5MV:
177+
- info->vrm_version = vr12;
178+
- break;
179+
- default:
180+
- return -EINVAL;
181+
+ int i, ret;
182+
+
183+
+ for (i = 0; i < TPS53679_PAGE_NUM; i++) {
184+
+ /* Read the register with VOUT scaling value.*/
185+
+ ret = pmbus_read_byte_data(client, i, PMBUS_VOUT_MODE);
186+
+ if (ret < 0)
187+
+ return ret;
188+
+
189+
+ vout_params = ret & GENMASK(4, 0);
190+
+
191+
+ switch (vout_params) {
192+
+ case TPS53679_PROT_VR13_10MV:
193+
+ case TPS53679_PROT_VR12_5_10MV:
194+
+ info->vrm_version[i] = vr13;
195+
+ break;
196+
+ case TPS53679_PROT_VR13_5MV:
197+
+ case TPS53679_PROT_VR12_5MV:
198+
+ case TPS53679_PROT_IMVP8_5MV:
199+
+ info->vrm_version[i] = vr12;
200+
+ break;
201+
+ default:
202+
+ return -EINVAL;
203+
+ }
204+
}
205+
206+
return 0;
207+
diff --git a/drivers/hwmon/pmbus/xdpe12284.c b/drivers/hwmon/pmbus/xdpe12284.c
208+
new file mode 100644
209+
index 000000000000..660556b89e9f
210+
--- /dev/null
211+
+++ b/drivers/hwmon/pmbus/xdpe12284.c
212+
@@ -0,0 +1,171 @@
213+
+// SPDX-License-Identifier: GPL-2.0-or-later
214+
+/*
215+
+ * Hardware monitoring driver for Infineon Multi-phase Digital VR Controllers
216+
+ *
217+
+ * Copyright (c) 2020 Mellanox Technologies. All rights reserved.
218+
+ */
219+
+
220+
+#include <linux/err.h>
221+
+#include <linux/i2c.h>
222+
+#include <linux/init.h>
223+
+#include <linux/kernel.h>
224+
+#include <linux/module.h>
225+
+#include "pmbus.h"
226+
+
227+
+#define XDPE122_PROT_VR12_5MV 0x01 /* VR12.0 mode, 5-mV DAC */
228+
+#define XDPE122_PROT_VR12_5_10MV 0x02 /* VR12.5 mode, 10-mV DAC */
229+
+#define XDPE122_PROT_IMVP9_10MV 0x03 /* IMVP9 mode, 10-mV DAC */
230+
+#define XDPE122_AMD_625MV 0x10 /* AMD mode 6.25mV */
231+
+#define XDPE122_PAGE_NUM 2
232+
+
233+
+static int xdpe122_read_word_data(struct i2c_client *client, int page, int reg)
234+
+{
235+
+ const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
236+
+ long val;
237+
+ s16 exponent;
238+
+ s32 mantissa;
239+
+ int ret;
240+
+
241+
+ switch (reg) {
242+
+ case PMBUS_VOUT_OV_FAULT_LIMIT:
243+
+ case PMBUS_VOUT_UV_FAULT_LIMIT:
244+
+ ret = pmbus_read_word_data(client, page, reg);
245+
+ if (ret < 0)
246+
+ return ret;
247+
+
248+
+ /* Convert register value to LINEAR11 data. */
249+
+ exponent = ((s16)ret) >> 11;
250+
+ mantissa = ((s16)((ret & GENMASK(10, 0)) << 5)) >> 5;
251+
+ val = mantissa * 1000L;
252+
+ if (exponent >= 0)
253+
+ val <<= exponent;
254+
+ else
255+
+ val >>= -exponent;
256+
+
257+
+ /* Convert data to VID register. */
258+
+ switch (info->vrm_version[page]) {
259+
+ case vr13:
260+
+ if (val >= 500)
261+
+ return 1 + DIV_ROUND_CLOSEST(val - 500, 10);
262+
+ return 0;
263+
+ case vr12:
264+
+ if (val >= 250)
265+
+ return 1 + DIV_ROUND_CLOSEST(val - 250, 5);
266+
+ return 0;
267+
+ case imvp9:
268+
+ if (val >= 200)
269+
+ return 1 + DIV_ROUND_CLOSEST(val - 200, 10);
270+
+ return 0;
271+
+ case amd625mv:
272+
+ if (val >= 200 && val <= 1550)
273+
+ return DIV_ROUND_CLOSEST((1550 - val) * 100,
274+
+ 625);
275+
+ return 0;
276+
+ default:
277+
+ return -EINVAL;
278+
+ }
279+
+ default:
280+
+ return -ENODATA;
281+
+ }
282+
+
283+
+ return 0;
284+
+}
285+
+
286+
+static int xdpe122_identify(struct i2c_client *client,
287+
+ struct pmbus_driver_info *info)
288+
+{
289+
+ u8 vout_params;
290+
+ int i, ret;
291+
+
292+
+ for (i = 0; i < XDPE122_PAGE_NUM; i++) {
293+
+ /* Read the register with VOUT scaling value.*/
294+
+ ret = pmbus_read_byte_data(client, i, PMBUS_VOUT_MODE);
295+
+ if (ret < 0)
296+
+ return ret;
297+
+
298+
+ vout_params = ret & GENMASK(4, 0);
299+
+
300+
+ switch (vout_params) {
301+
+ case XDPE122_PROT_VR12_5_10MV:
302+
+ info->vrm_version[i] = vr13;
303+
+ break;
304+
+ case XDPE122_PROT_VR12_5MV:
305+
+ info->vrm_version[i] = vr12;
306+
+ break;
307+
+ case XDPE122_PROT_IMVP9_10MV:
308+
+ info->vrm_version[i] = imvp9;
309+
+ break;
310+
+ case XDPE122_AMD_625MV:
311+
+ info->vrm_version[i] = amd625mv;
312+
+ break;
313+
+ default:
314+
+ return -EINVAL;
315+
+ }
316+
+ }
317+
+
318+
+ return 0;
319+
+}
320+
+
321+
+static struct pmbus_driver_info xdpe122_info = {
322+
+ .pages = XDPE122_PAGE_NUM,
323+
+ .format[PSC_VOLTAGE_IN] = linear,
324+
+ .format[PSC_VOLTAGE_OUT] = vid,
325+
+ .format[PSC_TEMPERATURE] = linear,
326+
+ .format[PSC_CURRENT_IN] = linear,
327+
+ .format[PSC_CURRENT_OUT] = linear,
328+
+ .format[PSC_POWER] = linear,
329+
+ .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
330+
+ PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT |
331+
+ PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP |
332+
+ PMBUS_HAVE_POUT | PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT,
333+
+ .func[1] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
334+
+ PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT |
335+
+ PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP |
336+
+ PMBUS_HAVE_POUT | PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT,
337+
+ .identify = xdpe122_identify,
338+
+ .read_word_data = xdpe122_read_word_data,
339+
+};
340+
+
341+
+static int xdpe122_probe(struct i2c_client *client,
342+
+ const struct i2c_device_id *id)
343+
+{
344+
+ struct pmbus_driver_info *info;
345+
+
346+
+ info = devm_kmemdup(&client->dev, &xdpe122_info, sizeof(*info),
347+
+ GFP_KERNEL);
348+
+ if (!info)
349+
+ return -ENOMEM;
350+
+
351+
+ return pmbus_do_probe(client, id, info);
352+
+}
353+
+
354+
+static const struct i2c_device_id xdpe122_id[] = {
355+
+ {"xdpe12254", 0},
356+
+ {"xdpe12284", 0},
357+
+ {}
358+
+};
359+
+
360+
+MODULE_DEVICE_TABLE(i2c, xdpe122_id);
361+
+
362+
+static const struct of_device_id __maybe_unused xdpe122_of_match[] = {
363+
+ {.compatible = "infineon,xdpe12254"},
364+
+ {.compatible = "infineon,xdpe12284"},
365+
+ {}
366+
+};
367+
+MODULE_DEVICE_TABLE(of, xdpe122_of_match);
368+
+
369+
+static struct i2c_driver xdpe122_driver = {
370+
+ .driver = {
371+
+ .name = "xdpe12284",
372+
+ .of_match_table = of_match_ptr(xdpe122_of_match),
373+
+ },
374+
+ .probe = xdpe122_probe,
375+
+ .remove = pmbus_do_remove,
376+
+ .id_table = xdpe122_id,
377+
+};
378+
+
379+
+module_i2c_driver(xdpe122_driver);
380+
+
381+
+MODULE_AUTHOR("Vadim Pasternak <[email protected]>");
382+
+MODULE_DESCRIPTION("PMBus driver for Infineon XDPE122 family");
383+
+MODULE_LICENSE("GPL");
384+
--
385+
2.11.0
386+

0 commit comments

Comments
 (0)