From nobody Tue Nov 26 00:56:44 2024 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8DE2015C15F for ; Wed, 23 Oct 2024 08:53:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729673585; cv=none; b=qSv7he9SPSrvsnzs24TtHT7Cxzsw73kzGm8Tc64jp/aMx64JPwCZN5oSgCmqhMHPd4i/nYIeYPOah/liEcyZBLv9ka68sSV7MQzrSWrU0i9Xvnq7elZ7fmx0RoJKD+8yks6kYtZRbNhzSPq0YC1b+MmPXI/1C1RX6GrYunnVT68= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729673585; c=relaxed/simple; bh=802g1h4r/ff4whcawzRjqzDjQ672DUINQlcqcuTqXw4=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=Z6oxIz+GaqLNRmCUhqoaP97K0MMEdiPVJdEhtgxLEuNBpRNLH7jt1oi2lt73IIRZjEYTz19eYW8ODRLCWgUvBJWfhbeqO32sA29rS5tvpVH56MADuomzx4b7jMbNERxwAytAb7lqTTDjScgqfCyuK82NAVhKDWVcefdqjlIVOj0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=ahXEHfTm; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="ahXEHfTm" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1729673582; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=ozMWCQ/Dg+iN+ZjZ0nwJppDwUchQ354tkp3R0a2EIWE=; b=ahXEHfTmNHpJ1H0soFJ/iAdSHDN+lMf2ODCqsgvVrkwn2HZxQnj3RN6J2InSgf9CKKjSuh C5Pd44CpPnFKdeLydqrPc6mhZn65fL7mOmD0z4g2RScZfrw5BonWZ56YLsGzmX+hVG1W8+ WnpcQY7t4kF8H761vnT9soo2CdarfEI= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-625-gPsboIxNPHO-K3slQa4CvA-1; Wed, 23 Oct 2024 04:52:59 -0400 X-MC-Unique: gPsboIxNPHO-K3slQa4CvA-1 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id D6F2419560BA; Wed, 23 Oct 2024 08:52:55 +0000 (UTC) Received: from hydra.redhat.com (unknown [10.39.193.145]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id F130830001A5; Wed, 23 Oct 2024 08:52:48 +0000 (UTC) From: Jocelyn Falempe To: Harry Wentland , Leo Li , Rodrigo Siqueira , Alex Deucher , =?UTF-8?q?Christian=20K=C3=B6nig?= , Xinhui Pan , David Airlie , Simona Vetter , Aurabindo Pillai , Melissa Wen , Joshua Ashton , =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= , Jocelyn Falempe , Tom Chung , Roman Li , Bhuvana Chandra Pinninti , Alvin Lee , Sung Joon Kim , Duncan Ma , Hamza Mahfooz , Lu Yao , amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org Subject: [PATCH v3] drm/amdgpu: Add dcn30 drm_panic support Date: Wed, 23 Oct 2024 10:47:54 +0200 Message-ID: <20241023085227.1165451-1-jfalempe@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 Content-Type: text/plain; charset="utf-8" Add support for the drm_panic module, which displays a pretty user friendly message on the screen when a Linux kernel panic occurs. It should work on all radeon using amdgpu_dm_plane.c, when the framebuffer is linear (like when in a VT). For tiled framebuffer, it will only work on radeon with dcn3x. It should be easy to add support for dcn20, but I can't test it. I've tested it on a Radeon W6400 pro, Radeon 7900XTX and Radeon RX 5700. Also it doesn't work yet on laptop's panel, maybe due to PSR. Signed-off-by: Jocelyn Falempe --- v2: - Disable tiling, and force page flip in the panic_flush() callback. - Enable tiling support for dcn31. - Force immediate page flip. v3: * Add hubp_clear_tiling hook to dcn32 and dcn35 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c | 136 +++++++++++++++++- .../amd/display/dc/hubp/dcn30/dcn30_hubp.c | 17 +++ .../amd/display/dc/hubp/dcn30/dcn30_hubp.h | 2 + .../amd/display/dc/hubp/dcn31/dcn31_hubp.c | 1 + .../amd/display/dc/hubp/dcn32/dcn32_hubp.c | 3 +- .../amd/display/dc/hubp/dcn35/dcn35_hubp.c | 1 + drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h | 1 + 7 files changed, 159 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/driv= ers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c index 495e3cd70426d..60606b36f07bd 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c @@ -26,7 +26,9 @@ =20 #include #include +#include "drm/drm_framebuffer.h" #include +#include #include #include #include @@ -36,6 +38,7 @@ #include "amdgpu_display.h" #include "amdgpu_dm_trace.h" #include "amdgpu_dm_plane.h" +#include "bif/bif_4_1_d.h" #include "gc/gc_11_0_0_offset.h" #include "gc/gc_11_0_0_sh_mask.h" =20 @@ -1421,6 +1424,124 @@ static void amdgpu_dm_plane_atomic_async_update(str= uct drm_plane *plane, amdgpu_dm_plane_handle_cursor_update(plane, old_state); } =20 +/* panic_bo is set in amdgpu_dm_plane_get_scanout_buffer() and only used i= n amdgpu_dm_set_pixel() + * they are called from the panic handler, and protected by the drm_panic = spinlock. + */ +static struct amdgpu_bo *panic_abo; + +/* Use the indirect MMIO to write each pixel to the GPU VRAM, + * This is a simplified version of amdgpu_device_mm_access() + */ +static void amdgpu_dm_set_pixel(struct drm_scanout_buffer *sb, + unsigned int x, + unsigned int y, + u32 color) +{ + struct amdgpu_res_cursor cursor; + unsigned long offset; + struct amdgpu_bo *abo =3D panic_abo; + struct amdgpu_device *adev =3D amdgpu_ttm_adev(abo->tbo.bdev); + uint32_t tmp; + + offset =3D x * 4 + y * sb->pitch[0]; + amdgpu_res_first(abo->tbo.resource, offset, 4, &cursor); + + tmp =3D cursor.start >> 31; + WREG32_NO_KIQ(mmMM_INDEX, ((uint32_t) cursor.start) | 0x80000000); + if (tmp !=3D 0xffffffff) + WREG32_NO_KIQ(mmMM_INDEX_HI, tmp); + WREG32_NO_KIQ(mmMM_DATA, color); +} + +static int amdgpu_dm_plane_get_scanout_buffer(struct drm_plane *plane, + struct drm_scanout_buffer *sb) +{ + struct amdgpu_bo *abo; + struct drm_framebuffer *fb =3D plane->state->fb; + + if (!fb) + return -EINVAL; + + DRM_DEBUG_KMS("Framebuffer %dx%d %p4cc\n", fb->width, fb->height, &fb->fo= rmat->format); + + abo =3D gem_to_amdgpu_bo(fb->obj[0]); + if (!abo) + return -EINVAL; + + sb->width =3D fb->width; + sb->height =3D fb->height; + /* Use the generic linear format, because tiling will be disabled in pani= c_flush() */ + sb->format =3D drm_format_info(fb->format->format); + if (!sb->format) + return -EINVAL; + + sb->pitch[0] =3D fb->pitches[0]; + + if (abo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) { + if (abo->tbo.resource->mem_type !=3D TTM_PL_VRAM) { + drm_warn(plane->dev, "amdgpu panic, framebuffer not in VRAM\n"); + return -EINVAL; + } + /* Only handle 32bits format, to simplify mmio access */ + if (fb->format->cpp[0] !=3D 4) { + drm_warn(plane->dev, "amdgpu panic, pixel format is not 32bits\n"); + return -EINVAL; + } + sb->set_pixel =3D amdgpu_dm_set_pixel; + panic_abo =3D abo; + return 0; + } + if (!abo->kmap.virtual && + ttm_bo_kmap(&abo->tbo, 0, PFN_UP(abo->tbo.base.size), &abo->kmap)) { + drm_warn(plane->dev, "amdgpu bo map failed, panic won't be displayed\n"); + return -ENOMEM; + } + if (abo->kmap.bo_kmap_type & TTM_BO_MAP_IOMEM_MASK) + iosys_map_set_vaddr_iomem(&sb->map[0], abo->kmap.virtual); + else + iosys_map_set_vaddr(&sb->map[0], abo->kmap.virtual); + + return 0; +} + +static void amdgpu_dm_plane_panic_flush(struct drm_plane *plane) +{ + struct dm_plane_state *dm_plane_state =3D to_dm_plane_state(plane->state); + struct drm_framebuffer *fb =3D plane->state->fb; + struct dc_plane_state *dc_plane_state; + struct dc *dc; + int i; + + if (!dm_plane_state || !dm_plane_state->dc_state) + return; + + dc_plane_state =3D dm_plane_state->dc_state; + dc =3D dc_plane_state->ctx->dc; + if (!dc || !dc->current_state) + return; + + for (i =3D 0; i < dc->res_pool->pipe_count; i++) { + struct pipe_ctx *pipe_ctx =3D &dc->current_state->res_ctx.pipe_ctx[i]; + struct hubp *hubp; + + if (!pipe_ctx) + continue; + + hubp =3D pipe_ctx->plane_res.hubp; + if (!hubp) + continue; + + /* if framebuffer is tiled, disable tiling */ + if (fb->modifier && hubp->funcs->hubp_clear_tiling) + hubp->funcs->hubp_clear_tiling(hubp); + + /* force page flip to see the new content of the framebuffer */ + hubp->funcs->hubp_program_surface_flip_and_addr(hubp, + &dc_plane_state->address, + true); + } +} + static const struct drm_plane_helper_funcs dm_plane_helper_funcs =3D { .prepare_fb =3D amdgpu_dm_plane_helper_prepare_fb, .cleanup_fb =3D amdgpu_dm_plane_helper_cleanup_fb, @@ -1429,6 +1550,16 @@ static const struct drm_plane_helper_funcs dm_plane_= helper_funcs =3D { .atomic_async_update =3D amdgpu_dm_plane_atomic_async_update }; =20 +static const struct drm_plane_helper_funcs dm_primary_plane_helper_funcs = =3D { + .prepare_fb =3D amdgpu_dm_plane_helper_prepare_fb, + .cleanup_fb =3D amdgpu_dm_plane_helper_cleanup_fb, + .atomic_check =3D amdgpu_dm_plane_atomic_check, + .atomic_async_check =3D amdgpu_dm_plane_atomic_async_check, + .atomic_async_update =3D amdgpu_dm_plane_atomic_async_update, + .get_scanout_buffer =3D amdgpu_dm_plane_get_scanout_buffer, + .panic_flush =3D amdgpu_dm_plane_panic_flush, +}; + static void amdgpu_dm_plane_drm_plane_reset(struct drm_plane *plane) { struct dm_plane_state *amdgpu_state =3D NULL; @@ -1855,7 +1986,10 @@ int amdgpu_dm_plane_init(struct amdgpu_display_manag= er *dm, plane->type !=3D DRM_PLANE_TYPE_CURSOR) drm_plane_enable_fb_damage_clips(plane); =20 - drm_plane_helper_add(plane, &dm_plane_helper_funcs); + if (plane->type =3D=3D DRM_PLANE_TYPE_PRIMARY) + drm_plane_helper_add(plane, &dm_primary_plane_helper_funcs); + else + drm_plane_helper_add(plane, &dm_plane_helper_funcs); =20 #ifdef AMD_PRIVATE_COLOR dm_atomic_plane_attach_color_mgmt_properties(dm, plane); diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c b/drive= rs/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c index 60a64d2903527..3b16c3cda2c3e 100644 --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c @@ -334,6 +334,22 @@ void hubp3_program_tiling( =20 } =20 +void hubp3_clear_tiling(struct hubp *hubp) +{ + struct dcn20_hubp *hubp2 =3D TO_DCN20_HUBP(hubp); + + REG_UPDATE(DCHUBP_REQ_SIZE_CONFIG, SWATH_HEIGHT, 0); + REG_UPDATE(DCSURF_TILING_CONFIG, SW_MODE, DC_SW_LINEAR); + + REG_UPDATE_6(DCSURF_SURFACE_CONTROL, + PRIMARY_SURFACE_DCC_EN, 0, + PRIMARY_SURFACE_DCC_IND_BLK, 0, + PRIMARY_SURFACE_DCC_IND_BLK_C, 0, + SECONDARY_SURFACE_DCC_EN, 0, + SECONDARY_SURFACE_DCC_IND_BLK, 0, + SECONDARY_SURFACE_DCC_IND_BLK_C, 0); +} + void hubp3_dcc_control(struct hubp *hubp, bool enable, enum hubp_ind_block_size blk_size) { @@ -512,6 +528,7 @@ static struct hubp_funcs dcn30_hubp_funcs =3D { .hubp_in_blank =3D hubp1_in_blank, .hubp_soft_reset =3D hubp1_soft_reset, .hubp_set_flip_int =3D hubp1_set_flip_int, + .hubp_clear_tiling =3D hubp3_clear_tiling, }; =20 bool hubp3_construct( diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.h b/drive= rs/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.h index b010531a7fe88..cfb01bf340a1a 100644 --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.h +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.h @@ -297,6 +297,8 @@ void hubp3_read_state(struct hubp *hubp); =20 void hubp3_init(struct hubp *hubp); =20 +void hubp3_clear_tiling(struct hubp *hubp); + #endif /* __DC_HUBP_DCN30_H__ */ =20 =20 diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn31/dcn31_hubp.c b/drive= rs/gpu/drm/amd/display/dc/hubp/dcn31/dcn31_hubp.c index 8394e8c069199..46b804ed05fba 100644 --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn31/dcn31_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn31/dcn31_hubp.c @@ -96,6 +96,7 @@ static struct hubp_funcs dcn31_hubp_funcs =3D { .hubp_set_flip_int =3D hubp1_set_flip_int, .hubp_in_blank =3D hubp1_in_blank, .program_extended_blank =3D hubp31_program_extended_blank, + .hubp_clear_tiling =3D hubp3_clear_tiling, }; =20 bool hubp31_construct( diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn32/dcn32_hubp.c b/drive= rs/gpu/drm/amd/display/dc/hubp/dcn32/dcn32_hubp.c index ca5b4b28a6644..8b5bd73b8094a 100644 --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn32/dcn32_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn32/dcn32_hubp.c @@ -201,7 +201,8 @@ static struct hubp_funcs dcn32_hubp_funcs =3D { .hubp_update_force_cursor_pstate_disallow =3D hubp32_update_force_cursor_= pstate_disallow, .phantom_hubp_post_enable =3D hubp32_phantom_hubp_post_enable, .hubp_update_mall_sel =3D hubp32_update_mall_sel, - .hubp_prepare_subvp_buffering =3D hubp32_prepare_subvp_buffering + .hubp_prepare_subvp_buffering =3D hubp32_prepare_subvp_buffering, + .hubp_clear_tiling =3D hubp3_clear_tiling, }; =20 bool hubp32_construct( diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn35/dcn35_hubp.c b/drive= rs/gpu/drm/amd/display/dc/hubp/dcn35/dcn35_hubp.c index d1f05b82b3dd5..eb62042dfafc2 100644 --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn35/dcn35_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn35/dcn35_hubp.c @@ -216,6 +216,7 @@ static struct hubp_funcs dcn35_hubp_funcs =3D { .hubp_set_flip_int =3D hubp1_set_flip_int, .hubp_in_blank =3D hubp1_in_blank, .program_extended_blank =3D hubp31_program_extended_blank_value, + .hubp_clear_tiling =3D hubp3_clear_tiling, }; =20 bool hubp35_construct( diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h b/drivers/gpu/drm= /amd/display/dc/inc/hw/hubp.h index 16580d6242789..d0878fc0cc948 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h @@ -275,6 +275,7 @@ struct hubp_funcs { enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cb_b, enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cr_r); int (*hubp_get_3dlut_fl_done)(struct hubp *hubp); + void (*hubp_clear_tiling)(struct hubp *hubp); }; =20 #endif base-commit: 91e21479c81dd4e9e22a78d7446f92f6b96a7284 --=20 2.47.0