mirror of
https://github.com/torvalds/linux.git
synced 2026-06-05 21:15:53 +02:00
drm fixes for 6.16-rc4
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 -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEEKbZHaGwW9KfbeusDHTzWXnEhr4FAmhfBuMACgkQDHTzWXnE hr7W8g/9Gro8VxzVjiGuPXTP8em3B7mzw6FKWyGRHq4gRSPQySoEep6vh7iySFvp oFZjWEzLW1y9GElxfMss2zj4ZwRWo6x8VhjCqW6B8rM3HNgIAaMyF1IMWeb2tTHd QU+NAsMmy63VHp2gG8XrMWAP1cigXuI2bmCVsgqEl8bP0ZAU7ndlGD6WPENbpIvm +EH4Dnr8kC2V9SXzbKmZ9B3Vc4EDaHUyeVkDZ9eQfvYOwjY5gh8BXH2xdN95478X qUzGXUsfz2Z9vFJoCYThxtMjFiEyIc6A4ZOBE6CvEXk0ZE0+VasguVsBaa9b1lyW X/2GB3bhM20O5Y9zKW7CRdjUV7L0H4VAXT/yZNzbgF17lWTUTxCt1Q/tOaR2E0BG mRabuz/LWDGQrunUbFxcA8a1SNmmcxU1RVkvg3yn9ZoVLD/i89agUBj+Ef2+PYFr ukpyqy33lPBSEsWiqV7kVa6KYpIDOrNPzVfmLSA4mxDT1HrU0fZcRiExEG9WmiQm zNtdiCBEas0QVZ60VlH+pvPLz56eYaOvMzKHc1yTQk8hdMSqg0h/DG+HGkiA6z29 4jD/P5GXdjKiFaKNi1Z0Zc9jsLWsCdTsAOtXO34ZM+D70riyPTaBhcsCBMz0RCW5 XHqzdslf4OW5X/dY6jrlNY6hAm+JzRO0GhK//h8Z3van4BXiGRI= =AAHI -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
7abdafd234
|
|
@ -321,10 +321,12 @@ static int amdgpu_discovery_read_binary_from_file(struct amdgpu_device *adev,
|
|||
const struct firmware *fw;
|
||||
int r;
|
||||
|
||||
r = request_firmware(&fw, fw_name, adev->dev);
|
||||
r = firmware_request_nowarn(&fw, fw_name, adev->dev);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "can't load firmware \"%s\"\n",
|
||||
fw_name);
|
||||
if (amdgpu_discovery == 2)
|
||||
dev_err(adev->dev, "can't load firmware \"%s\"\n", fw_name);
|
||||
else
|
||||
drm_info(&adev->ddev, "Optional firmware \"%s\" was not found\n", fw_name);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
@ -459,16 +461,12 @@ static int amdgpu_discovery_init(struct amdgpu_device *adev)
|
|||
/* Read from file if it is the preferred option */
|
||||
fw_name = amdgpu_discovery_get_fw_name(adev);
|
||||
if (fw_name != NULL) {
|
||||
dev_info(adev->dev, "use ip discovery information from file");
|
||||
drm_dbg(&adev->ddev, "use ip discovery information from file");
|
||||
r = amdgpu_discovery_read_binary_from_file(adev, adev->mman.discovery_bin, fw_name);
|
||||
|
||||
if (r) {
|
||||
dev_err(adev->dev, "failed to read ip discovery binary from file\n");
|
||||
r = -EINVAL;
|
||||
if (r)
|
||||
goto out;
|
||||
}
|
||||
|
||||
} else {
|
||||
drm_dbg(&adev->ddev, "use ip discovery information from memory");
|
||||
r = amdgpu_discovery_read_binary_from_mem(
|
||||
adev, adev->mman.discovery_bin);
|
||||
if (r)
|
||||
|
|
@ -1338,10 +1336,8 @@ static int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev)
|
|||
int r;
|
||||
|
||||
r = amdgpu_discovery_init(adev);
|
||||
if (r) {
|
||||
DRM_ERROR("amdgpu_discovery_init failed\n");
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
wafl_ver = 0;
|
||||
adev->gfx.xcc_mask = 0;
|
||||
|
|
@ -2579,8 +2575,10 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
|
|||
break;
|
||||
default:
|
||||
r = amdgpu_discovery_reg_base_init(adev);
|
||||
if (r)
|
||||
return -EINVAL;
|
||||
if (r) {
|
||||
drm_err(&adev->ddev, "discovery failed: %d\n", r);
|
||||
return r;
|
||||
}
|
||||
|
||||
amdgpu_discovery_harvest_ip(adev);
|
||||
amdgpu_discovery_get_gfx_info(adev);
|
||||
|
|
|
|||
|
|
@ -2235,6 +2235,25 @@ static int gfx_v9_0_sw_init(struct amdgpu_ip_block *ip_block)
|
|||
}
|
||||
|
||||
switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
|
||||
case IP_VERSION(9, 0, 1):
|
||||
case IP_VERSION(9, 2, 1):
|
||||
case IP_VERSION(9, 4, 0):
|
||||
case IP_VERSION(9, 2, 2):
|
||||
case IP_VERSION(9, 1, 0):
|
||||
case IP_VERSION(9, 3, 0):
|
||||
adev->gfx.cleaner_shader_ptr = gfx_9_4_2_cleaner_shader_hex;
|
||||
adev->gfx.cleaner_shader_size = sizeof(gfx_9_4_2_cleaner_shader_hex);
|
||||
if (adev->gfx.me_fw_version >= 167 &&
|
||||
adev->gfx.pfp_fw_version >= 196 &&
|
||||
adev->gfx.mec_fw_version >= 474) {
|
||||
adev->gfx.enable_cleaner_shader = true;
|
||||
r = amdgpu_gfx_cleaner_shader_sw_init(adev, adev->gfx.cleaner_shader_size);
|
||||
if (r) {
|
||||
adev->gfx.enable_cleaner_shader = false;
|
||||
dev_err(adev->dev, "Failed to initialize cleaner shader\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IP_VERSION(9, 4, 2):
|
||||
adev->gfx.cleaner_shader_ptr = gfx_9_4_2_cleaner_shader_hex;
|
||||
adev->gfx.cleaner_shader_size = sizeof(gfx_9_4_2_cleaner_shader_hex);
|
||||
|
|
|
|||
|
|
@ -1630,10 +1630,12 @@ static int mes_v11_0_hw_init(struct amdgpu_ip_block *ip_block)
|
|||
if (r)
|
||||
goto failure;
|
||||
|
||||
r = mes_v11_0_set_hw_resources_1(&adev->mes);
|
||||
if (r) {
|
||||
DRM_ERROR("failed mes_v11_0_set_hw_resources_1, r=%d\n", r);
|
||||
goto failure;
|
||||
if ((adev->mes.sched_version & AMDGPU_MES_VERSION_MASK) >= 0x50) {
|
||||
r = mes_v11_0_set_hw_resources_1(&adev->mes);
|
||||
if (r) {
|
||||
DRM_ERROR("failed mes_v11_0_set_hw_resources_1, r=%d\n", r);
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
|
||||
r = mes_v11_0_query_sched_status(&adev->mes);
|
||||
|
|
|
|||
|
|
@ -1742,7 +1742,8 @@ static int mes_v12_0_hw_init(struct amdgpu_ip_block *ip_block)
|
|||
if (r)
|
||||
goto failure;
|
||||
|
||||
mes_v12_0_set_hw_resources_1(&adev->mes, AMDGPU_MES_SCHED_PIPE);
|
||||
if ((adev->mes.sched_version & AMDGPU_MES_VERSION_MASK) >= 0x4b)
|
||||
mes_v12_0_set_hw_resources_1(&adev->mes, AMDGPU_MES_SCHED_PIPE);
|
||||
|
||||
mes_v12_0_init_aggregated_doorbell(&adev->mes);
|
||||
|
||||
|
|
|
|||
|
|
@ -1374,9 +1374,22 @@ static int sdma_v6_0_sw_init(struct amdgpu_ip_block *ip_block)
|
|||
else
|
||||
DRM_ERROR("Failed to allocated memory for SDMA IP Dump\n");
|
||||
|
||||
/* add firmware version checks here */
|
||||
if (0 && !adev->sdma.disable_uq)
|
||||
adev->userq_funcs[AMDGPU_HW_IP_DMA] = &userq_mes_funcs;
|
||||
switch (amdgpu_ip_version(adev, SDMA0_HWIP, 0)) {
|
||||
case IP_VERSION(6, 0, 0):
|
||||
if ((adev->sdma.instance[0].fw_version >= 24) && !adev->sdma.disable_uq)
|
||||
adev->userq_funcs[AMDGPU_HW_IP_DMA] = &userq_mes_funcs;
|
||||
break;
|
||||
case IP_VERSION(6, 0, 2):
|
||||
if ((adev->sdma.instance[0].fw_version >= 21) && !adev->sdma.disable_uq)
|
||||
adev->userq_funcs[AMDGPU_HW_IP_DMA] = &userq_mes_funcs;
|
||||
break;
|
||||
case IP_VERSION(6, 0, 3):
|
||||
if ((adev->sdma.instance[0].fw_version >= 25) && !adev->sdma.disable_uq)
|
||||
adev->userq_funcs[AMDGPU_HW_IP_DMA] = &userq_mes_funcs;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
r = amdgpu_sdma_sysfs_reset_mask_init(adev);
|
||||
if (r)
|
||||
|
|
|
|||
|
|
@ -1349,9 +1349,15 @@ static int sdma_v7_0_sw_init(struct amdgpu_ip_block *ip_block)
|
|||
else
|
||||
DRM_ERROR("Failed to allocated memory for SDMA IP Dump\n");
|
||||
|
||||
/* add firmware version checks here */
|
||||
if (0 && !adev->sdma.disable_uq)
|
||||
adev->userq_funcs[AMDGPU_HW_IP_DMA] = &userq_mes_funcs;
|
||||
switch (amdgpu_ip_version(adev, SDMA0_HWIP, 0)) {
|
||||
case IP_VERSION(7, 0, 0):
|
||||
case IP_VERSION(7, 0, 1):
|
||||
if ((adev->sdma.instance[0].fw_version >= 7836028) && !adev->sdma.disable_uq)
|
||||
adev->userq_funcs[AMDGPU_HW_IP_DMA] = &userq_mes_funcs;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4718,16 +4718,16 @@ static int get_brightness_range(const struct amdgpu_dm_backlight_caps *caps,
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* Rescale from [min..max] to [0..AMDGPU_MAX_BL_LEVEL] */
|
||||
/* Rescale from [min..max] to [0..MAX_BACKLIGHT_LEVEL] */
|
||||
static inline u32 scale_input_to_fw(int min, int max, u64 input)
|
||||
{
|
||||
return DIV_ROUND_CLOSEST_ULL(input * AMDGPU_MAX_BL_LEVEL, max - min);
|
||||
return DIV_ROUND_CLOSEST_ULL(input * MAX_BACKLIGHT_LEVEL, max - min);
|
||||
}
|
||||
|
||||
/* Rescale from [0..AMDGPU_MAX_BL_LEVEL] to [min..max] */
|
||||
/* Rescale from [0..MAX_BACKLIGHT_LEVEL] to [min..max] */
|
||||
static inline u32 scale_fw_to_input(int min, int max, u64 input)
|
||||
{
|
||||
return min + DIV_ROUND_CLOSEST_ULL(input * (max - min), AMDGPU_MAX_BL_LEVEL);
|
||||
return min + DIV_ROUND_CLOSEST_ULL(input * (max - min), MAX_BACKLIGHT_LEVEL);
|
||||
}
|
||||
|
||||
static void convert_custom_brightness(const struct amdgpu_dm_backlight_caps *caps,
|
||||
|
|
@ -4947,7 +4947,7 @@ amdgpu_dm_register_backlight_device(struct amdgpu_dm_connector *aconnector)
|
|||
drm_dbg(drm, "Backlight caps: min: %d, max: %d, ac %d, dc %d\n", min, max,
|
||||
caps->ac_level, caps->dc_level);
|
||||
} else
|
||||
props.brightness = props.max_brightness = AMDGPU_MAX_BL_LEVEL;
|
||||
props.brightness = props.max_brightness = MAX_BACKLIGHT_LEVEL;
|
||||
|
||||
if (caps->data_points && !(amdgpu_dc_debug_mask & DC_DISABLE_CUSTOM_BRIGHTNESS_CURVE))
|
||||
drm_info(drm, "Using custom brightness curve\n");
|
||||
|
|
|
|||
|
|
@ -1029,6 +1029,10 @@ enum dc_edid_status dm_helpers_read_local_edid(
|
|||
return EDID_NO_RESPONSE;
|
||||
|
||||
edid = drm_edid_raw(drm_edid); // FIXME: Get rid of drm_edid_raw()
|
||||
if (!edid ||
|
||||
edid->extensions >= sizeof(sink->dc_edid.raw_edid) / EDID_LENGTH)
|
||||
return EDID_BAD_INPUT;
|
||||
|
||||
sink->dc_edid.length = EDID_LENGTH * (edid->extensions + 1);
|
||||
memmove(sink->dc_edid.raw_edid, (uint8_t *)edid, sink->dc_edid.length);
|
||||
|
||||
|
|
|
|||
|
|
@ -348,12 +348,18 @@ static void ti_sn65dsi86_enable_comms(struct ti_sn65dsi86 *pdata,
|
|||
* 200 ms. We'll assume that the panel driver will have the hardcoded
|
||||
* delay in its prepare and always disable HPD.
|
||||
*
|
||||
* If HPD somehow makes sense on some future panel we'll have to
|
||||
* change this to be conditional on someone specifying that HPD should
|
||||
* be used.
|
||||
* For DisplayPort bridge type, we need HPD. So we use the bridge type
|
||||
* to conditionally disable HPD.
|
||||
* NOTE: The bridge type is set in ti_sn_bridge_probe() but enable_comms()
|
||||
* can be called before. So for DisplayPort, HPD will be enabled once
|
||||
* bridge type is set. We are using bridge type instead of "no-hpd"
|
||||
* property because it is not used properly in devicetree description
|
||||
* and hence is unreliable.
|
||||
*/
|
||||
regmap_update_bits(pdata->regmap, SN_HPD_DISABLE_REG, HPD_DISABLE,
|
||||
HPD_DISABLE);
|
||||
|
||||
if (pdata->bridge.type != DRM_MODE_CONNECTOR_DisplayPort)
|
||||
regmap_update_bits(pdata->regmap, SN_HPD_DISABLE_REG, HPD_DISABLE,
|
||||
HPD_DISABLE);
|
||||
|
||||
pdata->comms_enabled = true;
|
||||
|
||||
|
|
@ -1195,9 +1201,14 @@ static enum drm_connector_status ti_sn_bridge_detect(struct drm_bridge *bridge)
|
|||
struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge);
|
||||
int val = 0;
|
||||
|
||||
pm_runtime_get_sync(pdata->dev);
|
||||
/*
|
||||
* Runtime reference is grabbed in ti_sn_bridge_hpd_enable()
|
||||
* as the chip won't report HPD just after being powered on.
|
||||
* HPD_DEBOUNCED_STATE reflects correct state only after the
|
||||
* debounce time (~100-400 ms).
|
||||
*/
|
||||
|
||||
regmap_read(pdata->regmap, SN_HPD_DISABLE_REG, &val);
|
||||
pm_runtime_put_autosuspend(pdata->dev);
|
||||
|
||||
return val & HPD_DEBOUNCED_STATE ? connector_status_connected
|
||||
: connector_status_disconnected;
|
||||
|
|
@ -1220,6 +1231,26 @@ static void ti_sn65dsi86_debugfs_init(struct drm_bridge *bridge, struct dentry *
|
|||
debugfs_create_file("status", 0600, debugfs, pdata, &status_fops);
|
||||
}
|
||||
|
||||
static void ti_sn_bridge_hpd_enable(struct drm_bridge *bridge)
|
||||
{
|
||||
struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge);
|
||||
|
||||
/*
|
||||
* Device needs to be powered on before reading the HPD state
|
||||
* for reliable hpd detection in ti_sn_bridge_detect() due to
|
||||
* the high debounce time.
|
||||
*/
|
||||
|
||||
pm_runtime_get_sync(pdata->dev);
|
||||
}
|
||||
|
||||
static void ti_sn_bridge_hpd_disable(struct drm_bridge *bridge)
|
||||
{
|
||||
struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge);
|
||||
|
||||
pm_runtime_put_autosuspend(pdata->dev);
|
||||
}
|
||||
|
||||
static const struct drm_bridge_funcs ti_sn_bridge_funcs = {
|
||||
.attach = ti_sn_bridge_attach,
|
||||
.detach = ti_sn_bridge_detach,
|
||||
|
|
@ -1234,6 +1265,8 @@ static const struct drm_bridge_funcs ti_sn_bridge_funcs = {
|
|||
.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
|
||||
.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
|
||||
.debugfs_init = ti_sn65dsi86_debugfs_init,
|
||||
.hpd_enable = ti_sn_bridge_hpd_enable,
|
||||
.hpd_disable = ti_sn_bridge_hpd_disable,
|
||||
};
|
||||
|
||||
static void ti_sn_bridge_parse_lanes(struct ti_sn65dsi86 *pdata,
|
||||
|
|
@ -1321,8 +1354,26 @@ static int ti_sn_bridge_probe(struct auxiliary_device *adev,
|
|||
pdata->bridge.type = pdata->next_bridge->type == DRM_MODE_CONNECTOR_DisplayPort
|
||||
? DRM_MODE_CONNECTOR_DisplayPort : DRM_MODE_CONNECTOR_eDP;
|
||||
|
||||
if (pdata->bridge.type == DRM_MODE_CONNECTOR_DisplayPort)
|
||||
pdata->bridge.ops = DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_DETECT;
|
||||
if (pdata->bridge.type == DRM_MODE_CONNECTOR_DisplayPort) {
|
||||
pdata->bridge.ops = DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_DETECT |
|
||||
DRM_BRIDGE_OP_HPD;
|
||||
/*
|
||||
* If comms were already enabled they would have been enabled
|
||||
* with the wrong value of HPD_DISABLE. Update it now. Comms
|
||||
* could be enabled if anyone is holding a pm_runtime reference
|
||||
* (like if a GPIO is in use). Note that in most cases nobody
|
||||
* is doing AUX channel xfers before the bridge is added so
|
||||
* HPD doesn't _really_ matter then. The only exception is in
|
||||
* the eDP case where the panel wants to read the EDID before
|
||||
* the bridge is added. We always consistently have HPD disabled
|
||||
* for eDP.
|
||||
*/
|
||||
mutex_lock(&pdata->comms_mutex);
|
||||
if (pdata->comms_enabled)
|
||||
regmap_update_bits(pdata->regmap, SN_HPD_DISABLE_REG,
|
||||
HPD_DISABLE, 0);
|
||||
mutex_unlock(&pdata->comms_mutex);
|
||||
};
|
||||
|
||||
drm_bridge_add(&pdata->bridge);
|
||||
|
||||
|
|
|
|||
|
|
@ -708,11 +708,14 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
|
|||
if (bridge_connector->bridge_hdmi_audio ||
|
||||
bridge_connector->bridge_dp_audio) {
|
||||
struct device *dev;
|
||||
struct drm_bridge *bridge;
|
||||
|
||||
if (bridge_connector->bridge_hdmi_audio)
|
||||
dev = bridge_connector->bridge_hdmi_audio->hdmi_audio_dev;
|
||||
bridge = bridge_connector->bridge_hdmi_audio;
|
||||
else
|
||||
dev = bridge_connector->bridge_dp_audio->hdmi_audio_dev;
|
||||
bridge = bridge_connector->bridge_dp_audio;
|
||||
|
||||
dev = bridge->hdmi_audio_dev;
|
||||
|
||||
ret = drm_connector_hdmi_audio_init(connector, dev,
|
||||
&drm_bridge_connector_hdmi_audio_funcs,
|
||||
|
|
|
|||
|
|
@ -725,7 +725,7 @@ ssize_t drm_dp_dpcd_read(struct drm_dp_aux *aux, unsigned int offset,
|
|||
* monitor doesn't power down exactly after the throw away read.
|
||||
*/
|
||||
if (!aux->is_remote) {
|
||||
ret = drm_dp_dpcd_probe(aux, DP_DPCD_REV);
|
||||
ret = drm_dp_dpcd_probe(aux, DP_LANE0_1_STATUS);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -343,17 +343,18 @@ EXPORT_SYMBOL(drm_writeback_connector_init_with_encoder);
|
|||
/**
|
||||
* drm_writeback_connector_cleanup - Cleanup the writeback connector
|
||||
* @dev: DRM device
|
||||
* @wb_connector: Pointer to the writeback connector to clean up
|
||||
* @data: Pointer to the writeback connector to clean up
|
||||
*
|
||||
* This will decrement the reference counter of blobs and destroy properties. It
|
||||
* will also clean the remaining jobs in this writeback connector. Caution: This helper will not
|
||||
* clean up the attached encoder and the drm_connector.
|
||||
*/
|
||||
static void drm_writeback_connector_cleanup(struct drm_device *dev,
|
||||
struct drm_writeback_connector *wb_connector)
|
||||
void *data)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct drm_writeback_job *pos, *n;
|
||||
struct drm_writeback_connector *wb_connector = data;
|
||||
|
||||
delete_writeback_properties(dev);
|
||||
drm_property_blob_put(wb_connector->pixel_formats_blob_ptr);
|
||||
|
|
@ -405,7 +406,7 @@ int drmm_writeback_connector_init(struct drm_device *dev,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = drmm_add_action_or_reset(dev, (void *)drm_writeback_connector_cleanup,
|
||||
ret = drmm_add_action_or_reset(dev, drm_writeback_connector_cleanup,
|
||||
wb_connector);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -103,8 +103,8 @@ static void get_ana_cp_int_prop(u64 vco_clk,
|
|||
DIV_ROUND_DOWN_ULL(curve_1_interpolated, CURVE0_MULTIPLIER)));
|
||||
|
||||
ana_cp_int_temp =
|
||||
DIV_ROUND_CLOSEST_ULL(DIV_ROUND_DOWN_ULL(adjusted_vco_clk1, curve_2_scaled1),
|
||||
CURVE2_MULTIPLIER);
|
||||
DIV64_U64_ROUND_CLOSEST(DIV_ROUND_DOWN_ULL(adjusted_vco_clk1, curve_2_scaled1),
|
||||
CURVE2_MULTIPLIER);
|
||||
|
||||
*ana_cp_int = max(1, min(ana_cp_int_temp, 127));
|
||||
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ static unsigned int config_bit(const u64 config)
|
|||
return other_bit(config);
|
||||
}
|
||||
|
||||
static u32 config_mask(const u64 config)
|
||||
static __always_inline u32 config_mask(const u64 config)
|
||||
{
|
||||
unsigned int bit = config_bit(config);
|
||||
|
||||
|
|
|
|||
|
|
@ -104,6 +104,8 @@ int xe_display_create(struct xe_device *xe)
|
|||
spin_lock_init(&xe->display.fb_tracking.lock);
|
||||
|
||||
xe->display.hotplug.dp_wq = alloc_ordered_workqueue("xe-dp", 0);
|
||||
if (!xe->display.hotplug.dp_wq)
|
||||
return -ENOMEM;
|
||||
|
||||
return drmm_add_action_or_reset(&xe->drm, display_destroy, NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,10 +17,7 @@ u32 intel_dsb_buffer_ggtt_offset(struct intel_dsb_buffer *dsb_buf)
|
|||
|
||||
void intel_dsb_buffer_write(struct intel_dsb_buffer *dsb_buf, u32 idx, u32 val)
|
||||
{
|
||||
struct xe_device *xe = dsb_buf->vma->bo->tile->xe;
|
||||
|
||||
iosys_map_wr(&dsb_buf->vma->bo->vmap, idx * 4, u32, val);
|
||||
xe_device_l2_flush(xe);
|
||||
}
|
||||
|
||||
u32 intel_dsb_buffer_read(struct intel_dsb_buffer *dsb_buf, u32 idx)
|
||||
|
|
@ -30,12 +27,9 @@ u32 intel_dsb_buffer_read(struct intel_dsb_buffer *dsb_buf, u32 idx)
|
|||
|
||||
void intel_dsb_buffer_memset(struct intel_dsb_buffer *dsb_buf, u32 idx, u32 val, size_t size)
|
||||
{
|
||||
struct xe_device *xe = dsb_buf->vma->bo->tile->xe;
|
||||
|
||||
WARN_ON(idx > (dsb_buf->buf_size - size) / sizeof(*dsb_buf->cmd_buf));
|
||||
|
||||
iosys_map_memset(&dsb_buf->vma->bo->vmap, idx * 4, val, size);
|
||||
xe_device_l2_flush(xe);
|
||||
}
|
||||
|
||||
bool intel_dsb_buffer_create(struct intel_crtc *crtc, struct intel_dsb_buffer *dsb_buf, size_t size)
|
||||
|
|
@ -74,9 +68,12 @@ void intel_dsb_buffer_cleanup(struct intel_dsb_buffer *dsb_buf)
|
|||
|
||||
void intel_dsb_buffer_flush_map(struct intel_dsb_buffer *dsb_buf)
|
||||
{
|
||||
struct xe_device *xe = dsb_buf->vma->bo->tile->xe;
|
||||
|
||||
/*
|
||||
* The memory barrier here is to ensure coherency of DSB vs MMIO,
|
||||
* both for weak ordering archs and discrete cards.
|
||||
*/
|
||||
xe_device_wmb(dsb_buf->vma->bo->tile->xe);
|
||||
xe_device_wmb(xe);
|
||||
xe_device_l2_flush(xe);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -164,6 +164,9 @@ static int __xe_pin_fb_vma_dpt(const struct intel_framebuffer *fb,
|
|||
|
||||
vma->dpt = dpt;
|
||||
vma->node = dpt->ggtt_node[tile0->id];
|
||||
|
||||
/* Ensure DPT writes are flushed */
|
||||
xe_device_l2_flush(xe);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -333,8 +336,6 @@ static struct i915_vma *__xe_pin_fb_vma(const struct intel_framebuffer *fb,
|
|||
if (ret)
|
||||
goto err_unpin;
|
||||
|
||||
/* Ensure DPT writes are flushed */
|
||||
xe_device_l2_flush(xe);
|
||||
return vma;
|
||||
|
||||
err_unpin:
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
#define PCU_CR_PACKAGE_RAPL_LIMIT XE_REG(MCHBAR_MIRROR_BASE_SNB + 0x59a0)
|
||||
#define PWR_LIM_VAL REG_GENMASK(14, 0)
|
||||
#define PWR_LIM_EN REG_BIT(15)
|
||||
#define PWR_LIM REG_GENMASK(15, 0)
|
||||
#define PWR_LIM_TIME REG_GENMASK(23, 17)
|
||||
#define PWR_LIM_TIME_X REG_GENMASK(23, 22)
|
||||
#define PWR_LIM_TIME_Y REG_GENMASK(21, 17)
|
||||
|
|
|
|||
|
|
@ -201,6 +201,13 @@ static const struct xe_ggtt_pt_ops xelpg_pt_wa_ops = {
|
|||
.ggtt_set_pte = xe_ggtt_set_pte_and_flush,
|
||||
};
|
||||
|
||||
static void dev_fini_ggtt(void *arg)
|
||||
{
|
||||
struct xe_ggtt *ggtt = arg;
|
||||
|
||||
drain_workqueue(ggtt->wq);
|
||||
}
|
||||
|
||||
/**
|
||||
* xe_ggtt_init_early - Early GGTT initialization
|
||||
* @ggtt: the &xe_ggtt to be initialized
|
||||
|
|
@ -257,6 +264,10 @@ int xe_ggtt_init_early(struct xe_ggtt *ggtt)
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
err = devm_add_action_or_reset(xe->drm.dev, dev_fini_ggtt, ggtt);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (IS_SRIOV_VF(xe)) {
|
||||
err = xe_gt_sriov_vf_prepare_ggtt(xe_tile_get_gt(ggtt->tile, 0));
|
||||
if (err)
|
||||
|
|
|
|||
|
|
@ -34,6 +34,11 @@
|
|||
#include "xe_pm.h"
|
||||
#include "xe_trace_guc.h"
|
||||
|
||||
static void receive_g2h(struct xe_guc_ct *ct);
|
||||
static void g2h_worker_func(struct work_struct *w);
|
||||
static void safe_mode_worker_func(struct work_struct *w);
|
||||
static void ct_exit_safe_mode(struct xe_guc_ct *ct);
|
||||
|
||||
#if IS_ENABLED(CONFIG_DRM_XE_DEBUG)
|
||||
enum {
|
||||
/* Internal states, not error conditions */
|
||||
|
|
@ -186,14 +191,11 @@ static void guc_ct_fini(struct drm_device *drm, void *arg)
|
|||
{
|
||||
struct xe_guc_ct *ct = arg;
|
||||
|
||||
ct_exit_safe_mode(ct);
|
||||
destroy_workqueue(ct->g2h_wq);
|
||||
xa_destroy(&ct->fence_lookup);
|
||||
}
|
||||
|
||||
static void receive_g2h(struct xe_guc_ct *ct);
|
||||
static void g2h_worker_func(struct work_struct *w);
|
||||
static void safe_mode_worker_func(struct work_struct *w);
|
||||
|
||||
static void primelockdep(struct xe_guc_ct *ct)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_LOCKDEP))
|
||||
|
|
|
|||
|
|
@ -159,8 +159,8 @@ static int xe_hwmon_pcode_read_power_limit(const struct xe_hwmon *hwmon, u32 att
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int xe_hwmon_pcode_write_power_limit(const struct xe_hwmon *hwmon, u32 attr, u8 channel,
|
||||
u32 uval)
|
||||
static int xe_hwmon_pcode_rmw_power_limit(const struct xe_hwmon *hwmon, u32 attr, u8 channel,
|
||||
u32 clr, u32 set)
|
||||
{
|
||||
struct xe_tile *root_tile = xe_device_get_root_tile(hwmon->xe);
|
||||
u32 val0, val1;
|
||||
|
|
@ -179,7 +179,7 @@ static int xe_hwmon_pcode_write_power_limit(const struct xe_hwmon *hwmon, u32 at
|
|||
channel, val0, val1, ret);
|
||||
|
||||
if (attr == PL1_HWMON_ATTR)
|
||||
val0 = uval;
|
||||
val0 = (val0 & ~clr) | set;
|
||||
else
|
||||
return -EIO;
|
||||
|
||||
|
|
@ -339,7 +339,7 @@ static int xe_hwmon_power_max_write(struct xe_hwmon *hwmon, u32 attr, int channe
|
|||
if (hwmon->xe->info.has_mbx_power_limits) {
|
||||
drm_dbg(&hwmon->xe->drm, "disabling %s on channel %d\n",
|
||||
PWR_ATTR_TO_STR(attr), channel);
|
||||
xe_hwmon_pcode_write_power_limit(hwmon, attr, channel, 0);
|
||||
xe_hwmon_pcode_rmw_power_limit(hwmon, attr, channel, PWR_LIM_EN, 0);
|
||||
xe_hwmon_pcode_read_power_limit(hwmon, attr, channel, ®_val);
|
||||
} else {
|
||||
reg_val = xe_mmio_rmw32(mmio, rapl_limit, PWR_LIM_EN, 0);
|
||||
|
|
@ -370,10 +370,9 @@ static int xe_hwmon_power_max_write(struct xe_hwmon *hwmon, u32 attr, int channe
|
|||
}
|
||||
|
||||
if (hwmon->xe->info.has_mbx_power_limits)
|
||||
ret = xe_hwmon_pcode_write_power_limit(hwmon, attr, channel, reg_val);
|
||||
ret = xe_hwmon_pcode_rmw_power_limit(hwmon, attr, channel, PWR_LIM, reg_val);
|
||||
else
|
||||
reg_val = xe_mmio_rmw32(mmio, rapl_limit, PWR_LIM_EN | PWR_LIM_VAL,
|
||||
reg_val);
|
||||
reg_val = xe_mmio_rmw32(mmio, rapl_limit, PWR_LIM, reg_val);
|
||||
unlock:
|
||||
mutex_unlock(&hwmon->hwmon_lock);
|
||||
return ret;
|
||||
|
|
@ -563,14 +562,11 @@ xe_hwmon_power_max_interval_store(struct device *dev, struct device_attribute *a
|
|||
|
||||
mutex_lock(&hwmon->hwmon_lock);
|
||||
|
||||
if (hwmon->xe->info.has_mbx_power_limits) {
|
||||
ret = xe_hwmon_pcode_read_power_limit(hwmon, power_attr, channel, (u32 *)&r);
|
||||
r = (r & ~PWR_LIM_TIME) | rxy;
|
||||
xe_hwmon_pcode_write_power_limit(hwmon, power_attr, channel, r);
|
||||
} else {
|
||||
if (hwmon->xe->info.has_mbx_power_limits)
|
||||
xe_hwmon_pcode_rmw_power_limit(hwmon, power_attr, channel, PWR_LIM_TIME, rxy);
|
||||
else
|
||||
r = xe_mmio_rmw32(mmio, xe_hwmon_get_reg(hwmon, REG_PKG_RAPL_LIMIT, channel),
|
||||
PWR_LIM_TIME, rxy);
|
||||
}
|
||||
|
||||
mutex_unlock(&hwmon->hwmon_lock);
|
||||
|
||||
|
|
@ -1138,12 +1134,12 @@ xe_hwmon_get_preregistration_info(struct xe_hwmon *hwmon)
|
|||
} else {
|
||||
drm_info(&hwmon->xe->drm, "Using mailbox commands for power limits\n");
|
||||
/* Write default limits to read from pcode from now on. */
|
||||
xe_hwmon_pcode_write_power_limit(hwmon, PL1_HWMON_ATTR,
|
||||
CHANNEL_CARD,
|
||||
hwmon->pl1_on_boot[CHANNEL_CARD]);
|
||||
xe_hwmon_pcode_write_power_limit(hwmon, PL1_HWMON_ATTR,
|
||||
CHANNEL_PKG,
|
||||
hwmon->pl1_on_boot[CHANNEL_PKG]);
|
||||
xe_hwmon_pcode_rmw_power_limit(hwmon, PL1_HWMON_ATTR,
|
||||
CHANNEL_CARD, PWR_LIM | PWR_LIM_TIME,
|
||||
hwmon->pl1_on_boot[CHANNEL_CARD]);
|
||||
xe_hwmon_pcode_rmw_power_limit(hwmon, PL1_HWMON_ATTR,
|
||||
CHANNEL_PKG, PWR_LIM | PWR_LIM_TIME,
|
||||
hwmon->pl1_on_boot[CHANNEL_PKG]);
|
||||
hwmon->scl_shift_power = PWR_UNIT;
|
||||
hwmon->scl_shift_energy = ENERGY_UNIT;
|
||||
hwmon->scl_shift_time = TIME_UNIT;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user