public inbox for drm-ai-reviews@public-inbox.freedesktop.org
 help / color / mirror / Atom feed
* [PATCH v3] drm/tegra: Enable cmu for Tegra186 and Tegra194
@ 2026-04-06  7:47 Aaron Kling via B4 Relay
  2026-04-07  4:59 ` Mikko Perttunen
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Aaron Kling via B4 Relay @ 2026-04-06  7:47 UTC (permalink / raw)
  To: Thierry Reding, Mikko Perttunen, David Airlie, Simona Vetter,
	Jonathan Hunter, Thierry Reding
  Cc: dri-devel, linux-tegra, linux-kernel, Kurt Kiefer, Aaron Kling,
	Jasper Korten

From: Aaron Kling <webgeek1234@gmail.com>

Without the cmu, nvdisplay will display colors that are notably darker
than intended. The vendor bootloader and the downstream display driver
enable the cmu and sets a sRGB table. Loading that table here results in
the intended colors.

Co-developed-by: Kurt Kiefer <kekiefer@gmail.com>
Signed-off-by: Aaron Kling <webgeek1234@gmail.com>
Tested-by: Jasper Korten <jja2000@gmail.com>
---
Changes in v3:
- Remove improper IOVA null check
- Use dmam_alloc_coherent instead of manually tracking memory
- Address other review comments
- Link to v2: https://lore.kernel.org/r/20260202-tegra-drm-cmu-v2-1-a1bcb37f3e85@gmail.com

Changes in v2:
- Several formatting changes per v1 review
- Move cmu alloc/free to dc, where it can be handled in probe/remove
- Enable cmu for displayport as well
- Link to v1: https://lore.kernel.org/r/20251101-tegra-drm-cmu-v1-1-211799755ab8@gmail.com
---
 drivers/gpu/drm/tegra/dc.c  | 116 ++++++++++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/tegra/dc.h  |  13 +++++
 drivers/gpu/drm/tegra/sor.c |  25 ++++++++++
 3 files changed, 154 insertions(+)

diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 06370b7e0e5678c7a91f288bc98599503fe9f049..4500b970f05d856a44533fd6c7daec9e81cc2be5 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -36,6 +36,103 @@
 #include "hub.h"
 #include "plane.h"
 
+static const u16 default_srgb_lut[] = {
+	0x6000, 0x60CE, 0x619D, 0x626C, 0x632D, 0x63D4, 0x6469, 0x64F0, 0x656B, 0x65DF, 0x664A,
+	0x66B0, 0x6711, 0x676D, 0x67C4, 0x6819, 0x686A, 0x68B8, 0x6904, 0x694D, 0x6994, 0x69D8,
+	0x6A1B, 0x6A5D, 0x6A9C, 0x6ADA, 0x6B17, 0x6B52, 0x6B8C, 0x6BC5, 0x6BFD, 0x6C33, 0x6C69,
+	0x6C9E, 0x6CD1, 0x6D04, 0x6D36, 0x6D67, 0x6D98, 0x6DC7, 0x6DF6, 0x6E25, 0x6E52, 0x6E7F,
+	0x6EAC, 0x6ED7, 0x6F03, 0x6F2D, 0x6F58, 0x6F81, 0x6FAA, 0x6FD3, 0x6FFB, 0x7023, 0x704B,
+	0x7071, 0x7098, 0x70BE, 0x70E4, 0x7109, 0x712E, 0x7153, 0x7177, 0x719B, 0x71BF, 0x71E2,
+	0x7205, 0x7227, 0x724A, 0x726C, 0x728E, 0x72AF, 0x72D0, 0x72F1, 0x7312, 0x7333, 0x7353,
+	0x7373, 0x7392, 0x73B2, 0x73D1, 0x73F0, 0x740F, 0x742D, 0x744C, 0x746A, 0x7488, 0x74A6,
+	0x74C3, 0x74E0, 0x74FE, 0x751B, 0x7537, 0x7554, 0x7570, 0x758D, 0x75A9, 0x75C4, 0x75E0,
+	0x75FC, 0x7617, 0x7632, 0x764D, 0x7668, 0x7683, 0x769E, 0x76B8, 0x76D3, 0x76ED, 0x7707,
+	0x7721, 0x773B, 0x7754, 0x776E, 0x7787, 0x77A0, 0x77B9, 0x77D2, 0x77EB, 0x7804, 0x781D,
+	0x7835, 0x784E, 0x7866, 0x787E, 0x7896, 0x78AE, 0x78C6, 0x78DD, 0x78F5, 0x790D, 0x7924,
+	0x793B, 0x7952, 0x796A, 0x7981, 0x7997, 0x79AE, 0x79C5, 0x79DB, 0x79F2, 0x7A08, 0x7A1F,
+	0x7A35, 0x7A4B, 0x7A61, 0x7A77, 0x7A8D, 0x7AA3, 0x7AB8, 0x7ACE, 0x7AE3, 0x7AF9, 0x7B0E,
+	0x7B24, 0x7B39, 0x7B4E, 0x7B63, 0x7B78, 0x7B8D, 0x7BA2, 0x7BB6, 0x7BCB, 0x7BE0, 0x7BF4,
+	0x7C08, 0x7C1D, 0x7C31, 0x7C45, 0x7C59, 0x7C6E, 0x7C82, 0x7C96, 0x7CA9, 0x7CBD, 0x7CD1,
+	0x7CE5, 0x7CF8, 0x7D0C, 0x7D1F, 0x7D33, 0x7D46, 0x7D59, 0x7D6D, 0x7D80, 0x7D93, 0x7DA6,
+	0x7DB9, 0x7DCC, 0x7DDF, 0x7DF2, 0x7E04, 0x7E17, 0x7E2A, 0x7E3C, 0x7E4F, 0x7E61, 0x7E74,
+	0x7E86, 0x7E98, 0x7EAB, 0x7EBD, 0x7ECF, 0x7EE1, 0x7EF3, 0x7F05, 0x7F17, 0x7F29, 0x7F3B,
+	0x7F4D, 0x7F5E, 0x7F70, 0x7F82, 0x7F93, 0x7FA5, 0x7FB6, 0x7FC8, 0x7FD9, 0x7FEB, 0x7FFC,
+	0x800D, 0x801E, 0x8030, 0x8041, 0x8052, 0x8063, 0x8074, 0x8085, 0x8096, 0x80A7, 0x80B7,
+	0x80C8, 0x80D9, 0x80EA, 0x80FA, 0x810B, 0x811C, 0x812C, 0x813D, 0x814D, 0x815D, 0x816E,
+	0x817E, 0x818E, 0x819F, 0x81AF, 0x81BF, 0x81CF, 0x81DF, 0x81EF, 0x81FF, 0x820F, 0x821F,
+	0x822F, 0x823F, 0x824F, 0x825F, 0x826F, 0x827E, 0x828E, 0x829E, 0x82AD, 0x82BD, 0x82CC,
+	0x82DC, 0x82EB, 0x82FB, 0x830A, 0x831A, 0x8329, 0x8338, 0x8348, 0x8357, 0x8366, 0x8375,
+	0x8385, 0x8394, 0x83A3, 0x83B2, 0x83C1, 0x83D0, 0x83DF, 0x83EE, 0x83FD, 0x840C, 0x841A,
+	0x8429, 0x8438, 0x8447, 0x8455, 0x8464, 0x8473, 0x8481, 0x8490, 0x849F, 0x84AD, 0x84BC,
+	0x84CA, 0x84D9, 0x84E7, 0x84F5, 0x8504, 0x8512, 0x8521, 0x852F, 0x853D, 0x854B, 0x855A,
+	0x8568, 0x8576, 0x8584, 0x8592, 0x85A0, 0x85AE, 0x85BC, 0x85CA, 0x85D8, 0x85E6, 0x85F4,
+	0x8602, 0x8610, 0x861E, 0x862C, 0x8639, 0x8647, 0x8655, 0x8663, 0x8670, 0x867E, 0x868C,
+	0x8699, 0x86A7, 0x86B5, 0x86C2, 0x86D0, 0x86DD, 0x86EB, 0x86F8, 0x8705, 0x8713, 0x8720,
+	0x872E, 0x873B, 0x8748, 0x8756, 0x8763, 0x8770, 0x877D, 0x878B, 0x8798, 0x87A5, 0x87B2,
+	0x87BF, 0x87CC, 0x87D9, 0x87E6, 0x87F3, 0x8801, 0x880E, 0x881A, 0x8827, 0x8834, 0x8841,
+	0x884E, 0x885B, 0x8868, 0x8875, 0x8882, 0x888E, 0x889B, 0x88A8, 0x88B5, 0x88C1, 0x88CE,
+	0x88DB, 0x88E7, 0x88F4, 0x8900, 0x890D, 0x891A, 0x8926, 0x8933, 0x893F, 0x894C, 0x8958,
+	0x8965, 0x8971, 0x897D, 0x898A, 0x8996, 0x89A3, 0x89AF, 0x89BB, 0x89C8, 0x89D4, 0x89E0,
+	0x89EC, 0x89F9, 0x8A05, 0x8A11, 0x8A1D, 0x8A29, 0x8A36, 0x8A42, 0x8A4E, 0x8A5A, 0x8A66,
+	0x8A72, 0x8A7E, 0x8A8A, 0x8A96, 0x8AA2, 0x8AAE, 0x8ABA, 0x8AC6, 0x8AD2, 0x8ADE, 0x8AEA,
+	0x8AF5, 0x8B01, 0x8B0D, 0x8B19, 0x8B25, 0x8B31, 0x8B3C, 0x8B48, 0x8B54, 0x8B60, 0x8B6B,
+	0x8B77, 0x8B83, 0x8B8E, 0x8B9A, 0x8BA6, 0x8BB1, 0x8BBD, 0x8BC8, 0x8BD4, 0x8BDF, 0x8BEB,
+	0x8BF6, 0x8C02, 0x8C0D, 0x8C19, 0x8C24, 0x8C30, 0x8C3B, 0x8C47, 0x8C52, 0x8C5D, 0x8C69,
+	0x8C74, 0x8C80, 0x8C8B, 0x8C96, 0x8CA1, 0x8CAD, 0x8CB8, 0x8CC3, 0x8CCF, 0x8CDA, 0x8CE5,
+	0x8CF0, 0x8CFB, 0x8D06, 0x8D12, 0x8D1D, 0x8D28, 0x8D33, 0x8D3E, 0x8D49, 0x8D54, 0x8D5F,
+	0x8D6A, 0x8D75, 0x8D80, 0x8D8B, 0x8D96, 0x8DA1, 0x8DAC, 0x8DB7, 0x8DC2, 0x8DCD, 0x8DD8,
+	0x8DE3, 0x8DEE, 0x8DF9, 0x8E04, 0x8E0E, 0x8E19, 0x8E24, 0x8E2F, 0x8E3A, 0x8E44, 0x8E4F,
+	0x8E5A, 0x8E65, 0x8E6F, 0x8E7A, 0x8E85, 0x8E90, 0x8E9A, 0x8EA5, 0x8EB0, 0x8EBA, 0x8EC5,
+	0x8ECF, 0x8EDA, 0x8EE5, 0x8EEF, 0x8EFA, 0x8F04, 0x8F0F, 0x8F19, 0x8F24, 0x8F2E, 0x8F39,
+	0x8F43, 0x8F4E, 0x8F58, 0x8F63, 0x8F6D, 0x8F78, 0x8F82, 0x8F8C, 0x8F97, 0x8FA1, 0x8FAC,
+	0x8FB6, 0x8FC0, 0x8FCB, 0x8FD5, 0x8FDF, 0x8FEA, 0x8FF4, 0x8FFE, 0x9008, 0x9013, 0x901D,
+	0x9027, 0x9031, 0x903C, 0x9046, 0x9050, 0x905A, 0x9064, 0x906E, 0x9079, 0x9083, 0x908D,
+	0x9097, 0x90A1, 0x90AB, 0x90B5, 0x90BF, 0x90C9, 0x90D3, 0x90DD, 0x90E7, 0x90F1, 0x90FB,
+	0x9105, 0x910F, 0x9119, 0x9123, 0x912D, 0x9137, 0x9141, 0x914B, 0x9155, 0x915F, 0x9169,
+	0x9173, 0x917D, 0x9186, 0x9190, 0x919A, 0x91A4, 0x91AE, 0x91B8, 0x91C1, 0x91CB, 0x91D5,
+	0x91DF, 0x91E9, 0x91F2, 0x91FC, 0x9206, 0x9210, 0x9219, 0x9223, 0x922D, 0x9236, 0x9240,
+	0x924A, 0x9253, 0x925D, 0x9267, 0x9270, 0x927A, 0x9283, 0x928D, 0x9297, 0x92A0, 0x92AA,
+	0x92B3, 0x92BD, 0x92C6, 0x92D0, 0x92DA, 0x92E3, 0x92ED, 0x92F6, 0x9300, 0x9309, 0x9313,
+	0x931C, 0x9325, 0x932F, 0x9338, 0x9342, 0x934B, 0x9355, 0x935E, 0x9367, 0x9371, 0x937A,
+	0x9384, 0x938D, 0x9396, 0x93A0, 0x93A9, 0x93B2, 0x93BC, 0x93C5, 0x93CE, 0x93D7, 0x93E1,
+	0x93EA, 0x93F3, 0x93FC, 0x9406, 0x940F, 0x9418, 0x9421, 0x942B, 0x9434, 0x943D, 0x9446,
+	0x944F, 0x9459, 0x9462, 0x946B, 0x9474, 0x947D, 0x9486, 0x948F, 0x9499, 0x94A2, 0x94AB,
+	0x94B4, 0x94BD, 0x94C6, 0x94CF, 0x94D8, 0x94E1, 0x94EA, 0x94F3, 0x94FC, 0x9505, 0x950E,
+	0x9517, 0x9520, 0x9529, 0x9532, 0x953B, 0x9544, 0x954D, 0x9556, 0x955F, 0x9568, 0x9571,
+	0x957A, 0x9583, 0x958C, 0x9595, 0x959D, 0x95A6, 0x95AF, 0x95B8, 0x95C1, 0x95CA, 0x95D3,
+	0x95DB, 0x95E4, 0x95ED, 0x95F6, 0x95FF, 0x9608, 0x9610, 0x9619, 0x9622, 0x962B, 0x9633,
+	0x963C, 0x9645, 0x964E, 0x9656, 0x965F, 0x9668, 0x9671, 0x9679, 0x9682, 0x968B, 0x9693,
+	0x969C, 0x96A5, 0x96AD, 0x96B6, 0x96BF, 0x96C7, 0x96D0, 0x96D9, 0x96E1, 0x96EA, 0x96F2,
+	0x96FB, 0x9704, 0x970C, 0x9715, 0x971D, 0x9726, 0x972E, 0x9737, 0x9740, 0x9748, 0x9751,
+	0x9759, 0x9762, 0x976A, 0x9773, 0x977B, 0x9784, 0x978C, 0x9795, 0x979D, 0x97A6, 0x97AE,
+	0x97B6, 0x97BF, 0x97C7, 0x97D0, 0x97D8, 0x97E1, 0x97E9, 0x97F1, 0x97FA, 0x9802, 0x980B,
+	0x9813, 0x981B, 0x9824, 0x982C, 0x9834, 0x983D, 0x9845, 0x984D, 0x9856, 0x985E, 0x9866,
+	0x986F, 0x9877, 0x987F, 0x9888, 0x9890, 0x9898, 0x98A0, 0x98A9, 0x98B1, 0x98B9, 0x98C1,
+	0x98CA, 0x98D2, 0x98DA, 0x98E2, 0x98EB, 0x98F3, 0x98FB, 0x9903, 0x990B, 0x9914, 0x991C,
+	0x9924, 0x992C, 0x9934, 0x993C, 0x9945, 0x994D, 0x9955, 0x995D, 0x9965, 0x996D, 0x9975,
+	0x997D, 0x9986, 0x998E, 0x9996, 0x999E, 0x99A6, 0x99AE, 0x99B6, 0x99BE, 0x99C6, 0x99CE,
+	0x99D6, 0x99DE, 0x99E6, 0x99EE, 0x99F6, 0x99FE, 0x9A06, 0x9A0E, 0x9A16, 0x9A1E, 0x9A26,
+	0x9A2E, 0x9A36, 0x9A3E, 0x9A46, 0x9A4E, 0x9A56, 0x9A5E, 0x9A66, 0x9A6E, 0x9A76, 0x9A7E,
+	0x9A86, 0x9A8E, 0x9A96, 0x9A9D, 0x9AA5, 0x9AAD, 0x9AB5, 0x9ABD, 0x9AC5, 0x9ACD, 0x9AD5,
+	0x9ADC, 0x9AE4, 0x9AEC, 0x9AF4, 0x9AFC, 0x9B04, 0x9B0C, 0x9B13, 0x9B1B, 0x9B23, 0x9B2B,
+	0x9B33, 0x9B3A, 0x9B42, 0x9B4A, 0x9B52, 0x9B59, 0x9B61, 0x9B69, 0x9B71, 0x9B79, 0x9B80,
+	0x9B88, 0x9B90, 0x9B97, 0x9B9F, 0x9BA7, 0x9BAF, 0x9BB6, 0x9BBE, 0x9BC6, 0x9BCD, 0x9BD5,
+	0x9BDD, 0x9BE5, 0x9BEC, 0x9BF4, 0x9BFC, 0x9C03, 0x9C0B, 0x9C12, 0x9C1A, 0x9C22, 0x9C29,
+	0x9C31, 0x9C39, 0x9C40, 0x9C48, 0x9C50, 0x9C57, 0x9C5F, 0x9C66, 0x9C6E, 0x9C75, 0x9C7D,
+	0x9C85, 0x9C8C, 0x9C94, 0x9C9B, 0x9CA3, 0x9CAA, 0x9CB2, 0x9CBA, 0x9CC1, 0x9CC9, 0x9CD0,
+	0x9CD8, 0x9CDF, 0x9CE7, 0x9CEE, 0x9CF6, 0x9CFD, 0x9D05, 0x9D0C, 0x9D14, 0x9D1B, 0x9D23,
+	0x9D2A, 0x9D32, 0x9D39, 0x9D40, 0x9D48, 0x9D4F, 0x9D57, 0x9D5E, 0x9D66, 0x9D6D, 0x9D75,
+	0x9D7C, 0x9D83, 0x9D8B, 0x9D92, 0x9D9A, 0x9DA1, 0x9DA8, 0x9DB0, 0x9DB7, 0x9DBE, 0x9DC6,
+	0x9DCD, 0x9DD5, 0x9DDC, 0x9DE3, 0x9DEB, 0x9DF2, 0x9DF9, 0x9E01, 0x9E08, 0x9E0F, 0x9E17,
+	0x9E1E, 0x9E25, 0x9E2D, 0x9E34, 0x9E3B, 0x9E43, 0x9E4A, 0x9E51, 0x9E58, 0x9E60, 0x9E67,
+	0x9E6E, 0x9E75, 0x9E7D, 0x9E84, 0x9E8B, 0x9E92, 0x9E9A, 0x9EA1, 0x9EA8, 0x9EAF, 0x9EB7,
+	0x9EBE, 0x9EC5, 0x9ECC, 0x9ED4, 0x9EDB, 0x9EE2, 0x9EE9, 0x9EF0, 0x9EF7, 0x9EFF, 0x9F06,
+	0x9F0D, 0x9F14, 0x9F1B, 0x9F23, 0x9F2A, 0x9F31, 0x9F38, 0x9F3F, 0x9F46, 0x9F4D, 0x9F55,
+	0x9F5C, 0x9F63, 0x9F6A, 0x9F71, 0x9F78, 0x9F7F, 0x9F86, 0x9F8D, 0x9F95, 0x9F9C, 0x9FA3,
+	0x9FAA, 0x9FB1, 0x9FB8, 0x9FBF, 0x9FC6, 0x9FCD, 0x9FD4, 0x9FDB, 0x9FE2, 0x9FE9, 0x9FF0,
+	0x9FF7, 0x9FFF,
+};
+
 static void tegra_crtc_atomic_destroy_state(struct drm_crtc *crtc,
 					    struct drm_crtc_state *state);
 
@@ -3251,6 +3348,25 @@ static int tegra_dc_probe(struct platform_device *pdev)
 	if (dc->irq < 0)
 		return -ENXIO;
 
+	if (dc->soc->has_nvdisplay) {
+		unsigned int i;
+		u64 r;
+
+		dc->cmu_output_lut =
+			dmam_alloc_coherent(dc->dev, ARRAY_SIZE(default_srgb_lut) * sizeof(u64),
+					    &dc->cmu_output_phys, GFP_KERNEL);
+
+		if (!dc->cmu_output_lut) {
+			dev_err(dc->dev, "failed to allocate lut for cmu\n");
+			return -ENOMEM;
+		}
+
+		for (i = 0; i < ARRAY_SIZE(default_srgb_lut); i++) {
+			r = default_srgb_lut[i];
+			dc->cmu_output_lut[i] = (r << 32) | (r << 16) | r;
+		}
+	}
+
 	err = tegra_dc_rgb_probe(dc);
 	if (err < 0 && err != -ENODEV)
 		return dev_err_probe(&pdev->dev, err,
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h
index 0559fa6b1bf70416e51d5067cc04a6ae6572de23..973ab0bb15c9260be6256b4459cd03c018d3dea5 100644
--- a/drivers/gpu/drm/tegra/dc.h
+++ b/drivers/gpu/drm/tegra/dc.h
@@ -103,6 +103,9 @@ struct tegra_dc {
 	const struct tegra_dc_soc_info *soc;
 
 	bool has_opp_table;
+
+	u64 *cmu_output_lut;
+	dma_addr_t cmu_output_phys;
 };
 
 static inline struct tegra_dc *
@@ -447,6 +450,7 @@ int tegra_dc_rgb_exit(struct tegra_dc *dc);
 #define BASE_COLOR_SIZE_888    (  8 << 0)
 #define BASE_COLOR_SIZE_101010 ( 10 << 0)
 #define BASE_COLOR_SIZE_121212 ( 12 << 0)
+#define CMU_ENABLE_ENABLE      (1 << 20)
 
 #define DC_DISP_SHIFT_CLOCK_OPTIONS		0x431
 #define  SC1_H_QUALIFIER_NONE	(1 << 16)
@@ -732,6 +736,15 @@ int tegra_dc_rgb_exit(struct tegra_dc *dc);
 #define PROTOCOL_MASK (0xf << 8)
 #define PROTOCOL_SINGLE_TMDS_A (0x1 << 8)
 
+#define DC_DISP_CORE_HEAD_SET_CONTROL_OUTPUT_LUT	0x431
+#define  OUTPUT_LUT_MODE_MASK        (3 << 5)
+#define  OUTPUT_LUT_MODE_INTERPOLATE (1 << 5)
+#define  OUTPUT_LUT_SIZE_MASK        (3 << 1)
+#define  OUTPUT_LUT_SIZE_SIZE_1025   (2 << 1)
+
+#define DC_DISP_COREPVT_HEAD_SET_OUTPUT_LUT_BASE	0x432
+#define DC_DISP_COREPVT_HEAD_SET_OUTPUT_LUT_BASE_HI	0x433
+
 #define DC_DISP_PCALC_HEAD_SET_CROPPED_POINT_IN_CURSOR	0x442
 #define DC_DISP_PCALC_HEAD_SET_CROPPED_SIZE_IN_CURSOR	0x446
 
diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c
index de8b2dfc4984c4534b723ebf043f2eb0f277157a..78e71a3ff02632e60872c442d4c2f7ab7bc0e2d2 100644
--- a/drivers/gpu/drm/tegra/sor.c
+++ b/drivers/gpu/drm/tegra/sor.c
@@ -2557,6 +2557,17 @@ static void tegra_sor_hdmi_enable(struct drm_encoder *encoder)
 	value = tegra_dc_readl(dc, DC_DISP_DISP_COLOR_CONTROL);
 	value &= ~DITHER_CONTROL_MASK;
 	value &= ~BASE_COLOR_SIZE_MASK;
+	if (dc->soc->has_nvdisplay && dc->cmu_output_lut) {
+		tegra_dc_writel(dc, lower_32_bits(dc->cmu_output_phys),
+				DC_DISP_COREPVT_HEAD_SET_OUTPUT_LUT_BASE);
+		tegra_dc_writel(dc, upper_32_bits(dc->cmu_output_phys),
+				DC_DISP_COREPVT_HEAD_SET_OUTPUT_LUT_BASE_HI);
+
+		tegra_dc_writel(dc, OUTPUT_LUT_MODE_INTERPOLATE | OUTPUT_LUT_SIZE_SIZE_1025,
+				DC_DISP_CORE_HEAD_SET_CONTROL_OUTPUT_LUT);
+
+		value |= CMU_ENABLE_ENABLE;
+	}
 
 	switch (state->bpc) {
 	case 6:
@@ -2921,6 +2932,20 @@ static void tegra_sor_dp_enable(struct drm_encoder *encoder)
 	if (err < 0)
 		dev_err(sor->dev, "failed to attach SOR: %d\n", err);
 
+	if (dc->soc->has_nvdisplay && dc->cmu_output_lut) {
+		value = tegra_dc_readl(dc, DC_DISP_DISP_COLOR_CONTROL);
+		tegra_dc_writel(dc, lower_32_bits(dc->cmu_output_phys),
+				DC_DISP_COREPVT_HEAD_SET_OUTPUT_LUT_BASE);
+		tegra_dc_writel(dc, upper_32_bits(dc->cmu_output_phys),
+				DC_DISP_COREPVT_HEAD_SET_OUTPUT_LUT_BASE_HI);
+
+		tegra_dc_writel(dc, OUTPUT_LUT_MODE_INTERPOLATE | OUTPUT_LUT_SIZE_SIZE_1025,
+				DC_DISP_CORE_HEAD_SET_CONTROL_OUTPUT_LUT);
+
+		value |= CMU_ENABLE_ENABLE;
+		tegra_dc_writel(dc, value, DC_DISP_DISP_COLOR_CONTROL);
+	}
+
 	value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
 	value |= SOR_ENABLE(sor->index);
 	tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);

---
base-commit: 2febe6e6ee6e34c7754eff3c4d81aa7b0dcb7979
change-id: 20251031-tegra-drm-cmu-697e8e030978

Best regards,
-- 
Aaron Kling <webgeek1234@gmail.com>



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v3] drm/tegra: Enable cmu for Tegra186 and Tegra194
  2026-04-06  7:47 [PATCH v3] drm/tegra: Enable cmu for Tegra186 and Tegra194 Aaron Kling via B4 Relay
@ 2026-04-07  4:59 ` Mikko Perttunen
  2026-04-12  4:39 ` Claude review: " Claude Code Review Bot
  2026-04-12  4:39 ` Claude Code Review Bot
  2 siblings, 0 replies; 4+ messages in thread
From: Mikko Perttunen @ 2026-04-07  4:59 UTC (permalink / raw)
  To: Aaron Kling
  Cc: Thierry Reding, Mikko Perttunen, David Airlie, Simona Vetter,
	Jonathan Hunter, Thierry Reding, dri-devel, linux-tegra,
	linux-kernel, Kurt Kiefer, Jasper Korten

On Mon, 06 Apr 2026 02:47:31 -0500, Aaron Kling <webgeek1234@gmail.com> wrote:
> Without the cmu, nvdisplay will display colors that are notably darker
> than intended. The vendor bootloader and the downstream display driver
> enable the cmu and sets a sRGB table. Loading that table here results in
> the intended colors.
> 
> Co-developed-by: Kurt Kiefer <kekiefer@gmail.com>

You need to include a Signed-off-by with each Co-developed-by tag.
>From submitting-patches.rst:

    Co-developed-by: states that the patch was co-created by multiple developers;
    it is used to give attribution to co-authors (in addition to the author
    attributed by the From: tag) when several people work on a single patch.  Since
    Co-developed-by: denotes authorship, every Co-developed-by: must be immediately
    followed by a Signed-off-by: of the associated co-author.

checkpatch.pl should also flag this.

>
>
> diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h
> index 0559fa6b1bf7..973ab0bb15c9 100644
> --- a/drivers/gpu/drm/tegra/dc.h
> +++ b/drivers/gpu/drm/tegra/dc.h
> @@ -103,6 +103,9 @@ struct tegra_dc {
>  	const struct tegra_dc_soc_info *soc;
>  
>  	bool has_opp_table;
> +
> +	u64 *cmu_output_lut;
> +	dma_addr_t cmu_output_phys;

I think 'cmu_output_lut_phys' would be slightly clearer.

>
> diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c
> index de8b2dfc4984..78e71a3ff026 100644
> --- a/drivers/gpu/drm/tegra/sor.c
> +++ b/drivers/gpu/drm/tegra/sor.c
> @@ -2557,6 +2557,17 @@ static void tegra_sor_hdmi_enable(struct drm_encoder *encoder)
>  	value = tegra_dc_readl(dc, DC_DISP_DISP_COLOR_CONTROL);
>  	value &= ~DITHER_CONTROL_MASK;
>  	value &= ~BASE_COLOR_SIZE_MASK;
> +	if (dc->soc->has_nvdisplay && dc->cmu_output_lut) {

Checking for cmu_output_lut not being NULL shouldn't be necessary,
since we fail probe if it's NULL. (Checking here gives the impression
it might be NULL).

Otherwise looks good to me. Main thing is the trailers in the commit
message.

Thanks!
Mikko

-- 


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Claude review: drm/tegra: Enable cmu for Tegra186 and Tegra194
  2026-04-06  7:47 [PATCH v3] drm/tegra: Enable cmu for Tegra186 and Tegra194 Aaron Kling via B4 Relay
  2026-04-07  4:59 ` Mikko Perttunen
  2026-04-12  4:39 ` Claude review: " Claude Code Review Bot
@ 2026-04-12  4:39 ` Claude Code Review Bot
  2 siblings, 0 replies; 4+ messages in thread
From: Claude Code Review Bot @ 2026-04-12  4:39 UTC (permalink / raw)
  To: dri-devel-reviews

Overall Series Review

Subject: drm/tegra: Enable cmu for Tegra186 and Tegra194
Author: Aaron Kling via B4 Relay <devnull+webgeek1234.gmail.com@kernel.org>
Patches: 2
Reviewed: 2026-04-12T14:39:02.640673

---

This is a single-patch series (v3) that enables the Color Management Unit (CMU) on Tegra186/Tegra194 nvdisplay hardware, loading an sRGB LUT to correct dark color output. The motivation is sound -- without CMU, colors are noticeably darker than intended, and the vendor bootloader/downstream driver both enable this.

The implementation is straightforward: allocate a DMA-coherent buffer at probe time, populate it with an sRGB correction table, and program the CMU registers during HDMI and DisplayPort enable paths. v3 improvements (dmam_alloc_coherent, removal of improper IOVA null check) are welcome simplifications.

**Key issues:**
- Missing `Signed-off-by` for the `Co-developed-by` tag (process requirement).
- The HDMI and DP paths duplicate the LUT programming sequence -- could be a small helper.
- Minor style nits.

Overall this looks correct and ready with the tagging fix.

---

---
Generated by Claude Code Patch Reviewer

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Claude review: drm/tegra: Enable cmu for Tegra186 and Tegra194
  2026-04-06  7:47 [PATCH v3] drm/tegra: Enable cmu for Tegra186 and Tegra194 Aaron Kling via B4 Relay
  2026-04-07  4:59 ` Mikko Perttunen
@ 2026-04-12  4:39 ` Claude Code Review Bot
  2026-04-12  4:39 ` Claude Code Review Bot
  2 siblings, 0 replies; 4+ messages in thread
From: Claude Code Review Bot @ 2026-04-12  4:39 UTC (permalink / raw)
  To: dri-devel-reviews

Patch Review

**Commit message tags (must fix):**

The `Co-developed-by` tag requires a corresponding `Signed-off-by` immediately after it per kernel documentation (Documentation/process/submitting-patches.rst). Currently:

```
Co-developed-by: Kurt Kiefer <kekiefer@gmail.com>
Signed-off-by: Aaron Kling <webgeek1234@gmail.com>
```

Should be:

```
Co-developed-by: Kurt Kiefer <kekiefer@gmail.com>
Signed-off-by: Kurt Kiefer <kekiefer@gmail.com>
Signed-off-by: Aaron Kling <webgeek1234@gmail.com>
```

**dc.c -- LUT table and probe:**

The `default_srgb_lut` table has exactly 1025 entries, matching the `OUTPUT_LUT_SIZE_SIZE_1025` hardware setting. Good.

The LUT entry packing looks correct:
```c
r = default_srgb_lut[i];
dc->cmu_output_lut[i] = (r << 32) | (r << 16) | r;
```
This applies the same sRGB curve to R, G, and B channels within a 64-bit entry (three 16-bit fields in the lower 48 bits). This matches what's expected for a uniform gamma correction.

Use of `dmam_alloc_coherent` is appropriate -- the LUT must persist for the device's lifetime and this avoids manual cleanup. No issues here.

**dc.h -- Register definitions:**

The new `CMU_ENABLE_ENABLE` is correctly placed as a bit flag for `DC_DISP_DISP_COLOR_CONTROL` (0x430), alongside the existing `BASE_COLOR_SIZE_*` and `DITHER_CONTROL_*` definitions. Bit 20 doesn't conflict with any existing masks (`BASE_COLOR_SIZE_MASK` is bits 0-3, `DITHER_CONTROL_MASK` is bits 8-9).

The new nvdisplay-specific registers:
```c
#define DC_DISP_CORE_HEAD_SET_CONTROL_OUTPUT_LUT    0x431
#define DC_DISP_COREPVT_HEAD_SET_OUTPUT_LUT_BASE    0x432
#define DC_DISP_COREPVT_HEAD_SET_OUTPUT_LUT_BASE_HI 0x433
```
These overlap with legacy registers (`DC_DISP_SHIFT_CLOCK_OPTIONS` at 0x431, `DC_DISP_DATA_ENABLE_OPTIONS` at 0x432, `DC_DISP_SERIAL_INTERFACE_OPTIONS` at 0x433), which is expected since nvdisplay (Tegra186+) uses a different register layout at the same offsets. The placement after the existing `/* Tegra186 and later */` section at the `DC_DISP_CORE_SOR_SET_CONTROL` block is correct. A brief comment like `/* Tegra186+ CMU output LUT registers */` would aid readability but is not strictly necessary.

**sor.c -- HDMI enable path:**

The insertion point is well-chosen. The CMU setup is inserted between the mask-clearing and the `switch(state->bpc)`:

```c
value = tegra_dc_readl(dc, DC_DISP_DISP_COLOR_CONTROL);
value &= ~DITHER_CONTROL_MASK;
value &= ~BASE_COLOR_SIZE_MASK;
+   if (dc->soc->has_nvdisplay && dc->cmu_output_lut) {
+       /* ... program LUT base & control ... */
+       value |= CMU_ENABLE_ENABLE;
+   }

    switch (state->bpc) {
```

This is clean -- `CMU_ENABLE_ENABLE` (bit 20) is accumulated into `value` alongside the color size bits, and all are written together at the existing `tegra_dc_writel(dc, value, DC_DISP_DISP_COLOR_CONTROL)` at the end of the switch. No bit conflicts.

**sor.c -- DP enable path:**

```c
+   if (dc->soc->has_nvdisplay && dc->cmu_output_lut) {
+       value = tegra_dc_readl(dc, DC_DISP_DISP_COLOR_CONTROL);
+       tegra_dc_writel(dc, lower_32_bits(dc->cmu_output_phys),
+                       DC_DISP_COREPVT_HEAD_SET_OUTPUT_LUT_BASE);
+       ...
+       value |= CMU_ENABLE_ENABLE;
+       tegra_dc_writel(dc, value, DC_DISP_DISP_COLOR_CONTROL);
+   }
```

This is a standalone read-modify-write, which is correct for the DP path since there's no existing color control manipulation there (confirmed: `DC_DISP_DISP_COLOR_CONTROL` is only touched in the HDMI enable path at lines 2557/2584 of the current tree).

**Code duplication (minor):** The LUT base/control/CMU-enable programming sequence is nearly identical between the HDMI and DP paths (~8 lines duplicated). Consider extracting a helper like `tegra_dc_setup_cmu(dc)` in dc.c to avoid this. This is a style preference, not a correctness issue.

**No disable path (observation):** CMU is enabled but never explicitly disabled on encoder disable. This is acceptable because: (a) CMU is always desired on nvdisplay hardware (matching vendor behavior), (b) the LUT buffer persists via dmam_alloc_coherent, and (c) CMU is re-programmed on every enable. However, if future work adds runtime CMU control or drm color management properties, a disable path would be needed.

**Summary of required changes:**
1. Add missing `Signed-off-by: Kurt Kiefer <kekiefer@gmail.com>` after the `Co-developed-by` tag.

**Suggestions (optional):**
1. Extract the duplicated LUT programming into a small helper function.
2. Add a brief comment above the new nvdisplay register definitions noting they overlap with legacy register addresses.

---
Generated by Claude Code Patch Reviewer

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-04-12  4:39 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-06  7:47 [PATCH v3] drm/tegra: Enable cmu for Tegra186 and Tegra194 Aaron Kling via B4 Relay
2026-04-07  4:59 ` Mikko Perttunen
2026-04-12  4:39 ` Claude review: " Claude Code Review Bot
2026-04-12  4:39 ` Claude Code Review Bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox