From 8a31fe1856860fad834882729201855e758b45c8 Mon Sep 17 00:00:00 2001 From: Chris Kearney <303316+chriskearney@users.noreply.github.com> Date: Mon, 26 Oct 2026 00:29:01 +0000 Subject: [PATCH 1/2] drm/asahi: prepare supported M3 native GPU defaults Generated-by: LLM Signed-off-by: Chris Kearney <303316+chriskearney@users.noreply.github.com> --- arch/arm64/configs/asahi.config | 2 ++ drivers/gpu/drm/asahi/Kconfig | 9 +++---- drivers/gpu/drm/asahi/m3/t8122_knobs.rs | 24 +++++++++++++++++++ drivers/gpu/drm/asahi/m3/t8122_start.rs | 31 ++++++++++++++----------- 4 files changed, 48 insertions(+), 18 deletions(-) diff --git a/arch/arm64/configs/asahi.config b/arch/arm64/configs/asahi.config index 98f9a98ab90285..ffecb85c3beb69 100644 --- a/arch/arm64/configs/asahi.config +++ b/arch/arm64/configs/asahi.config @@ -45,6 +45,8 @@ CONFIG_VIDEO_APPLE_AVD=m CONFIG_VIDEO_APPLE_ISP=m CONFIG_DRM=y CONFIG_DRM_ASAHI=m +CONFIG_DRM_ASAHI_M3_T8122=y +CONFIG_DRM_ASAHI_G15=y CONFIG_DRM_ADP=m CONFIG_DRM_APPLE=m CONFIG_DRM_APPLE_AUDIO=y diff --git a/drivers/gpu/drm/asahi/Kconfig b/drivers/gpu/drm/asahi/Kconfig index ec2a588054e229..45e907b5af86de 100644 --- a/drivers/gpu/drm/asahi/Kconfig +++ b/drivers/gpu/drm/asahi/Kconfig @@ -56,10 +56,11 @@ config DRM_ASAHI_M3_T8122 help Build the M3 runtime that starts the GPU of the M3 MacBook Air (J613, J615) on the 14.8.3 GPU firmware the boot loader leaves - loaded. It starts only with asahi.t8122_start=1 on the kernel - command line, after the boot loader handed the GPU over; without - it the T8122 probe is refused as before. Other GPUs are not - affected. + loaded. On the listed Air boards it starts after the boot loader + handed the GPU over and resource/firmware identity checks pass. + asahi.t8122_start=0 keeps startup disabled for recovery. Unknown + boards and firmware do not gain automatic admission. Other GPUs + are not affected. config DRM_ASAHI_G15 bool "Native G15 firmware backend (M3 Pro/Max)" diff --git a/drivers/gpu/drm/asahi/m3/t8122_knobs.rs b/drivers/gpu/drm/asahi/m3/t8122_knobs.rs index b48e561f677ef1..ca0f8a6d499ccd 100644 --- a/drivers/gpu/drm/asahi/m3/t8122_knobs.rs +++ b/drivers/gpu/drm/asahi/m3/t8122_knobs.rs @@ -132,6 +132,17 @@ pub(crate) fn start(raw: &Raw) -> Start { } } +/// The shipped board policy changes only an omitted start parameter. Explicit recovery-off, +/// explicit experimental start, and malformed values retain their original meanings. +/// Hardware resources and firmware identity are admitted separately by the caller. +pub(crate) fn start_for_board(raw: &Raw, admitted_board: bool) -> Start { + if raw.start == UNSET && admitted_board { + Start::On + } else { + start(raw) + } +} + /// The GPU clock-generator IO mapping. #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub(crate) enum ClockGen { @@ -232,6 +243,19 @@ mod tests { assert!(with(|r| r.fender = INVALID).values_given()); } + #[test] + fn automatic_start_is_board_scoped_and_explicit_values_win() { + assert_eq!(start_for_board(&Raw::NONE, true), Start::On); + assert_eq!(start_for_board(&Raw::NONE, false), Start::Off); + for admitted_board in [false, true] { + assert_eq!(start_for_board(&with(|r| r.start = 0), admitted_board), Start::Off); + assert_eq!(start_for_board(&with(|_| {}), admitted_board), Start::On); + assert_eq!(start_for_board(&with(|r| r.start = 2), admitted_board), Start::Invalid); + assert_eq!(start_for_board(&with(|r| r.start = INVALID), admitted_board), Start::Invalid); + assert_eq!(start_for_board(&with(|r| r.start = parse_number("bogus")), admitted_board), Start::Invalid); + } + } + #[test] fn defaults_are_the_plan_baseline() { let v = resolve(&with(|_| {})).unwrap(); diff --git a/drivers/gpu/drm/asahi/m3/t8122_start.rs b/drivers/gpu/drm/asahi/m3/t8122_start.rs index ca9f21b56dbb66..8f03a973decb81 100644 --- a/drivers/gpu/drm/asahi/m3/t8122_start.rs +++ b/drivers/gpu/drm/asahi/m3/t8122_start.rs @@ -1,11 +1,11 @@ // SPDX-License-Identifier: GPL-2.0-only OR MIT -//! The T8122 (M3, G15G) start, `asahi.t8122_start=1`. +//! T8122 (M3, G15G) board-default startup and bounded experiment values. //! -//! The T8122 table (`m3_soc::T8122`) is complete, but the runtime has not passed on an M3 -//! MacBook Air yet, so the SoC is refused unless `asahi.t8122_start=1` arms the start. On a T8122 -//! whose GPU the boot loader handed over (resource admission passed), an armed start uses the -//! table's values, with a performance-state cap. Each value can be overridden for a lab A/B by +//! The T8122 table (`m3_soc::T8122`) is complete. An omitted start parameter starts +//! automatically only on its listed Air boards; explicit `asahi.t8122_start=0` +//! remains the recovery opt-out. Resource and known-firmware admission still run. +//! The same table values can be changed for a controlled experiment by //! rebooting with a parameter: //! //! | Parameter | Default | Others | @@ -19,7 +19,7 @@ //! | `asahi.t8122_pstate_cap` | `2` | 1 to 5 | //! //! The defaults are the T8122 table's values. A parameter given with a value it does not accept -//! refuses the start. Without `asahi.t8122_start=1` nothing here runs, and T8122 is refused. +//! refuses the start. Unlisted boards remain refused by the existing backend admission. //! Nothing here applies to any other SoC. use core::mem::offset_of; @@ -237,16 +237,16 @@ pub(crate) fn mmio_prot(read_only: u32, slot: usize) -> Prot { /// Decide, after resource admission, whether `soc` starts with the experiment values. /// -/// Any SoC but T8122: Ok(None), silently. T8122 without `asahi.t8122_start=1`: Ok(None), so the -/// caller refuses it as before (one extra line when experiment parameters were given). T8122 -/// with `asahi.t8122_start=1`: the experiment, after logging every value, or a refusal for a -/// parameter value it does not accept. +/// Any SoC but T8122: Ok(None). On its listed Air boards, an omitted parameter +/// selects the table values; explicit 0 disables startup, and invalid values fail +/// closed. Existing backend admission still refuses an unlisted board, even +/// with an explicit start request. pub(crate) fn arm(dev: &device::Device, soc: &Soc) -> Result> { if !is_t8122(soc) { return Ok(None); } let raw = crate::m3::m3_params::t8122_params(); - match knobs::start(&raw) { + match knobs::start_for_board(&raw, crate::m3::m3_board::runtime_validated_board(soc)) { Start::On => {} Start::Off => { if raw.values_given() { @@ -283,7 +283,7 @@ pub(crate) fn arm(dev: &device::Device, soc: &Soc) -> Result> let e = Experiment(v); dev_warn!( dev, - "M3 G15G start: armed (asahi.t8122_start=1, boot loader handoff admitted): initdata_version={:#018x} fender={:#x} clkgen={} sgx_setup={} unit_mask_a={:#x} unit_mask_b={:#x} pstate_cap={}\n", + "M3 G15G start: armed (board default or asahi.t8122_start=1, boot loader handoff admitted): initdata_version={:#018x} fender={:#x} clkgen={} sgx_setup={} unit_mask_a={:#x} unit_mask_b={:#x} pstate_cap={}\n", v.initdata_version, v.fender, clkgen_label(v.clock_gen, v.fender), @@ -352,9 +352,12 @@ pub(crate) fn refused(dev: &device::Device, experiment: Option<&Experiment>, sta } } -/// Log, on a T8122 armed with `asahi.t8122_start=1`, that resource admission refused it. +/// Log that resource admission refused a T8122 start selected by board default or flag. pub(crate) fn not_admitted(dev: &device::Device, soc: &Soc) { - if is_t8122(soc) && knobs::start(&crate::m3::m3_params::t8122_params()) == Start::On { + if is_t8122(soc) && knobs::start_for_board( + &crate::m3::m3_params::t8122_params(), + crate::m3::m3_board::runtime_validated_board(soc), + ) == Start::On { dev_err!( dev, "M3 G15G start: not armed: resource admission refused the GPU (see the lines above); the boot loader did not hand it over completely\n" From fc5391123e5ab821f6143456bab21a0dfe78784a Mon Sep 17 00:00:00 2001 From: Chris Kearney <303316+chriskearney@users.noreply.github.com> Date: Mon, 26 Oct 2026 02:16:02 +0000 Subject: [PATCH 2/2] drm/asahi: align M3 Air startup diagnostics with board defaults Signed-off-by: Chris Kearney <303316+chriskearney@users.noreply.github.com> --- drivers/gpu/drm/asahi/m3/m3_soc.rs | 9 ++++----- drivers/gpu/drm/asahi/m3/t8122_start.rs | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/asahi/m3/m3_soc.rs b/drivers/gpu/drm/asahi/m3/m3_soc.rs index 7be649415cccce..4b81475612b6fa 100644 --- a/drivers/gpu/drm/asahi/m3/m3_soc.rs +++ b/drivers/gpu/drm/asahi/m3/m3_soc.rs @@ -272,10 +272,9 @@ pub(crate) fn by_chip(chip_id: u32) -> Option<&'static Soc> { /// the one the T8122 identity gate admits (`t8122_admission`: family 7, variant 2, revision 0x20, /// core slots in the first core-mask word only), with the die count of the AGX3 identification /// table (`hw::agx3::T8122`). The hardware configuration is `hw::t8122`; power configuration -/// comes from the boot loader. The rest of the runtime configuration is complete, but until the -/// runtime has passed on an M3 MacBook Air the SoC is refused, before the GPU is accessed, unless -/// `asahi.t8122_start=1` arms the start (`t8122_start`), which uses this table's values and adds a -/// performance-state cap. +/// comes from the boot loader. Startup uses the guarded `t8122_start` path, which selects this +/// table's values by default on admitted Air boards and adds a performance-state cap. Explicit +/// `asahi.t8122_start=0` disables startup; firmware, board and resource admission still apply. pub(crate) static T8122: Soc = Soc { name: "T8122", gpu_name: "G15G", @@ -326,7 +325,7 @@ pub(crate) static T8122: Soc = Soc { }, power_from_boot_loader: true, unported: &[ - "a pass on an M3 MacBook Air: until then the GPU starts only with asahi.t8122_start=1", + "M3 Air startup requires the guarded t8122_start path and its performance-state cap", ], // The performance state only. On the single-cluster G15G, reading the engine-busy or the // fault-bank registers after every job hangs the SoC within seconds at about 1000 jobs/s; diff --git a/drivers/gpu/drm/asahi/m3/t8122_start.rs b/drivers/gpu/drm/asahi/m3/t8122_start.rs index 8f03a973decb81..737034dd6f8c13 100644 --- a/drivers/gpu/drm/asahi/m3/t8122_start.rs +++ b/drivers/gpu/drm/asahi/m3/t8122_start.rs @@ -252,7 +252,7 @@ pub(crate) fn arm(dev: &device::Device, soc: &Soc) -> Result> if raw.values_given() { dev_info!( dev, - "M3 G15G start: asahi.t8122_* values given without asahi.t8122_start=1; ignored\n" + "M3 G15G start: disabled by asahi.t8122_start=0; other asahi.t8122_* values ignored\n" ); } return Ok(None);