Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'drm-fixes-2025-06-28' of https://gitlab.freedesktop.org/drm/kernel

Pull drm fixes from Dave Airlie:
"Regular weekly drm updates, nothing out of the ordinary, amdgpu, xe,
i915 and a few misc bits. Seems about right for this time in the
release cycle.

core:
- fix drm_writeback_connector_cleanup function signature
- use correct HDMI audio bridge in drm_connector_hdmi_audio_init

bridge:
- SN65DSI86: fix HPD

amdgpu:
- Cleaner shader support for additional GFX9 GPUs
- MES firmware compatibility fixes
- Discovery error reporting fixes
- SDMA6/7 userq fixes
- Backlight fix
- EDID sanity check

i915:
- Fix for SNPS PHY HDMI for 1080p@120Hz
- Correct DP AUX DPCD probe address
- Followup build fix for GCOV and AutoFDO enabled config

xe:
- Missing error check
- Fix xe_hwmon_power_max_write
- Move flushes
- Explicitly exit CT safe mode on unwind
- Process deferred GGTT node removals on device unwind"

* tag 'drm-fixes-2025-06-28' of https://gitlab.freedesktop.org/drm/kernel:
drm/xe: Process deferred GGTT node removals on device unwind
drm/xe/guc: Explicitly exit CT safe mode on unwind
drm/xe: move DPT l2 flush to a more sensible place
drm/xe: Move DSB l2 flush to a more sensible place
drm/bridge: ti-sn65dsi86: Add HPD for DisplayPort connector type
drm/i915: fix build error some more
drm/xe/hwmon: Fix xe_hwmon_power_max_write
drm/xe/display: Add check for alloc_ordered_workqueue()
drm/amd/display: Add sanity checks for drm_edid_raw()
drm/amd/display: Fix AMDGPU_MAX_BL_LEVEL value
drm/amdgpu/sdma7: add ucode version checks for userq support
drm/amdgpu/sdma6: add ucode version checks for userq support
drm/amd: Adjust output for discovery error handling
drm/amdgpu/mes: add compatibility checks for set_hw_resource_1
drm/amdgpu/gfx9: Add Cleaner Shader Support for GFX9.x GPUs
drm/bridge-connector: Fix bridge in drm_connector_hdmi_audio_init()
drm/dp: Change AUX DPCD probe address from DPCD_REV to LANE0_1_STATUS
drm/i915/snps_hdmi_pll: Fix 64-bit divisor truncation by using div64_u64
drm: writeback: Fix drm_writeback_connector_cleanup signature

+189 -81
+13 -15
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
··· 321 321 const struct firmware *fw; 322 322 int r; 323 323 324 - r = request_firmware(&fw, fw_name, adev->dev); 324 + r = firmware_request_nowarn(&fw, fw_name, adev->dev); 325 325 if (r) { 326 - dev_err(adev->dev, "can't load firmware \"%s\"\n", 327 - fw_name); 326 + if (amdgpu_discovery == 2) 327 + dev_err(adev->dev, "can't load firmware \"%s\"\n", fw_name); 328 + else 329 + drm_info(&adev->ddev, "Optional firmware \"%s\" was not found\n", fw_name); 328 330 return r; 329 331 } 330 332 ··· 461 459 /* Read from file if it is the preferred option */ 462 460 fw_name = amdgpu_discovery_get_fw_name(adev); 463 461 if (fw_name != NULL) { 464 - dev_info(adev->dev, "use ip discovery information from file"); 462 + drm_dbg(&adev->ddev, "use ip discovery information from file"); 465 463 r = amdgpu_discovery_read_binary_from_file(adev, adev->mman.discovery_bin, fw_name); 466 - 467 - if (r) { 468 - dev_err(adev->dev, "failed to read ip discovery binary from file\n"); 469 - r = -EINVAL; 464 + if (r) 470 465 goto out; 471 - } 472 - 473 466 } else { 467 + drm_dbg(&adev->ddev, "use ip discovery information from memory"); 474 468 r = amdgpu_discovery_read_binary_from_mem( 475 469 adev, adev->mman.discovery_bin); 476 470 if (r) ··· 1336 1338 int r; 1337 1339 1338 1340 r = amdgpu_discovery_init(adev); 1339 - if (r) { 1340 - DRM_ERROR("amdgpu_discovery_init failed\n"); 1341 + if (r) 1341 1342 return r; 1342 - } 1343 1343 1344 1344 wafl_ver = 0; 1345 1345 adev->gfx.xcc_mask = 0; ··· 2575 2579 break; 2576 2580 default: 2577 2581 r = amdgpu_discovery_reg_base_init(adev); 2578 - if (r) 2579 - return -EINVAL; 2582 + if (r) { 2583 + drm_err(&adev->ddev, "discovery failed: %d\n", r); 2584 + return r; 2585 + } 2580 2586 2581 2587 amdgpu_discovery_harvest_ip(adev); 2582 2588 amdgpu_discovery_get_gfx_info(adev);
+19
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
··· 2235 2235 } 2236 2236 2237 2237 switch (amdgpu_ip_version(adev, GC_HWIP, 0)) { 2238 + case IP_VERSION(9, 0, 1): 2239 + case IP_VERSION(9, 2, 1): 2240 + case IP_VERSION(9, 4, 0): 2241 + case IP_VERSION(9, 2, 2): 2242 + case IP_VERSION(9, 1, 0): 2243 + case IP_VERSION(9, 3, 0): 2244 + adev->gfx.cleaner_shader_ptr = gfx_9_4_2_cleaner_shader_hex; 2245 + adev->gfx.cleaner_shader_size = sizeof(gfx_9_4_2_cleaner_shader_hex); 2246 + if (adev->gfx.me_fw_version >= 167 && 2247 + adev->gfx.pfp_fw_version >= 196 && 2248 + adev->gfx.mec_fw_version >= 474) { 2249 + adev->gfx.enable_cleaner_shader = true; 2250 + r = amdgpu_gfx_cleaner_shader_sw_init(adev, adev->gfx.cleaner_shader_size); 2251 + if (r) { 2252 + adev->gfx.enable_cleaner_shader = false; 2253 + dev_err(adev->dev, "Failed to initialize cleaner shader\n"); 2254 + } 2255 + } 2256 + break; 2238 2257 case IP_VERSION(9, 4, 2): 2239 2258 adev->gfx.cleaner_shader_ptr = gfx_9_4_2_cleaner_shader_hex; 2240 2259 adev->gfx.cleaner_shader_size = sizeof(gfx_9_4_2_cleaner_shader_hex);
+6 -4
drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
··· 1630 1630 if (r) 1631 1631 goto failure; 1632 1632 1633 - r = mes_v11_0_set_hw_resources_1(&adev->mes); 1634 - if (r) { 1635 - DRM_ERROR("failed mes_v11_0_set_hw_resources_1, r=%d\n", r); 1636 - goto failure; 1633 + if ((adev->mes.sched_version & AMDGPU_MES_VERSION_MASK) >= 0x50) { 1634 + r = mes_v11_0_set_hw_resources_1(&adev->mes); 1635 + if (r) { 1636 + DRM_ERROR("failed mes_v11_0_set_hw_resources_1, r=%d\n", r); 1637 + goto failure; 1638 + } 1637 1639 } 1638 1640 1639 1641 r = mes_v11_0_query_sched_status(&adev->mes);
+2 -1
drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
··· 1742 1742 if (r) 1743 1743 goto failure; 1744 1744 1745 - mes_v12_0_set_hw_resources_1(&adev->mes, AMDGPU_MES_SCHED_PIPE); 1745 + if ((adev->mes.sched_version & AMDGPU_MES_VERSION_MASK) >= 0x4b) 1746 + mes_v12_0_set_hw_resources_1(&adev->mes, AMDGPU_MES_SCHED_PIPE); 1746 1747 1747 1748 mes_v12_0_init_aggregated_doorbell(&adev->mes); 1748 1749
+16 -3
drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
··· 1374 1374 else 1375 1375 DRM_ERROR("Failed to allocated memory for SDMA IP Dump\n"); 1376 1376 1377 - /* add firmware version checks here */ 1378 - if (0 && !adev->sdma.disable_uq) 1379 - adev->userq_funcs[AMDGPU_HW_IP_DMA] = &userq_mes_funcs; 1377 + switch (amdgpu_ip_version(adev, SDMA0_HWIP, 0)) { 1378 + case IP_VERSION(6, 0, 0): 1379 + if ((adev->sdma.instance[0].fw_version >= 24) && !adev->sdma.disable_uq) 1380 + adev->userq_funcs[AMDGPU_HW_IP_DMA] = &userq_mes_funcs; 1381 + break; 1382 + case IP_VERSION(6, 0, 2): 1383 + if ((adev->sdma.instance[0].fw_version >= 21) && !adev->sdma.disable_uq) 1384 + adev->userq_funcs[AMDGPU_HW_IP_DMA] = &userq_mes_funcs; 1385 + break; 1386 + case IP_VERSION(6, 0, 3): 1387 + if ((adev->sdma.instance[0].fw_version >= 25) && !adev->sdma.disable_uq) 1388 + adev->userq_funcs[AMDGPU_HW_IP_DMA] = &userq_mes_funcs; 1389 + break; 1390 + default: 1391 + break; 1392 + } 1380 1393 1381 1394 r = amdgpu_sdma_sysfs_reset_mask_init(adev); 1382 1395 if (r)
+9 -3
drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
··· 1349 1349 else 1350 1350 DRM_ERROR("Failed to allocated memory for SDMA IP Dump\n"); 1351 1351 1352 - /* add firmware version checks here */ 1353 - if (0 && !adev->sdma.disable_uq) 1354 - adev->userq_funcs[AMDGPU_HW_IP_DMA] = &userq_mes_funcs; 1352 + switch (amdgpu_ip_version(adev, SDMA0_HWIP, 0)) { 1353 + case IP_VERSION(7, 0, 0): 1354 + case IP_VERSION(7, 0, 1): 1355 + if ((adev->sdma.instance[0].fw_version >= 7836028) && !adev->sdma.disable_uq) 1356 + adev->userq_funcs[AMDGPU_HW_IP_DMA] = &userq_mes_funcs; 1357 + break; 1358 + default: 1359 + break; 1360 + } 1355 1361 1356 1362 return r; 1357 1363 }
+5 -5
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
··· 4718 4718 return 1; 4719 4719 } 4720 4720 4721 - /* Rescale from [min..max] to [0..AMDGPU_MAX_BL_LEVEL] */ 4721 + /* Rescale from [min..max] to [0..MAX_BACKLIGHT_LEVEL] */ 4722 4722 static inline u32 scale_input_to_fw(int min, int max, u64 input) 4723 4723 { 4724 - return DIV_ROUND_CLOSEST_ULL(input * AMDGPU_MAX_BL_LEVEL, max - min); 4724 + return DIV_ROUND_CLOSEST_ULL(input * MAX_BACKLIGHT_LEVEL, max - min); 4725 4725 } 4726 4726 4727 - /* Rescale from [0..AMDGPU_MAX_BL_LEVEL] to [min..max] */ 4727 + /* Rescale from [0..MAX_BACKLIGHT_LEVEL] to [min..max] */ 4728 4728 static inline u32 scale_fw_to_input(int min, int max, u64 input) 4729 4729 { 4730 - return min + DIV_ROUND_CLOSEST_ULL(input * (max - min), AMDGPU_MAX_BL_LEVEL); 4730 + return min + DIV_ROUND_CLOSEST_ULL(input * (max - min), MAX_BACKLIGHT_LEVEL); 4731 4731 } 4732 4732 4733 4733 static void convert_custom_brightness(const struct amdgpu_dm_backlight_caps *caps, ··· 4947 4947 drm_dbg(drm, "Backlight caps: min: %d, max: %d, ac %d, dc %d\n", min, max, 4948 4948 caps->ac_level, caps->dc_level); 4949 4949 } else 4950 - props.brightness = props.max_brightness = AMDGPU_MAX_BL_LEVEL; 4950 + props.brightness = props.max_brightness = MAX_BACKLIGHT_LEVEL; 4951 4951 4952 4952 if (caps->data_points && !(amdgpu_dc_debug_mask & DC_DISABLE_CUSTOM_BRIGHTNESS_CURVE)) 4953 4953 drm_info(drm, "Using custom brightness curve\n");
+4
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
··· 1029 1029 return EDID_NO_RESPONSE; 1030 1030 1031 1031 edid = drm_edid_raw(drm_edid); // FIXME: Get rid of drm_edid_raw() 1032 + if (!edid || 1033 + edid->extensions >= sizeof(sink->dc_edid.raw_edid) / EDID_LENGTH) 1034 + return EDID_BAD_INPUT; 1035 + 1032 1036 sink->dc_edid.length = EDID_LENGTH * (edid->extensions + 1); 1033 1037 memmove(sink->dc_edid.raw_edid, (uint8_t *)edid, sink->dc_edid.length); 1034 1038
+60 -9
drivers/gpu/drm/bridge/ti-sn65dsi86.c
··· 348 348 * 200 ms. We'll assume that the panel driver will have the hardcoded 349 349 * delay in its prepare and always disable HPD. 350 350 * 351 - * If HPD somehow makes sense on some future panel we'll have to 352 - * change this to be conditional on someone specifying that HPD should 353 - * be used. 351 + * For DisplayPort bridge type, we need HPD. So we use the bridge type 352 + * to conditionally disable HPD. 353 + * NOTE: The bridge type is set in ti_sn_bridge_probe() but enable_comms() 354 + * can be called before. So for DisplayPort, HPD will be enabled once 355 + * bridge type is set. We are using bridge type instead of "no-hpd" 356 + * property because it is not used properly in devicetree description 357 + * and hence is unreliable. 354 358 */ 355 - regmap_update_bits(pdata->regmap, SN_HPD_DISABLE_REG, HPD_DISABLE, 356 - HPD_DISABLE); 359 + 360 + if (pdata->bridge.type != DRM_MODE_CONNECTOR_DisplayPort) 361 + regmap_update_bits(pdata->regmap, SN_HPD_DISABLE_REG, HPD_DISABLE, 362 + HPD_DISABLE); 357 363 358 364 pdata->comms_enabled = true; 359 365 ··· 1201 1195 struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge); 1202 1196 int val = 0; 1203 1197 1204 - pm_runtime_get_sync(pdata->dev); 1198 + /* 1199 + * Runtime reference is grabbed in ti_sn_bridge_hpd_enable() 1200 + * as the chip won't report HPD just after being powered on. 1201 + * HPD_DEBOUNCED_STATE reflects correct state only after the 1202 + * debounce time (~100-400 ms). 1203 + */ 1204 + 1205 1205 regmap_read(pdata->regmap, SN_HPD_DISABLE_REG, &val); 1206 - pm_runtime_put_autosuspend(pdata->dev); 1207 1206 1208 1207 return val & HPD_DEBOUNCED_STATE ? connector_status_connected 1209 1208 : connector_status_disconnected; ··· 1231 1220 debugfs_create_file("status", 0600, debugfs, pdata, &status_fops); 1232 1221 } 1233 1222 1223 + static void ti_sn_bridge_hpd_enable(struct drm_bridge *bridge) 1224 + { 1225 + struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge); 1226 + 1227 + /* 1228 + * Device needs to be powered on before reading the HPD state 1229 + * for reliable hpd detection in ti_sn_bridge_detect() due to 1230 + * the high debounce time. 1231 + */ 1232 + 1233 + pm_runtime_get_sync(pdata->dev); 1234 + } 1235 + 1236 + static void ti_sn_bridge_hpd_disable(struct drm_bridge *bridge) 1237 + { 1238 + struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge); 1239 + 1240 + pm_runtime_put_autosuspend(pdata->dev); 1241 + } 1242 + 1234 1243 static const struct drm_bridge_funcs ti_sn_bridge_funcs = { 1235 1244 .attach = ti_sn_bridge_attach, 1236 1245 .detach = ti_sn_bridge_detach, ··· 1265 1234 .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, 1266 1235 .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, 1267 1236 .debugfs_init = ti_sn65dsi86_debugfs_init, 1237 + .hpd_enable = ti_sn_bridge_hpd_enable, 1238 + .hpd_disable = ti_sn_bridge_hpd_disable, 1268 1239 }; 1269 1240 1270 1241 static void ti_sn_bridge_parse_lanes(struct ti_sn65dsi86 *pdata, ··· 1354 1321 pdata->bridge.type = pdata->next_bridge->type == DRM_MODE_CONNECTOR_DisplayPort 1355 1322 ? DRM_MODE_CONNECTOR_DisplayPort : DRM_MODE_CONNECTOR_eDP; 1356 1323 1357 - if (pdata->bridge.type == DRM_MODE_CONNECTOR_DisplayPort) 1358 - pdata->bridge.ops = DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_DETECT; 1324 + if (pdata->bridge.type == DRM_MODE_CONNECTOR_DisplayPort) { 1325 + pdata->bridge.ops = DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_DETECT | 1326 + DRM_BRIDGE_OP_HPD; 1327 + /* 1328 + * If comms were already enabled they would have been enabled 1329 + * with the wrong value of HPD_DISABLE. Update it now. Comms 1330 + * could be enabled if anyone is holding a pm_runtime reference 1331 + * (like if a GPIO is in use). Note that in most cases nobody 1332 + * is doing AUX channel xfers before the bridge is added so 1333 + * HPD doesn't _really_ matter then. The only exception is in 1334 + * the eDP case where the panel wants to read the EDID before 1335 + * the bridge is added. We always consistently have HPD disabled 1336 + * for eDP. 1337 + */ 1338 + mutex_lock(&pdata->comms_mutex); 1339 + if (pdata->comms_enabled) 1340 + regmap_update_bits(pdata->regmap, SN_HPD_DISABLE_REG, 1341 + HPD_DISABLE, 0); 1342 + mutex_unlock(&pdata->comms_mutex); 1343 + }; 1359 1344 1360 1345 drm_bridge_add(&pdata->bridge); 1361 1346
+5 -2
drivers/gpu/drm/display/drm_bridge_connector.c
··· 708 708 if (bridge_connector->bridge_hdmi_audio || 709 709 bridge_connector->bridge_dp_audio) { 710 710 struct device *dev; 711 + struct drm_bridge *bridge; 711 712 712 713 if (bridge_connector->bridge_hdmi_audio) 713 - dev = bridge_connector->bridge_hdmi_audio->hdmi_audio_dev; 714 + bridge = bridge_connector->bridge_hdmi_audio; 714 715 else 715 - dev = bridge_connector->bridge_dp_audio->hdmi_audio_dev; 716 + bridge = bridge_connector->bridge_dp_audio; 717 + 718 + dev = bridge->hdmi_audio_dev; 716 719 717 720 ret = drm_connector_hdmi_audio_init(connector, dev, 718 721 &drm_bridge_connector_hdmi_audio_funcs,
+1 -1
drivers/gpu/drm/display/drm_dp_helper.c
··· 725 725 * monitor doesn't power down exactly after the throw away read. 726 726 */ 727 727 if (!aux->is_remote) { 728 - ret = drm_dp_dpcd_probe(aux, DP_DPCD_REV); 728 + ret = drm_dp_dpcd_probe(aux, DP_LANE0_1_STATUS); 729 729 if (ret < 0) 730 730 return ret; 731 731 }
+4 -3
drivers/gpu/drm/drm_writeback.c
··· 343 343 /** 344 344 * drm_writeback_connector_cleanup - Cleanup the writeback connector 345 345 * @dev: DRM device 346 - * @wb_connector: Pointer to the writeback connector to clean up 346 + * @data: Pointer to the writeback connector to clean up 347 347 * 348 348 * This will decrement the reference counter of blobs and destroy properties. It 349 349 * will also clean the remaining jobs in this writeback connector. Caution: This helper will not 350 350 * clean up the attached encoder and the drm_connector. 351 351 */ 352 352 static void drm_writeback_connector_cleanup(struct drm_device *dev, 353 - struct drm_writeback_connector *wb_connector) 353 + void *data) 354 354 { 355 355 unsigned long flags; 356 356 struct drm_writeback_job *pos, *n; 357 + struct drm_writeback_connector *wb_connector = data; 357 358 358 359 delete_writeback_properties(dev); 359 360 drm_property_blob_put(wb_connector->pixel_formats_blob_ptr); ··· 406 405 if (ret) 407 406 return ret; 408 407 409 - ret = drmm_add_action_or_reset(dev, (void *)drm_writeback_connector_cleanup, 408 + ret = drmm_add_action_or_reset(dev, drm_writeback_connector_cleanup, 410 409 wb_connector); 411 410 if (ret) 412 411 return ret;
+2 -2
drivers/gpu/drm/i915/display/intel_snps_hdmi_pll.c
··· 103 103 DIV_ROUND_DOWN_ULL(curve_1_interpolated, CURVE0_MULTIPLIER))); 104 104 105 105 ana_cp_int_temp = 106 - DIV_ROUND_CLOSEST_ULL(DIV_ROUND_DOWN_ULL(adjusted_vco_clk1, curve_2_scaled1), 107 - CURVE2_MULTIPLIER); 106 + DIV64_U64_ROUND_CLOSEST(DIV_ROUND_DOWN_ULL(adjusted_vco_clk1, curve_2_scaled1), 107 + CURVE2_MULTIPLIER); 108 108 109 109 *ana_cp_int = max(1, min(ana_cp_int_temp, 127)); 110 110
+1 -1
drivers/gpu/drm/i915/i915_pmu.c
··· 108 108 return other_bit(config); 109 109 } 110 110 111 - static u32 config_mask(const u64 config) 111 + static __always_inline u32 config_mask(const u64 config) 112 112 { 113 113 unsigned int bit = config_bit(config); 114 114
+2
drivers/gpu/drm/xe/display/xe_display.c
··· 104 104 spin_lock_init(&xe->display.fb_tracking.lock); 105 105 106 106 xe->display.hotplug.dp_wq = alloc_ordered_workqueue("xe-dp", 0); 107 + if (!xe->display.hotplug.dp_wq) 108 + return -ENOMEM; 107 109 108 110 return drmm_add_action_or_reset(&xe->drm, display_destroy, NULL); 109 111 }
+4 -7
drivers/gpu/drm/xe/display/xe_dsb_buffer.c
··· 17 17 18 18 void intel_dsb_buffer_write(struct intel_dsb_buffer *dsb_buf, u32 idx, u32 val) 19 19 { 20 - struct xe_device *xe = dsb_buf->vma->bo->tile->xe; 21 - 22 20 iosys_map_wr(&dsb_buf->vma->bo->vmap, idx * 4, u32, val); 23 - xe_device_l2_flush(xe); 24 21 } 25 22 26 23 u32 intel_dsb_buffer_read(struct intel_dsb_buffer *dsb_buf, u32 idx) ··· 27 30 28 31 void intel_dsb_buffer_memset(struct intel_dsb_buffer *dsb_buf, u32 idx, u32 val, size_t size) 29 32 { 30 - struct xe_device *xe = dsb_buf->vma->bo->tile->xe; 31 - 32 33 WARN_ON(idx > (dsb_buf->buf_size - size) / sizeof(*dsb_buf->cmd_buf)); 33 34 34 35 iosys_map_memset(&dsb_buf->vma->bo->vmap, idx * 4, val, size); 35 - xe_device_l2_flush(xe); 36 36 } 37 37 38 38 bool intel_dsb_buffer_create(struct intel_crtc *crtc, struct intel_dsb_buffer *dsb_buf, size_t size) ··· 68 74 69 75 void intel_dsb_buffer_flush_map(struct intel_dsb_buffer *dsb_buf) 70 76 { 77 + struct xe_device *xe = dsb_buf->vma->bo->tile->xe; 78 + 71 79 /* 72 80 * The memory barrier here is to ensure coherency of DSB vs MMIO, 73 81 * both for weak ordering archs and discrete cards. 74 82 */ 75 - xe_device_wmb(dsb_buf->vma->bo->tile->xe); 83 + xe_device_wmb(xe); 84 + xe_device_l2_flush(xe); 76 85 }
+3 -2
drivers/gpu/drm/xe/display/xe_fb_pin.c
··· 164 164 165 165 vma->dpt = dpt; 166 166 vma->node = dpt->ggtt_node[tile0->id]; 167 + 168 + /* Ensure DPT writes are flushed */ 169 + xe_device_l2_flush(xe); 167 170 return 0; 168 171 } 169 172 ··· 336 333 if (ret) 337 334 goto err_unpin; 338 335 339 - /* Ensure DPT writes are flushed */ 340 - xe_device_l2_flush(xe); 341 336 return vma; 342 337 343 338 err_unpin:
+1
drivers/gpu/drm/xe/regs/xe_mchbar_regs.h
··· 40 40 #define PCU_CR_PACKAGE_RAPL_LIMIT XE_REG(MCHBAR_MIRROR_BASE_SNB + 0x59a0) 41 41 #define PWR_LIM_VAL REG_GENMASK(14, 0) 42 42 #define PWR_LIM_EN REG_BIT(15) 43 + #define PWR_LIM REG_GENMASK(15, 0) 43 44 #define PWR_LIM_TIME REG_GENMASK(23, 17) 44 45 #define PWR_LIM_TIME_X REG_GENMASK(23, 22) 45 46 #define PWR_LIM_TIME_Y REG_GENMASK(21, 17)
+11
drivers/gpu/drm/xe/xe_ggtt.c
··· 201 201 .ggtt_set_pte = xe_ggtt_set_pte_and_flush, 202 202 }; 203 203 204 + static void dev_fini_ggtt(void *arg) 205 + { 206 + struct xe_ggtt *ggtt = arg; 207 + 208 + drain_workqueue(ggtt->wq); 209 + } 210 + 204 211 /** 205 212 * xe_ggtt_init_early - Early GGTT initialization 206 213 * @ggtt: the &xe_ggtt to be initialized ··· 261 254 primelockdep(ggtt); 262 255 263 256 err = drmm_add_action_or_reset(&xe->drm, ggtt_fini_early, ggtt); 257 + if (err) 258 + return err; 259 + 260 + err = devm_add_action_or_reset(xe->drm.dev, dev_fini_ggtt, ggtt); 264 261 if (err) 265 262 return err; 266 263
+6 -4
drivers/gpu/drm/xe/xe_guc_ct.c
··· 34 34 #include "xe_pm.h" 35 35 #include "xe_trace_guc.h" 36 36 37 + static void receive_g2h(struct xe_guc_ct *ct); 38 + static void g2h_worker_func(struct work_struct *w); 39 + static void safe_mode_worker_func(struct work_struct *w); 40 + static void ct_exit_safe_mode(struct xe_guc_ct *ct); 41 + 37 42 #if IS_ENABLED(CONFIG_DRM_XE_DEBUG) 38 43 enum { 39 44 /* Internal states, not error conditions */ ··· 191 186 { 192 187 struct xe_guc_ct *ct = arg; 193 188 189 + ct_exit_safe_mode(ct); 194 190 destroy_workqueue(ct->g2h_wq); 195 191 xa_destroy(&ct->fence_lookup); 196 192 } 197 - 198 - static void receive_g2h(struct xe_guc_ct *ct); 199 - static void g2h_worker_func(struct work_struct *w); 200 - static void safe_mode_worker_func(struct work_struct *w); 201 193 202 194 static void primelockdep(struct xe_guc_ct *ct) 203 195 {
+15 -19
drivers/gpu/drm/xe/xe_hwmon.c
··· 159 159 return ret; 160 160 } 161 161 162 - static int xe_hwmon_pcode_write_power_limit(const struct xe_hwmon *hwmon, u32 attr, u8 channel, 163 - u32 uval) 162 + static int xe_hwmon_pcode_rmw_power_limit(const struct xe_hwmon *hwmon, u32 attr, u8 channel, 163 + u32 clr, u32 set) 164 164 { 165 165 struct xe_tile *root_tile = xe_device_get_root_tile(hwmon->xe); 166 166 u32 val0, val1; ··· 179 179 channel, val0, val1, ret); 180 180 181 181 if (attr == PL1_HWMON_ATTR) 182 - val0 = uval; 182 + val0 = (val0 & ~clr) | set; 183 183 else 184 184 return -EIO; 185 185 ··· 339 339 if (hwmon->xe->info.has_mbx_power_limits) { 340 340 drm_dbg(&hwmon->xe->drm, "disabling %s on channel %d\n", 341 341 PWR_ATTR_TO_STR(attr), channel); 342 - xe_hwmon_pcode_write_power_limit(hwmon, attr, channel, 0); 342 + xe_hwmon_pcode_rmw_power_limit(hwmon, attr, channel, PWR_LIM_EN, 0); 343 343 xe_hwmon_pcode_read_power_limit(hwmon, attr, channel, &reg_val); 344 344 } else { 345 345 reg_val = xe_mmio_rmw32(mmio, rapl_limit, PWR_LIM_EN, 0); ··· 370 370 } 371 371 372 372 if (hwmon->xe->info.has_mbx_power_limits) 373 - ret = xe_hwmon_pcode_write_power_limit(hwmon, attr, channel, reg_val); 373 + ret = xe_hwmon_pcode_rmw_power_limit(hwmon, attr, channel, PWR_LIM, reg_val); 374 374 else 375 - reg_val = xe_mmio_rmw32(mmio, rapl_limit, PWR_LIM_EN | PWR_LIM_VAL, 376 - reg_val); 375 + reg_val = xe_mmio_rmw32(mmio, rapl_limit, PWR_LIM, reg_val); 377 376 unlock: 378 377 mutex_unlock(&hwmon->hwmon_lock); 379 378 return ret; ··· 562 563 563 564 mutex_lock(&hwmon->hwmon_lock); 564 565 565 - if (hwmon->xe->info.has_mbx_power_limits) { 566 - ret = xe_hwmon_pcode_read_power_limit(hwmon, power_attr, channel, (u32 *)&r); 567 - r = (r & ~PWR_LIM_TIME) | rxy; 568 - xe_hwmon_pcode_write_power_limit(hwmon, power_attr, channel, r); 569 - } else { 566 + if (hwmon->xe->info.has_mbx_power_limits) 567 + xe_hwmon_pcode_rmw_power_limit(hwmon, power_attr, channel, PWR_LIM_TIME, rxy); 568 + else 570 569 r = xe_mmio_rmw32(mmio, xe_hwmon_get_reg(hwmon, REG_PKG_RAPL_LIMIT, channel), 571 570 PWR_LIM_TIME, rxy); 572 - } 573 571 574 572 mutex_unlock(&hwmon->hwmon_lock); 575 573 ··· 1134 1138 } else { 1135 1139 drm_info(&hwmon->xe->drm, "Using mailbox commands for power limits\n"); 1136 1140 /* Write default limits to read from pcode from now on. */ 1137 - xe_hwmon_pcode_write_power_limit(hwmon, PL1_HWMON_ATTR, 1138 - CHANNEL_CARD, 1139 - hwmon->pl1_on_boot[CHANNEL_CARD]); 1140 - xe_hwmon_pcode_write_power_limit(hwmon, PL1_HWMON_ATTR, 1141 - CHANNEL_PKG, 1142 - hwmon->pl1_on_boot[CHANNEL_PKG]); 1141 + xe_hwmon_pcode_rmw_power_limit(hwmon, PL1_HWMON_ATTR, 1142 + CHANNEL_CARD, PWR_LIM | PWR_LIM_TIME, 1143 + hwmon->pl1_on_boot[CHANNEL_CARD]); 1144 + xe_hwmon_pcode_rmw_power_limit(hwmon, PL1_HWMON_ATTR, 1145 + CHANNEL_PKG, PWR_LIM | PWR_LIM_TIME, 1146 + hwmon->pl1_on_boot[CHANNEL_PKG]); 1143 1147 hwmon->scl_shift_power = PWR_UNIT; 1144 1148 hwmon->scl_shift_energy = ENERGY_UNIT; 1145 1149 hwmon->scl_shift_time = TIME_UNIT;