From 37eed892cc5ff36aeee59bb78f6aa417a44030a9 Mon Sep 17 00:00:00 2001 From: Petr Mladek Date: Mon, 28 Apr 2025 14:31:32 +0200 Subject: [PATCH 01/38] vsprintf: Use %p4chR instead of %p4cn for reading data in reversed host ordering The generic FourCC format always prints the data using the big endian order. It is generic because it allows to read the data using a custom ordering. The current code uses "n" for reading data in the reverse host ordering. It makes the 4 variants [hnbl] consistent with the generic printing of IPv4 addresses. Unfortunately, it creates confusion on big endian systems. For example, it shows the data &(u32)0x67503030 as %p4cn 00Pg (0x30305067) But people expect that the ordering stays the same. The network ordering is a big-endian ordering. The problem is that the semantic is not the same. The modifiers affect the output ordering of IPv4 addresses while they affect the reading order in case of FourCC code. Avoid the confusion by replacing the "n" modifier with "hR", aka reverse host ordering. It is inspired by the existing %p[mM]R printf format. Reported-by: Geert Uytterhoeven Closes: https://lore.kernel.org/r/CAMuHMdV9tX=TG7E_CrSF=2PY206tXf+_yYRuacG48EWEtJLo-Q@mail.gmail.com Signed-off-by: Petr Mladek Acked-by: Alyssa Rosenzweig Reviewed-by: Geert Uytterhoeven Reviewed-by: Aditya Garg Link: https://lore.kernel.org/r/20250428123132.578771-1-pmladek@suse.com Signed-off-by: Alyssa Rosenzweig --- Documentation/core-api/printk-formats.rst | 10 +++++----- lib/tests/printf_kunit.c | 4 ++-- lib/vsprintf.c | 11 ++++++++--- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/Documentation/core-api/printk-formats.rst b/Documentation/core-api/printk-formats.rst index 125fd0397510..f531873bb3c9 100644 --- a/Documentation/core-api/printk-formats.rst +++ b/Documentation/core-api/printk-formats.rst @@ -652,7 +652,7 @@ Generic FourCC code ------------------- :: - %p4c[hnlb] gP00 (0x67503030) + %p4c[h[R]lb] gP00 (0x67503030) Print a generic FourCC code, as both ASCII characters and its numerical value as hexadecimal. @@ -660,23 +660,23 @@ value as hexadecimal. The generic FourCC code is always printed in the big-endian format, the most significant byte first. This is the opposite of V4L/DRM FourCCs. -The additional ``h``, ``n``, ``l``, and ``b`` specifiers define what +The additional ``h``, ``hR``, ``l``, and ``b`` specifiers define what endianness is used to load the stored bytes. The data might be interpreted -using the host byte order, network byte order, little-endian, or big-endian. +using the host, reversed host byte order, little-endian, or big-endian. Passed by reference. Examples for a little-endian machine, given &(u32)0x67503030:: %p4ch gP00 (0x67503030) - %p4cn 00Pg (0x30305067) + %p4chR 00Pg (0x30305067) %p4cl gP00 (0x67503030) %p4cb 00Pg (0x30305067) Examples for a big-endian machine, given &(u32)0x67503030:: %p4ch gP00 (0x67503030) - %p4cn 00Pg (0x30305067) + %p4chR 00Pg (0x30305067) %p4cl 00Pg (0x30305067) %p4cb gP00 (0x67503030) diff --git a/lib/tests/printf_kunit.c b/lib/tests/printf_kunit.c index b1fa0dcea52f..bc54cca2d7a6 100644 --- a/lib/tests/printf_kunit.c +++ b/lib/tests/printf_kunit.c @@ -726,7 +726,7 @@ static void fourcc_pointer(struct kunit *kunittest) static const struct fourcc_struct try_ch[] = { { 0x41424344, "ABCD (0x41424344)", }, }; - static const struct fourcc_struct try_cn[] = { + static const struct fourcc_struct try_chR[] = { { 0x41424344, "DCBA (0x44434241)", }, }; static const struct fourcc_struct try_cl[] = { @@ -738,7 +738,7 @@ static void fourcc_pointer(struct kunit *kunittest) fourcc_pointer_test(kunittest, try_cc, ARRAY_SIZE(try_cc), "%p4cc"); fourcc_pointer_test(kunittest, try_ch, ARRAY_SIZE(try_ch), "%p4ch"); - fourcc_pointer_test(kunittest, try_cn, ARRAY_SIZE(try_cn), "%p4cn"); + fourcc_pointer_test(kunittest, try_chR, ARRAY_SIZE(try_chR), "%p4chR"); fourcc_pointer_test(kunittest, try_cl, ARRAY_SIZE(try_cl), "%p4cl"); fourcc_pointer_test(kunittest, try_cb, ARRAY_SIZE(try_cb), "%p4cb"); } diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 6bc64ae52166..d8a2ec083ace 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1805,9 +1805,8 @@ char *fourcc_string(char *buf, char *end, const u32 *fourcc, orig = get_unaligned(fourcc); switch (fmt[2]) { case 'h': - break; - case 'n': - orig = swab32(orig); + if (fmt[3] == 'R') + orig = swab32(orig); break; case 'l': orig = (__force u32)cpu_to_le32(orig); @@ -2397,6 +2396,12 @@ early_param("no_hash_pointers", no_hash_pointers_enable); * read the documentation (path below) first. * - 'NF' For a netdev_features_t * - '4cc' V4L2 or DRM FourCC code, with endianness and raw numerical value. + * - '4c[h[R]lb]' For generic FourCC code with raw numerical value. Both are + * displayed in the big-endian format. This is the opposite of V4L2 or + * DRM FourCCs. + * The additional specifiers define what endianness is used to load + * the stored bytes. The data might be interpreted using the host, + * reversed host byte order, little-endian, or big-endian. * - 'h[CDN]' For a variable-length buffer, it prints it as a hex string with * a certain separator (' ' by default): * C colon From de5fbbe1531f645c8b56098be8d1faf31e46f7f0 Mon Sep 17 00:00:00 2001 From: Aditya Garg Date: Thu, 10 Apr 2025 23:50:01 +0530 Subject: [PATCH 02/38] drm/appletbdrm: Make appletbdrm depend on X86 The appletbdrm driver is exclusively for Touch Bars on x86 Intel Macs. The M1 Macs have a separate driver. So, lets avoid compiling it for other architectures. Signed-off-by: Aditya Garg Reviewed-by: Alyssa Rosenzweig Link: https://lore.kernel.org/r/PN3PR01MB95970778982F28E4A3751392B8B72@PN3PR01MB9597.INDPRD01.PROD.OUTLOOK.COM Signed-off-by: Alyssa Rosenzweig --- drivers/gpu/drm/tiny/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig index ad4dab525f93..daa1adbb1b43 100644 --- a/drivers/gpu/drm/tiny/Kconfig +++ b/drivers/gpu/drm/tiny/Kconfig @@ -3,6 +3,7 @@ config DRM_APPLETBDRM tristate "DRM support for Apple Touch Bars" depends on DRM && USB && MMU + depends on X86 || COMPILE_TEST select DRM_GEM_SHMEM_HELPER select DRM_KMS_HELPER help From c1a32a041aecffe41bf7a1d1696d90617528f082 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Larumbe?= Date: Thu, 24 Apr 2025 19:40:34 +0100 Subject: [PATCH 03/38] drm/panthor: Fix build warning when DEBUG_FS is disabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit a3707f53eb3f ("drm/panthor: show device-wide list of DRM GEM objects over DebugFS") causes a build warning and linking error when built without support for DebugFS, because of a non-inline non-static function declaration in a header file. On top of that, the function is only being used inside a single compilation unit, so there is no point in exposing it as a global symbol. This is a follow-up from Arnd Bergmann's first fix. Also move panthor_gem_debugfs_set_usage_flags() into panthor_gem.c and declare it static. Fixes: a3707f53eb3f ("drm/panthor: show device-wide list of DRM GEM objects over DebugFS") Reported-by: Arnd Bergmann Closes: https://lore.kernel.org/dri-devel/20250424142419.47b9d457@collabora.com/T/#t Signed-off-by: Adrián Larumbe Reviewed-by: Steven Price Reviewed-by: Liviu Dudau Link: https://lore.kernel.org/r/20250424184041.356191-1-adrian.larumbe@collabora.com Signed-off-by: Boris Brezillon --- drivers/gpu/drm/panthor/panthor_gem.c | 5 +++++ drivers/gpu/drm/panthor/panthor_gem.h | 8 -------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/panthor/panthor_gem.c index 2dcf308094b2..7c00fd77758b 100644 --- a/drivers/gpu/drm/panthor/panthor_gem.c +++ b/drivers/gpu/drm/panthor/panthor_gem.c @@ -42,11 +42,16 @@ static void panthor_gem_debugfs_bo_rm(struct panthor_gem_object *bo) mutex_unlock(&ptdev->gems.lock); } +static void panthor_gem_debugfs_set_usage_flags(struct panthor_gem_object *bo, u32 usage_flags) +{ + bo->debugfs.flags = usage_flags | PANTHOR_DEBUGFS_GEM_USAGE_FLAG_INITIALIZED; +} #else static void panthor_gem_debugfs_bo_add(struct panthor_device *ptdev, struct panthor_gem_object *bo) {} static void panthor_gem_debugfs_bo_rm(struct panthor_gem_object *bo) {} +static void panthor_gem_debugfs_set_usage_flags(struct panthor_gem_object *bo, u32 usage_flags) {} #endif static void panthor_gem_free_object(struct drm_gem_object *obj) diff --git a/drivers/gpu/drm/panthor/panthor_gem.h b/drivers/gpu/drm/panthor/panthor_gem.h index 4641994ddd7f..4dd732dcd59f 100644 --- a/drivers/gpu/drm/panthor/panthor_gem.h +++ b/drivers/gpu/drm/panthor/panthor_gem.h @@ -212,14 +212,6 @@ void panthor_kernel_bo_destroy(struct panthor_kernel_bo *bo); #ifdef CONFIG_DEBUG_FS void panthor_gem_debugfs_print_bos(struct panthor_device *pfdev, struct seq_file *m); -static inline void -panthor_gem_debugfs_set_usage_flags(struct panthor_gem_object *bo, u32 usage_flags) -{ - bo->debugfs.flags = usage_flags | PANTHOR_DEBUGFS_GEM_USAGE_FLAG_INITIALIZED; -} - -#else -void panthor_gem_debugfs_set_usage_flags(struct panthor_gem_object *bo, u32 usage_flags) {}; #endif #endif /* __PANTHOR_GEM_H__ */ From 5f8f898b14b2401e980b1f206b827d985e040ebe Mon Sep 17 00:00:00 2001 From: Zhengqiao Xia Date: Tue, 29 Apr 2025 17:20:28 +0800 Subject: [PATCH 04/38] drm/panel-edp: Add support for AUO B140QAN08.H panel AUO B140QAN08.H EDID: edid-decode (hex): 00 ff ff ff ff ff ff 00 06 af b9 fe 00 00 00 00 00 23 01 04 a5 1e 13 78 03 c1 45 a8 55 48 9d 24 0f 50 54 00 00 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 18 86 40 a0 b0 08 52 70 30 20 65 00 2d bc 10 00 00 18 00 00 00 0f 00 00 00 00 00 00 00 00 00 00 00 00 00 20 00 00 00 fd 00 28 3c 71 71 22 01 0a 20 20 20 20 20 20 00 00 00 fc 00 42 31 34 30 51 41 4e 30 38 2e 48 20 0a 01 79 70 20 79 02 00 21 01 1d c2 0b 58 07 40 0b 08 07 88 8b fa 54 7e 24 9d 45 12 0f 02 35 54 40 5e 40 5e 00 44 12 78 22 00 14 ef 3c 05 85 3f 0b 9f 00 2f 80 1f 00 07 07 51 00 05 00 04 00 25 01 09 ef 3c 05 ef 3c 05 28 3c 80 2e 00 06 00 44 40 5e 40 5e 81 00 15 74 1a 00 00 03 00 28 3c 00 00 60 ff 60 ff 3c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 4f 90 Signed-off-by: Zhengqiao Xia Reviewed-by: Dmitry Baryshkov Signed-off-by: Douglas Anderson Link: https://lore.kernel.org/r/20250429092030.8025-2-xiazhengqiao@huaqin.corp-partner.google.com --- drivers/gpu/drm/panel/panel-edp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c index e8fe0014143f..450db0b72457 100644 --- a/drivers/gpu/drm/panel/panel-edp.c +++ b/drivers/gpu/drm/panel/panel-edp.c @@ -1877,6 +1877,7 @@ static const struct edp_panel_entry edp_panels[] = { EDP_PANEL_ENTRY('A', 'U', 'O', 0xa199, &delay_200_500_e50, "B116XAN06.1"), EDP_PANEL_ENTRY('A', 'U', 'O', 0xa7b3, &delay_200_500_e50, "B140UAN04.4"), EDP_PANEL_ENTRY('A', 'U', 'O', 0xc4b4, &delay_200_500_e50, "B116XAT04.1"), + EDP_PANEL_ENTRY('A', 'U', 'O', 0xc9a8, &delay_200_500_e50, "B140QAN08.H"), EDP_PANEL_ENTRY('A', 'U', 'O', 0xd497, &delay_200_500_e50, "B120XAN01.0"), EDP_PANEL_ENTRY('A', 'U', 'O', 0xf390, &delay_200_500_e50, "B140XTN07.7"), From 800c2180705a87829f7833df3d9e73b548bf65ff Mon Sep 17 00:00:00 2001 From: Zhengqiao Xia Date: Tue, 29 Apr 2025 17:20:29 +0800 Subject: [PATCH 05/38] drm/panel-edp: Add support for BOE NE140WUM-N6S panel BOE NE140WUM-N6S EDID: edid-decode (hex): 00 ff ff ff ff ff ff 00 09 e5 73 0d 00 00 00 00 32 22 01 04 a5 1e 13 78 07 13 45 a6 54 4d a0 27 0c 50 54 00 00 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 03 3e 80 a0 70 b0 48 40 30 20 36 00 2e bc 10 00 00 1a 00 00 00 fd 00 1e 78 99 99 20 01 0a 20 20 20 20 20 20 00 00 00 fc 00 4e 45 31 34 30 57 55 4d 2d 4e 36 53 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 45 70 20 79 02 00 22 00 14 33 d8 04 85 7f 07 9f 00 2f 00 1f 00 af 04 47 00 02 00 05 00 81 00 13 72 1a 00 00 03 01 1e 78 00 00 5a 4a 5a 4a 78 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ad 90 Signed-off-by: Zhengqiao Xia Reviewed-by: Douglas Anderson Signed-off-by: Douglas Anderson Link: https://lore.kernel.org/r/20250429092030.8025-3-xiazhengqiao@huaqin.corp-partner.google.com --- drivers/gpu/drm/panel/panel-edp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c index 450db0b72457..81fc2da94484 100644 --- a/drivers/gpu/drm/panel/panel-edp.c +++ b/drivers/gpu/drm/panel/panel-edp.c @@ -1938,6 +1938,7 @@ static const struct edp_panel_entry edp_panels[] = { EDP_PANEL_ENTRY('B', 'O', 'E', 0x0c93, &delay_200_500_e200, "Unknown"), EDP_PANEL_ENTRY('B', 'O', 'E', 0x0cb6, &delay_200_500_e200, "NT116WHM-N44"), EDP_PANEL_ENTRY('B', 'O', 'E', 0x0cfa, &delay_200_500_e50, "NV116WHM-A4D"), + EDP_PANEL_ENTRY('B', 'O', 'E', 0x0d73, &delay_200_500_e80, "NE140WUM-N6S"), EDP_PANEL_ENTRY('C', 'M', 'N', 0x1130, &delay_200_500_e50, "N116BGE-EB2"), EDP_PANEL_ENTRY('C', 'M', 'N', 0x1132, &delay_200_500_e80_d50, "N116BGE-EA2"), From 0d607a59a0f6593e72630854a8bcb8b01b8dce40 Mon Sep 17 00:00:00 2001 From: Zhengqiao Xia Date: Tue, 29 Apr 2025 17:20:30 +0800 Subject: [PATCH 06/38] drm/panel-edp: Add support for CSW MNE007QS3-8 panel CSW MNE007QS3-8 EDID: edid-decode (hex): 00 ff ff ff ff ff ff 00 0e 77 57 14 00 00 00 00 34 22 01 04 a5 1e 13 78 07 ee 95 a3 54 4c 99 26 0f 50 54 00 00 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 cd 7c 80 a0 70 b0 50 40 30 20 26 04 2e bc 10 00 00 1a cd 7c 80 a0 70 b0 50 45 30 20 26 04 2e bc 10 00 00 1a 00 00 00 fd 00 1e 78 9a 9a 20 01 0a 20 20 20 20 20 20 00 00 00 fc 00 4d 4e 45 30 30 37 51 53 33 2d 38 0a 20 01 3f 70 20 79 02 00 21 00 1d c8 0b 5d 07 80 07 b0 04 80 3d 8a 54 cd a4 99 66 62 0f 02 45 54 7c 5d 7c 5d 00 43 12 78 2b 00 0c 27 00 1e 77 00 00 27 00 1e 3b 00 00 2e 00 06 00 43 7c 5d 7c 5d 81 00 20 74 1a 00 00 03 01 1e 78 00 00 5a ff 5a ff 78 00 00 00 00 8d 00 e3 05 04 00 e6 06 01 01 5a 5a ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 76 90 Signed-off-by: Zhengqiao Xia Reviewed-by: Douglas Anderson Reviewed-by: Dmitry Baryshkov Signed-off-by: Douglas Anderson Link: https://lore.kernel.org/r/20250429092030.8025-4-xiazhengqiao@huaqin.corp-partner.google.com --- drivers/gpu/drm/panel/panel-edp.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c index 81fc2da94484..90e8c154a978 100644 --- a/drivers/gpu/drm/panel/panel-edp.c +++ b/drivers/gpu/drm/panel/panel-edp.c @@ -1762,6 +1762,13 @@ static const struct panel_delay delay_80_500_e50 = { .enable = 50, }; +static const struct panel_delay delay_80_500_e80_p2e200 = { + .hpd_absent = 80, + .unprepare = 500, + .enable = 80, + .prepare_to_enable = 200, +}; + static const struct panel_delay delay_100_500_e200 = { .hpd_absent = 100, .unprepare = 500, @@ -1974,6 +1981,7 @@ static const struct edp_panel_entry edp_panels[] = { EDP_PANEL_ENTRY('C', 'S', 'W', 0x1103, &delay_200_500_e80_d50, "MNB601LS1-3"), EDP_PANEL_ENTRY('C', 'S', 'W', 0x1104, &delay_200_500_e50, "MNB601LS1-4"), EDP_PANEL_ENTRY('C', 'S', 'W', 0x1448, &delay_200_500_e50, "MNE007QS3-7"), + EDP_PANEL_ENTRY('C', 'S', 'W', 0x1457, &delay_80_500_e80_p2e200, "MNE007QS3-8"), EDP_PANEL_ENTRY('E', 'T', 'C', 0x0000, &delay_50_500_e200_d200_po2e335, "LP079QX1-SP0V"), From b389df0f6b5a2e0655e9f101af97d75e35fb874c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 30 Apr 2025 11:03:46 +0300 Subject: [PATCH 07/38] drm/st7571-i2c: Fix IS_ERR() vs NULL checks in probe() The devm_kzalloc() function returns NULL on failure, not error pointers. Also printing an error message for kmalloc() failures is against kernel style so just return -ENOMEM without printing a message. (Kmalloc already prints a message). Fixes: 4b35f0f41ee2 ("drm/st7571-i2c: add support for Sitronix ST7571 LCD controller") Signed-off-by: Dan Carpenter Reviewed-by: Javier Martinez Canillas Link: https://lore.kernel.org/r/aBHZYgPPPYY-J8Vd@stanley.mountain Signed-off-by: Javier Martinez Canillas --- drivers/gpu/drm/tiny/st7571-i2c.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/tiny/st7571-i2c.c b/drivers/gpu/drm/tiny/st7571-i2c.c index dc410ec41baf..eec846892962 100644 --- a/drivers/gpu/drm/tiny/st7571-i2c.c +++ b/drivers/gpu/drm/tiny/st7571-i2c.c @@ -908,16 +908,14 @@ static int st7571_probe(struct i2c_client *client) st7571->hwbuf = devm_kzalloc(&client->dev, (st7571->nlines * st7571->ncols * st7571->bpp) / 8, GFP_KERNEL); - if (IS_ERR(st7571->hwbuf)) - return dev_err_probe(&client->dev, PTR_ERR(st7571->hwbuf), - "Failed to allocate intermediate buffer\n"); + if (!st7571->hwbuf) + return -ENOMEM; st7571->row = devm_kzalloc(&client->dev, (st7571->ncols * st7571->bpp), GFP_KERNEL); - if (IS_ERR(st7571->row)) - return dev_err_probe(&client->dev, PTR_ERR(st7571->row), - "Failed to allocate row buffer\n"); + if (!st7571->row) + return -ENOMEM; ret = st7571_mode_config_init(st7571); if (ret) From 9b33df36b45136d301241920d13a0a3ecc77b8f9 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 14 Apr 2025 08:56:56 +0000 Subject: [PATCH 08/38] drm/doc: document front-buffer rendering Explain how to perform front-buffer rendering. v2: apply Pekka's rewrite Signed-off-by: Pekka Paalanen Signed-off-by: Simon Ser Reviewed-by: Simon Ser Link: https://lore.kernel.org/r/20250414085652.43904-1-contact@emersion.fr --- drivers/gpu/drm/drm_blend.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c index 6e74de833466..6852d73c931c 100644 --- a/drivers/gpu/drm/drm_blend.c +++ b/drivers/gpu/drm/drm_blend.c @@ -75,6 +75,12 @@ * the currently visible vertical area of the &drm_crtc. * FB_ID: * Mode object ID of the &drm_framebuffer this plane should scan out. + * + * When a KMS client is performing front-buffer rendering, it should set + * FB_ID to the same front-buffer FB on each atomic commit. This implies + * to the driver that it needs to re-read the same FB again. Otherwise + * drivers which do not employ continuously repeated scanout cycles might + * not update the screen. * CRTC_ID: * Mode object ID of the &drm_crtc this plane should be connected to. * From 4f1a965d592a0ca7d4ee2125f54d19ba8292295a Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 23 Apr 2025 18:44:16 +0200 Subject: [PATCH 09/38] drm/rockchip: add CONFIG_OF dependency DRM_DISPLAY_DP_AUX_BUS cannot be selected when CONFIG_OF is disabled: WARNING: unmet direct dependencies detected for DRM_DISPLAY_DP_AUX_BUS Depends on [n]: HAS_IOMEM [=y] && DRM [=y] && OF [=n] Selected by [y]: - DRM_ROCKCHIP [=y] && HAS_IOMEM [=y] && DRM [=y] && ROCKCHIP_IOMMU [=y] && ROCKCHIP_ANALOGIX_DP [=y] Rockchip platforms all depend on OF anyway, so add the dependency here for compile testing. Fixes: d7b4936b2bc0 ("drm/rockchip: analogix_dp: Add support to get panel from the DP AUX bus") Signed-off-by: Arnd Bergmann Reviewed-by: Dmitry Baryshkov Acked-by: Andy Yan Signed-off-by: Heiko Stuebner Link: https://lore.kernel.org/r/20250423164422.2793634-1-arnd@kernel.org --- drivers/gpu/drm/rockchip/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig index f9d7776a859a..ab525668939a 100644 --- a/drivers/gpu/drm/rockchip/Kconfig +++ b/drivers/gpu/drm/rockchip/Kconfig @@ -2,6 +2,7 @@ config DRM_ROCKCHIP tristate "DRM Support for Rockchip" depends on DRM && ROCKCHIP_IOMMU + depends on OF select DRM_CLIENT_SELECTION select DRM_GEM_DMA_HELPER select DRM_KMS_HELPER From 91e3bf09a90bb4340c0c3c51396e7531555efda4 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Thu, 16 Nov 2023 12:24:24 +0000 Subject: [PATCH 10/38] drm: rcar-du: Fix memory leak in rcar_du_vsps_init() The rcar_du_vsps_init() doesn't free the np allocated by of_parse_phandle_with_fixed_args() for the non-error case. Fix memory leak for the non-error case. While at it, replace the label 'error'->'done' as it applies to non-error case as well and update the error check condition for rcar_du_vsp_init() to avoid breakage in future, if it returns positive value. Fixes: 3e81374e2014 ("drm: rcar-du: Support multiple sources from the same VSP") Signed-off-by: Biju Das Reviewed-by: Laurent Pinchart Link: https://lore.kernel.org/r/20231116122424.80136-1-biju.das.jz@bp.renesas.com Signed-off-by: Tomi Valkeinen --- drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c index 70d8ad065bfa..4c8fe83dd610 100644 --- a/drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c @@ -705,7 +705,7 @@ static int rcar_du_vsps_init(struct rcar_du_device *rcdu) ret = of_parse_phandle_with_fixed_args(np, vsps_prop_name, cells, i, &args); if (ret < 0) - goto error; + goto done; /* * Add the VSP to the list or update the corresponding existing @@ -743,13 +743,11 @@ static int rcar_du_vsps_init(struct rcar_du_device *rcdu) vsp->dev = rcdu; ret = rcar_du_vsp_init(vsp, vsps[i].np, vsps[i].crtcs_mask); - if (ret < 0) - goto error; + if (ret) + goto done; } - return 0; - -error: +done: for (i = 0; i < ARRAY_SIZE(vsps); ++i) of_node_put(vsps[i].np); From 760e296124ef3b6e14cd1d940f2a01c5ed7c0dac Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Wed, 19 Jun 2024 15:54:36 +0800 Subject: [PATCH 11/38] drm: Remove unused function rcar_cmm_write The function are defined in the rcar_cmm.c file, but not called elsewhere, so delete the unused function. drivers/gpu/drm/renesas/rcar-du/rcar_cmm.c:35:19: warning: unused function 'rcar_cmm_read'. Reported-by: Abaci Robot Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=9364 Signed-off-by: Jiapeng Chong Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart Link: https://lore.kernel.org/r/20240619075436.86407-1-jiapeng.chong@linux.alibaba.com Signed-off-by: Tomi Valkeinen --- drivers/gpu/drm/renesas/rcar-du/rcar_cmm.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_cmm.c b/drivers/gpu/drm/renesas/rcar-du/rcar_cmm.c index 79b67c406bd6..93ba115d654f 100644 --- a/drivers/gpu/drm/renesas/rcar-du/rcar_cmm.c +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_cmm.c @@ -32,11 +32,6 @@ struct rcar_cmm { } lut; }; -static inline int rcar_cmm_read(struct rcar_cmm *rcmm, u32 reg) -{ - return ioread32(rcmm->base + reg); -} - static inline void rcar_cmm_write(struct rcar_cmm *rcmm, u32 reg, u32 data) { iowrite32(data, rcmm->base + reg); From 675008f196ca5c8d8413204e861cc2a2238581aa Mon Sep 17 00:00:00 2001 From: Jocelyn Falempe Date: Fri, 18 Apr 2025 18:48:16 +0200 Subject: [PATCH 12/38] drm/panic: Use a decimal fifo to avoid u64 by u64 divide On 32bits ARM, u64/u64 is not supported [1], so change the algorithm to use a simple fifo with decimal digits as u8 instead. This is slower but should compile on all architecture. Link: https://lore.kernel.org/dri-devel/CANiq72ke45eOwckMhWHvmwxc03dxr4rnxxKvx+HvWdBLopZfrQ@mail.gmail.com/ [1] Reported-by: Miguel Ojeda Closes: https://lore.kernel.org/dri-devel/CANiq72ke45eOwckMhWHvmwxc03dxr4rnxxKvx+HvWdBLopZfrQ@mail.gmail.com/ Fixes: ccb8ce526807 ("ARM: 9441/1: rust: Enable Rust support for ARMv7") Signed-off-by: Jocelyn Falempe Link: https://lore.kernel.org/r/20250418165059.560503-1-jfalempe@redhat.com Acked-by: Javier Martinez Canillas --- drivers/gpu/drm/drm_panic_qr.rs | 71 ++++++++++++++++++++++----------- 1 file changed, 48 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/drm_panic_qr.rs b/drivers/gpu/drm/drm_panic_qr.rs index 6025a705530e..dd55b1cb764d 100644 --- a/drivers/gpu/drm/drm_panic_qr.rs +++ b/drivers/gpu/drm/drm_panic_qr.rs @@ -366,8 +366,48 @@ fn iter(&self) -> SegmentIterator<'_> { SegmentIterator { segment: self, offset: 0, - carry: 0, - carry_len: 0, + decfifo: Default::default(), + } + } +} + +/// Max fifo size is 17 (max push) + 2 (max remaining) +const MAX_FIFO_SIZE: usize = 19; + +/// A simple Decimal digit FIFO +#[derive(Default)] +struct DecFifo { + decimals: [u8; MAX_FIFO_SIZE], + len: usize, +} + +impl DecFifo { + fn push(&mut self, data: u64, len: usize) { + let mut chunk = data; + for i in (0..self.len).rev() { + self.decimals[i + len] = self.decimals[i]; + } + for i in 0..len { + self.decimals[i] = (chunk % 10) as u8; + chunk /= 10; + } + self.len += len; + } + + /// Pop 3 decimal digits from the FIFO + fn pop3(&mut self) -> Option<(u16, usize)> { + if self.len == 0 { + None + } else { + let poplen = 3.min(self.len); + self.len -= poplen; + let mut out = 0; + let mut exp = 1; + for i in 0..poplen { + out += self.decimals[self.len + i] as u16 * exp; + exp *= 10; + } + Some((out, NUM_CHARS_BITS[poplen])) } } } @@ -375,8 +415,7 @@ fn iter(&self) -> SegmentIterator<'_> { struct SegmentIterator<'a> { segment: &'a Segment<'a>, offset: usize, - carry: u64, - carry_len: usize, + decfifo: DecFifo, } impl Iterator for SegmentIterator<'_> { @@ -394,31 +433,17 @@ fn next(&mut self) -> Option { } } Segment::Numeric(data) => { - if self.carry_len < 3 && self.offset < data.len() { - // If there are less than 3 decimal digits in the carry, - // take the next 7 bytes of input, and add them to the carry. + if self.decfifo.len < 3 && self.offset < data.len() { + // If there are less than 3 decimal digits in the fifo, + // take the next 7 bytes of input, and push them to the fifo. let mut buf = [0u8; 8]; let len = 7.min(data.len() - self.offset); buf[..len].copy_from_slice(&data[self.offset..self.offset + len]); let chunk = u64::from_le_bytes(buf); - let pow = u64::pow(10, BYTES_TO_DIGITS[len] as u32); - self.carry = chunk + self.carry * pow; + self.decfifo.push(chunk, BYTES_TO_DIGITS[len]); self.offset += len; - self.carry_len += BYTES_TO_DIGITS[len]; - } - match self.carry_len { - 0 => None, - len => { - // take the next 3 decimal digits of the carry - // and return 10bits of numeric data. - let out_len = 3.min(len); - self.carry_len -= out_len; - let pow = u64::pow(10, self.carry_len as u32); - let out = (self.carry / pow) as u16; - self.carry %= pow; - Some((out, NUM_CHARS_BITS[out_len])) - } } + self.decfifo.pop3() } } } From a912b0c8b5eabd9b70dc24cc97a167eb7287a20a Mon Sep 17 00:00:00 2001 From: Dafna Hirschfeld Date: Tue, 22 Apr 2025 12:59:43 +0300 Subject: [PATCH 13/38] drm/gpusvm: remove unused pages pointer The pages pointer is not used, remove it. Signed-off-by: Dafna Hirschfeld Reviewed-by: Matthew Brost Link: https://lore.kernel.org/r/20250422095943.1198393-1-dafna.hirschfeld@intel.com Signed-off-by: Lucas De Marchi --- drivers/gpu/drm/drm_gpusvm.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/gpu/drm/drm_gpusvm.c b/drivers/gpu/drm/drm_gpusvm.c index 38431e8360e7..df76f30bd3d7 100644 --- a/drivers/gpu/drm/drm_gpusvm.c +++ b/drivers/gpu/drm/drm_gpusvm.c @@ -1330,7 +1330,6 @@ int drm_gpusvm_range_get_pages(struct drm_gpusvm *gpusvm, unsigned long num_dma_mapped; unsigned int order = 0; unsigned long *pfns; - struct page **pages; int err = 0; struct dev_pagemap *pagemap; struct drm_pagemap *dpagemap; @@ -1369,7 +1368,6 @@ int drm_gpusvm_range_get_pages(struct drm_gpusvm *gpusvm, if (err) goto err_free; - pages = (struct page **)pfns; map_pages: /* * Perform all dma mappings under the notifier lock to not @@ -1444,8 +1442,6 @@ int drm_gpusvm_range_get_pages(struct drm_gpusvm *gpusvm, err = -EFAULT; goto err_unmap; } - - pages[i] = page; } else { dma_addr_t addr; From bf0636f4348e098e2338eebbe42d7780c58a1195 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Wed, 30 Apr 2025 10:28:49 +0200 Subject: [PATCH 14/38] dt-bindings: display: ltk050h3146w: add port property The panel can be connected to via graph nodes, so allow the port property. This fixes dtc checker warnings like: >> arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou-haikou-video-demo.dtb: panel@0 (leadtek,ltk050h3148w): 'port' does not match any of the regexes: 'pinctrl-[0-9]+' from schema $id: http://devicetree.org/schemas/display/panel/leadtek,ltk050h3146w.yaml# arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou-haikou-video-demo.dtb: /edp@fdec0000: failed to match any schema with compatible: ['rockchip,rk3588-edp'] Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202504300218.VDqQqGTT-lkp@intel.com/ Signed-off-by: Heiko Stuebner Acked-by: Conor Dooley Link: https://lore.kernel.org/r/20250430082850.244199-2-heiko@sntech.de Signed-off-by: Dmitry Baryshkov --- .../devicetree/bindings/display/panel/leadtek,ltk050h3146w.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/display/panel/leadtek,ltk050h3146w.yaml b/Documentation/devicetree/bindings/display/panel/leadtek,ltk050h3146w.yaml index e2a2dd4ef5fa..5fcea62fd58f 100644 --- a/Documentation/devicetree/bindings/display/panel/leadtek,ltk050h3146w.yaml +++ b/Documentation/devicetree/bindings/display/panel/leadtek,ltk050h3146w.yaml @@ -23,6 +23,7 @@ properties: maxItems: 1 backlight: true + port: true reset-gpios: true iovcc-supply: description: regulator that supplies the iovcc voltage From e782ac936941cff4c5580bb5cc2ec0e91468068c Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Wed, 30 Apr 2025 10:28:50 +0200 Subject: [PATCH 15/38] dt-bindings: display: ltk500hd1829: add port property The panel can be connected to via graph nodes, so allow the port property. Signed-off-by: Heiko Stuebner Acked-by: Conor Dooley Link: https://lore.kernel.org/r/20250430082850.244199-3-heiko@sntech.de Signed-off-by: Dmitry Baryshkov --- .../devicetree/bindings/display/panel/leadtek,ltk500hd1829.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/display/panel/leadtek,ltk500hd1829.yaml b/Documentation/devicetree/bindings/display/panel/leadtek,ltk500hd1829.yaml index af9e0ea0e72f..b0e2c82232d3 100644 --- a/Documentation/devicetree/bindings/display/panel/leadtek,ltk500hd1829.yaml +++ b/Documentation/devicetree/bindings/display/panel/leadtek,ltk500hd1829.yaml @@ -22,6 +22,7 @@ properties: maxItems: 1 backlight: true + port: true reset-gpios: true iovcc-supply: description: regulator that supplies the iovcc voltage From 57d6811e8a6d179aeadb7f102369d1ddefe5aae0 Mon Sep 17 00:00:00 2001 From: Andy Yan Date: Mon, 28 Apr 2025 18:23:07 +0800 Subject: [PATCH 16/38] drm/rockchip: rk3066_hdmi: switch to drm bridge Convert it to drm bridge driver, it will be convenient for us to migrate the connector part to the display driver later. Note: I don't have the hardware to test this driver, so for now I can only do the compilation test. Signed-off-by: Andy Yan Tested-by: Heiko Stuebner #rk3066-marsboard Signed-off-by: Heiko Stuebner Link: https://lore.kernel.org/r/20250428102309.1501986-1-andyshrk@163.com --- drivers/gpu/drm/rockchip/rk3066_hdmi.c | 315 ++++++++++++------------- 1 file changed, 146 insertions(+), 169 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rk3066_hdmi.c b/drivers/gpu/drm/rockchip/rk3066_hdmi.c index f7a460190313..e7875b52f298 100644 --- a/drivers/gpu/drm/rockchip/rk3066_hdmi.c +++ b/drivers/gpu/drm/rockchip/rk3066_hdmi.c @@ -5,6 +5,9 @@ */ #include +#include +#include +#include #include #include #include @@ -46,27 +49,20 @@ struct rk3066_hdmi { struct clk *hclk; void __iomem *regs; - struct drm_connector connector; + struct drm_bridge bridge; + struct drm_connector *connector; struct rockchip_encoder encoder; struct rk3066_hdmi_i2c *i2c; - struct i2c_adapter *ddc; unsigned int tmdsclk; struct hdmi_data_info hdmi_data; }; -static struct rk3066_hdmi *encoder_to_rk3066_hdmi(struct drm_encoder *encoder) +static struct rk3066_hdmi *bridge_to_rk3066_hdmi(struct drm_bridge *bridge) { - struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder); - - return container_of(rkencoder, struct rk3066_hdmi, encoder); -} - -static struct rk3066_hdmi *connector_to_rk3066_hdmi(struct drm_connector *connector) -{ - return container_of(connector, struct rk3066_hdmi, connector); + return container_of(bridge, struct rk3066_hdmi, bridge); } static inline u8 hdmi_readb(struct rk3066_hdmi *hdmi, u16 offset) @@ -161,57 +157,40 @@ static void rk3066_hdmi_set_power_mode(struct rk3066_hdmi *hdmi, int mode) hdmi->tmdsclk = DEFAULT_PLLA_RATE; } -static int -rk3066_hdmi_upload_frame(struct rk3066_hdmi *hdmi, int setup_rc, - union hdmi_infoframe *frame, u32 frame_index, - u32 mask, u32 disable, u32 enable) +static int rk3066_hdmi_bridge_clear_infoframe(struct drm_bridge *bridge, + enum hdmi_infoframe_type type) { - if (mask) - hdmi_modb(hdmi, HDMI_CP_AUTO_SEND_CTRL, mask, disable); + struct rk3066_hdmi *hdmi = bridge_to_rk3066_hdmi(bridge); - hdmi_writeb(hdmi, HDMI_CP_BUF_INDEX, frame_index); - - if (setup_rc >= 0) { - u8 packed_frame[HDMI_MAXIMUM_INFO_FRAME_SIZE]; - ssize_t rc, i; - - rc = hdmi_infoframe_pack(frame, packed_frame, - sizeof(packed_frame)); - if (rc < 0) - return rc; - - for (i = 0; i < rc; i++) - hdmi_writeb(hdmi, HDMI_CP_BUF_ACC_HB0 + i * 4, - packed_frame[i]); - - if (mask) - hdmi_modb(hdmi, HDMI_CP_AUTO_SEND_CTRL, mask, enable); + if (type != HDMI_INFOFRAME_TYPE_AVI) { + drm_err(bridge->dev, "Unsupported infoframe type: %u\n", type); + return 0; } - return setup_rc; + hdmi_writeb(hdmi, HDMI_CP_BUF_INDEX, HDMI_INFOFRAME_AVI); + + return 0; } -static int rk3066_hdmi_config_avi(struct rk3066_hdmi *hdmi, - struct drm_display_mode *mode) +static int +rk3066_hdmi_bridge_write_infoframe(struct drm_bridge *bridge, + enum hdmi_infoframe_type type, + const u8 *buffer, size_t len) { - union hdmi_infoframe frame; - int rc; + struct rk3066_hdmi *hdmi = bridge_to_rk3066_hdmi(bridge); + ssize_t i; - rc = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, - &hdmi->connector, mode); + if (type != HDMI_INFOFRAME_TYPE_AVI) { + drm_err(bridge->dev, "Unsupported infoframe type: %u\n", type); + return 0; + } - if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV444) - frame.avi.colorspace = HDMI_COLORSPACE_YUV444; - else if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV422) - frame.avi.colorspace = HDMI_COLORSPACE_YUV422; - else - frame.avi.colorspace = HDMI_COLORSPACE_RGB; + rk3066_hdmi_bridge_clear_infoframe(bridge, type); - frame.avi.colorimetry = hdmi->hdmi_data.colorimetry; - frame.avi.scan_mode = HDMI_SCAN_MODE_NONE; + for (i = 0; i < len; i++) + hdmi_writeb(hdmi, HDMI_CP_BUF_ACC_HB0 + i * 4, buffer[i]); - return rk3066_hdmi_upload_frame(hdmi, rc, &frame, - HDMI_INFOFRAME_AVI, 0, 0, 0); + return 0; } static int rk3066_hdmi_config_video_timing(struct rk3066_hdmi *hdmi, @@ -324,9 +303,27 @@ static void rk3066_hdmi_config_phy(struct rk3066_hdmi *hdmi) } static int rk3066_hdmi_setup(struct rk3066_hdmi *hdmi, - struct drm_display_mode *mode) + struct drm_atomic_state *state) { - struct drm_display_info *display = &hdmi->connector.display_info; + struct drm_bridge *bridge = &hdmi->bridge; + struct drm_connector *connector; + struct drm_display_info *display; + struct drm_display_mode *mode; + struct drm_connector_state *new_conn_state; + struct drm_crtc_state *new_crtc_state; + + connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder); + + new_conn_state = drm_atomic_get_new_connector_state(state, connector); + if (WARN_ON(!new_conn_state)) + return -EINVAL; + + new_crtc_state = drm_atomic_get_new_crtc_state(state, new_conn_state->crtc); + if (WARN_ON(!new_crtc_state)) + return -EINVAL; + + display = &connector->display_info; + mode = &new_crtc_state->adjusted_mode; hdmi->hdmi_data.vic = drm_match_cea_mode(mode); hdmi->hdmi_data.enc_out_format = HDMI_COLORSPACE_RGB; @@ -363,7 +360,7 @@ static int rk3066_hdmi_setup(struct rk3066_hdmi *hdmi, if (display->is_hdmi) { hdmi_modb(hdmi, HDMI_HDCP_CTRL, HDMI_VIDEO_MODE_MASK, HDMI_VIDEO_MODE_HDMI); - rk3066_hdmi_config_avi(hdmi, mode); + drm_atomic_helper_connector_hdmi_update_infoframes(connector, state); } else { hdmi_modb(hdmi, HDMI_HDCP_CTRL, HDMI_VIDEO_MODE_MASK, 0); } @@ -386,15 +383,15 @@ static int rk3066_hdmi_setup(struct rk3066_hdmi *hdmi, return 0; } -static void rk3066_hdmi_encoder_enable(struct drm_encoder *encoder, - struct drm_atomic_state *state) +static void rk3066_hdmi_bridge_atomic_enable(struct drm_bridge *bridge, + struct drm_atomic_state *state) { - struct rk3066_hdmi *hdmi = encoder_to_rk3066_hdmi(encoder); + struct rk3066_hdmi *hdmi = bridge_to_rk3066_hdmi(bridge); struct drm_connector_state *conn_state; struct drm_crtc_state *crtc_state; int mux, val; - conn_state = drm_atomic_get_new_connector_state(state, &hdmi->connector); + conn_state = drm_atomic_get_new_connector_state(state, hdmi->connector); if (WARN_ON(!conn_state)) return; @@ -402,7 +399,7 @@ static void rk3066_hdmi_encoder_enable(struct drm_encoder *encoder, if (WARN_ON(!crtc_state)) return; - mux = drm_of_encoder_active_endpoint_id(hdmi->dev->of_node, encoder); + mux = drm_of_encoder_active_endpoint_id(hdmi->dev->of_node, &hdmi->encoder.encoder); if (mux) val = (HDMI_VIDEO_SEL << 16) | HDMI_VIDEO_SEL; else @@ -413,13 +410,13 @@ static void rk3066_hdmi_encoder_enable(struct drm_encoder *encoder, DRM_DEV_DEBUG(hdmi->dev, "hdmi encoder enable select: vop%s\n", (mux) ? "1" : "0"); - rk3066_hdmi_setup(hdmi, &crtc_state->adjusted_mode); + rk3066_hdmi_setup(hdmi, state); } -static void rk3066_hdmi_encoder_disable(struct drm_encoder *encoder, - struct drm_atomic_state *state) +static void rk3066_hdmi_bridge_atomic_disable(struct drm_bridge *bridge, + struct drm_atomic_state *state) { - struct rk3066_hdmi *hdmi = encoder_to_rk3066_hdmi(encoder); + struct rk3066_hdmi *hdmi = bridge_to_rk3066_hdmi(bridge); DRM_DEV_DEBUG(hdmi->dev, "hdmi encoder disable\n"); @@ -450,39 +447,34 @@ rk3066_hdmi_encoder_atomic_check(struct drm_encoder *encoder, static const struct drm_encoder_helper_funcs rk3066_hdmi_encoder_helper_funcs = { .atomic_check = rk3066_hdmi_encoder_atomic_check, - .atomic_enable = rk3066_hdmi_encoder_enable, - .atomic_disable = rk3066_hdmi_encoder_disable, }; static enum drm_connector_status -rk3066_hdmi_connector_detect(struct drm_connector *connector, bool force) +rk3066_hdmi_bridge_detect(struct drm_bridge *bridge) { - struct rk3066_hdmi *hdmi = connector_to_rk3066_hdmi(connector); + struct rk3066_hdmi *hdmi = bridge_to_rk3066_hdmi(bridge); return (hdmi_readb(hdmi, HDMI_HPG_MENS_STA) & HDMI_HPG_IN_STATUS_HIGH) ? connector_status_connected : connector_status_disconnected; } -static int rk3066_hdmi_connector_get_modes(struct drm_connector *connector) +static const struct drm_edid * +rk3066_hdmi_bridge_edid_read(struct drm_bridge *bridge, struct drm_connector *connector) { - struct rk3066_hdmi *hdmi = connector_to_rk3066_hdmi(connector); + struct rk3066_hdmi *hdmi = bridge_to_rk3066_hdmi(bridge); const struct drm_edid *drm_edid; - int ret = 0; - if (!hdmi->ddc) - return 0; + drm_edid = drm_edid_read_ddc(connector, bridge->ddc); + if (!drm_edid) + dev_dbg(hdmi->dev, "failed to get edid\n"); - drm_edid = drm_edid_read_ddc(connector, hdmi->ddc); - drm_edid_connector_update(connector, drm_edid); - ret = drm_edid_connector_add_modes(connector); - drm_edid_free(drm_edid); - - return ret; + return drm_edid; } static enum drm_mode_status -rk3066_hdmi_connector_mode_valid(struct drm_connector *connector, - const struct drm_display_mode *mode) +rk3066_hdmi_bridge_mode_valid(struct drm_bridge *bridge, + const struct drm_display_info *info, + const struct drm_display_mode *mode) { u32 vic = drm_match_cea_mode(mode); @@ -492,82 +484,19 @@ rk3066_hdmi_connector_mode_valid(struct drm_connector *connector, return MODE_BAD; } -static struct drm_encoder * -rk3066_hdmi_connector_best_encoder(struct drm_connector *connector) -{ - struct rk3066_hdmi *hdmi = connector_to_rk3066_hdmi(connector); - - return &hdmi->encoder.encoder; -} - -static int -rk3066_hdmi_probe_single_connector_modes(struct drm_connector *connector, - uint32_t maxX, uint32_t maxY) -{ - if (maxX > 1920) - maxX = 1920; - if (maxY > 1080) - maxY = 1080; - - return drm_helper_probe_single_connector_modes(connector, maxX, maxY); -} - -static void rk3066_hdmi_connector_destroy(struct drm_connector *connector) -{ - drm_connector_unregister(connector); - drm_connector_cleanup(connector); -} - -static const struct drm_connector_funcs rk3066_hdmi_connector_funcs = { - .fill_modes = rk3066_hdmi_probe_single_connector_modes, - .detect = rk3066_hdmi_connector_detect, - .destroy = rk3066_hdmi_connector_destroy, - .reset = drm_atomic_helper_connector_reset, - .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, - .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, +static const struct drm_bridge_funcs rk3066_hdmi_bridge_funcs = { + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_reset = drm_atomic_helper_bridge_reset, + .atomic_enable = rk3066_hdmi_bridge_atomic_enable, + .atomic_disable = rk3066_hdmi_bridge_atomic_disable, + .detect = rk3066_hdmi_bridge_detect, + .edid_read = rk3066_hdmi_bridge_edid_read, + .hdmi_clear_infoframe = rk3066_hdmi_bridge_clear_infoframe, + .hdmi_write_infoframe = rk3066_hdmi_bridge_write_infoframe, + .mode_valid = rk3066_hdmi_bridge_mode_valid, }; -static const -struct drm_connector_helper_funcs rk3066_hdmi_connector_helper_funcs = { - .get_modes = rk3066_hdmi_connector_get_modes, - .mode_valid = rk3066_hdmi_connector_mode_valid, - .best_encoder = rk3066_hdmi_connector_best_encoder, -}; - -static int -rk3066_hdmi_register(struct drm_device *drm, struct rk3066_hdmi *hdmi) -{ - struct drm_encoder *encoder = &hdmi->encoder.encoder; - struct device *dev = hdmi->dev; - - encoder->possible_crtcs = - drm_of_find_possible_crtcs(drm, dev->of_node); - - /* - * If we failed to find the CRTC(s) which this encoder is - * supposed to be connected to, it's because the CRTC has - * not been registered yet. Defer probing, and hope that - * the required CRTC is added later. - */ - if (encoder->possible_crtcs == 0) - return -EPROBE_DEFER; - - drm_encoder_helper_add(encoder, &rk3066_hdmi_encoder_helper_funcs); - drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS); - - hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD; - - drm_connector_helper_add(&hdmi->connector, - &rk3066_hdmi_connector_helper_funcs); - drm_connector_init_with_ddc(drm, &hdmi->connector, - &rk3066_hdmi_connector_funcs, - DRM_MODE_CONNECTOR_HDMIA, - hdmi->ddc); - - drm_connector_attach_encoder(&hdmi->connector, encoder); - - return 0; -} static irqreturn_t rk3066_hdmi_hardirq(int irq, void *dev_id) { @@ -597,7 +526,7 @@ static irqreturn_t rk3066_hdmi_irq(int irq, void *dev_id) { struct rk3066_hdmi *hdmi = dev_id; - drm_helper_hpd_irq_event(hdmi->connector.dev); + drm_helper_hpd_irq_event(hdmi->connector->dev); return IRQ_HANDLED; } @@ -720,7 +649,7 @@ static struct i2c_adapter *rk3066_hdmi_i2c_adapter(struct rk3066_hdmi *hdmi) strscpy(adap->name, "RK3066 HDMI", sizeof(adap->name)); i2c_set_adapdata(adap, hdmi); - ret = i2c_add_adapter(adap); + ret = devm_i2c_add_adapter(hdmi->dev, adap); if (ret) { DRM_DEV_ERROR(hdmi->dev, "cannot add %s I2C adapter\n", adap->name); @@ -735,6 +664,66 @@ static struct i2c_adapter *rk3066_hdmi_i2c_adapter(struct rk3066_hdmi *hdmi) return adap; } +static int +rk3066_hdmi_register(struct drm_device *drm, struct rk3066_hdmi *hdmi) +{ + struct drm_encoder *encoder = &hdmi->encoder.encoder; + struct device *dev = hdmi->dev; + int ret; + + encoder->possible_crtcs = + drm_of_find_possible_crtcs(drm, dev->of_node); + + /* + * If we failed to find the CRTC(s) which this encoder is + * supposed to be connected to, it's because the CRTC has + * not been registered yet. Defer probing, and hope that + * the required CRTC is added later. + */ + if (encoder->possible_crtcs == 0) + return -EPROBE_DEFER; + + drm_encoder_helper_add(encoder, &rk3066_hdmi_encoder_helper_funcs); + drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS); + + hdmi->bridge.driver_private = hdmi; + hdmi->bridge.funcs = &rk3066_hdmi_bridge_funcs; + hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | + DRM_BRIDGE_OP_EDID | + DRM_BRIDGE_OP_HDMI | + DRM_BRIDGE_OP_HPD; + hdmi->bridge.of_node = hdmi->dev->of_node; + hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA; + hdmi->bridge.vendor = "Rockchip"; + hdmi->bridge.product = "RK3066 HDMI"; + + hdmi->bridge.ddc = rk3066_hdmi_i2c_adapter(hdmi); + if (IS_ERR(hdmi->bridge.ddc)) + return PTR_ERR(hdmi->bridge.ddc); + + if (IS_ERR(hdmi->bridge.ddc)) + return PTR_ERR(hdmi->bridge.ddc); + + ret = devm_drm_bridge_add(dev, &hdmi->bridge); + if (ret) + return ret; + + ret = drm_bridge_attach(encoder, &hdmi->bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR); + if (ret) + return ret; + + hdmi->connector = drm_bridge_connector_init(drm, encoder); + if (IS_ERR(hdmi->connector)) { + ret = PTR_ERR(hdmi->connector); + dev_err(hdmi->dev, "failed to init bridge connector: %d\n", ret); + return ret; + } + + drm_connector_attach_encoder(hdmi->connector, encoder); + + return 0; +} + static int rk3066_hdmi_bind(struct device *dev, struct device *master, void *data) { @@ -781,13 +770,6 @@ static int rk3066_hdmi_bind(struct device *dev, struct device *master, /* internal hclk = hdmi_hclk / 25 */ hdmi_writeb(hdmi, HDMI_INTERNAL_CLK_DIVIDER, 25); - hdmi->ddc = rk3066_hdmi_i2c_adapter(hdmi); - if (IS_ERR(hdmi->ddc)) { - ret = PTR_ERR(hdmi->ddc); - hdmi->ddc = NULL; - goto err_disable_hclk; - } - rk3066_hdmi_set_power_mode(hdmi, HDMI_SYS_POWER_MODE_B); usleep_range(999, 1000); hdmi_writeb(hdmi, HDMI_INTR_MASK1, HDMI_INTR_HOTPLUG); @@ -798,7 +780,7 @@ static int rk3066_hdmi_bind(struct device *dev, struct device *master, ret = rk3066_hdmi_register(drm, hdmi); if (ret) - goto err_disable_i2c; + goto err_disable_hclk; dev_set_drvdata(dev, hdmi); @@ -813,10 +795,7 @@ static int rk3066_hdmi_bind(struct device *dev, struct device *master, return 0; err_cleanup_hdmi: - hdmi->connector.funcs->destroy(&hdmi->connector); hdmi->encoder.encoder.funcs->destroy(&hdmi->encoder.encoder); -err_disable_i2c: - i2c_put_adapter(hdmi->ddc); err_disable_hclk: clk_disable_unprepare(hdmi->hclk); @@ -828,10 +807,8 @@ static void rk3066_hdmi_unbind(struct device *dev, struct device *master, { struct rk3066_hdmi *hdmi = dev_get_drvdata(dev); - hdmi->connector.funcs->destroy(&hdmi->connector); hdmi->encoder.encoder.funcs->destroy(&hdmi->encoder.encoder); - i2c_put_adapter(hdmi->ddc); clk_disable_unprepare(hdmi->hclk); } From c0673bb356557136954b6725bf5fe327b94c6233 Mon Sep 17 00:00:00 2001 From: Andy Yan Date: Tue, 22 Apr 2025 15:04:40 +0800 Subject: [PATCH 17/38] dt-bindings: display: rockchip,inno-hdmi: Fix Document of RK3036 compatible The RK3036 HDMI DDC bus requires it's PHY's reference clock to be enabled first before normal DDC communication can be carried out. Therefore, both RK3036 and RK3128 HDMI require two identical clocks. Signed-off-by: Andy Yan Reviewed-by: "Rob Herring (Arm)" Signed-off-by: Heiko Stuebner Link: https://lore.kernel.org/r/20250422070455.432666-2-andyshrk@163.com --- .../bindings/display/rockchip/rockchip,inno-hdmi.yaml | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,inno-hdmi.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,inno-hdmi.yaml index 5b87b0f1963e..9d1e7f894ea5 100644 --- a/Documentation/devicetree/bindings/display/rockchip/rockchip,inno-hdmi.yaml +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,inno-hdmi.yaml @@ -23,13 +23,11 @@ properties: maxItems: 1 clocks: - minItems: 1 items: - description: The HDMI controller main clock - description: The HDMI PHY reference clock clock-names: - minItems: 1 items: - const: pclk - const: ref @@ -87,11 +85,6 @@ allOf: const: rockchip,rk3128-inno-hdmi then: - properties: - clocks: - minItems: 2 - clock-names: - minItems: 2 required: - power-domains @@ -106,8 +99,8 @@ examples: compatible = "rockchip,rk3036-inno-hdmi"; reg = <0x20034000 0x4000>; interrupts = ; - clocks = <&cru PCLK_HDMI>; - clock-names = "pclk"; + clocks = <&cru PCLK_HDMI>, <&cru SCLK_LCDC>; + clock-names = "pclk", "ref"; pinctrl-names = "default"; pinctrl-0 = <&hdmi_ctl>; #sound-dai-cells = <0>; From e0c93980d293b6e6eb7483fd5d665f84e725b518 Mon Sep 17 00:00:00 2001 From: Andy Yan Date: Tue, 22 Apr 2025 15:04:41 +0800 Subject: [PATCH 18/38] dt-bindings: display: rockchip,inno-hdmi: Document GRF for RK3036 HDMI HDMI on RK3036 use GRF control the HSYNC/VSYNC polarity, but this part is missing when it first landing upstream. Document that it is mandatory for RK3036 HDMI. Signed-off-by: Andy Yan Reviewed-by: Krzysztof Kozlowski Signed-off-by: Heiko Stuebner Link: https://lore.kernel.org/r/20250422070455.432666-3-andyshrk@163.com --- .../bindings/display/rockchip/rockchip,inno-hdmi.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,inno-hdmi.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,inno-hdmi.yaml index 9d1e7f894ea5..290376bec079 100644 --- a/Documentation/devicetree/bindings/display/rockchip/rockchip,inno-hdmi.yaml +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,inno-hdmi.yaml @@ -56,6 +56,12 @@ properties: - port@0 - port@1 + rockchip,grf: + $ref: /schemas/types.yaml#/definitions/phandle + description: + Phandle to GRF used for control the polarity of hsync/vsync of rk3036 + HDMI. + required: - compatible - reg @@ -75,6 +81,8 @@ allOf: const: rockchip,rk3036-inno-hdmi then: + required: + - rockchip,grf properties: power-domains: false @@ -103,6 +111,7 @@ examples: clock-names = "pclk", "ref"; pinctrl-names = "default"; pinctrl-0 = <&hdmi_ctl>; + rockchip,grf = <&grf>; #sound-dai-cells = <0>; ports { From 31b4403c6c523a710205eadb9ca75c6cfe1478ab Mon Sep 17 00:00:00 2001 From: Andy Yan Date: Tue, 22 Apr 2025 15:04:42 +0800 Subject: [PATCH 19/38] drm/rockchip: inno-hdmi: Simplify error handler with dev_err_probe Use dev_err_probe simplify the error handle. Signed-off-by: Andy Yan Tested-by: Heiko Stuebner #rk3036-kylin Signed-off-by: Heiko Stuebner Link: https://lore.kernel.org/r/20250422070455.432666-4-andyshrk@163.com --- drivers/gpu/drm/rockchip/inno_hdmi.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c index 483ecfeaebb0..e891d42dd08a 100644 --- a/drivers/gpu/drm/rockchip/inno_hdmi.c +++ b/drivers/gpu/drm/rockchip/inno_hdmi.c @@ -885,29 +885,22 @@ static int inno_hdmi_bind(struct device *dev, struct device *master, return PTR_ERR(hdmi->regs); hdmi->pclk = devm_clk_get(hdmi->dev, "pclk"); - if (IS_ERR(hdmi->pclk)) { - DRM_DEV_ERROR(hdmi->dev, "Unable to get HDMI pclk clk\n"); - return PTR_ERR(hdmi->pclk); - } + if (IS_ERR(hdmi->pclk)) + return dev_err_probe(dev, PTR_ERR(hdmi->pclk), "Unable to get HDMI pclk\n"); ret = clk_prepare_enable(hdmi->pclk); - if (ret) { - DRM_DEV_ERROR(hdmi->dev, - "Cannot enable HDMI pclk clock: %d\n", ret); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "Cannot enable HDMI pclk: %d\n", ret); hdmi->refclk = devm_clk_get_optional(hdmi->dev, "ref"); if (IS_ERR(hdmi->refclk)) { - DRM_DEV_ERROR(hdmi->dev, "Unable to get HDMI reference clock\n"); - ret = PTR_ERR(hdmi->refclk); + ret = dev_err_probe(dev, PTR_ERR(hdmi->refclk), "Unable to get HDMI refclk\n"); goto err_disable_pclk; } ret = clk_prepare_enable(hdmi->refclk); if (ret) { - DRM_DEV_ERROR(hdmi->dev, - "Cannot enable HDMI reference clock: %d\n", ret); + ret = dev_err_probe(dev, ret, "Cannot enable HDMI refclk: %d\n", ret); goto err_disable_pclk; } From ad10b82c2bcac7f87ac6eaecfca33378b43425ee Mon Sep 17 00:00:00 2001 From: Andy Yan Date: Tue, 22 Apr 2025 15:04:43 +0800 Subject: [PATCH 20/38] drm/rockchip: inno-hdmi: Fix video timing HSYNC/VSYNC polarity setting for rk3036 The HSYNC/VSYNC polarity of rk3036 HDMI are controlled by GRF. Without the polarity configuration in GRF, it can be observed from the HDMI protocol analyzer that the H/V front/back timing output by RK3036 HDMI are currently not in line with the specifications. Signed-off-by: Andy Yan Tested-by: Heiko Stuebner #rk3036-kylin Signed-off-by: Heiko Stuebner Link: https://lore.kernel.org/r/20250422070455.432666-5-andyshrk@163.com --- drivers/gpu/drm/rockchip/inno_hdmi.c | 36 +++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c index e891d42dd08a..db4b4038e51d 100644 --- a/drivers/gpu/drm/rockchip/inno_hdmi.c +++ b/drivers/gpu/drm/rockchip/inno_hdmi.c @@ -10,10 +10,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include @@ -29,8 +31,19 @@ #include "inno_hdmi.h" +#define HIWORD_UPDATE(val, mask) ((val) | (mask) << 16) + #define INNO_HDMI_MIN_TMDS_CLOCK 25000000U +#define RK3036_GRF_SOC_CON2 0x148 +#define RK3036_HDMI_PHSYNC BIT(4) +#define RK3036_HDMI_PVSYNC BIT(5) + +enum inno_hdmi_dev_type { + RK3036_HDMI, + RK3128_HDMI, +}; + struct inno_hdmi_phy_config { unsigned long pixelclock; u8 pre_emphasis; @@ -38,6 +51,7 @@ struct inno_hdmi_phy_config { }; struct inno_hdmi_variant { + enum inno_hdmi_dev_type dev_type; struct inno_hdmi_phy_config *phy_configs; struct inno_hdmi_phy_config *default_phy_config; }; @@ -58,6 +72,7 @@ struct inno_hdmi { struct clk *pclk; struct clk *refclk; void __iomem *regs; + struct regmap *grf; struct drm_connector connector; struct rockchip_encoder encoder; @@ -374,7 +389,15 @@ static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi) static int inno_hdmi_config_video_timing(struct inno_hdmi *hdmi, struct drm_display_mode *mode) { - int value; + int value, psync; + + if (hdmi->variant->dev_type == RK3036_HDMI) { + psync = mode->flags & DRM_MODE_FLAG_PHSYNC ? RK3036_HDMI_PHSYNC : 0; + value = HIWORD_UPDATE(psync, RK3036_HDMI_PHSYNC); + psync = mode->flags & DRM_MODE_FLAG_PVSYNC ? RK3036_HDMI_PVSYNC : 0; + value |= HIWORD_UPDATE(psync, RK3036_HDMI_PVSYNC); + regmap_write(hdmi->grf, RK3036_GRF_SOC_CON2, value); + } /* Set detail external video timing polarity and interlace mode */ value = v_EXTERANL_VIDEO(1); @@ -904,6 +927,15 @@ static int inno_hdmi_bind(struct device *dev, struct device *master, goto err_disable_pclk; } + if (hdmi->variant->dev_type == RK3036_HDMI) { + hdmi->grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf"); + if (IS_ERR(hdmi->grf)) { + ret = dev_err_probe(dev, PTR_ERR(hdmi->grf), + "Unable to get rockchip,grf\n"); + goto err_disable_clk; + } + } + irq = platform_get_irq(pdev, 0); if (irq < 0) { ret = irq; @@ -988,11 +1020,13 @@ static void inno_hdmi_remove(struct platform_device *pdev) } static const struct inno_hdmi_variant rk3036_inno_hdmi_variant = { + .dev_type = RK3036_HDMI, .phy_configs = rk3036_hdmi_phy_configs, .default_phy_config = &rk3036_hdmi_phy_configs[1], }; static const struct inno_hdmi_variant rk3128_inno_hdmi_variant = { + .dev_type = RK3128_HDMI, .phy_configs = rk3128_hdmi_phy_configs, .default_phy_config = &rk3128_hdmi_phy_configs[1], }; From af28dfc32bb4bffd9666ac20891db9d3bce8a742 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barnab=C3=A1s=20Cz=C3=A9m=C3=A1n?= Date: Wed, 30 Apr 2025 21:42:12 +0200 Subject: [PATCH 21/38] dt-bindings: display: panel: Add BOE TD4320 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Document BOE TD4320 6.3" 2340x1080 panel found in Xiaomi Redmi Note 7 smartphone. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Barnabás Czémán Link: https://lore.kernel.org/r/20250430-lavender-panel-v3-1-7625e62d62b2@mainlining.org Signed-off-by: Neil Armstrong Link: https://lore.kernel.org/r/20250430-lavender-panel-v3-1-7625e62d62b2@mainlining.org --- .../bindings/display/panel/boe,td4320.yaml | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/boe,td4320.yaml diff --git a/Documentation/devicetree/bindings/display/panel/boe,td4320.yaml b/Documentation/devicetree/bindings/display/panel/boe,td4320.yaml new file mode 100644 index 000000000000..c6bff0ece360 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/boe,td4320.yaml @@ -0,0 +1,65 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/boe,td4320.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: BOE TD4320 MIPI-DSI panels + +maintainers: + - Barnabas Czeman + +description: + BOE TD4320 6.3" 1080x2340 panel found in Xiaomi Redmi Note 7 smartphone. + +allOf: + - $ref: panel-common.yaml# + +properties: + compatible: + items: + - const: boe,td4320 + + reg: + maxItems: 1 + + iovcc-supply: + description: I/O voltage rail + + vsn-supply: + description: Negative source voltage rail + + vsp-supply: + description: Positive source voltage rail + +required: + - compatible + - reg + - reset-gpios + - port + +unevaluatedProperties: false + +examples: + - | + #include + + dsi { + #address-cells = <1>; + #size-cells = <0>; + + panel@0 { + compatible = "boe,td4320"; + reg = <0>; + backlight = <&backlight>; + reset-gpios = <&tlmm 45 GPIO_ACTIVE_LOW>; + + port { + panel_in: endpoint { + remote-endpoint = <&dsi_out>; + }; + }; + }; + }; + +... From 7220a310b9fbe431951e31487f7ae92498420e52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barnab=C3=A1s=20Cz=C3=A9m=C3=A1n?= Date: Wed, 30 Apr 2025 21:42:13 +0200 Subject: [PATCH 22/38] drivers: gpu: drm: panel: Add BOE TD4320 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add driver for BOE TD4320 DSI panel, used in Xiaomi Redmi Note 7 mobile phone. Signed-off-by: Barnabás Czémán Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20250430-lavender-panel-v3-2-7625e62d62b2@mainlining.org Signed-off-by: Neil Armstrong Link: https://lore.kernel.org/r/20250430-lavender-panel-v3-2-7625e62d62b2@mainlining.org --- drivers/gpu/drm/panel/Kconfig | 9 + drivers/gpu/drm/panel/Makefile | 1 + drivers/gpu/drm/panel/panel-boe-td4320.c | 247 +++++++++++++++++++++++ 3 files changed, 257 insertions(+) create mode 100644 drivers/gpu/drm/panel/panel-boe-td4320.c diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index 7e9c60a626fb..639f4324db61 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -67,6 +67,15 @@ config DRM_PANEL_BOE_HIMAX8279D 24 bit RGB per pixel. It provides a MIPI DSI interface to the host and has a built-in LED backlight. +config DRM_PANEL_BOE_TD4320 + tristate "BOE TD4320 DSI panel" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y here if you want to enable support for BOE TD4320 1080x2340 + video mode panel found in Xiaomi Redmi Note 7 smartphones. + config DRM_PANEL_BOE_TH101MB31UIG002_28A tristate "Boe TH101MB31UIG002-28A panel" depends on OF diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index 883974f0cba1..5eec88e4ac3d 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_DRM_PANEL_ASUS_Z00T_TM5P5_NT35596) += panel-asus-z00t-tm5p5-n35596. obj-$(CONFIG_DRM_PANEL_AUO_A030JTN01) += panel-auo-a030jtn01.o obj-$(CONFIG_DRM_PANEL_BOE_BF060Y8M_AJ0) += panel-boe-bf060y8m-aj0.o obj-$(CONFIG_DRM_PANEL_BOE_HIMAX8279D) += panel-boe-himax8279d.o +obj-$(CONFIG_DRM_PANEL_BOE_TD4320) += panel-boe-td4320.o obj-$(CONFIG_DRM_PANEL_BOE_TH101MB31UIG002_28A) += panel-boe-th101mb31ig002-28a.o obj-$(CONFIG_DRM_PANEL_BOE_TV101WUM_LL2) += panel-boe-tv101wum-ll2.o obj-$(CONFIG_DRM_PANEL_BOE_TV101WUM_NL6) += panel-boe-tv101wum-nl6.o diff --git a/drivers/gpu/drm/panel/panel-boe-td4320.c b/drivers/gpu/drm/panel/panel-boe-td4320.c new file mode 100644 index 000000000000..1956daa2c71b --- /dev/null +++ b/drivers/gpu/drm/panel/panel-boe-td4320.c @@ -0,0 +1,247 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (c) 2024 Barnabas Czeman +// Generated with linux-mdss-dsi-panel-driver-generator from vendor device tree: +// Copyright (c) 2013, The Linux Foundation. All rights reserved. + +#include +#include +#include +#include +#include + +#include