Skip to content

Commit 0ea07b6

Browse files
raagjadavrodrigovivi
authored andcommitted
drm/xe/pm: Wire up suspend/resume for I2C controller
Wire up suspend/resume handles for I2C controller to match its power state with SGUnit. Signed-off-by: Raag Jadav <[email protected]> Signed-off-by: Heikki Krogerus <[email protected]> Reviewed-by: Karthik Poosa <[email protected]> Reviewed-by: Andi Shyti <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Rodrigo Vivi <[email protected]>
1 parent f0e53aa commit 0ea07b6

File tree

4 files changed

+47
-0
lines changed

4 files changed

+47
-0
lines changed

drivers/gpu/drm/xe/regs/xe_i2c_regs.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
#ifndef _XE_I2C_REGS_H_
33
#define _XE_I2C_REGS_H_
44

5+
#include <linux/pci_regs.h>
6+
57
#include "xe_reg_defs.h"
68
#include "xe_regs.h"
79

@@ -12,4 +14,7 @@
1214
#define REG_SG_REMAP_ADDR_PREFIX XE_REG(SOC_BASE + 0x0164)
1315
#define REG_SG_REMAP_ADDR_POSTFIX XE_REG(SOC_BASE + 0x0168)
1416

17+
#define I2C_CONFIG_CMD XE_REG(I2C_CONFIG_SPACE_OFFSET + PCI_COMMAND)
18+
#define I2C_CONFIG_PMCSR XE_REG(I2C_CONFIG_SPACE_OFFSET + 0x84)
19+
1520
#endif /* _XE_I2C_REGS_H_ */

drivers/gpu/drm/xe/xe_i2c.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,31 @@ static const struct regmap_config i2c_regmap_config = {
226226
.fast_io = true,
227227
};
228228

229+
void xe_i2c_pm_suspend(struct xe_device *xe)
230+
{
231+
struct xe_mmio *mmio = xe_root_tile_mmio(xe);
232+
233+
if (!xe->i2c || xe->i2c->ep.cookie != XE_I2C_EP_COOKIE_DEVICE)
234+
return;
235+
236+
xe_mmio_rmw32(mmio, I2C_CONFIG_PMCSR, PCI_PM_CTRL_STATE_MASK, (__force u32)PCI_D3hot);
237+
drm_dbg(&xe->drm, "pmcsr: 0x%08x\n", xe_mmio_read32(mmio, I2C_CONFIG_PMCSR));
238+
}
239+
240+
void xe_i2c_pm_resume(struct xe_device *xe, bool d3cold)
241+
{
242+
struct xe_mmio *mmio = xe_root_tile_mmio(xe);
243+
244+
if (!xe->i2c || xe->i2c->ep.cookie != XE_I2C_EP_COOKIE_DEVICE)
245+
return;
246+
247+
if (d3cold)
248+
xe_mmio_rmw32(mmio, I2C_CONFIG_CMD, 0, PCI_COMMAND_MEMORY);
249+
250+
xe_mmio_rmw32(mmio, I2C_CONFIG_PMCSR, PCI_PM_CTRL_STATE_MASK, (__force u32)PCI_D0);
251+
drm_dbg(&xe->drm, "pmcsr: 0x%08x\n", xe_mmio_read32(mmio, I2C_CONFIG_PMCSR));
252+
}
253+
229254
static void xe_i2c_remove(void *data)
230255
{
231256
struct xe_i2c *i2c = data;
@@ -270,6 +295,10 @@ int xe_i2c_probe(struct xe_device *xe)
270295
i2c->mmio = xe_root_tile_mmio(xe);
271296
i2c->drm_dev = drm_dev;
272297
i2c->ep = ep;
298+
xe->i2c = i2c;
299+
300+
/* PCI PM isn't aware of this device, bring it up and match it with SGUnit state. */
301+
xe_i2c_pm_resume(xe, true);
273302

274303
regmap = devm_regmap_init(drm_dev, NULL, i2c, &i2c_regmap_config);
275304
if (IS_ERR(regmap))

drivers/gpu/drm/xe/xe_i2c.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,13 @@ struct xe_i2c {
5050
#if IS_ENABLED(CONFIG_I2C)
5151
int xe_i2c_probe(struct xe_device *xe);
5252
void xe_i2c_irq_handler(struct xe_device *xe, u32 master_ctl);
53+
void xe_i2c_pm_suspend(struct xe_device *xe);
54+
void xe_i2c_pm_resume(struct xe_device *xe, bool d3cold);
5355
#else
5456
static inline int xe_i2c_probe(struct xe_device *xe) { return 0; }
5557
static inline void xe_i2c_irq_handler(struct xe_device *xe, u32 master_ctl) { }
58+
static inline void xe_i2c_pm_suspend(struct xe_device *xe) { }
59+
static inline void xe_i2c_pm_resume(struct xe_device *xe, bool d3cold) { }
5660
#endif
5761

5862
#endif

drivers/gpu/drm/xe/xe_pm.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "xe_ggtt.h"
2020
#include "xe_gt.h"
2121
#include "xe_guc.h"
22+
#include "xe_i2c.h"
2223
#include "xe_irq.h"
2324
#include "xe_pcode.h"
2425
#include "xe_pxp.h"
@@ -146,6 +147,8 @@ int xe_pm_suspend(struct xe_device *xe)
146147

147148
xe_display_pm_suspend_late(xe);
148149

150+
xe_i2c_pm_suspend(xe);
151+
149152
drm_dbg(&xe->drm, "Device suspended\n");
150153
return 0;
151154

@@ -190,6 +193,8 @@ int xe_pm_resume(struct xe_device *xe)
190193
if (err)
191194
goto err;
192195

196+
xe_i2c_pm_resume(xe, xe->d3cold.allowed);
197+
193198
xe_irq_resume(xe);
194199

195200
for_each_gt(gt, xe, id)
@@ -487,6 +492,8 @@ int xe_pm_runtime_suspend(struct xe_device *xe)
487492

488493
xe_display_pm_runtime_suspend_late(xe);
489494

495+
xe_i2c_pm_suspend(xe);
496+
490497
xe_rpm_lockmap_release(xe);
491498
xe_pm_write_callback_task(xe, NULL);
492499
return 0;
@@ -534,6 +541,8 @@ int xe_pm_runtime_resume(struct xe_device *xe)
534541
goto out;
535542
}
536543

544+
xe_i2c_pm_resume(xe, xe->d3cold.allowed);
545+
537546
xe_irq_resume(xe);
538547

539548
for_each_gt(gt, xe, id)

0 commit comments

Comments
 (0)