Skip to content

Commit 5bc6b1d

Browse files
spandruvadarafaeljw
authored andcommitted
thermal: intel: int340x: Add DLVR support for RFIM control
Add support for DLVR (Digital Linear Voltage Regulator) attributes, which can be used to control RFIM. Here instead of "fivr" another directory "dlvr" is created with DLVR attributes: /sys/bus/pci/devices/0000:00:04.0/dlvr ├── dlvr_freq_mhz ├── dlvr_freq_select ├── dlvr_hardware_rev ├── dlvr_pll_busy ├── dlvr_rfim_enable └── dlvr_spread_spectrum_pct └── dlvr_control_mode └── dlvr_control_lock Attributes dlvr_freq_mhz (RO): Current DLVR PLL frequency in MHz. dlvr_freq_select (RW): Sets DLVR PLL clock frequency. dlvr_hardware_rev (RO): DLVR hardware revision. dlvr_pll_busy (RO): PLL can't accept frequency change when set. dlvr_rfim_enable (RW): 0: Disable RF frequency hopping, 1: Enable RF frequency hopping. dlvr_control_mode (RW): Specifies how frequencies are spread. 0: Down spread, 1: Spread in Center. dlvr_control_lock (RW): 1: future writes are ignored. dlvr_spread_spectrum_pct (RW) A write to this register updates the DLVR spread spectrum percent value. Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> [ rjw: Subject edits ] Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
1 parent 51699e4 commit 5bc6b1d

5 files changed

Lines changed: 135 additions & 9 deletions

File tree

Documentation/driver-api/thermal/intel_dptf.rst

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,9 @@ ABI.
184184
DPTF Processor thermal RFIM interface
185185
--------------------------------------------
186186

187-
RFIM interface allows adjustment of FIVR (Fully Integrated Voltage Regulator)
188-
and DDR (Double Data Rate)frequencies to avoid RF interference with WiFi and 5G.
187+
RFIM interface allows adjustment of FIVR (Fully Integrated Voltage Regulator),
188+
DDR (Double Data Rate) and DLVR (Digital Linear Voltage Regulator)
189+
frequencies to avoid RF interference with WiFi and 5G.
189190

190191
Switching voltage regulators (VR) generate radiated EMI or RFI at the
191192
fundamental frequency and its harmonics. Some harmonics may interfere
@@ -196,6 +197,15 @@ small % and shift away the switching noise harmonic interference from
196197
radio channels. OEM or ODMs can use the driver to control SOC IVR
197198
operation within the range where it does not impact IVR performance.
198199

200+
Some products use DLVR instead of FIVR as switching voltage regulator.
201+
In this case attributes of DLVR must be adjusted instead of FIVR.
202+
203+
While shifting the frequencies additional clock noise can be introduced,
204+
which is compensated by adjusting Spread spectrum percent. This helps
205+
to reduce the clock noise to meet regulatory compliance. This spreading
206+
% increases bandwidth of signal transmission and hence reduces the
207+
effects of interference, noise and signal fading.
208+
199209
DRAM devices of DDR IO interface and their power plane can generate EMI
200210
at the data rates. Similar to IVR control mechanism, Intel offers a
201211
mechanism by which DDR data rates can be changed if several conditions
@@ -264,6 +274,38 @@ DVFS attributes
264274
``rfi_disable (RW)``
265275
Disable DDR rate change feature
266276

277+
DLVR attributes
278+
279+
:file:`/sys/bus/pci/devices/0000\:00\:04.0/dlvr/`
280+
281+
``dlvr_hardware_rev`` (RO)
282+
DLVR hardware revision.
283+
284+
``dlvr_freq_mhz`` (RO)
285+
Current DLVR PLL frequency in MHz.
286+
287+
``dlvr_freq_select`` (RW)
288+
Sets DLVR PLL clock frequency. Once set, and enabled via
289+
dlvr_rfim_enable, the dlvr_freq_mhz will show the current
290+
DLVR PLL frequency.
291+
292+
``dlvr_pll_busy`` (RO)
293+
PLL can't accept frequency change when set.
294+
295+
``dlvr_rfim_enable`` (RW)
296+
0: Disable RF frequency hopping, 1: Enable RF frequency hopping.
297+
298+
``dlvr_spread_spectrum_pct`` (RW)
299+
Sets DLVR spread spectrum percent value.
300+
301+
``dlvr_control_mode`` (RW)
302+
Specifies how frequencies are spread using spread spectrum.
303+
0: Down spread,
304+
1: Spread in the Center.
305+
306+
``dlvr_control_lock`` (RW)
307+
1: future writes are ignored.
308+
267309
DPTF Power supply and Battery Interface
268310
----------------------------------------
269311

drivers/thermal/intel/int340x_thermal/processor_thermal_device.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,8 @@ int proc_thermal_mmio_add(struct pci_dev *pdev,
337337
}
338338

339339
if (feature_mask & PROC_THERMAL_FEATURE_FIVR ||
340-
feature_mask & PROC_THERMAL_FEATURE_DVFS) {
340+
feature_mask & PROC_THERMAL_FEATURE_DVFS ||
341+
feature_mask & PROC_THERMAL_FEATURE_DLVR) {
341342
ret = proc_thermal_rfim_add(pdev, proc_priv);
342343
if (ret) {
343344
dev_err(&pdev->dev, "failed to add RFIM interface\n");

drivers/thermal/intel/int340x_thermal/processor_thermal_device.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ struct rapl_mmio_regs {
6060
#define PROC_THERMAL_FEATURE_FIVR 0x02
6161
#define PROC_THERMAL_FEATURE_DVFS 0x04
6262
#define PROC_THERMAL_FEATURE_MBOX 0x08
63+
#define PROC_THERMAL_FEATURE_DLVR 0x10
6364

6465
#if IS_ENABLED(CONFIG_PROC_THERMAL_MMIO_RAPL)
6566
int proc_thermal_rapl_add(struct pci_dev *pdev, struct proc_thermal_device *proc_priv);

drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ static SIMPLE_DEV_PM_OPS(proc_thermal_pci_pm, proc_thermal_pci_suspend,
351351

352352
static const struct pci_device_id proc_thermal_pci_ids[] = {
353353
{ PCI_DEVICE_DATA(INTEL, ADL_THERMAL, PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_MBOX) },
354-
{ PCI_DEVICE_DATA(INTEL, MTLP_THERMAL, PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_MBOX) },
354+
{ PCI_DEVICE_DATA(INTEL, MTLP_THERMAL, PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_MBOX | PROC_THERMAL_FEATURE_DLVR) },
355355
{ PCI_DEVICE_DATA(INTEL, RPL_THERMAL, PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_MBOX) },
356356
{ },
357357
};

drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c

Lines changed: 87 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,29 @@ static const struct mmio_reg tgl_fivr_mmio_regs[] = {
3939
{ 1, 0x5A14, 2, 0x3, 1}, /* fivr_fffc_rev */
4040
};
4141

42+
static const char * const dlvr_strings[] = {
43+
"dlvr_spread_spectrum_pct",
44+
"dlvr_control_mode",
45+
"dlvr_control_lock",
46+
"dlvr_rfim_enable",
47+
"dlvr_freq_select",
48+
"dlvr_hardware_rev",
49+
"dlvr_freq_mhz",
50+
"dlvr_pll_busy",
51+
NULL
52+
};
53+
54+
static const struct mmio_reg dlvr_mmio_regs[] = {
55+
{ 0, 0x15A08, 5, 0x1F, 0}, /* dlvr_spread_spectrum_pct */
56+
{ 0, 0x15A08, 1, 0x1, 5}, /* dlvr_control_mode */
57+
{ 0, 0x15A08, 1, 0x1, 6}, /* dlvr_control_lock */
58+
{ 0, 0x15A08, 1, 0x1, 7}, /* dlvr_rfim_enable */
59+
{ 0, 0x15A08, 12, 0xFFF, 8}, /* dlvr_freq_select */
60+
{ 1, 0x15A10, 2, 0x3, 30}, /* dlvr_hardware_rev */
61+
{ 1, 0x15A10, 16, 0xFFFF, 0}, /* dlvr_freq_mhz */
62+
{ 1, 0x15A10, 1, 0x1, 16}, /* dlvr_pll_busy */
63+
};
64+
4265
/* These will represent sysfs attribute names */
4366
static const char * const dvfs_strings[] = {
4467
"rfi_restriction_run_busy",
@@ -78,14 +101,16 @@ static ssize_t suffix##_show(struct device *dev,\
78101
int ret;\
79102
\
80103
proc_priv = pci_get_drvdata(pdev);\
81-
if (table) {\
104+
if (table == 1) {\
82105
match_strs = (const char **)dvfs_strings;\
83106
mmio_regs = adl_dvfs_mmio_regs;\
84-
} else { \
107+
} else if (table == 2) { \
108+
match_strs = (const char **)dlvr_strings;\
109+
mmio_regs = dlvr_mmio_regs;\
110+
} else {\
85111
match_strs = (const char **)fivr_strings;\
86112
mmio_regs = tgl_fivr_mmio_regs;\
87113
} \
88-
\
89114
ret = match_string(match_strs, -1, attr->attr.name);\
90115
if (ret < 0)\
91116
return ret;\
@@ -109,10 +134,13 @@ static ssize_t suffix##_store(struct device *dev,\
109134
u32 mask;\
110135
\
111136
proc_priv = pci_get_drvdata(pdev);\
112-
if (table) {\
137+
if (table == 1) {\
113138
match_strs = (const char **)dvfs_strings;\
114139
mmio_regs = adl_dvfs_mmio_regs;\
115-
} else { \
140+
} else if (table == 2) { \
141+
match_strs = (const char **)dlvr_strings;\
142+
mmio_regs = dlvr_mmio_regs;\
143+
} else {\
116144
match_strs = (const char **)fivr_strings;\
117145
mmio_regs = tgl_fivr_mmio_regs;\
118146
} \
@@ -147,6 +175,47 @@ RFIM_STORE(spread_spectrum_clk_enable, 0)
147175
RFIM_STORE(rfi_vco_ref_code, 0)
148176
RFIM_STORE(fivr_fffc_rev, 0)
149177

178+
RFIM_SHOW(dlvr_spread_spectrum_pct, 2)
179+
RFIM_SHOW(dlvr_control_mode, 2)
180+
RFIM_SHOW(dlvr_control_lock, 2)
181+
RFIM_SHOW(dlvr_hardware_rev, 2)
182+
RFIM_SHOW(dlvr_freq_mhz, 2)
183+
RFIM_SHOW(dlvr_pll_busy, 2)
184+
RFIM_SHOW(dlvr_freq_select, 2)
185+
RFIM_SHOW(dlvr_rfim_enable, 2)
186+
187+
RFIM_STORE(dlvr_spread_spectrum_pct, 2)
188+
RFIM_STORE(dlvr_rfim_enable, 2)
189+
RFIM_STORE(dlvr_freq_select, 2)
190+
RFIM_STORE(dlvr_control_mode, 2)
191+
RFIM_STORE(dlvr_control_lock, 2)
192+
193+
static DEVICE_ATTR_RW(dlvr_spread_spectrum_pct);
194+
static DEVICE_ATTR_RW(dlvr_control_mode);
195+
static DEVICE_ATTR_RW(dlvr_control_lock);
196+
static DEVICE_ATTR_RW(dlvr_freq_select);
197+
static DEVICE_ATTR_RO(dlvr_hardware_rev);
198+
static DEVICE_ATTR_RO(dlvr_freq_mhz);
199+
static DEVICE_ATTR_RO(dlvr_pll_busy);
200+
static DEVICE_ATTR_RW(dlvr_rfim_enable);
201+
202+
static struct attribute *dlvr_attrs[] = {
203+
&dev_attr_dlvr_spread_spectrum_pct.attr,
204+
&dev_attr_dlvr_control_mode.attr,
205+
&dev_attr_dlvr_control_lock.attr,
206+
&dev_attr_dlvr_freq_select.attr,
207+
&dev_attr_dlvr_hardware_rev.attr,
208+
&dev_attr_dlvr_freq_mhz.attr,
209+
&dev_attr_dlvr_pll_busy.attr,
210+
&dev_attr_dlvr_rfim_enable.attr,
211+
NULL
212+
};
213+
214+
static const struct attribute_group dlvr_attribute_group = {
215+
.attrs = dlvr_attrs,
216+
.name = "dlvr"
217+
};
218+
150219
static DEVICE_ATTR_RW(vco_ref_code_lo);
151220
static DEVICE_ATTR_RW(vco_ref_code_hi);
152221
static DEVICE_ATTR_RW(spread_spectrum_pct);
@@ -277,12 +346,22 @@ int proc_thermal_rfim_add(struct pci_dev *pdev, struct proc_thermal_device *proc
277346
return ret;
278347
}
279348

349+
if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_DLVR) {
350+
ret = sysfs_create_group(&pdev->dev.kobj, &dlvr_attribute_group);
351+
if (ret)
352+
return ret;
353+
}
354+
280355
if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_DVFS) {
281356
ret = sysfs_create_group(&pdev->dev.kobj, &dvfs_attribute_group);
282357
if (ret && proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_FIVR) {
283358
sysfs_remove_group(&pdev->dev.kobj, &fivr_attribute_group);
284359
return ret;
285360
}
361+
if (ret && proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_DLVR) {
362+
sysfs_remove_group(&pdev->dev.kobj, &dlvr_attribute_group);
363+
return ret;
364+
}
286365
}
287366

288367
return 0;
@@ -296,6 +375,9 @@ void proc_thermal_rfim_remove(struct pci_dev *pdev)
296375
if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_FIVR)
297376
sysfs_remove_group(&pdev->dev.kobj, &fivr_attribute_group);
298377

378+
if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_DLVR)
379+
sysfs_remove_group(&pdev->dev.kobj, &dlvr_attribute_group);
380+
299381
if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_DVFS)
300382
sysfs_remove_group(&pdev->dev.kobj, &dvfs_attribute_group);
301383
}

0 commit comments

Comments
 (0)