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/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_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..737034dd6f8c13 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,22 +237,22 @@ 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