diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c index aa73023b7398..053abd6f6514 100644 --- a/drivers/gpu/drm/xe/display/xe_display.c +++ b/drivers/gpu/drm/xe/display/xe_display.c @@ -36,6 +36,7 @@ #include "intel_hotplug.h" #include "intel_opregion.h" #include "skl_watermark.h" +#include "xe_device.h" #include "xe_display_bo.h" #include "xe_display_pcode.h" #include "xe_display_rpm.h" @@ -70,31 +71,9 @@ bool xe_display_driver_probe_defer(struct pci_dev *pdev) return intel_display_driver_probe_defer(pdev); } -/** - * xe_display_driver_set_hooks - Add driver flags and hooks for display - * @driver: DRM device driver - * - * Set features and function hooks in @driver that are needed for driving the - * display IP. This sets the driver's capability of driving display, regardless - * if the device has it enabled - * - * Note: This is called before xe or display device creation. - */ -void xe_display_driver_set_hooks(struct drm_driver *driver) -{ - if (!xe_modparam.probe_display) - return; - -#ifdef CONFIG_DRM_FBDEV_EMULATION - driver->fbdev_probe = intel_fbdev_driver_fbdev_probe; -#endif - - driver->driver_features |= DRIVER_MODESET | DRIVER_ATOMIC; -} - static void unset_display_features(struct xe_device *xe) { - xe->drm.driver_features &= ~(DRIVER_MODESET | DRIVER_ATOMIC); + xe->drm.driver_features &= ~XE_DISPLAY_DRIVER_FEATURES; } static void xe_display_fini_early(void *arg) @@ -604,3 +583,11 @@ int xe_display_probe(struct xe_device *xe) unset_display_features(xe); return 0; } + +#ifdef CONFIG_DRM_FBDEV_EMULATION +int xe_display_driver_fbdev_probe(struct drm_fb_helper *fbh, + struct drm_fb_helper_surface_size *sizes) +{ + return intel_fbdev_driver_fbdev_probe(fbh, sizes); +} +#endif diff --git a/drivers/gpu/drm/xe/display/xe_display.h b/drivers/gpu/drm/xe/display/xe_display.h index 76db95c25f7e..60291cb154df 100644 --- a/drivers/gpu/drm/xe/display/xe_display.h +++ b/drivers/gpu/drm/xe/display/xe_display.h @@ -6,14 +6,20 @@ #ifndef _XE_DISPLAY_H_ #define _XE_DISPLAY_H_ -#include "xe_device.h" +#include struct drm_driver; +struct drm_fb_helper; +struct drm_fb_helper_surface_size; +struct pci_dev; +struct xe_device; #if IS_ENABLED(CONFIG_DRM_XE_DISPLAY) bool xe_display_driver_probe_defer(struct pci_dev *pdev); -void xe_display_driver_set_hooks(struct drm_driver *driver); + +int xe_display_driver_fbdev_probe(struct drm_fb_helper *fbh, + struct drm_fb_helper_surface_size *sizes); int xe_display_probe(struct xe_device *xe); @@ -38,11 +44,18 @@ void xe_display_pm_runtime_suspend(struct xe_device *xe); void xe_display_pm_runtime_suspend_late(struct xe_device *xe); void xe_display_pm_runtime_resume(struct xe_device *xe); +#define XE_DISPLAY_DRIVER_FEATURES (DRIVER_MODESET | DRIVER_ATOMIC) +#define XE_DISPLAY_DRIVER_OPS \ + .fbdev_probe = PTR_IF(IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION), \ + xe_display_driver_fbdev_probe) + #else +#define XE_DISPLAY_DRIVER_FEATURES 0 +#define XE_DISPLAY_DRIVER_OPS \ + .fbdev_probe = NULL + static inline int xe_display_driver_probe_defer(struct pci_dev *pdev) { return 0; } -static inline void xe_display_driver_set_hooks(struct drm_driver *driver) { } -static inline void xe_display_driver_remove(struct xe_device *xe) {} static inline int xe_display_probe(struct xe_device *xe) { return 0; } diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h b/drivers/gpu/drm/xe/regs/xe_gt_regs.h index 16c87ce3f614..08251c7a1a4b 100644 --- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h +++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h @@ -152,10 +152,11 @@ #define XEHPG_INSTDONE_GEOM_SVGUNIT XE_REG_MCR(0x666c) -#define CACHE_MODE_1 XE_REG(0x7004, XE_REG_OPTION_MASKED) +#define CACHE_MODE_1 XE_REG_MCR(0x7004, XE_REG_OPTION_MASKED) #define MSAA_OPTIMIZATION_REDUC_DISABLE REG_BIT(11) #define COMMON_SLICE_CHICKEN1 XE_REG(0x7010, XE_REG_OPTION_MASKED) +#define XEHP_COMMON_SLICE_CHICKEN1 XE_REG_MCR(0x7010, XE_REG_OPTION_MASKED) #define DISABLE_BOTTOM_CLIP_RECTANGLE_TEST REG_BIT(14) #define HIZ_CHICKEN XE_REG(0x7018, XE_REG_OPTION_MASKED) @@ -178,6 +179,7 @@ #define XEHPG_SC_INSTDONE_EXTRA2 XE_REG_MCR(0x7108) #define COMMON_SLICE_CHICKEN4 XE_REG(0x7300, XE_REG_OPTION_MASKED) +#define XEHP_COMMON_SLICE_CHICKEN4 XE_REG_MCR(0x7300, XE_REG_OPTION_MASKED) #define SBE_PUSH_CONSTANT_BEHIND_FIX_ENABLE REG_BIT(12) #define DISABLE_TDC_LOAD_BALANCING_CALC REG_BIT(6) #define HW_FILTERING REG_BIT(5) diff --git a/drivers/gpu/drm/xe/tests/xe_rtp_test.c b/drivers/gpu/drm/xe/tests/xe_rtp_test.c index e5a0f985a700..5d78f2283df9 100644 --- a/drivers/gpu/drm/xe/tests/xe_rtp_test.c +++ b/drivers/gpu/drm/xe/tests/xe_rtp_test.c @@ -9,24 +9,30 @@ #include #include +#include #include #include "regs/xe_gt_regs.h" #include "regs/xe_reg_defs.h" #include "xe_device.h" #include "xe_device_types.h" +#include "xe_gt_mcr.h" #include "xe_kunit_helpers.h" #include "xe_pci_test.h" #include "xe_reg_sr.h" #include "xe_rtp.h" -#define REGULAR_REG1 XE_REG(1) -#define REGULAR_REG2 XE_REG(2) -#define REGULAR_REG3 XE_REG(3) -#define MCR_REG1 XE_REG_MCR(1) -#define MCR_REG2 XE_REG_MCR(2) -#define MCR_REG3 XE_REG_MCR(3) -#define MASKED_REG1 XE_REG(1, XE_REG_OPTION_MASKED) +#define REGULAR_REG1 XE_REG(1) +#define REGULAR_REG2 XE_REG(2) +#define REGULAR_REG3 XE_REG(3) +#define REGULAR_REG4 XE_REG(4) +#define BAD_REGULAR_REG5 XE_REG(5) +#define MCR_REG1 XE_REG_MCR(1) +#define MCR_REG2 XE_REG_MCR(2) +#define MCR_REG3 XE_REG_MCR(3) +#define BAD_MCR_REG4 XE_REG_MCR(4) +#define MCR_REG5 XE_REG_MCR(5) +#define MASKED_REG1 XE_REG(1, XE_REG_OPTION_MASKED) #undef XE_REG_MCR #define XE_REG_MCR(...) XE_REG(__VA_ARGS__, .mcr = 1) @@ -48,6 +54,23 @@ struct rtp_test_case { const struct xe_rtp_entry *entries; }; +static bool fake_xe_gt_mcr_check_reg(struct xe_gt *gt, struct xe_reg reg) +{ + /* + * All supported platforms in this imaginary setup will always have REG4 + * as a non-MCR register and REG5 as MCR, meaning that BAD_MCR_REG4 and + * BAD_REGULAR_REG5 represent programming errors to be captured by our + * tests. + */ + if (reg.raw == BAD_REGULAR_REG5.raw) + return true; + + if (reg.raw == BAD_MCR_REG4.raw) + return false; + + return reg.mcr; +} + static bool match_yes(const struct xe_device *xe, const struct xe_gt *gt, const struct xe_hw_engine *hwe) { @@ -304,6 +327,38 @@ static const struct rtp_to_sr_test_case rtp_to_sr_cases[] = { {} }, }, + { + .name = "bad-mcr-reg-forced-to-regular", + .expected_reg = REGULAR_REG4, + .expected_set_bits = REG_BIT(0), + .expected_clr_bits = REG_BIT(0), + .expected_active = BIT(0), + .expected_count_sr_entries = 1, + .expected_sr_errors = 1, + .entries = (const struct xe_rtp_entry_sr[]) { + { XE_RTP_NAME("bad-mcr-regular-reg"), + XE_RTP_RULES(FUNC(match_yes)), + XE_RTP_ACTIONS(SET(BAD_MCR_REG4, REG_BIT(0))) + }, + {} + }, + }, + { + .name = "bad-regular-reg-forced-to-mcr", + .expected_reg = MCR_REG5, + .expected_set_bits = REG_BIT(0), + .expected_clr_bits = REG_BIT(0), + .expected_active = BIT(0), + .expected_count_sr_entries = 1, + .expected_sr_errors = 1, + .entries = (const struct xe_rtp_entry_sr[]) { + { XE_RTP_NAME("bad-regular-reg"), + XE_RTP_RULES(FUNC(match_yes)), + XE_RTP_ACTIONS(SET(BAD_REGULAR_REG5, REG_BIT(0))) + }, + {} + }, + }, }; static void xe_rtp_process_to_sr_tests(struct kunit *test) @@ -523,6 +578,8 @@ static int xe_rtp_test_init(struct kunit *test) xe->drm.dev = dev; test->priv = xe; + kunit_activate_static_stub(test, xe_gt_mcr_check_reg, fake_xe_gt_mcr_check_reg); + return 0; } diff --git a/drivers/gpu/drm/xe/tests/xe_wa_test.c b/drivers/gpu/drm/xe/tests/xe_wa_test.c index 49d191043dfa..ff0e2502b39f 100644 --- a/drivers/gpu/drm/xe/tests/xe_wa_test.c +++ b/drivers/gpu/drm/xe/tests/xe_wa_test.c @@ -9,6 +9,8 @@ #include #include "xe_device.h" +#include "xe_gt.h" +#include "xe_gt_mcr.h" #include "xe_kunit_helpers.h" #include "xe_pci_test.h" #include "xe_reg_sr.h" @@ -19,8 +21,10 @@ static int xe_wa_test_init(struct kunit *test) { const struct xe_pci_fake_data *param = test->param_value; struct xe_pci_fake_data data = *param; - struct xe_device *xe; struct device *dev; + struct xe_device *xe; + struct xe_gt *gt; + int id; int ret; dev = drm_kunit_helper_alloc_device(test); @@ -33,6 +37,12 @@ static int xe_wa_test_init(struct kunit *test) ret = xe_pci_fake_device_init(xe); KUNIT_ASSERT_EQ(test, ret, 0); + /* Needed for sanitize_mcr(). */ + for_each_gt(gt, xe, id) { + xe_gt_mcr_init_early(gt); + xe_gt_mmio_init(gt); + } + if (!param->graphics_verx100) xe->info.step = param->step; @@ -55,7 +65,7 @@ static void xe_wa_gt(struct kunit *test) xe_wa_process_gt(gt); xe_tuning_process_gt(gt); - KUNIT_ASSERT_EQ(test, gt->reg_sr.errors, 0); + KUNIT_EXPECT_EQ(test, gt->reg_sr.errors, 0); } } diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c index 4b45b617a039..576095cf0952 100644 --- a/drivers/gpu/drm/xe/xe_device.c +++ b/drivers/gpu/drm/xe/xe_device.c @@ -10,7 +10,6 @@ #include #include -#include #include #include #include @@ -392,8 +391,9 @@ bool xe_is_xe_file(const struct file *file) return file->f_op == &xe_driver_fops; } -static struct drm_driver regular_driver = { +static const struct drm_driver regular_driver = { .driver_features = + XE_DISPLAY_DRIVER_FEATURES | DRIVER_GEM | DRIVER_RENDER | DRIVER_SYNCOBJ | DRIVER_SYNCOBJ_TIMELINE | DRIVER_GEM_GPUVA, @@ -415,6 +415,7 @@ static struct drm_driver regular_driver = { .major = DRIVER_MAJOR, .minor = DRIVER_MINOR, .patchlevel = DRIVER_PATCHLEVEL, + XE_DISPLAY_DRIVER_OPS, }; #ifdef CONFIG_PCI_IOV @@ -423,8 +424,9 @@ static const struct drm_ioctl_desc xe_ioctls_admin_only[] = { DRM_IOCTL_DEF_DRV(XE_OBSERVATION, xe_observation_ioctl, DRM_RENDER_ALLOW), }; -static struct drm_driver admin_only_driver = { +static const struct drm_driver admin_only_driver = { .driver_features = + XE_DISPLAY_DRIVER_FEATURES | DRIVER_GEM | DRIVER_RENDER | DRIVER_GEM_GPUVA, .open = xe_file_open, .postclose = xe_file_close, @@ -436,6 +438,7 @@ static struct drm_driver admin_only_driver = { .major = DRIVER_MAJOR, .minor = DRIVER_MINOR, .patchlevel = DRIVER_PATCHLEVEL, + XE_DISPLAY_DRIVER_OPS, }; /** @@ -475,7 +478,7 @@ static void xe_device_destroy(struct drm_device *dev, void *dummy) struct xe_device *xe_device_create(struct pci_dev *pdev, const struct pci_device_id *ent) { - struct drm_driver *driver = ®ular_driver; + const struct drm_driver *driver = ®ular_driver; struct xe_device *xe; int err; @@ -488,8 +491,6 @@ struct xe_device *xe_device_create(struct pci_dev *pdev, driver = &admin_only_driver; #endif - xe_display_driver_set_hooks(driver); - err = aperture_remove_conflicting_pci_devices(pdev, driver->name); if (err) return ERR_PTR(err); diff --git a/drivers/gpu/drm/xe/xe_gsc.c b/drivers/gpu/drm/xe/xe_gsc.c index 0d13e357fb43..aab59dc647fb 100644 --- a/drivers/gpu/drm/xe/xe_gsc.c +++ b/drivers/gpu/drm/xe/xe_gsc.c @@ -482,8 +482,7 @@ int xe_gsc_init_post_hwconfig(struct xe_gsc *gsc) EXEC_QUEUE_FLAG_PERMANENT, 0); if (IS_ERR(q)) { xe_gt_err(gt, "Failed to create queue for GSC submission\n"); - err = PTR_ERR(q); - goto out_bo; + return PTR_ERR(q); } wq = alloc_ordered_workqueue("gsc-ordered-wq", 0); @@ -506,8 +505,6 @@ int xe_gsc_init_post_hwconfig(struct xe_gsc *gsc) out_q: xe_exec_queue_put(q); -out_bo: - xe_bo_unpin_map_no_vm(bo); return err; } diff --git a/drivers/gpu/drm/xe/xe_gt.c b/drivers/gpu/drm/xe/xe_gt.c index cdc678d1ae1f..783eb6d631b5 100644 --- a/drivers/gpu/drm/xe/xe_gt.c +++ b/drivers/gpu/drm/xe/xe_gt.c @@ -7,6 +7,8 @@ #include +#include + #include #include @@ -393,10 +395,7 @@ int xe_gt_record_default_lrcs(struct xe_gt *gt) if (gt->default_lrc[hwe->class]) continue; - xe_reg_sr_init(&hwe->reg_lrc, hwe->name, xe); - xe_wa_process_lrc(hwe); - xe_hw_engine_setup_default_lrc_state(hwe); - xe_tuning_process_lrc(hwe); + xe_hw_engine_setup_reg_lrc(hwe); default_lrc = drmm_kzalloc(&xe->drm, xe_gt_lrc_size(gt, hwe->class), @@ -788,6 +787,7 @@ void xe_gt_mmio_init(struct xe_gt *gt) if (IS_SRIOV_VF(xe)) gt->mmio.sriov_vf_gt = gt; } +EXPORT_SYMBOL_IF_KUNIT(xe_gt_mmio_init); void xe_gt_record_user_engines(struct xe_gt *gt) { diff --git a/drivers/gpu/drm/xe/xe_gt_idle.c b/drivers/gpu/drm/xe/xe_gt_idle.c index 4a2d9edb6a4c..04b24e1c8b78 100644 --- a/drivers/gpu/drm/xe/xe_gt_idle.c +++ b/drivers/gpu/drm/xe/xe_gt_idle.c @@ -3,6 +3,8 @@ * Copyright © 2023 Intel Corporation */ +#include + #include #include @@ -93,7 +95,7 @@ static u64 get_residency_ms(struct xe_gt_idle *gtidle, u64 cur_residency) gtidle->cur_residency = cur_residency; /* residency multiplier in ns, convert to ms */ - cur_residency = mul_u64_u32_div(cur_residency, gtidle->residency_multiplier, 1e6); + cur_residency = mul_u64_u32_div(cur_residency, gtidle->residency_multiplier, NSEC_PER_MSEC); return cur_residency; } diff --git a/drivers/gpu/drm/xe/xe_gt_mcr.c b/drivers/gpu/drm/xe/xe_gt_mcr.c index df281688c617..04f0098070a4 100644 --- a/drivers/gpu/drm/xe/xe_gt_mcr.c +++ b/drivers/gpu/drm/xe/xe_gt_mcr.c @@ -3,6 +3,9 @@ * Copyright © 2022 Intel Corporation */ +#include +#include + #include "xe_gt_mcr.h" #include "regs/xe_gt_regs.h" @@ -553,6 +556,7 @@ void xe_gt_mcr_init_early(struct xe_gt *gt) /* Mark instance 0 as initialized, we need this early for VRAM and CCS probe. */ gt->steering[INSTANCE0].initialized = true; } +EXPORT_SYMBOL_IF_KUNIT(xe_gt_mcr_init_early); /** * xe_gt_mcr_init - Normal initialization of the MCR support @@ -600,6 +604,40 @@ void xe_gt_mcr_set_implicit_defaults(struct xe_gt *gt) } } +static bool reg_in_steering_type_ranges(struct xe_gt *gt, + struct xe_reg reg, + int type) +{ + if (!gt->steering[type].ranges) + return false; + + for (int i = 0; gt->steering[type].ranges[i].end > 0; i++) + if (xe_mmio_in_range(>->mmio, >->steering[type].ranges[i], reg)) + return true; + + return false; +} + +/* + * xe_gt_mcr_check_reg - check if a register is recognized by this GT as MCR + * @gt: GT structure + * @reg: The register to check + * + * Returns true if the register offset falls within one of the MMIO ranges + * classified as MCR for the GT. + */ +bool xe_gt_mcr_check_reg(struct xe_gt *gt, struct xe_reg reg) +{ + KUNIT_STATIC_STUB_REDIRECT(xe_gt_mcr_check_reg, gt, reg); + + for (int type = 0; type <= IMPLICIT_STEERING; type++) + if (reg_in_steering_type_ranges(gt, reg, type)) + return true; + + return false; +} +EXPORT_SYMBOL_IF_KUNIT(xe_gt_mcr_check_reg); + /* * xe_gt_mcr_get_nonterminated_steering - find group/instance values that * will steer a register to a non-terminated instance @@ -621,30 +659,21 @@ bool xe_gt_mcr_get_nonterminated_steering(struct xe_gt *gt, u8 *group, u8 *instance) { const struct xe_reg reg = to_xe_reg(reg_mcr); - const struct xe_mmio_range *implicit_ranges; for (int type = 0; type < IMPLICIT_STEERING; type++) { - if (!gt->steering[type].ranges) - continue; + if (reg_in_steering_type_ranges(gt, reg, type)) { + drm_WARN(>_to_xe(gt)->drm, !gt->steering[type].initialized, + "Uninitialized usage of MCR register %s/%#x\n", + xe_steering_types[type].name, reg.addr); - for (int i = 0; gt->steering[type].ranges[i].end > 0; i++) { - if (xe_mmio_in_range(>->mmio, >->steering[type].ranges[i], reg)) { - drm_WARN(>_to_xe(gt)->drm, !gt->steering[type].initialized, - "Uninitialized usage of MCR register %s/%#x\n", - xe_steering_types[type].name, reg.addr); - - *group = gt->steering[type].group_target; - *instance = gt->steering[type].instance_target; - return true; - } + *group = gt->steering[type].group_target; + *instance = gt->steering[type].instance_target; + return true; } } - implicit_ranges = gt->steering[IMPLICIT_STEERING].ranges; - if (implicit_ranges) - for (int i = 0; implicit_ranges[i].end > 0; i++) - if (xe_mmio_in_range(>->mmio, &implicit_ranges[i], reg)) - return false; + if (reg_in_steering_type_ranges(gt, reg, IMPLICIT_STEERING)) + return false; /* * Not found in a steering table and not a register with implicit diff --git a/drivers/gpu/drm/xe/xe_gt_mcr.h b/drivers/gpu/drm/xe/xe_gt_mcr.h index 2be9419b8acc..75374662f10d 100644 --- a/drivers/gpu/drm/xe/xe_gt_mcr.h +++ b/drivers/gpu/drm/xe/xe_gt_mcr.h @@ -26,6 +26,7 @@ void xe_gt_mcr_unicast_write(struct xe_gt *gt, struct xe_reg_mcr mcr_reg, void xe_gt_mcr_multicast_write(struct xe_gt *gt, struct xe_reg_mcr mcr_reg, u32 value); +bool xe_gt_mcr_check_reg(struct xe_gt *gt, struct xe_reg reg); bool xe_gt_mcr_get_nonterminated_steering(struct xe_gt *gt, struct xe_reg_mcr reg_mcr, u8 *group, u8 *instance); diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_monitor.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf_monitor.c index 7d532bded02a..a85ba4435378 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_monitor.c +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_monitor.c @@ -114,8 +114,10 @@ int xe_gt_sriov_pf_monitor_process_guc2pf(struct xe_gt *gt, const u32 *msg, u32 * VFs with no events are not printed. * * This function can only be called on PF. + * + * Return: always 0 */ -void xe_gt_sriov_pf_monitor_print_events(struct xe_gt *gt, struct drm_printer *p) +int xe_gt_sriov_pf_monitor_print_events(struct xe_gt *gt, struct drm_printer *p) { unsigned int n, total_vfs = xe_gt_sriov_pf_get_totalvfs(gt); const struct xe_gt_sriov_monitor *data; @@ -144,4 +146,6 @@ void xe_gt_sriov_pf_monitor_print_events(struct xe_gt *gt, struct drm_printer *p #undef __format #undef __value } + + return 0; } diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_monitor.h b/drivers/gpu/drm/xe/xe_gt_sriov_pf_monitor.h index 7ca9351a271b..0b8f088d3a16 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_monitor.h +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_monitor.h @@ -13,7 +13,7 @@ struct drm_printer; struct xe_gt; void xe_gt_sriov_pf_monitor_flr(struct xe_gt *gt, u32 vfid); -void xe_gt_sriov_pf_monitor_print_events(struct xe_gt *gt, struct drm_printer *p); +int xe_gt_sriov_pf_monitor_print_events(struct xe_gt *gt, struct drm_printer *p); #ifdef CONFIG_PCI_IOV int xe_gt_sriov_pf_monitor_process_guc2pf(struct xe_gt *gt, const u32 *msg, u32 len); diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_vf.c b/drivers/gpu/drm/xe/xe_gt_sriov_vf.c index 8989c8e1be95..0cd9d77f3351 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_vf.c +++ b/drivers/gpu/drm/xe/xe_gt_sriov_vf.c @@ -1137,13 +1137,15 @@ void xe_gt_sriov_vf_write32(struct xe_gt *gt, struct xe_reg reg, u32 val) } /** - * xe_gt_sriov_vf_print_config - Print VF self config. + * xe_gt_sriov_vf_print_config() - Print VF self config. * @gt: the &xe_gt * @p: the &drm_printer * * This function is for VF use only. + * + * Return: always 0. */ -void xe_gt_sriov_vf_print_config(struct xe_gt *gt, struct drm_printer *p) +int xe_gt_sriov_vf_print_config(struct xe_gt *gt, struct drm_printer *p) { struct xe_gt_sriov_vf_selfconfig *config = >->sriov.vf.self_config; struct xe_device *xe = gt_to_xe(gt); @@ -1170,16 +1172,20 @@ void xe_gt_sriov_vf_print_config(struct xe_gt *gt, struct drm_printer *p) drm_printf(p, "GuC contexts:\t%u\n", config->num_ctxs); drm_printf(p, "GuC doorbells:\t%u\n", config->num_dbs); + + return 0; } /** - * xe_gt_sriov_vf_print_runtime - Print VF's runtime regs received from PF. + * xe_gt_sriov_vf_print_runtime() - Print VF's runtime regs received from PF. * @gt: the &xe_gt * @p: the &drm_printer * * This function is for VF use only. + * + * Return: always 0. */ -void xe_gt_sriov_vf_print_runtime(struct xe_gt *gt, struct drm_printer *p) +int xe_gt_sriov_vf_print_runtime(struct xe_gt *gt, struct drm_printer *p) { struct vf_runtime_reg *vf_regs = gt->sriov.vf.runtime.regs; unsigned int size = gt->sriov.vf.runtime.num_regs; @@ -1188,16 +1194,20 @@ void xe_gt_sriov_vf_print_runtime(struct xe_gt *gt, struct drm_printer *p) for (; size--; vf_regs++) drm_printf(p, "%#x = %#x\n", vf_regs->offset, vf_regs->value); + + return 0; } /** - * xe_gt_sriov_vf_print_version - Print VF ABI versions. + * xe_gt_sriov_vf_print_version() - Print VF ABI versions. * @gt: the &xe_gt * @p: the &drm_printer * * This function is for VF use only. + * + * Return: always 0. */ -void xe_gt_sriov_vf_print_version(struct xe_gt *gt, struct drm_printer *p) +int xe_gt_sriov_vf_print_version(struct xe_gt *gt, struct drm_printer *p) { struct xe_device *xe = gt_to_xe(gt); struct xe_uc_fw_version *guc_version = >->sriov.vf.guc_version; @@ -1227,6 +1237,8 @@ void xe_gt_sriov_vf_print_version(struct xe_gt *gt, struct drm_printer *p) GUC_RELAY_VERSION_LATEST_MAJOR, GUC_RELAY_VERSION_LATEST_MINOR); drm_printf(p, "\thandshake:\t%u.%u\n", pf_version->major, pf_version->minor); + + return 0; } static bool vf_post_migration_shutdown(struct xe_gt *gt) diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_vf.h b/drivers/gpu/drm/xe/xe_gt_sriov_vf.h index a6f7127521a5..79878f21b1da 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_vf.h +++ b/drivers/gpu/drm/xe/xe_gt_sriov_vf.h @@ -35,9 +35,9 @@ bool xe_gt_sriov_vf_sched_groups_enabled(struct xe_gt *gt); u32 xe_gt_sriov_vf_read32(struct xe_gt *gt, struct xe_reg reg); void xe_gt_sriov_vf_write32(struct xe_gt *gt, struct xe_reg reg, u32 val); -void xe_gt_sriov_vf_print_config(struct xe_gt *gt, struct drm_printer *p); -void xe_gt_sriov_vf_print_runtime(struct xe_gt *gt, struct drm_printer *p); -void xe_gt_sriov_vf_print_version(struct xe_gt *gt, struct drm_printer *p); +int xe_gt_sriov_vf_print_config(struct xe_gt *gt, struct drm_printer *p); +int xe_gt_sriov_vf_print_runtime(struct xe_gt *gt, struct drm_printer *p); +int xe_gt_sriov_vf_print_version(struct xe_gt *gt, struct drm_printer *p); int xe_gt_sriov_vf_wait_valid_ggtt(struct xe_gt *gt); int xe_vf_migration_fixups_complete_count(struct xe_gt *gt); diff --git a/drivers/gpu/drm/xe/xe_guc.c b/drivers/gpu/drm/xe/xe_guc.c index e468b638271b..4023700ff2a9 100644 --- a/drivers/gpu/drm/xe/xe_guc.c +++ b/drivers/gpu/drm/xe/xe_guc.c @@ -98,7 +98,7 @@ static u32 guc_ctl_feature_flags(struct xe_guc *guc) if (xe_guc_using_main_gamctrl_queues(guc)) flags |= GUC_CTL_MAIN_GAMCTRL_QUEUES; - if (GRAPHICS_VER(xe) >= 35 && !IS_DGFX(xe) && xe_gt_is_media_type(guc_to_gt(guc))) + if (xe_device_is_l2_flush_optimized(xe) && xe_gt_is_media_type(guc_to_gt(guc))) flags |= GUC_CTL_ENABLE_L2FLUSH_OPT; return flags; diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c index 4171eff4e8ad..afd8cc7bd231 100644 --- a/drivers/gpu/drm/xe/xe_guc_submit.c +++ b/drivers/gpu/drm/xe/xe_guc_submit.c @@ -1665,6 +1665,14 @@ static void guc_exec_queue_fini(struct xe_exec_queue *q) struct xe_guc_exec_queue *ge = q->guc; struct xe_guc *guc = exec_queue_to_guc(q); + if (xe_exec_queue_is_multi_queue_secondary(q)) { + struct xe_exec_queue_group *group = q->multi_queue.group; + + mutex_lock(&group->list_lock); + list_del(&q->multi_queue.link); + mutex_unlock(&group->list_lock); + } + release_guc_id(guc, q); xe_sched_entity_fini(&ge->entity); xe_sched_fini(&ge->sched); @@ -1686,14 +1694,6 @@ static void __guc_exec_queue_destroy_async(struct work_struct *w) guard(xe_pm_runtime)(guc_to_xe(guc)); trace_xe_exec_queue_destroy(q); - if (xe_exec_queue_is_multi_queue_secondary(q)) { - struct xe_exec_queue_group *group = q->multi_queue.group; - - mutex_lock(&group->list_lock); - list_del(&q->multi_queue.link); - mutex_unlock(&group->list_lock); - } - /* Confirm no work left behind accessing device structures */ cancel_delayed_work_sync(&ge->sched.base.work_tdr); diff --git a/drivers/gpu/drm/xe/xe_hw_engine.c b/drivers/gpu/drm/xe/xe_hw_engine.c index 0f0e08bcc182..8c66ff6f3d3c 100644 --- a/drivers/gpu/drm/xe/xe_hw_engine.c +++ b/drivers/gpu/drm/xe/xe_hw_engine.c @@ -337,8 +337,8 @@ static bool xe_rtp_cfeg_wmtp_disabled(const struct xe_device *xe, return xe_mmio_read32(&hwe->gt->mmio, XEHP_FUSE4) & CFEG_WMTP_DISABLE; } -void -xe_hw_engine_setup_default_lrc_state(struct xe_hw_engine *hwe) +static void +hw_engine_setup_default_lrc_state(struct xe_hw_engine *hwe) { struct xe_gt *gt = hwe->gt; const u8 mocs_write_idx = gt->mocs.uc_index; @@ -375,6 +375,17 @@ xe_hw_engine_setup_default_lrc_state(struct xe_hw_engine *hwe) &hwe->reg_lrc, true); } +void xe_hw_engine_setup_reg_lrc(struct xe_hw_engine *hwe) +{ + struct xe_gt *gt = hwe->gt; + struct xe_device *xe = gt_to_xe(gt); + + xe_reg_sr_init(&hwe->reg_lrc, hwe->name, xe); + xe_wa_process_lrc(hwe); + hw_engine_setup_default_lrc_state(hwe); + xe_tuning_process_lrc(hwe); +} + static void hw_engine_setup_default_state(struct xe_hw_engine *hwe) { @@ -503,9 +514,14 @@ static void hw_engine_init_early(struct xe_gt *gt, struct xe_hw_engine *hwe, hwe->class = info->class; hwe->instance = info->instance; hwe->mmio_base = info->mmio_base; - hwe->irq_offset = xe_device_has_msix(gt_to_xe(gt)) ? - get_msix_irq_offset(gt, info->class) : - info->irq_offset; + if (xe_device_has_msix(gt_to_xe(gt))) { + hwe->irq_offset = get_msix_irq_offset(gt, info->class); + hwe->irq_page = info->instance; + + } else { + hwe->irq_offset = info->irq_offset; + hwe->irq_page = 0; + } hwe->domain = info->domain; hwe->name = info->name; hwe->fence_irq = >->fence_irq[info->class]; diff --git a/drivers/gpu/drm/xe/xe_hw_engine.h b/drivers/gpu/drm/xe/xe_hw_engine.h index ee9218773b51..c3ee37f8cfc0 100644 --- a/drivers/gpu/drm/xe/xe_hw_engine.h +++ b/drivers/gpu/drm/xe/xe_hw_engine.h @@ -59,7 +59,7 @@ struct xe_hw_engine_snapshot * xe_hw_engine_snapshot_capture(struct xe_hw_engine *hwe, struct xe_exec_queue *q); void xe_hw_engine_snapshot_free(struct xe_hw_engine_snapshot *snapshot); void xe_hw_engine_print(struct xe_hw_engine *hwe, struct drm_printer *p); -void xe_hw_engine_setup_default_lrc_state(struct xe_hw_engine *hwe); +void xe_hw_engine_setup_reg_lrc(struct xe_hw_engine *hwe); bool xe_hw_engine_is_reserved(struct xe_hw_engine *hwe); diff --git a/drivers/gpu/drm/xe/xe_hw_engine_types.h b/drivers/gpu/drm/xe/xe_hw_engine_types.h index 0f87128c6529..2cf898e682f5 100644 --- a/drivers/gpu/drm/xe/xe_hw_engine_types.h +++ b/drivers/gpu/drm/xe/xe_hw_engine_types.h @@ -118,6 +118,8 @@ struct xe_hw_engine { u16 logical_instance; /** @irq_offset: IRQ offset of this hw engine */ u16 irq_offset; + /** @irq_page: MEMIRQ page used by this HW engine */ + u16 irq_page; /** @mmio_base: MMIO base address of this hw engine*/ u32 mmio_base; /** diff --git a/drivers/gpu/drm/xe/xe_memirq.c b/drivers/gpu/drm/xe/xe_memirq.c index 3848ff81c1f9..9dfe965cb46e 100644 --- a/drivers/gpu/drm/xe/xe_memirq.c +++ b/drivers/gpu/drm/xe/xe_memirq.c @@ -152,6 +152,16 @@ static const char *guc_name(struct xe_guc *guc) * */ +/* ISR */ +#define XE_MEMIRQ_STATUS_OFFSET(inst) ((inst) * SZ_4K + 0x0) +/* IIR */ +#define XE_MEMIRQ_SOURCE_OFFSET(inst) ((inst) * SZ_4K + 0x400) +/* IMR */ +#define XE_MEMIRQ_ENABLE_OFFSET 0x440 + +/* engine ISR vector offset */ +#define XE_MEMIRQ_VECTOR_OFFSET(page, source) (XE_MEMIRQ_STATUS_OFFSET(page) + (source) * SZ_16) + static inline bool hw_reports_to_instance_zero(struct xe_memirq *memirq) { /* @@ -162,18 +172,35 @@ static inline bool hw_reports_to_instance_zero(struct xe_memirq *memirq) return xe_device_has_msix(memirq_to_xe(memirq)); } +static unsigned int hwe_max_count(struct xe_tile *tile) +{ + unsigned int max_instance = 0; + unsigned int gtid, hweid; + struct xe_hw_engine *hwe; + struct xe_gt *gt; + + for_each_gt_on_tile(gt, tile, gtid) + for_each_hw_engine(hwe, gt, hweid) + max_instance = max(max_instance, hwe->instance); + + return max_instance + 1; +} + static int memirq_alloc_pages(struct xe_memirq *memirq) { struct xe_device *xe = memirq_to_xe(memirq); struct xe_tile *tile = memirq_to_tile(memirq); - size_t bo_size = hw_reports_to_instance_zero(memirq) ? - XE_HW_ENGINE_MAX_INSTANCE * SZ_4K : SZ_4K; + unsigned int num_pages; struct xe_bo *bo; + size_t bo_size; int err; BUILD_BUG_ON(!IS_ALIGNED(XE_MEMIRQ_SOURCE_OFFSET(0), SZ_64)); BUILD_BUG_ON(!IS_ALIGNED(XE_MEMIRQ_STATUS_OFFSET(0), SZ_4K)); + num_pages = hw_reports_to_instance_zero(memirq) ? hwe_max_count(tile) : 1; + bo_size = num_pages * SZ_4K; + bo = xe_managed_bo_create_pin_map(xe, tile, bo_size, XE_BO_FLAG_SYSTEM | XE_BO_FLAG_GGTT | @@ -192,16 +219,15 @@ static int memirq_alloc_pages(struct xe_memirq *memirq) memirq->bo = bo; memirq->source = IOSYS_MAP_INIT_OFFSET(&bo->vmap, XE_MEMIRQ_SOURCE_OFFSET(0)); - memirq->status = IOSYS_MAP_INIT_OFFSET(&bo->vmap, XE_MEMIRQ_STATUS_OFFSET(0)); - memirq->mask = IOSYS_MAP_INIT_OFFSET(&bo->vmap, XE_MEMIRQ_ENABLE_OFFSET); + memirq->num_pages = num_pages; memirq_assert(memirq, !memirq->source.is_iomem); - memirq_assert(memirq, !memirq->status.is_iomem); - memirq_assert(memirq, !memirq->mask.is_iomem); - memirq_debug(memirq, "page offsets: bo %#x bo_size %zu source %#x status %#x\n", - xe_bo_ggtt_addr(bo), bo_size, XE_MEMIRQ_SOURCE_OFFSET(0), - XE_MEMIRQ_STATUS_OFFSET(0)); + memirq_debug(memirq, "pages: count %u size %zu\n", num_pages, bo_size); + memirq_debug(memirq, "page0: source %#x status %#x mask %#x\n", + xe_bo_ggtt_addr(bo) + XE_MEMIRQ_SOURCE_OFFSET(0), + xe_bo_ggtt_addr(bo) + XE_MEMIRQ_STATUS_OFFSET(0), + xe_bo_ggtt_addr(bo) + XE_MEMIRQ_ENABLE_OFFSET); return 0; @@ -216,7 +242,8 @@ static void memirq_set_enable(struct xe_memirq *memirq, bool enable) * We only care about the GT_MI_USER_INTERRUPT from the engines and * the GuC does not look at the ENABLE mask at all. */ - iosys_map_wr(&memirq->mask, 0, u32, enable ? GT_MI_USER_INTERRUPT : 0); + iosys_map_wr(&memirq->bo->vmap, XE_MEMIRQ_ENABLE_OFFSET, u32, + enable ? GT_MI_USER_INTERRUPT : 0); memirq->enabled = enable; } @@ -253,15 +280,6 @@ int xe_memirq_init(struct xe_memirq *memirq) return 0; } -static u32 __memirq_source_page(struct xe_memirq *memirq, u16 instance) -{ - memirq_assert(memirq, instance <= XE_HW_ENGINE_MAX_INSTANCE); - memirq_assert(memirq, memirq->bo); - - instance = hw_reports_to_instance_zero(memirq) ? instance : 0; - return xe_bo_ggtt_addr(memirq->bo) + XE_MEMIRQ_SOURCE_OFFSET(instance); -} - /** * xe_memirq_source_ptr - Get GGTT's offset of the `Interrupt Source Report Page`_. * @memirq: the &xe_memirq to query @@ -276,16 +294,7 @@ u32 xe_memirq_source_ptr(struct xe_memirq *memirq, struct xe_hw_engine *hwe) { memirq_assert(memirq, xe_device_uses_memirq(memirq_to_xe(memirq))); - return __memirq_source_page(memirq, hwe->instance); -} - -static u32 __memirq_status_page(struct xe_memirq *memirq, u16 instance) -{ - memirq_assert(memirq, instance <= XE_HW_ENGINE_MAX_INSTANCE); - memirq_assert(memirq, memirq->bo); - - instance = hw_reports_to_instance_zero(memirq) ? instance : 0; - return xe_bo_ggtt_addr(memirq->bo) + XE_MEMIRQ_STATUS_OFFSET(instance); + return xe_bo_ggtt_addr(memirq->bo) + XE_MEMIRQ_SOURCE_OFFSET(hwe->irq_page); } /** @@ -302,7 +311,7 @@ u32 xe_memirq_status_ptr(struct xe_memirq *memirq, struct xe_hw_engine *hwe) { memirq_assert(memirq, xe_device_uses_memirq(memirq_to_xe(memirq))); - return __memirq_status_page(memirq, hwe->instance); + return xe_bo_ggtt_addr(memirq->bo) + XE_MEMIRQ_STATUS_OFFSET(hwe->irq_page); } /** @@ -339,13 +348,14 @@ int xe_memirq_init_guc(struct xe_memirq *memirq, struct xe_guc *guc) { bool is_media = xe_gt_is_media_type(guc_to_gt(guc)); u32 offset = is_media ? ilog2(INTR_MGUC) : ilog2(INTR_GUC); - u32 source, status; + u64 source, status; int err; memirq_assert(memirq, xe_device_uses_memirq(memirq_to_xe(memirq))); - source = __memirq_source_page(memirq, 0) + offset; - status = __memirq_status_page(memirq, 0) + offset * SZ_16; + /* GuC expects exact locations, it doesn't add anything on its own */ + source = xe_bo_ggtt_addr(memirq->bo) + XE_MEMIRQ_SOURCE_OFFSET(0) + offset; + status = xe_bo_ggtt_addr(memirq->bo) + XE_MEMIRQ_VECTOR_OFFSET(0, offset); err = xe_guc_self_cfg64(guc, GUC_KLV_SELF_CFG_MEMIRQ_SOURCE_ADDR_KEY, source); @@ -489,16 +499,16 @@ static void memirq_dispatch_guc(struct xe_memirq *memirq, struct iosys_map *stat */ void xe_memirq_hwe_handler(struct xe_memirq *memirq, struct xe_hw_engine *hwe) { - u16 offset = hwe->irq_offset; - u16 instance = hw_reports_to_instance_zero(memirq) ? hwe->instance : 0; - struct iosys_map src_offset = IOSYS_MAP_INIT_OFFSET(&memirq->bo->vmap, - XE_MEMIRQ_SOURCE_OFFSET(instance)); + struct iosys_map source = + IOSYS_MAP_INIT_OFFSET(&memirq->bo->vmap, + XE_MEMIRQ_SOURCE_OFFSET(hwe->irq_page)); - if (memirq_received(memirq, &src_offset, offset, "SRC")) { - struct iosys_map status_offset = + if (memirq_received(memirq, &source, hwe->irq_offset, "SRC")) { + struct iosys_map status = IOSYS_MAP_INIT_OFFSET(&memirq->bo->vmap, - XE_MEMIRQ_STATUS_OFFSET(instance) + offset * SZ_16); - memirq_dispatch_engine(memirq, &status_offset, hwe); + XE_MEMIRQ_VECTOR_OFFSET(hwe->irq_page, + hwe->irq_offset)); + memirq_dispatch_engine(memirq, &status, hwe); } } @@ -513,12 +523,25 @@ bool xe_memirq_guc_sw_int_0_irq_pending(struct xe_memirq *memirq, struct xe_guc { struct xe_gt *gt = guc_to_gt(guc); u32 offset = xe_gt_is_media_type(gt) ? ilog2(INTR_MGUC) : ilog2(INTR_GUC); - struct iosys_map map = IOSYS_MAP_INIT_OFFSET(&memirq->status, offset * SZ_16); + struct iosys_map map = IOSYS_MAP_INIT_OFFSET(&memirq->bo->vmap, + XE_MEMIRQ_VECTOR_OFFSET(0, offset)); return memirq_received_noclear(memirq, &map, ilog2(GUC_INTR_SW_INT_0), guc_name(guc)); } +static void memirq_dump_source_pages(struct xe_memirq *memirq) +{ + memirq_assert(memirq, !memirq->bo->vmap.is_iomem); + + for (int n = 0; n < memirq->num_pages; n++) { + memirq_debug(memirq, "SOURCE %*ph\n", 32, + memirq->bo->vmap.vaddr + XE_MEMIRQ_SOURCE_OFFSET(n)); + memirq_debug(memirq, "SOURCE %*ph\n", 32, + memirq->bo->vmap.vaddr + XE_MEMIRQ_SOURCE_OFFSET(n) + 32); + } +} + /** * xe_memirq_handler - The `Memory Based Interrupts`_ Handler. * @memirq: the &xe_memirq @@ -538,9 +561,8 @@ void xe_memirq_handler(struct xe_memirq *memirq) if (!memirq->bo) return; - memirq_assert(memirq, !memirq->source.is_iomem); - memirq_debug(memirq, "SOURCE %*ph\n", 32, memirq->source.vaddr); - memirq_debug(memirq, "SOURCE %*ph\n", 32, memirq->source.vaddr + 32); + if (IS_ENABLED(CONFIG_DRM_XE_DEBUG_MEMIRQ)) + memirq_dump_source_pages(memirq); for_each_gt(gt, xe, gtid) { if (gt->tile != tile) @@ -553,7 +575,8 @@ void xe_memirq_handler(struct xe_memirq *memirq) /* GuC and media GuC (if present) must be checked separately */ if (memirq_received(memirq, &memirq->source, ilog2(INTR_GUC), "SRC")) { - map = IOSYS_MAP_INIT_OFFSET(&memirq->status, ilog2(INTR_GUC) * SZ_16); + map = IOSYS_MAP_INIT_OFFSET(&memirq->bo->vmap, + XE_MEMIRQ_VECTOR_OFFSET(0, ilog2(INTR_GUC))); memirq_dispatch_guc(memirq, &map, &tile->primary_gt->uc.guc); } @@ -561,7 +584,8 @@ void xe_memirq_handler(struct xe_memirq *memirq) return; if (memirq_received(memirq, &memirq->source, ilog2(INTR_MGUC), "SRC")) { - map = IOSYS_MAP_INIT_OFFSET(&memirq->status, ilog2(INTR_MGUC) * SZ_16); + map = IOSYS_MAP_INIT_OFFSET(&memirq->bo->vmap, + XE_MEMIRQ_VECTOR_OFFSET(0, ilog2(INTR_MGUC))); memirq_dispatch_guc(memirq, &map, &tile->media_gt->uc.guc); } } diff --git a/drivers/gpu/drm/xe/xe_memirq_types.h b/drivers/gpu/drm/xe/xe_memirq_types.h index 9d0f6c1cdb9d..c2b0b33d55cd 100644 --- a/drivers/gpu/drm/xe/xe_memirq_types.h +++ b/drivers/gpu/drm/xe/xe_memirq_types.h @@ -10,27 +10,18 @@ struct xe_bo; -/* ISR */ -#define XE_MEMIRQ_STATUS_OFFSET(inst) ((inst) * SZ_4K + 0x0) -/* IIR */ -#define XE_MEMIRQ_SOURCE_OFFSET(inst) ((inst) * SZ_4K + 0x400) -/* IMR */ -#define XE_MEMIRQ_ENABLE_OFFSET 0x440 - /** * struct xe_memirq - Data used by the `Memory Based Interrupts`_. * * @bo: buffer object with `Memory Based Interrupts Page Layout`_. + * @num_pages: number of per-instance source/status pages. * @source: iosys pointer to `Interrupt Source Report Page`_. - * @status: iosys pointer to `Interrupt Status Report Page`_. - * @mask: iosys pointer to Interrupt Enable Mask. * @enabled: internal flag used to control processing of the interrupts. */ struct xe_memirq { struct xe_bo *bo; + unsigned int num_pages; struct iosys_map source; - struct iosys_map status; - struct iosys_map mask; bool enabled; }; diff --git a/drivers/gpu/drm/xe/xe_oa.c b/drivers/gpu/drm/xe/xe_oa.c index 7c9071abb44f..4bf4b1f65929 100644 --- a/drivers/gpu/drm/xe/xe_oa.c +++ b/drivers/gpu/drm/xe/xe_oa.c @@ -2051,8 +2051,10 @@ int xe_oa_stream_open_ioctl(struct drm_device *dev, u64 data, struct drm_file *f if (XE_IOCTL_DBG(oa->xe, !param.exec_q)) return -ENOENT; - if (XE_IOCTL_DBG(oa->xe, param.exec_q->width > 1)) - return -EOPNOTSUPP; + if (XE_IOCTL_DBG(oa->xe, param.exec_q->width > 1)) { + ret = -EOPNOTSUPP; + goto err_exec_q; + } } /* diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c index 12d3be7f9f6c..1243c7d8ed10 100644 --- a/drivers/gpu/drm/xe/xe_pci.c +++ b/drivers/gpu/drm/xe/xe_pci.c @@ -444,6 +444,7 @@ static const struct xe_device_desc nvls_desc = { .has_display = true, .has_flat_ccs = 1, .has_pre_prod_wa = 1, + .has_sriov = true, .max_gt_per_tile = 2, MULTI_LRC_MASK, .require_force_probe = true, @@ -482,6 +483,7 @@ static const struct xe_device_desc nvlp_desc = { .has_flat_ccs = 1, .has_page_reclaim_hw_assist = true, .has_pre_prod_wa = true, + .has_sriov = true, .max_gt_per_tile = 2, MULTI_LRC_MASK, .require_force_probe = true, diff --git a/drivers/gpu/drm/xe/xe_reg_sr.c b/drivers/gpu/drm/xe/xe_reg_sr.c index 2df0277efb2f..e328f5072557 100644 --- a/drivers/gpu/drm/xe/xe_reg_sr.c +++ b/drivers/gpu/drm/xe/xe_reg_sr.c @@ -70,14 +70,49 @@ static void reg_sr_inc_error(struct xe_reg_sr *sr) #endif } +static struct xe_reg sanitize_mcr(struct xe_reg_sr *sr, + const struct xe_reg_sr_entry *e, + struct xe_gt *gt) +{ + struct xe_reg reg = e->reg; + bool is_mcr; + + /* + * We need the gt structure to check MCR ranges. + */ + if (!gt) + return reg; + + is_mcr = xe_gt_mcr_check_reg(gt, reg); + + if (is_mcr && !reg.mcr) { + reg.mcr = 1; + xe_gt_notice(gt, "xe_reg_sr_entry using non-MCR register for address 0x%x, forcing MCR\n", + reg.addr); + reg_sr_inc_error(sr); + } + + if (!is_mcr && reg.mcr) { + reg.mcr = 0; + xe_gt_notice(gt, "xe_reg_sr_entry using MCR register for address 0x%x, forcing non-MCR\n", + reg.addr); + reg_sr_inc_error(sr); + } + + return reg; +} + int xe_reg_sr_add(struct xe_reg_sr *sr, const struct xe_reg_sr_entry *e, struct xe_gt *gt) { unsigned long idx = e->reg.addr; struct xe_reg_sr_entry *pentry = xa_load(&sr->xa, idx); + struct xe_reg reg; int ret; + reg = sanitize_mcr(sr, e, gt); + if (pentry) { if (!compatible_entries(pentry, e)) { ret = -EINVAL; @@ -98,6 +133,7 @@ int xe_reg_sr_add(struct xe_reg_sr *sr, } *pentry = *e; + pentry->reg = reg; ret = xa_err(xa_store(&sr->xa, idx, pentry, GFP_KERNEL)); if (ret) goto fail_free; diff --git a/drivers/gpu/drm/xe/xe_tuning.c b/drivers/gpu/drm/xe/xe_tuning.c index ce39b77a084a..9a1b3862e192 100644 --- a/drivers/gpu/drm/xe/xe_tuning.c +++ b/drivers/gpu/drm/xe/xe_tuning.c @@ -134,7 +134,7 @@ static const struct xe_rtp_entry_sr engine_tunings[] = { static const struct xe_rtp_entry_sr lrc_tunings[] = { { XE_RTP_NAME("Tuning: Windower HW Filtering"), XE_RTP_RULES(GRAPHICS_VERSION_RANGE(3000, 3599), ENGINE_CLASS(RENDER)), - XE_RTP_ACTIONS(SET(COMMON_SLICE_CHICKEN4, HW_FILTERING)) + XE_RTP_ACTIONS(SET(XEHP_COMMON_SLICE_CHICKEN4, HW_FILTERING)) }, /* DG2 */ diff --git a/drivers/gpu/drm/xe/xe_wa.c b/drivers/gpu/drm/xe/xe_wa.c index 49f5e3e4c7cc..cb811f8a7781 100644 --- a/drivers/gpu/drm/xe/xe_wa.c +++ b/drivers/gpu/drm/xe/xe_wa.c @@ -664,7 +664,7 @@ static const struct xe_rtp_entry_sr lrc_was[] = { }, { XE_RTP_NAME("18033852989"), XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2004), ENGINE_CLASS(RENDER)), - XE_RTP_ACTIONS(SET(COMMON_SLICE_CHICKEN1, DISABLE_BOTTOM_CLIP_RECTANGLE_TEST)) + XE_RTP_ACTIONS(SET(XEHP_COMMON_SLICE_CHICKEN1, DISABLE_BOTTOM_CLIP_RECTANGLE_TEST)) }, { XE_RTP_NAME("15016589081"), XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2004), ENGINE_CLASS(RENDER)), @@ -767,7 +767,7 @@ static const struct xe_rtp_entry_sr lrc_was[] = { }, { XE_RTP_NAME("22021007897"), XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), ENGINE_CLASS(RENDER)), - XE_RTP_ACTIONS(SET(COMMON_SLICE_CHICKEN4, SBE_PUSH_CONSTANT_BEHIND_FIX_ENABLE)) + XE_RTP_ACTIONS(SET(XEHP_COMMON_SLICE_CHICKEN4, SBE_PUSH_CONSTANT_BEHIND_FIX_ENABLE)) }, /* Xe3_LPG */ @@ -783,7 +783,7 @@ static const struct xe_rtp_entry_sr lrc_was[] = { }, { XE_RTP_NAME("22021007897"), XE_RTP_RULES(GRAPHICS_VERSION_RANGE(3000, 3005), ENGINE_CLASS(RENDER)), - XE_RTP_ACTIONS(SET(COMMON_SLICE_CHICKEN4, SBE_PUSH_CONSTANT_BEHIND_FIX_ENABLE)) + XE_RTP_ACTIONS(SET(XEHP_COMMON_SLICE_CHICKEN4, SBE_PUSH_CONSTANT_BEHIND_FIX_ENABLE)) }, { XE_RTP_NAME("14024681466"), XE_RTP_RULES(GRAPHICS_VERSION_RANGE(3000, 3005), ENGINE_CLASS(RENDER)),