Skip to content

Commit 227bcf2

Browse files
committed
Merge tag 'drm-xe-next-fixes-2025-03-27' of https://gitlab.freedesktop.org/drm/xe/kernel into drm-next
Driver Changes: - Fix NULL pointer dereference on error path - Add missing HW workaround for BMG - Fix survivability mode not triggering - Fix build warning when DRM_FBDEV_EMULATION is not set Signed-off-by: Dave Airlie <airlied@redhat.com> From: Lucas De Marchi <lucas.demarchi@intel.com> Link: https://lore.kernel.org/r/vxy5kwdkzgp2u2umnyxv4ygslmdlvzjl22xotzxaw55dv7plpz@34miqxkbvggu
2 parents 41ae768 + 5e66cf6 commit 227bcf2

File tree

12 files changed

+131
-45
lines changed

12 files changed

+131
-45
lines changed

drivers/gpu/drm/xe/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ config DRM_XE
5353
config DRM_XE_DISPLAY
5454
bool "Enable display support"
5555
depends on DRM_XE && DRM_XE=m && HAS_IOPORT
56-
select FB_IOMEM_HELPERS
56+
select FB_IOMEM_HELPERS if DRM_FBDEV_EMULATION
5757
select I2C
5858
select I2C_ALGOBIT
5959
default y

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,10 @@
130130
#define RING_EXECLIST_STATUS_LO(base) XE_REG((base) + 0x234)
131131
#define RING_EXECLIST_STATUS_HI(base) XE_REG((base) + 0x234 + 4)
132132

133+
#define RING_IDLEDLY(base) XE_REG((base) + 0x23c)
134+
#define INHIBIT_SWITCH_UNTIL_PREEMPTED REG_BIT(31)
135+
#define IDLE_DELAY REG_GENMASK(20, 0)
136+
133137
#define RING_CONTEXT_CONTROL(base) XE_REG((base) + 0x244, XE_REG_OPTION_MASKED)
134138
#define CTX_CTRL_PXP_ENABLE REG_BIT(10)
135139
#define CTX_CTRL_OAC_CONTEXT_ENABLE REG_BIT(8)

drivers/gpu/drm/xe/xe_device.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
#include "xe_pxp.h"
5454
#include "xe_query.h"
5555
#include "xe_shrinker.h"
56+
#include "xe_survivability_mode.h"
5657
#include "xe_sriov.h"
5758
#include "xe_tile.h"
5859
#include "xe_ttm_stolen_mgr.h"
@@ -705,8 +706,20 @@ int xe_device_probe_early(struct xe_device *xe)
705706
sriov_update_device_info(xe);
706707

707708
err = xe_pcode_probe_early(xe);
708-
if (err)
709-
return err;
709+
if (err) {
710+
int save_err = err;
711+
712+
/*
713+
* Try to leave device in survivability mode if device is
714+
* possible, but still return the previous error for error
715+
* propagation
716+
*/
717+
err = xe_survivability_mode_enable(xe);
718+
if (err)
719+
return err;
720+
721+
return save_err;
722+
}
710723

711724
err = wait_for_lmem_ready(xe);
712725
if (err)

drivers/gpu/drm/xe/xe_eu_stall.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -222,13 +222,7 @@ int xe_eu_stall_init(struct xe_gt *gt)
222222
goto exit_free;
223223
}
224224

225-
ret = devm_add_action_or_reset(xe->drm.dev, xe_eu_stall_fini, gt);
226-
if (ret)
227-
goto exit_destroy;
228-
229-
return 0;
230-
exit_destroy:
231-
destroy_workqueue(gt->eu_stall->buf_ptr_poll_wq);
225+
return devm_add_action_or_reset(xe->drm.dev, xe_eu_stall_fini, gt);
232226
exit_free:
233227
mutex_destroy(&gt->eu_stall->stream_lock);
234228
kfree(gt->eu_stall);

drivers/gpu/drm/xe/xe_gt_clock.c

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,35 +16,47 @@
1616
#include "xe_macros.h"
1717
#include "xe_mmio.h"
1818

19-
static u32 get_crystal_clock_freq(u32 rpm_config_reg)
19+
#define f19_2_mhz 19200000
20+
#define f24_mhz 24000000
21+
#define f25_mhz 25000000
22+
#define f38_4_mhz 38400000
23+
#define ts_base_83 83333
24+
#define ts_base_52 52083
25+
#define ts_base_80 80000
26+
27+
static void read_crystal_clock(struct xe_gt *gt, u32 rpm_config_reg, u32 *freq,
28+
u32 *timestamp_base)
2029
{
21-
const u32 f19_2_mhz = 19200000;
22-
const u32 f24_mhz = 24000000;
23-
const u32 f25_mhz = 25000000;
24-
const u32 f38_4_mhz = 38400000;
2530
u32 crystal_clock = REG_FIELD_GET(RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_MASK,
2631
rpm_config_reg);
2732

2833
switch (crystal_clock) {
2934
case RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_24_MHZ:
30-
return f24_mhz;
35+
*freq = f24_mhz;
36+
*timestamp_base = ts_base_83;
37+
return;
3138
case RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_19_2_MHZ:
32-
return f19_2_mhz;
39+
*freq = f19_2_mhz;
40+
*timestamp_base = ts_base_52;
41+
return;
3342
case RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_38_4_MHZ:
34-
return f38_4_mhz;
43+
*freq = f38_4_mhz;
44+
*timestamp_base = ts_base_52;
45+
return;
3546
case RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_25_MHZ:
36-
return f25_mhz;
47+
*freq = f25_mhz;
48+
*timestamp_base = ts_base_80;
49+
return;
3750
default:
38-
XE_WARN_ON("NOT_POSSIBLE");
39-
return 0;
51+
xe_gt_warn(gt, "Invalid crystal clock frequency: %u", crystal_clock);
52+
*freq = 0;
53+
*timestamp_base = 0;
54+
return;
4055
}
4156
}
4257

43-
int xe_gt_clock_init(struct xe_gt *gt)
58+
static void check_ctc_mode(struct xe_gt *gt)
4459
{
45-
u32 c0 = xe_mmio_read32(&gt->mmio, RPM_CONFIG0);
46-
u32 freq = 0;
47-
4860
/*
4961
* CTC_MODE[0] = 1 is definitely not supported for Xe2 and later
5062
* platforms. In theory it could be a valid setting for pre-Xe2
@@ -57,8 +69,18 @@ int xe_gt_clock_init(struct xe_gt *gt)
5769
*/
5870
if (xe_mmio_read32(&gt->mmio, CTC_MODE) & CTC_SOURCE_DIVIDE_LOGIC)
5971
xe_gt_warn(gt, "CTC_MODE[0] is set; this is unexpected and undocumented\n");
72+
}
73+
74+
int xe_gt_clock_init(struct xe_gt *gt)
75+
{
76+
u32 freq;
77+
u32 c0;
78+
79+
if (!IS_SRIOV_VF(gt_to_xe(gt)))
80+
check_ctc_mode(gt);
6081

61-
freq = get_crystal_clock_freq(c0);
82+
c0 = xe_mmio_read32(&gt->mmio, RPM_CONFIG0);
83+
read_crystal_clock(gt, c0, &freq, &gt->info.timestamp_base);
6284

6385
/*
6486
* Now figure out how the command stream's timestamp

drivers/gpu/drm/xe/xe_gt_types.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ struct xe_gt {
121121
enum xe_gt_type type;
122122
/** @info.reference_clock: clock frequency */
123123
u32 reference_clock;
124+
/** @info.timestamp_base: GT timestamp base */
125+
u32 timestamp_base;
124126
/**
125127
* @info.engine_mask: mask of engines present on GT. Some of
126128
* them may be reserved in runtime and not available for user.

drivers/gpu/drm/xe/xe_hw_engine.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
#include <linux/nospec.h>
99

1010
#include <drm/drm_managed.h>
11+
#include <drm/drm_print.h>
1112
#include <uapi/drm/xe_drm.h>
13+
#include <generated/xe_wa_oob.h>
1214

1315
#include "regs/xe_engine_regs.h"
1416
#include "regs/xe_gt_regs.h"
@@ -21,6 +23,7 @@
2123
#include "xe_gsc.h"
2224
#include "xe_gt.h"
2325
#include "xe_gt_ccs_mode.h"
26+
#include "xe_gt_clock.h"
2427
#include "xe_gt_printk.h"
2528
#include "xe_gt_mcr.h"
2629
#include "xe_gt_topology.h"
@@ -564,6 +567,33 @@ static void hw_engine_init_early(struct xe_gt *gt, struct xe_hw_engine *hwe,
564567
xe_reg_whitelist_process_engine(hwe);
565568
}
566569

570+
static void adjust_idledly(struct xe_hw_engine *hwe)
571+
{
572+
struct xe_gt *gt = hwe->gt;
573+
u32 idledly, maxcnt;
574+
u32 idledly_units_ps = 8 * gt->info.timestamp_base;
575+
u32 maxcnt_units_ns = 640;
576+
bool inhibit_switch = 0;
577+
578+
if (!IS_SRIOV_VF(gt_to_xe(hwe->gt)) && XE_WA(gt, 16023105232)) {
579+
idledly = xe_mmio_read32(&gt->mmio, RING_IDLEDLY(hwe->mmio_base));
580+
maxcnt = xe_mmio_read32(&gt->mmio, RING_PWRCTX_MAXCNT(hwe->mmio_base));
581+
582+
inhibit_switch = idledly & INHIBIT_SWITCH_UNTIL_PREEMPTED;
583+
idledly = REG_FIELD_GET(IDLE_DELAY, idledly);
584+
idledly = DIV_ROUND_CLOSEST(idledly * idledly_units_ps, 1000);
585+
maxcnt = REG_FIELD_GET(IDLE_WAIT_TIME, maxcnt);
586+
maxcnt *= maxcnt_units_ns;
587+
588+
if (xe_gt_WARN_ON(gt, idledly >= maxcnt || inhibit_switch)) {
589+
idledly = DIV_ROUND_CLOSEST(((maxcnt - 1) * maxcnt_units_ns),
590+
idledly_units_ps);
591+
idledly = DIV_ROUND_CLOSEST(idledly, 1000);
592+
xe_mmio_write32(&gt->mmio, RING_IDLEDLY(hwe->mmio_base), idledly);
593+
}
594+
}
595+
}
596+
567597
static int hw_engine_init(struct xe_gt *gt, struct xe_hw_engine *hwe,
568598
enum xe_hw_engine_id id)
569599
{
@@ -604,6 +634,9 @@ static int hw_engine_init(struct xe_gt *gt, struct xe_hw_engine *hwe,
604634
if (xe->info.has_usm && hwe->class == XE_ENGINE_CLASS_COPY)
605635
gt->usm.reserved_bcs_instance = hwe->instance;
606636

637+
/* Ensure IDLEDLY is lower than MAXCNT */
638+
adjust_idledly(hwe);
639+
607640
return devm_add_action_or_reset(xe->drm.dev, hw_engine_fini, hwe);
608641

609642
err_hwsp:

drivers/gpu/drm/xe/xe_pci.c

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -803,16 +803,14 @@ static int xe_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
803803
return err;
804804

805805
err = xe_device_probe_early(xe);
806-
807-
/*
808-
* In Boot Survivability mode, no drm card is exposed and driver is
809-
* loaded with bare minimum to allow for firmware to be flashed through
810-
* mei. If early probe fails, check if survivability mode is flagged by
811-
* HW to be enabled. In that case enable it and return success.
812-
*/
813806
if (err) {
814-
if (xe_survivability_mode_required(xe) &&
815-
xe_survivability_mode_enable(xe))
807+
/*
808+
* In Boot Survivability mode, no drm card is exposed and driver
809+
* is loaded with bare minimum to allow for firmware to be
810+
* flashed through mei. If early probe failed, but it managed to
811+
* enable survivability mode, return success.
812+
*/
813+
if (xe_survivability_mode_is_enabled(xe))
816814
return 0;
817815

818816
return err;

drivers/gpu/drm/xe/xe_survivability_mode.c

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -155,13 +155,21 @@ static int enable_survivability_mode(struct pci_dev *pdev)
155155
if (ret)
156156
return ret;
157157

158+
/* Make sure xe_heci_gsc_init() knows about survivability mode */
159+
survivability->mode = true;
160+
158161
ret = xe_heci_gsc_init(xe);
159-
if (ret)
162+
if (ret) {
163+
/*
164+
* But if it fails, device can't enter survivability
165+
* so move it back for correct error handling
166+
*/
167+
survivability->mode = false;
160168
return ret;
169+
}
161170

162171
xe_vsec_init(xe);
163172

164-
survivability->mode = true;
165173
dev_err(dev, "In Survivability Mode\n");
166174

167175
return 0;
@@ -178,15 +186,16 @@ bool xe_survivability_mode_is_enabled(struct xe_device *xe)
178186
return xe->survivability.mode;
179187
}
180188

181-
/**
182-
* xe_survivability_mode_required - checks if survivability mode is required
183-
* @xe: xe device instance
189+
/*
190+
* survivability_mode_requested - check if it's possible to enable
191+
* survivability mode and that was requested by firmware
184192
*
185-
* This function reads the boot status from Pcode
193+
* This function reads the boot status from Pcode.
186194
*
187-
* Return: true if boot status indicates failure, false otherwise
195+
* Return: true if platform support is available and boot status indicates
196+
* failure, false otherwise.
188197
*/
189-
bool xe_survivability_mode_required(struct xe_device *xe)
198+
static bool survivability_mode_requested(struct xe_device *xe)
190199
{
191200
struct xe_survivability *survivability = &xe->survivability;
192201
struct xe_mmio *mmio = xe_root_tile_mmio(xe);
@@ -208,14 +217,18 @@ bool xe_survivability_mode_required(struct xe_device *xe)
208217
*
209218
* Initialize survivability information and enable survivability mode
210219
*
211-
* Return: 0 for success, negative error code otherwise.
220+
* Return: 0 if survivability mode is enabled or not requested; negative error
221+
* code otherwise.
212222
*/
213223
int xe_survivability_mode_enable(struct xe_device *xe)
214224
{
215225
struct xe_survivability *survivability = &xe->survivability;
216226
struct xe_survivability_info *info;
217227
struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
218228

229+
if (!survivability_mode_requested(xe))
230+
return 0;
231+
219232
survivability->size = MAX_SCRATCH_MMIO;
220233

221234
info = devm_kcalloc(xe->drm.dev, survivability->size, sizeof(*info),

drivers/gpu/drm/xe/xe_survivability_mode.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,5 @@ struct xe_device;
1212

1313
int xe_survivability_mode_enable(struct xe_device *xe);
1414
bool xe_survivability_mode_is_enabled(struct xe_device *xe);
15-
bool xe_survivability_mode_required(struct xe_device *xe);
1615

1716
#endif /* _XE_SURVIVABILITY_MODE_H_ */

0 commit comments

Comments
 (0)