From 62fdfa4ffbaece3c19335388c0c4a85a04d0bedd Mon Sep 17 00:00:00 2001 From: Ryan Murray <81541646+RyanTheTide@users.noreply.github.com> Date: Mon, 9 Nov 2026 02:08:50 +1100 Subject: [PATCH 1/2] media: apple: jpeg: complete the T6000 reset image Add the 33 sparse scratch defaults the legacy32 reset image was missing (32 zero writes and 0x234 = 0x1f40; the holes in that block stay unwritten), so T6000 no longer refuses at probe. T6000 completes jobs with interrupt status bit 31, so accept only that bit. Tested on the M1 Pro (J316s, fleet36 + this driver, DT enabled at runtime): both engines identify as HWREV 0xd1013; NV12 encodes at 3840x2160/1920x1080/1280x720/640x480 decode with ffmpeg at 41.6-43.4 dB PSNR (q75) on both engines; GStreamer -e drains; every job completed with INT_STATUS 0x80000000; three pm_test device suspend cycles with both engines bound; no DART or JPEG faults. Signed-off-by: Ryan Murray <81541646+RyanTheTide@users.noreply.github.com> Assisted-by: LLM --- .../admin-guide/media/apple-jpeg.rst | 19 ++++----- drivers/media/platform/apple/jpeg/Kconfig | 2 - .../media/platform/apple/jpeg/apple-jpeg-hw.c | 39 +++++++++++++++++-- .../platform/apple/jpeg/apple-jpeg-test.c | 29 +++++++++++++- 4 files changed, 73 insertions(+), 16 deletions(-) diff --git a/Documentation/admin-guide/media/apple-jpeg.rst b/Documentation/admin-guide/media/apple-jpeg.rst index a5bc6e18de907..9dd4c8d2c7304 100644 --- a/Documentation/admin-guide/media/apple-jpeg.rst +++ b/Documentation/admin-guide/media/apple-jpeg.rst @@ -29,16 +29,17 @@ uses compact 32-bit DMA addresses and a separate reset image. DMA addresses and inclusive boundaries must fit the selected address width. They are never truncated to fit a register. -The T6000 reset image is incomplete: its sparse scratch-register defaults -still need a complete clean specification. Its layout and job programming are -testable without hardware, but probe refuses runtime use until that reset -image is complete. Do not enable T6000 engine nodes for streaming yet. +The legacy32 reset image is complete: 111 static defaults, including the +sparse scratch block, plus the tiling write the helper appends. Unlisted +registers in that block are left unwritten. T6000 completes jobs with +interrupt status bit 31. Each engine has a 16 KiB MMIO resource and a separate adjacent DART at SID 0. The engine's resource must not include the DART window. Both T8112 engines -and their DARTs are enabled in ``t8112.dtsi`` (qualified on the J413). The -T6000 pairs stay disabled until the reset image is complete. Enabling nodes on -another SoC requires qualifying both of its instances. +and their DARTs are enabled in ``t8112.dtsi`` (qualified on the J413), and +both T6000 engines in ``t6000.dtsi`` (qualified on the J316s). T6001 and T6002 +stay disabled. Enabling nodes on another SoC requires qualifying both of its +instances. KUnit ----- @@ -58,8 +59,8 @@ Qualification Before enabling a new board, qualify both instances: record raw HWREV, terminal interrupt status (bit 30 or bit 31 for initial older-family qualification), reset/idle handshakes, runtime PM, geometry, output-capacity -checks and error recovery. T8140 retains its qualified bit-31 completion -mask. The other variants initially accept bits 30 and 31; status/error and +checks and error recovery. T8140 and T6000 use their qualified bit-31 +completion mask. The other variants accept bits 30 and 31; status/error and output-capacity checks still apply. Check each encoder's advertised formats and use its actual video node. For diff --git a/drivers/media/platform/apple/jpeg/Kconfig b/drivers/media/platform/apple/jpeg/Kconfig index 9d8ca09462e55..e6f63c05b75d0 100644 --- a/drivers/media/platform/apple/jpeg/Kconfig +++ b/drivers/media/platform/apple/jpeg/Kconfig @@ -12,8 +12,6 @@ config VIDEO_APPLE_JPEG in T6000, T6041, T8112 and T8140 SoCs. It takes full-range NV12 (4:2:0) or NV16 (4:2:2) frames. The device compatible selects the register layout and address width; unrecognized revisions are refused. - T6000 has a layout description but remains refused until its complete - reset image is specified. To compile this driver as a module, choose M here: the module will be called apple-jpeg. diff --git a/drivers/media/platform/apple/jpeg/apple-jpeg-hw.c b/drivers/media/platform/apple/jpeg/apple-jpeg-hw.c index 88acd49dd1e63..7c25b25a18c20 100644 --- a/drivers/media/platform/apple/jpeg/apple-jpeg-hw.c +++ b/drivers/media/platform/apple/jpeg/apple-jpeg-hw.c @@ -184,7 +184,7 @@ static const struct apple_jpeg_write aj_wide64_defaults[] = { { 0x020, 0xff }, }; -/* Known legacy defaults; sparse scratch entries still need specification. */ +/* Complete legacy32 reset image; the layout helper appends tiling. */ static const struct apple_jpeg_write aj_legacy32_defaults[] = { { 0x000, 0x0 }, { 0x004, 0x0 }, @@ -263,6 +263,39 @@ static const struct apple_jpeg_write aj_legacy32_defaults[] = { { 0x0a8, 0xffffffff }, { 0x094, 0x1 }, { 0x098, 0x1 }, + { 0x1fc, 0x0 }, + { 0x200, 0x0 }, + { 0x204, 0x0 }, + { 0x208, 0x0 }, + { 0x214, 0x0 }, + { 0x218, 0x0 }, + { 0x21c, 0x0 }, + { 0x220, 0x0 }, + { 0x224, 0x0 }, + { 0x228, 0x0 }, + { 0x22c, 0x0 }, + { 0x230, 0x0 }, + { 0x234, 0x1f40 }, + { 0x244, 0x0 }, + { 0x248, 0x0 }, + { 0x258, 0x0 }, + { 0x25c, 0x0 }, + { 0x23c, 0x0 }, + { 0x240, 0x0 }, + { 0x250, 0x0 }, + { 0x254, 0x0 }, + { 0x1a0, 0x0 }, + { 0x1a8, 0x0 }, + { 0x1ac, 0x0 }, + { 0x1b0, 0x0 }, + { 0x1b4, 0x0 }, + { 0x1bc, 0x0 }, + { 0x1c0, 0x0 }, + { 0x1c4, 0x0 }, + { 0x1c8, 0x0 }, + { 0x1cc, 0x0 }, + { 0x1d0, 0x0 }, + { 0x1d4, 0x0 }, { 0x020, 0xff }, }; @@ -315,7 +348,7 @@ static const struct apple_jpeg_reg_layout aj_legacy32 = { .image_height = 0x210, .decode_block_base = 0x130, .dma_addr_bits = 32, - .reset_complete = false, + .reset_complete = true, .defaults = aj_legacy32_defaults, .num_defaults = ARRAY_SIZE(aj_legacy32_defaults), }; @@ -324,7 +357,7 @@ const struct apple_jpeg_variant apple_jpeg_t6000 = { .layout = &aj_legacy32, .hwrev_mask = AJ_HWREV_MASK, .hwrev = 0x0d0013, - .int_done_mask = BIT(31) | BIT(30), + .int_done_mask = BIT(31), }; EXPORT_SYMBOL_IF_KUNIT(apple_jpeg_t6000); diff --git a/drivers/media/platform/apple/jpeg/apple-jpeg-test.c b/drivers/media/platform/apple/jpeg/apple-jpeg-test.c index 615127af8093f..8e9b61e684e8f 100644 --- a/drivers/media/platform/apple/jpeg/apple-jpeg-test.c +++ b/drivers/media/platform/apple/jpeg/apple-jpeg-test.c @@ -164,7 +164,8 @@ static void apple_jpeg_layout_test(struct kunit *test) KUNIT_EXPECT_PTR_EQ(test, apple_jpeg_t6041.layout, wide); KUNIT_EXPECT_PTR_NE(test, legacy, wide); KUNIT_EXPECT_TRUE(test, wide->reset_complete); - KUNIT_EXPECT_FALSE(test, legacy->reset_complete); + KUNIT_EXPECT_TRUE(test, legacy->reset_complete); + KUNIT_EXPECT_EQ(test, legacy->num_defaults, 111); KUNIT_EXPECT_EQ(test, wide->dma_addr_bits, 64); KUNIT_EXPECT_EQ(test, legacy->dma_addr_bits, 32); KUNIT_EXPECT_EQ(test, wide->input_plane0, 0x090); @@ -209,7 +210,7 @@ static void apple_jpeg_layout_test(struct kunit *test) KUNIT_EXPECT_EQ(test, legacy->decode_block_base, 0x130); KUNIT_EXPECT_EQ(test, apple_jpeg_t8140.int_done_mask, BIT(31)); KUNIT_EXPECT_EQ(test, apple_jpeg_t8112.int_done_mask, BIT(31) | BIT(30)); - KUNIT_EXPECT_EQ(test, apple_jpeg_t6000.int_done_mask, BIT(31) | BIT(30)); + KUNIT_EXPECT_EQ(test, apple_jpeg_t6000.int_done_mask, BIT(31)); } static void apple_jpeg_older_hwrev_test(struct kunit *test) @@ -328,6 +329,30 @@ static void apple_jpeg_defaults_test(struct kunit *test) /* Wide reset literals must not leak into the legacy image. */ KUNIT_EXPECT_EQ(test, apple_jpeg_last(w, n, 0x280), 0xdeadbeef); KUNIT_EXPECT_EQ(test, apple_jpeg_last(w, n, 0x2b0), 0xdeadbeef); + /* The sparse scratch block: one non-zero default, holes stay holes. */ + KUNIT_EXPECT_EQ(test, n, 112); + KUNIT_EXPECT_EQ(test, apple_jpeg_last(w, n, 0x234), 0x1f40); + for (u32 off = 0x1fc; off <= 0x25c; off += 4) { + if (off == 0x20c || off == 0x210 || off == 0x234 || off == 0x238 || + off == 0x24c) + continue; + KUNIT_EXPECT_EQ(test, apple_jpeg_last(w, n, off), 0); + } + for (u32 off = 0x1a0; off <= 0x1d4; off += 4) { + if (off == 0x1a4 || off == 0x1b8) + continue; + KUNIT_EXPECT_EQ(test, apple_jpeg_last(w, n, off), 0); + } + KUNIT_EXPECT_EQ(test, apple_jpeg_last(w, n, 0x1a4), 0xdeadbeef); + KUNIT_EXPECT_EQ(test, apple_jpeg_last(w, n, 0x1b8), 0xdeadbeef); + KUNIT_EXPECT_EQ(test, apple_jpeg_last(w, n, 0x20c), 0xdeadbeef); + KUNIT_EXPECT_EQ(test, apple_jpeg_last(w, n, 0x210), 0xdeadbeef); + KUNIT_EXPECT_EQ(test, apple_jpeg_last(w, n, 0x238), 0xdeadbeef); + KUNIT_EXPECT_EQ(test, apple_jpeg_last(w, n, 0x24c), 0xdeadbeef); + n = apple_jpeg_defaults(legacy, false, w, APPLE_JPEG_MAX_WRITES); + KUNIT_EXPECT_EQ(test, n, 112); + KUNIT_EXPECT_EQ(test, apple_jpeg_last(w, n, 0x160), 0); + KUNIT_EXPECT_EQ(test, apple_jpeg_defaults(legacy, true, w, 111), -ENOSPC); KUNIT_EXPECT_EQ(test, apple_jpeg_defaults(wide, true, w, 1), -ENOSPC); KUNIT_EXPECT_EQ(test, apple_jpeg_defaults(legacy, true, w, 1), -ENOSPC); } From 4e0b2c3e1db5cd14d565d57b36b8ac85415ddf66 Mon Sep 17 00:00:00 2001 From: Ryan Murray <81541646+RyanTheTide@users.noreply.github.com> Date: Mon, 9 Nov 2026 02:08:50 +1100 Subject: [PATCH 2/2] arm64: dts: apple: t6000: enable the JPEG encoders Both T6000 JPEG engines now probe with a complete reset image. Enable them and their DARTs for the M1 Pro boards; they are SoC blocks with no board-specific wiring. T6001/T6002 stay disabled. Tested on the M1 Pro (J316s), see the driver change. Signed-off-by: Ryan Murray <81541646+RyanTheTide@users.noreply.github.com> Assisted-by: LLM --- arch/arm64/boot/dts/apple/t6000.dtsi | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/arch/arm64/boot/dts/apple/t6000.dtsi b/arch/arm64/boot/dts/apple/t6000.dtsi index 8cafe1065db0e..6c5e086626bda 100644 --- a/arch/arm64/boot/dts/apple/t6000.dtsi +++ b/arch/arm64/boot/dts/apple/t6000.dtsi @@ -101,3 +101,20 @@ &apr0 { status = "okay"; }; + +/* Both JPEG encoders are SoC blocks with no board wiring. */ +&jpeg0_dart { + status = "okay"; +}; + +&jpeg0 { + status = "okay"; +}; + +&jpeg1_dart { + status = "okay"; +}; + +&jpeg1 { + status = "okay"; +};