diff --git a/arch/arm64/boot/dts/apple/t6034-j516m.dts b/arch/arm64/boot/dts/apple/t6034-j516m.dts index 22ad5251eaecef..a8d651917c313e 100644 --- a/arch/arm64/boot/dts/apple/t6034-j516m.dts +++ b/arch/arm64/boot/dts/apple/t6034-j516m.dts @@ -10,6 +10,7 @@ /dts-v1/; #include "t6034.dtsi" +#include "t6034-dcp.dtsi" #include "t603x-j514-j516.dtsi" / { @@ -29,6 +30,17 @@ brcm,board-type = "apple,jura"; }; +/* J516 panel dimensions, as on the J516C (same 16-inch chassis and panel). */ +&dcp { + panel { + compatible = "apple,panel-j516", "apple,panel-mini-led", "apple,panel"; + width-mm = <346>; + height-mm = <223>; + adj-height-mm = <216>; + apple,max-brightness = <500>; + }; +}; + &aop_audio { apple,chassis-name = "J516"; apple,machine-kind = "MacBook Pro"; diff --git a/drivers/gpu/drm/apple/apple_drv.c b/drivers/gpu/drm/apple/apple_drv.c index b6a5be040ef9c8..9c9740a53a5048 100644 --- a/drivers/gpu/drm/apple/apple_drv.c +++ b/drivers/gpu/drm/apple/apple_drv.c @@ -139,7 +139,8 @@ EXPORT_SYMBOL_GPL(apple_drm_t6031_link_device); int apple_drm_t6034_link_device(struct device *consumer) { - if (!of_machine_is_compatible("apple,j514m")) + if (!of_machine_is_compatible("apple,j514m") && + !of_machine_is_compatible("apple,j516m")) return -ENODEV; return apple_g15_link_device(consumer, "apple,t6034", "apple,agx-t6034", &apple_t6034_display); diff --git a/drivers/gpu/drm/apple/iomfb_v14_7.c b/drivers/gpu/drm/apple/iomfb_v14_7.c index 4f381ab769f315..8497de19e4ae25 100644 --- a/drivers/gpu/drm/apple/iomfb_v14_7.c +++ b/drivers/gpu/drm/apple/iomfb_v14_7.c @@ -203,6 +203,26 @@ static const struct dcp_v14_board dcp_v14_board_j514m = { .log_bringup = true, }; +/* + * J516M (MacBook Pro 16", binned M3 Max): the T6034 DCP, image and handoff + * of the J514M in the J516C chassis, so the J516 panel: 3456x2234 with 74 + * notch rows above the 3456x2160 boot framebuffer. Panel controls stay off + * as on the J514M. + */ +static const struct dcp_v14_board dcp_v14_board_j516m = { + .name = "J516M", + .debugfs = "dcp-j516m", + .dcp_compatible = "apple,t6034-dcp", + .machine = "apple,j516m", + .soc = "apple,t6034", + .firmware_uuid = DCP_V14_J516C_FIRMWARE_UUID, + .handoff = "apple,t6034-handoff", + .panel_width = 3456, + .panel_height = 2234, + .promotion = true, + .log_bringup = true, +}; + static const struct dcp_v14_board *const dcp_v14_boards[] = { &dcp_v14_board_t6030, &dcp_v14_board_j613, @@ -210,6 +230,7 @@ static const struct dcp_v14_board *const dcp_v14_boards[] = { &dcp_v14_board_j516c, &dcp_v14_board_j514c, &dcp_v14_board_j514m, + &dcp_v14_board_j516m, }; struct dcp_v14_property { diff --git a/drivers/gpu/drm/apple/v14-board-test.c b/drivers/gpu/drm/apple/v14-board-test.c index 23453f1368ee14..1b2cbd0cd8d879 100644 --- a/drivers/gpu/drm/apple/v14-board-test.c +++ b/drivers/gpu/drm/apple/v14-board-test.c @@ -125,10 +125,33 @@ static void v14_board_j514m(struct kunit *test) KUNIT_EXPECT_FALSE(test, dcp_v14_board_admits(b, T6030_DCP_IMAGE)); KUNIT_EXPECT_FALSE(test, b->panel_nits); KUNIT_EXPECT_NULL(test, board_for("apple,t6034-dcp", j514m_wrong_soc, &known)); - KUNIT_EXPECT_NULL(test, board_for("apple,t6034-dcp", j516m, &known)); + /* The J516M has a record of its own. */ + KUNIT_EXPECT_PTR_NE(test, b, board_for("apple,t6034-dcp", j516m, &known)); KUNIT_EXPECT_NULL(test, board_for("apple,t6031-dcp", j514m, &known)); } +/* The J516M: the J514M's T6034 DCP and image, with the J516 panel. */ +static void v14_board_j516m(struct kunit *test) +{ + const struct dcp_v14_board *b; + bool known; + + b = board_for("apple,t6034-dcp", j516m, &known); + KUNIT_ASSERT_NOT_NULL(test, b); + KUNIT_EXPECT_TRUE(test, known); + KUNIT_EXPECT_STREQ(test, b->name, "J516M"); + KUNIT_EXPECT_STREQ(test, b->debugfs, "dcp-j516m"); + KUNIT_EXPECT_STREQ(test, b->machine, "apple,j516m"); + KUNIT_EXPECT_STREQ(test, b->soc, "apple,t6034"); + KUNIT_EXPECT_STREQ(test, b->handoff, "apple,t6034-handoff"); + KUNIT_EXPECT_EQ(test, b->panel_width, 3456); + KUNIT_EXPECT_EQ(test, b->panel_height, 2234); + KUNIT_EXPECT_TRUE(test, dcp_v14_board_admits(b, J516C_DCP_IMAGE)); + KUNIT_EXPECT_FALSE(test, dcp_v14_board_admits(b, T6030_DCP_IMAGE)); + KUNIT_EXPECT_FALSE(test, b->panel_nits); + KUNIT_EXPECT_NULL(test, board_for("apple,t6031-dcp", j516m, &known)); +} + /* A T6031 DCP on a T6034 has no record: refused. */ static void v14_board_t6031_other_boards(struct kunit *test) { @@ -277,6 +300,7 @@ static struct kunit_case v14_board_cases[] = { KUNIT_CASE(v14_board_j516c), KUNIT_CASE(v14_board_j514c), KUNIT_CASE(v14_board_j514m), + KUNIT_CASE(v14_board_j516m), KUNIT_CASE(v14_board_t6031_other_boards), KUNIT_CASE(v14_board_j516c_image), KUNIT_CASE(v14_board_unchanged), diff --git a/drivers/gpu/drm/asahi/g15/boot.rs b/drivers/gpu/drm/asahi/g15/boot.rs index b0ea7bfc44aedf..2b4c22f9af0d0b 100644 --- a/drivers/gpu/drm/asahi/g15/boot.rs +++ b/drivers/gpu/drm/asahi/g15/boot.rs @@ -476,9 +476,11 @@ pub(crate) fn admit( && cfg.platform == hw::Platform::DeviceTree && glue::machine(kernel::c_str!("apple,j514c")) && glue::machine(kernel::c_str!("apple,t6031")); - let j514m_board = cfg.chip_id == 0x6034 + // T6034 boards: the J514M and the 16-inch J516M, which carries the same die. + let t6034_board = cfg.chip_id == 0x6034 && cfg.platform == hw::Platform::DeviceTree - && glue::machine(kernel::c_str!("apple,j514m")) + && (glue::machine(kernel::c_str!("apple,j514m")) + || glue::machine(kernel::c_str!("apple,j516m"))) && glue::machine(kernel::c_str!("apple,t6034")); if pmp { if !glue::board() { @@ -494,8 +496,8 @@ pub(crate) fn admit( } return Err(err); } - } else if (cfg.chip_id == 0x6034 && !j514m_board) - || (!glue::machine(cfg.machine) && !j514c_board) + } else if (cfg.chip_id == 0x6034 && !t6034_board) + || (!glue::machine(cfg.machine) && !j514c_board && !t6034_board) { dev_err!(dev, "G15: not a {} machine\n", cfg.name); return Err(ENODEV); @@ -511,7 +513,7 @@ pub(crate) fn admit( return Err(err); } } - if j514c_board || j514m_board { + if j514c_board || t6034_board { if let hw::Board::DeviceTree(reference) = cfg.board { dev_warn!( dev, diff --git a/drivers/gpu/drm/asahi/g15/hw/t6034.rs b/drivers/gpu/drm/asahi/g15/hw/t6034.rs index 1c0ec130cc177e..a26bf06ea88e02 100644 --- a/drivers/gpu/drm/asahi/g15/hw/t6034.rs +++ b/drivers/gpu/drm/asahi/g15/hw/t6034.rs @@ -85,6 +85,19 @@ pub(crate) const CONFIG: Config = Config { 0xe4, 0x1e, 0x5d, 0xaf, 0x86, 0x32, 0x51, 0x50, 0x77, 0xb5, 0x37, 0xca, 0x19, 0xe6, 0xd0, 0xdc, 0x77, 0x04, 0xb7, ], + }, FirmwareBuild { + // Measured on a J516M: the J514M's 14.7 image (RTKit 2419.140.12), + // byte for byte. Pinned to the J516M on its own row. + name: "J516M RTKit 2419.140.12", + machine: Some(kernel::c_str!("apple,j516m")), + text_size: 0x64000, + data_size: 0x140000, + marker: 0x5cf28, + text_sha256: [ + 0x4c, 0xa2, 0x4b, 0x65, 0x8f, 0x8e, 0xbe, 0x7c, 0x27, 0x37, 0x5f, 0xdf, 0x38, + 0xe4, 0x1e, 0x5d, 0xaf, 0x86, 0x32, 0x51, 0x50, 0x77, 0xb5, 0x37, 0xca, 0x19, + 0xe6, 0xd0, 0xdc, 0x77, 0x04, 0xb7, + ], }], machine: kernel::c_str!("apple,j514m"), platform: super::Platform::DeviceTree, diff --git a/drivers/soc/apple/t6030-display-gate.c b/drivers/soc/apple/t6030-display-gate.c index 016abbcf6cf96f..0de143fd52db27 100644 --- a/drivers/soc/apple/t6030-display-gate.c +++ b/drivers/soc/apple/t6030-display-gate.c @@ -190,7 +190,8 @@ static bool gate_t6034_requested __initdata; static bool __init gate_t6034_default_board(void) { return of_machine_is_compatible("apple,t6034") && - of_machine_is_compatible("apple,j514m"); + (of_machine_is_compatible("apple,j514m") || + of_machine_is_compatible("apple,j516m")); } static bool __init gate_t6034_wanted(int sw) @@ -2060,7 +2061,7 @@ static void __init gate_run(void) } gate_t6034_requested = gate_t6034_wanted(gate_t6034_switch); if (gate_t6034_switch < 0) - gate_info("native display on by default on J514M; apple_t6034_display.enable=0 keeps the boot framebuffer\n"); + gate_info("native display on by default on J514M/J516M; apple_t6034_display.enable=0 keeps the boot framebuffer\n"); } if (!*gate_soc->requested) { diff --git a/tools/asahi/g15-display-order-tests.py b/tools/asahi/g15-display-order-tests.py index 6ff26493965c60..a1f7f8ea371381 100644 --- a/tools/asahi/g15-display-order-tests.py +++ b/tools/asahi/g15-display-order-tests.py @@ -221,9 +221,11 @@ def c_source(root): CHECK(publish(&d34) == 0 && d34.refs == 1); CHECK(prepare(&g34) == 0 && links_made == 1 && last_link.supplier == &d34); machine("apple,t6034", "apple,j516m"); - CHECK(prepare(&g34) == -ENODEV && links_made == 1); + CHECK(prepare(&g34) == 0 && links_made == 2 && last_link.supplier == &d34); + machine("apple,t6034", "apple,j999"); + CHECK(prepare(&g34) == -ENODEV && links_made == 2); machine("apple,t6031", "apple,j514m"); - CHECK(prepare(&g34) == -ENODEV && links_made == 1); + CHECK(prepare(&g34) == -ENODEV && links_made == 2); machine("apple,t6034", "apple,j514m"); withdraw(&d34); CHECK(!d34.refs && prepare(&g34) == -EPROBE_DEFER); @@ -243,7 +245,7 @@ def c_source(root): "t6031-reads-t6030-slot": ("&apple_t6031_display);", "&apple_t6030_display);"), "t6034-reads-t6031-slot": ("&apple_t6034_display);", "&apple_t6031_display);"), "t6034-published-as-t6031": ("return &apple_t6034_display;", "return &apple_t6031_display;"), - "t6034-no-board-check": ('if (!of_machine_is_compatible("apple,j514m"))', 'if (false)'), + "t6034-no-board-check": ('if (!of_machine_is_compatible("apple,j514m") &&\n\t !of_machine_is_compatible("apple,j516m"))', 'if (false)'), "t6031-published-as-t6030": ("return &apple_t6031_display;", "return &apple_t6030_display;"), "no-machine-check": ("!of_machine_is_compatible(machine) ||", ""), "withdraw-keeps-display": ("*slot = NULL;", ";"), diff --git a/tools/asahi/g15-t6034-profile-tests.py b/tools/asahi/g15-t6034-profile-tests.py index 4f73b5172aee76..16fde7183569a4 100644 --- a/tools/asahi/g15-t6034-profile-tests.py +++ b/tools/asahi/g15-t6034-profile-tests.py @@ -58,13 +58,17 @@ def item(text, marker): assert_eq!(c.gpu_revision,0x11); assert_eq!((c.hw_ids[0].version,c.hw_ids[0].counts),(0x07041100,0x0021040a)); // An empty table is the first diagnostic build. A completed profile may - // contain only the measured row for this exact board. - assert_eq!(c.firmware.len(),1); + // contain only the measured rows, each pinned to its exact board: the J514M, + // and the J516M, measured with the same image. + assert_eq!(c.firmware.len(),2); if !c.firmware.is_empty() { use lookup::{Measured,Verdict}; - assert_eq!(c.firmware.len(),1); let b=&c.firmware[0]; assert_eq!(b.machine.map(|m|m.to_bytes()),Some(b"apple,j514m".as_slice())); + let j516m=&c.firmware[1]; + assert_eq!(j516m.machine.map(|m|m.to_bytes()),Some(b"apple,j516m".as_slice())); + assert_eq!((j516m.text_size,j516m.data_size,j516m.marker,j516m.text_sha256), + (b.text_size,b.data_size,b.marker,b.text_sha256)); let exact=Measured {text_size:b.text_size,data_size:b.data_size,marker:b.marker,sha256:b.text_sha256}; let verdict=|measured:&Measured,board:&[u8]| { let qualified=c.firmware.iter().map(|b| { @@ -74,10 +78,13 @@ def item(text, marker): lookup::verdict(measured,qualified,0) }; assert_eq!(verdict(&exact,b"apple,j514m"),Verdict::Pinned(0)); - for board in [b"apple,j514c".as_slice(),b"apple,j516c",b"apple,j516m",b"apple,j514s",b"apple,j999"] { + assert_eq!(verdict(&exact,b"apple,j516m"),Verdict::Pinned(1)); + for board in [b"apple,j514c".as_slice(),b"apple,j516c",b"apple,j514s",b"apple,j999"] { assert_eq!(verdict(&exact,board),Verdict::Refused); } let mut changed=exact;changed.sha256[31]^=1; + assert_eq!(verdict(&changed,b"apple,j516m"),Verdict::Refused); + let mut changed=exact;changed.sha256[31]^=1; assert_eq!(verdict(&changed,b"apple,j514m"),Verdict::Refused); let mut changed=exact;changed.text_size+=0x4000; assert_eq!(verdict(&changed,b"apple,j514m"),Verdict::Refused); diff --git a/tools/asahi/t6034-display-tests.py b/tools/asahi/t6034-display-tests.py index ddd1cf54cc4c39..f2b1f14205edac 100644 --- a/tools/asahi/t6034-display-tests.py +++ b/tools/asahi/t6034-display-tests.py @@ -41,7 +41,7 @@ def item(s, marker): const char *socs[]={"apple,t6034","apple,t6031","apple,t6030",NULL}; dcp="apple,t6034-dcp"; for(unsigned i=0;ifirmware_uuid);','return uuid != NULL;'), }