mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 01:49:46 +00:00
Merge tag 'drm-fixes-2025-11-28' of https://gitlab.freedesktop.org/drm/kernel
Pull drm fixes from Dave Airlie: "Last one for this round hopefully, mostly the usual suspects, xe/amdgpu, with some single fixes otherwise. There is one amdgpu HDMI blackscreen bug that came in late in the cycle, but it was bisected and the revert is in here. i915: - Reject async flips when PSR's selective fetch is enabled xe: - Fix resource leak in xe_guc_ct_init_noalloc()'s error path - Fix stack_depot usage without STACKDEPOT_ALWAYS_INIT - Fix overflow in conversion from clock tics to msec amdgpu: - Unified MES fix - HDMI fix - Cursor fix - Bightness fix - EDID reading improvement - UserQ fix - Cyan Skillfish IP discovery fix bridge: - sil902x: Fix HDMI detection imagination: - Update documentation sti: - Fix leaks in probe vga_switcheroo: - Avoid race condition during fbcon initialization" * tag 'drm-fixes-2025-11-28' of https://gitlab.freedesktop.org/drm/kernel: drm/amdgpu: fix cyan_skillfish2 gpu info fw handling drm/amdgpu: attach tlb fence to the PTs update drm/amd/display: Increase EDID read retries drm/amd/display: Don't change brightness for disabled connectors drm/amd/display: Check NULL before accessing Revert "drm/amd/display: Move setup_stream_attribute" drm/xe: Fix conversion from clock ticks to milliseconds drm/xe/guc: Fix stack_depot usage drm/xe/guc: Fix resource leak in xe_guc_ct_init_noalloc() drm/i915/psr: Reject async flips when selective fetch is enabled drm, fbcon, vga_switcheroo: Avoid race condition in fbcon setup drm/amd/amdgpu: reserve vm invalidation engine for uni_mes drm: sti: fix device leaks at component probe drm/imagination: Document pvr_device.power member drm/bridge: sii902x: Fix HDMI detection with DRM_BRIDGE_ATTACH_NO_CONNECTOR
This commit is contained in:
@@ -2638,6 +2638,8 @@ static int amdgpu_device_parse_gpu_info_fw(struct amdgpu_device *adev)
|
||||
chip_name = "navi12";
|
||||
break;
|
||||
case CHIP_CYAN_SKILLFISH:
|
||||
if (adev->mman.discovery_bin)
|
||||
return 0;
|
||||
chip_name = "cyan_skillfish";
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -597,6 +597,9 @@ int amdgpu_gmc_allocate_vm_inv_eng(struct amdgpu_device *adev)
|
||||
/* reserve engine 5 for firmware */
|
||||
if (adev->enable_mes)
|
||||
vm_inv_engs[i] &= ~(1 << 5);
|
||||
/* reserve engine 6 for uni mes */
|
||||
if (adev->enable_uni_mes)
|
||||
vm_inv_engs[i] &= ~(1 << 6);
|
||||
/* reserve mmhub engine 3 for firmware */
|
||||
if (adev->enable_umsch_mm)
|
||||
vm_inv_engs[i] &= ~(1 << 3);
|
||||
|
||||
@@ -1066,7 +1066,7 @@ amdgpu_vm_tlb_flush(struct amdgpu_vm_update_params *params,
|
||||
}
|
||||
|
||||
/* Prepare a TLB flush fence to be attached to PTs */
|
||||
if (!params->unlocked && vm->is_compute_context) {
|
||||
if (!params->unlocked) {
|
||||
amdgpu_vm_tlb_fence_create(params->adev, vm, fence);
|
||||
|
||||
/* Makes sure no PD/PT is freed before the flush */
|
||||
|
||||
@@ -5052,6 +5052,21 @@ static void amdgpu_dm_backlight_set_level(struct amdgpu_display_manager *dm,
|
||||
struct dc_link *link;
|
||||
u32 brightness;
|
||||
bool rc, reallow_idle = false;
|
||||
struct drm_connector *connector;
|
||||
|
||||
list_for_each_entry(connector, &dm->ddev->mode_config.connector_list, head) {
|
||||
struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
|
||||
|
||||
if (aconnector->bl_idx != bl_idx)
|
||||
continue;
|
||||
|
||||
/* if connector is off, save the brightness for next time it's on */
|
||||
if (!aconnector->base.encoder) {
|
||||
dm->brightness[bl_idx] = user_brightness;
|
||||
dm->actual_brightness[bl_idx] = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
amdgpu_dm_update_backlight_caps(dm, bl_idx);
|
||||
caps = &dm->backlight_caps[bl_idx];
|
||||
|
||||
@@ -997,8 +997,8 @@ enum dc_edid_status dm_helpers_read_local_edid(
|
||||
struct amdgpu_dm_connector *aconnector = link->priv;
|
||||
struct drm_connector *connector = &aconnector->base;
|
||||
struct i2c_adapter *ddc;
|
||||
int retry = 3;
|
||||
enum dc_edid_status edid_status;
|
||||
int retry = 25;
|
||||
enum dc_edid_status edid_status = EDID_NO_RESPONSE;
|
||||
const struct drm_edid *drm_edid;
|
||||
const struct edid *edid;
|
||||
|
||||
@@ -1028,7 +1028,7 @@ enum dc_edid_status dm_helpers_read_local_edid(
|
||||
}
|
||||
|
||||
if (!drm_edid)
|
||||
return EDID_NO_RESPONSE;
|
||||
continue;
|
||||
|
||||
edid = drm_edid_raw(drm_edid); // FIXME: Get rid of drm_edid_raw()
|
||||
if (!edid ||
|
||||
@@ -1046,7 +1046,7 @@ enum dc_edid_status dm_helpers_read_local_edid(
|
||||
&sink->dc_edid,
|
||||
&sink->edid_caps);
|
||||
|
||||
} while (edid_status == EDID_BAD_CHECKSUM && --retry > 0);
|
||||
} while ((edid_status == EDID_BAD_CHECKSUM || edid_status == EDID_NO_RESPONSE) && --retry > 0);
|
||||
|
||||
if (edid_status != EDID_OK)
|
||||
DRM_ERROR("EDID err: %d, on connector: %s",
|
||||
|
||||
@@ -705,9 +705,14 @@ bool dc_stream_get_scanoutpos(const struct dc_stream_state *stream,
|
||||
{
|
||||
uint8_t i;
|
||||
bool ret = false;
|
||||
struct dc *dc = stream->ctx->dc;
|
||||
struct resource_context *res_ctx =
|
||||
&dc->current_state->res_ctx;
|
||||
struct dc *dc;
|
||||
struct resource_context *res_ctx;
|
||||
|
||||
if (!stream->ctx)
|
||||
return false;
|
||||
|
||||
dc = stream->ctx->dc;
|
||||
res_ctx = &dc->current_state->res_ctx;
|
||||
|
||||
dc_exit_ips_for_hw_access(dc);
|
||||
|
||||
|
||||
@@ -671,7 +671,6 @@ void dce110_enable_stream(struct pipe_ctx *pipe_ctx)
|
||||
uint32_t early_control = 0;
|
||||
struct timing_generator *tg = pipe_ctx->stream_res.tg;
|
||||
|
||||
link_hwss->setup_stream_attribute(pipe_ctx);
|
||||
link_hwss->setup_stream_encoder(pipe_ctx);
|
||||
|
||||
dc->hwss.update_info_frame(pipe_ctx);
|
||||
|
||||
@@ -3060,8 +3060,6 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx)
|
||||
link_enc->transmitter - TRANSMITTER_UNIPHY_A);
|
||||
}
|
||||
|
||||
link_hwss->setup_stream_attribute(pipe_ctx);
|
||||
|
||||
if (dc->res_pool->dccg->funcs->set_pixel_rate_div)
|
||||
dc->res_pool->dccg->funcs->set_pixel_rate_div(
|
||||
dc->res_pool->dccg,
|
||||
|
||||
@@ -971,8 +971,6 @@ void dcn401_enable_stream(struct pipe_ctx *pipe_ctx)
|
||||
}
|
||||
}
|
||||
|
||||
link_hwss->setup_stream_attribute(pipe_ctx);
|
||||
|
||||
if (dc->res_pool->dccg->funcs->set_pixel_rate_div) {
|
||||
dc->res_pool->dccg->funcs->set_pixel_rate_div(
|
||||
dc->res_pool->dccg,
|
||||
|
||||
@@ -2458,6 +2458,7 @@ void link_set_dpms_on(
|
||||
struct link_encoder *link_enc = pipe_ctx->link_res.dio_link_enc;
|
||||
enum otg_out_mux_dest otg_out_dest = OUT_MUX_DIO;
|
||||
struct vpg *vpg = pipe_ctx->stream_res.stream_enc->vpg;
|
||||
const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
|
||||
bool apply_edp_fast_boot_optimization =
|
||||
pipe_ctx->stream->apply_edp_fast_boot_optimization;
|
||||
|
||||
@@ -2502,6 +2503,8 @@ void link_set_dpms_on(
|
||||
pipe_ctx->stream_res.tg->funcs->set_out_mux(pipe_ctx->stream_res.tg, otg_out_dest);
|
||||
}
|
||||
|
||||
link_hwss->setup_stream_attribute(pipe_ctx);
|
||||
|
||||
pipe_ctx->stream->apply_edp_fast_boot_optimization = false;
|
||||
|
||||
// Enable VPG before building infoframe
|
||||
|
||||
@@ -44,11 +44,6 @@ static void virtual_stream_encoder_dvi_set_stream_attribute(
|
||||
struct dc_crtc_timing *crtc_timing,
|
||||
bool is_dual_link) {}
|
||||
|
||||
static void virtual_stream_encoder_lvds_set_stream_attribute(
|
||||
struct stream_encoder *enc,
|
||||
struct dc_crtc_timing *crtc_timing)
|
||||
{}
|
||||
|
||||
static void virtual_stream_encoder_set_throttled_vcp_size(
|
||||
struct stream_encoder *enc,
|
||||
struct fixed31_32 avg_time_slots_per_mtp)
|
||||
@@ -120,8 +115,6 @@ static const struct stream_encoder_funcs virtual_str_enc_funcs = {
|
||||
virtual_stream_encoder_hdmi_set_stream_attribute,
|
||||
.dvi_set_stream_attribute =
|
||||
virtual_stream_encoder_dvi_set_stream_attribute,
|
||||
.lvds_set_stream_attribute =
|
||||
virtual_stream_encoder_lvds_set_stream_attribute,
|
||||
.set_throttled_vcp_size =
|
||||
virtual_stream_encoder_set_throttled_vcp_size,
|
||||
.update_hdmi_info_packets =
|
||||
|
||||
@@ -179,7 +179,6 @@ struct sii902x {
|
||||
struct drm_connector connector;
|
||||
struct gpio_desc *reset_gpio;
|
||||
struct i2c_mux_core *i2cmux;
|
||||
bool sink_is_hdmi;
|
||||
u32 bus_width;
|
||||
|
||||
/*
|
||||
@@ -315,8 +314,6 @@ static int sii902x_get_modes(struct drm_connector *connector)
|
||||
drm_edid_free(drm_edid);
|
||||
}
|
||||
|
||||
sii902x->sink_is_hdmi = connector->display_info.is_hdmi;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
@@ -342,9 +339,17 @@ static void sii902x_bridge_atomic_enable(struct drm_bridge *bridge,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
struct sii902x *sii902x = bridge_to_sii902x(bridge);
|
||||
struct drm_connector *connector;
|
||||
u8 output_mode = SII902X_SYS_CTRL_OUTPUT_DVI;
|
||||
|
||||
connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
|
||||
if (connector && connector->display_info.is_hdmi)
|
||||
output_mode = SII902X_SYS_CTRL_OUTPUT_HDMI;
|
||||
|
||||
mutex_lock(&sii902x->mutex);
|
||||
|
||||
regmap_update_bits(sii902x->regmap, SII902X_SYS_CTRL_DATA,
|
||||
SII902X_SYS_CTRL_OUTPUT_MODE, output_mode);
|
||||
regmap_update_bits(sii902x->regmap, SII902X_PWR_STATE_CTRL,
|
||||
SII902X_AVI_POWER_STATE_MSK,
|
||||
SII902X_AVI_POWER_STATE_D(0));
|
||||
@@ -359,16 +364,12 @@ static void sii902x_bridge_mode_set(struct drm_bridge *bridge,
|
||||
const struct drm_display_mode *adj)
|
||||
{
|
||||
struct sii902x *sii902x = bridge_to_sii902x(bridge);
|
||||
u8 output_mode = SII902X_SYS_CTRL_OUTPUT_DVI;
|
||||
struct regmap *regmap = sii902x->regmap;
|
||||
u8 buf[HDMI_INFOFRAME_SIZE(AVI)];
|
||||
struct hdmi_avi_infoframe frame;
|
||||
u16 pixel_clock_10kHz = adj->clock / 10;
|
||||
int ret;
|
||||
|
||||
if (sii902x->sink_is_hdmi)
|
||||
output_mode = SII902X_SYS_CTRL_OUTPUT_HDMI;
|
||||
|
||||
buf[0] = pixel_clock_10kHz & 0xff;
|
||||
buf[1] = pixel_clock_10kHz >> 8;
|
||||
buf[2] = drm_mode_vrefresh(adj);
|
||||
@@ -384,11 +385,6 @@ static void sii902x_bridge_mode_set(struct drm_bridge *bridge,
|
||||
|
||||
mutex_lock(&sii902x->mutex);
|
||||
|
||||
ret = regmap_update_bits(sii902x->regmap, SII902X_SYS_CTRL_DATA,
|
||||
SII902X_SYS_CTRL_OUTPUT_MODE, output_mode);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = regmap_bulk_write(regmap, SII902X_TPI_VIDEO_DATA, buf, 10);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
@@ -31,9 +31,7 @@
|
||||
|
||||
#include <linux/console.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/sysrq.h>
|
||||
#include <linux/vga_switcheroo.h>
|
||||
|
||||
#include <drm/drm_atomic.h>
|
||||
#include <drm/drm_drv.h>
|
||||
@@ -566,11 +564,6 @@ EXPORT_SYMBOL(drm_fb_helper_release_info);
|
||||
*/
|
||||
void drm_fb_helper_unregister_info(struct drm_fb_helper *fb_helper)
|
||||
{
|
||||
struct fb_info *info = fb_helper->info;
|
||||
struct device *dev = info->device;
|
||||
|
||||
if (dev_is_pci(dev))
|
||||
vga_switcheroo_client_fb_set(to_pci_dev(dev), NULL);
|
||||
unregister_framebuffer(fb_helper->info);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_fb_helper_unregister_info);
|
||||
@@ -1632,7 +1625,6 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper)
|
||||
struct drm_client_dev *client = &fb_helper->client;
|
||||
struct drm_device *dev = fb_helper->dev;
|
||||
struct drm_fb_helper_surface_size sizes;
|
||||
struct fb_info *info;
|
||||
int ret;
|
||||
|
||||
if (drm_WARN_ON(dev, !dev->driver->fbdev_probe))
|
||||
@@ -1653,12 +1645,6 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper)
|
||||
|
||||
strcpy(fb_helper->fb->comm, "[fbcon]");
|
||||
|
||||
info = fb_helper->info;
|
||||
|
||||
/* Set the fb info for vgaswitcheroo clients. Does nothing otherwise. */
|
||||
if (dev_is_pci(info->device))
|
||||
vga_switcheroo_client_fb_set(to_pci_dev(info->device), info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -5964,6 +5964,14 @@ static int intel_async_flip_check_uapi(struct intel_atomic_state *state,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* FIXME: selective fetch should be disabled for async flips */
|
||||
if (new_crtc_state->enable_psr2_sel_fetch) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"[CRTC:%d:%s] async flip disallowed with PSR2 selective fetch\n",
|
||||
crtc->base.base.id, crtc->base.name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state,
|
||||
new_plane_state, i) {
|
||||
if (plane->pipe != crtc->pipe)
|
||||
|
||||
@@ -1256,12 +1256,6 @@ static bool intel_psr2_sel_fetch_config_valid(struct intel_dp *intel_dp,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (crtc_state->uapi.async_flip) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"PSR2 sel fetch not enabled, async flip enabled\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return crtc_state->enable_psr2_sel_fetch = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -146,6 +146,14 @@ struct pvr_device {
|
||||
*/
|
||||
struct clk *mem_clk;
|
||||
|
||||
/**
|
||||
* @power: Optional power domain devices.
|
||||
*
|
||||
* On platforms with more than one power domain for the GPU, they are
|
||||
* stored here in @domain_devs, along with links between them in
|
||||
* @domain_links. The size of @domain_devs is given by @domain_count,
|
||||
* while the size of @domain_links is (2 * @domain_count) - 1.
|
||||
*/
|
||||
struct pvr_device_power {
|
||||
struct device **domain_devs;
|
||||
struct device_link **domain_links;
|
||||
|
||||
@@ -143,12 +143,17 @@ struct sti_vtg {
|
||||
struct sti_vtg *of_vtg_find(struct device_node *np)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
struct sti_vtg *vtg;
|
||||
|
||||
pdev = of_find_device_by_node(np);
|
||||
if (!pdev)
|
||||
return NULL;
|
||||
|
||||
return (struct sti_vtg *)platform_get_drvdata(pdev);
|
||||
vtg = platform_get_drvdata(pdev);
|
||||
|
||||
put_device(&pdev->dev);
|
||||
|
||||
return vtg;
|
||||
}
|
||||
|
||||
static void vtg_reset(struct sti_vtg *vtg)
|
||||
|
||||
@@ -93,11 +93,6 @@ int xe_gt_clock_init(struct xe_gt *gt)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u64 div_u64_roundup(u64 n, u32 d)
|
||||
{
|
||||
return div_u64(n + d - 1, d);
|
||||
}
|
||||
|
||||
/**
|
||||
* xe_gt_clock_interval_to_ms - Convert sampled GT clock ticks to msec
|
||||
*
|
||||
@@ -108,5 +103,5 @@ static u64 div_u64_roundup(u64 n, u32 d)
|
||||
*/
|
||||
u64 xe_gt_clock_interval_to_ms(struct xe_gt *gt, u64 count)
|
||||
{
|
||||
return div_u64_roundup(count * MSEC_PER_SEC, gt->info.reference_clock);
|
||||
return mul_u64_u32_div(count, MSEC_PER_SEC, gt->info.reference_clock);
|
||||
}
|
||||
|
||||
@@ -226,6 +226,12 @@ int xe_guc_ct_init_noalloc(struct xe_guc_ct *ct)
|
||||
|
||||
xe_gt_assert(gt, !(guc_ct_size() % PAGE_SIZE));
|
||||
|
||||
err = drmm_mutex_init(&xe->drm, &ct->lock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
primelockdep(ct);
|
||||
|
||||
ct->g2h_wq = alloc_ordered_workqueue("xe-g2h-wq", WQ_MEM_RECLAIM);
|
||||
if (!ct->g2h_wq)
|
||||
return -ENOMEM;
|
||||
@@ -237,16 +243,13 @@ int xe_guc_ct_init_noalloc(struct xe_guc_ct *ct)
|
||||
#if IS_ENABLED(CONFIG_DRM_XE_DEBUG)
|
||||
spin_lock_init(&ct->dead.lock);
|
||||
INIT_WORK(&ct->dead.worker, ct_dead_worker_func);
|
||||
#if IS_ENABLED(CONFIG_DRM_XE_DEBUG_GUC)
|
||||
stack_depot_init();
|
||||
#endif
|
||||
#endif
|
||||
init_waitqueue_head(&ct->wq);
|
||||
init_waitqueue_head(&ct->g2h_fence_wq);
|
||||
|
||||
err = drmm_mutex_init(&xe->drm, &ct->lock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
primelockdep(ct);
|
||||
|
||||
err = drmm_add_action_or_reset(&xe->drm, guc_ct_fini, ct);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
#include <linux/string.h>
|
||||
#include <linux/kd.h>
|
||||
#include <linux/panic.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/printk.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/fb.h>
|
||||
@@ -78,6 +79,7 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/crc32.h> /* For counting font checksums */
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/vga_switcheroo.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
#include "fbcon.h"
|
||||
@@ -2899,6 +2901,9 @@ void fbcon_fb_unregistered(struct fb_info *info)
|
||||
|
||||
console_lock();
|
||||
|
||||
if (info->device && dev_is_pci(info->device))
|
||||
vga_switcheroo_client_fb_set(to_pci_dev(info->device), NULL);
|
||||
|
||||
fbcon_registered_fb[info->node] = NULL;
|
||||
fbcon_num_registered_fb--;
|
||||
|
||||
@@ -3032,6 +3037,10 @@ static int do_fb_registered(struct fb_info *info)
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the fb info for vga_switcheroo clients. Does nothing otherwise. */
|
||||
if (info->device && dev_is_pci(info->device))
|
||||
vga_switcheroo_client_fb_set(to_pci_dev(info->device), info);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user