drivers/gpu/drm/tegra/dc.h | 13 +++ drivers/gpu/drm/tegra/sor.c | 206 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 219 insertions(+)
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.
Signed-off-by: Aaron Kling <webgeek1234@gmail.com>
---
drivers/gpu/drm/tegra/dc.h | 13 +++
drivers/gpu/drm/tegra/sor.c | 206 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 219 insertions(+)
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h
index 0559fa6b1bf70416e51d5067cc04a6ae6572de23..286eddd89a28f7ea9e64c00f03af76f6c68ae9d8 100644
--- a/drivers/gpu/drm/tegra/dc.h
+++ b/drivers/gpu/drm/tegra/dc.h
@@ -447,11 +447,24 @@ 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_MASK (1 << 20)
+#define CMU_ENABLE_DISABLE (0 << 20)
+#define CMU_ENABLE_ENABLE (1 << 20)
#define DC_DISP_SHIFT_CLOCK_OPTIONS 0x431
#define SC1_H_QUALIFIER_NONE (1 << 16)
#define SC0_H_QUALIFIER_NONE (1 << 0)
+/* Nvdisplay */
+#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_DATA_ENABLE_OPTIONS 0x432
#define DE_SELECT_ACTIVE_BLANK (0 << 0)
#define DE_SELECT_ACTIVE (1 << 0)
diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c
index 21f3dfdcc5c9576580b9aa9990dd1bedcdeb4482..a381cb35113c0f3191d7204302f4024f33141622 100644
--- a/drivers/gpu/drm/tegra/sor.c
+++ b/drivers/gpu/drm/tegra/sor.c
@@ -443,6 +443,9 @@ struct tegra_sor {
bool scdc_enabled;
struct tegra_hda_format format;
+
+ u64 *cmu_output_lut;
+ dma_addr_t cmu_output_phys;
};
struct tegra_sor_state {
@@ -483,6 +486,180 @@ static inline struct tegra_sor *to_sor(struct tegra_output *output)
return container_of(output, struct tegra_sor, output);
}
+static 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 inline u32 tegra_sor_readl(struct tegra_sor *sor, unsigned int offset)
{
u32 value = readl(sor->regs + (offset << 2));
@@ -2241,6 +2418,13 @@ static void tegra_sor_hdmi_disable(struct drm_encoder *encoder)
dev_err(sor->dev, "failed to power off I/O pad: %d\n", err);
host1x_client_suspend(&sor->client);
+
+ if (sor->soc->has_nvdisplay) {
+ dma_free_coherent(dc->dev, ARRAY_SIZE(default_srgb_lut) * sizeof(u64),
+ sor->cmu_output_lut, sor->cmu_output_phys);
+ sor->cmu_output_lut = NULL;
+ sor->cmu_output_phys = 0;
+ }
}
static void tegra_sor_hdmi_enable(struct drm_encoder *encoder)
@@ -2255,6 +2439,7 @@ static void tegra_sor_hdmi_enable(struct drm_encoder *encoder)
unsigned long rate, pclk;
unsigned int div, i;
u32 value;
+ u64 r;
int err;
state = to_sor_state(output->connector.state);
@@ -2557,6 +2742,27 @@ static void tegra_sor_hdmi_enable(struct drm_encoder *encoder)
value &= ~DITHER_CONTROL_MASK;
value &= ~BASE_COLOR_SIZE_MASK;
+ if (dc->soc->has_nvdisplay) {
+ sor->cmu_output_lut =
+ dma_alloc_coherent(dc->dev, ARRAY_SIZE(default_srgb_lut) * sizeof(u64),
+ &sor->cmu_output_phys, GFP_KERNEL);
+
+ for (i = 0; i < ARRAY_SIZE(default_srgb_lut); i++) {
+ r = default_srgb_lut[i];
+ sor->cmu_output_lut[i] = (r << 32) | (r << 16) | r;
+ }
+
+ tegra_dc_writel(dc, (u32)(sor->cmu_output_phys & 0xffffffff),
+ DC_DISP_COREPVT_HEAD_SET_OUTPUT_LUT_BASE);
+ tegra_dc_writel(dc, (u32)(sor->cmu_output_phys >> 32),
+ 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:
value |= BASE_COLOR_SIZE_666;
---
base-commit: dcb6fa37fd7bc9c3d2b066329b0d27dedf8becaa
change-id: 20251031-tegra-drm-cmu-697e8e030978
Best regards,
--
Aaron Kling <webgeek1234@gmail.com>
On Sat, Nov 01, 2025 at 06:15:17PM -0500, Aaron Kling via B4 Relay wrote:
> 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.
>
> Signed-off-by: Aaron Kling <webgeek1234@gmail.com>
> ---
> drivers/gpu/drm/tegra/dc.h | 13 +++
> drivers/gpu/drm/tegra/sor.c | 206 ++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 219 insertions(+)
What does "darker than intended" mean? Who defines the intention? How do
we know what the intention is? What this patch ultimately seems to be
doing is define sRGB to be the default colorspace. Is that always the
right default choice? What if people want to specify a different
colorspace?
Looking at the enum dp_colorimetry it seems like sRGB is the default for
DP at least. But then it says the default is sRGB or ITU-R BT.601, but
if I compare that to the Wikipedia article for sRGB that says sRGB is
closer to ITU-R BT.709 than BT.601. Can we narrow in what exactly the
LUT in this patch corresponds to?
> diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h
> index 0559fa6b1bf70416e51d5067cc04a6ae6572de23..286eddd89a28f7ea9e64c00f03af76f6c68ae9d8 100644
> --- a/drivers/gpu/drm/tegra/dc.h
> +++ b/drivers/gpu/drm/tegra/dc.h
> @@ -447,11 +447,24 @@ 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_MASK (1 << 20)
> +#define CMU_ENABLE_DISABLE (0 << 20)
> +#define CMU_ENABLE_ENABLE (1 << 20)
_MASK and _DISABLE are unused (and also quite useless in this case).
>
> #define DC_DISP_SHIFT_CLOCK_OPTIONS 0x431
> #define SC1_H_QUALIFIER_NONE (1 << 16)
> #define SC0_H_QUALIFIER_NONE (1 << 0)
>
> +/* Nvdisplay */
> +#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
> +
There's a section in this header titled "Tegra186 and later", where
these new definitions should go. Anything in this section is part of the
old registers (or the emulated ones for backwards compatibility).
> #define DC_DISP_DATA_ENABLE_OPTIONS 0x432
> #define DE_SELECT_ACTIVE_BLANK (0 << 0)
> #define DE_SELECT_ACTIVE (1 << 0)
> diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c
> index 21f3dfdcc5c9576580b9aa9990dd1bedcdeb4482..a381cb35113c0f3191d7204302f4024f33141622 100644
> --- a/drivers/gpu/drm/tegra/sor.c
> +++ b/drivers/gpu/drm/tegra/sor.c
> @@ -443,6 +443,9 @@ struct tegra_sor {
> bool scdc_enabled;
>
> struct tegra_hda_format format;
> +
> + u64 *cmu_output_lut;
> + dma_addr_t cmu_output_phys;
> };
>
> struct tegra_sor_state {
> @@ -483,6 +486,180 @@ static inline struct tegra_sor *to_sor(struct tegra_output *output)
> return container_of(output, struct tegra_sor, output);
> }
>
> +static u16 default_srgb_lut[] = {
> + 0x6000, 0x60CE, 0x619D, 0x626C, 0x632D, 0x63D4,
[...]
> + 0x9FE2, 0x9FE9, 0x9FF0, 0x9FF7, 0x9FFF,
> +};
I don't take it there's a way to generate this table? And these are not
standard values that could be shared among different drivers?
You could probably make this a bit more compact by indenting the data
with a single tab and squeeze in 2 or 3 more values per line.
> static inline u32 tegra_sor_readl(struct tegra_sor *sor, unsigned int offset)
> {
> u32 value = readl(sor->regs + (offset << 2));
> @@ -2241,6 +2418,13 @@ static void tegra_sor_hdmi_disable(struct drm_encoder *encoder)
> dev_err(sor->dev, "failed to power off I/O pad: %d\n", err);
>
> host1x_client_suspend(&sor->client);
> +
> + if (sor->soc->has_nvdisplay) {
> + dma_free_coherent(dc->dev, ARRAY_SIZE(default_srgb_lut) * sizeof(u64),
> + sor->cmu_output_lut, sor->cmu_output_phys);
> + sor->cmu_output_lut = NULL;
> + sor->cmu_output_phys = 0;
> + }
> }
>
> static void tegra_sor_hdmi_enable(struct drm_encoder *encoder)
> @@ -2255,6 +2439,7 @@ static void tegra_sor_hdmi_enable(struct drm_encoder *encoder)
> unsigned long rate, pclk;
> unsigned int div, i;
> u32 value;
> + u64 r;
This can be moved into the branch to narrow the scope.
> int err;
>
> state = to_sor_state(output->connector.state);
> @@ -2557,6 +2742,27 @@ static void tegra_sor_hdmi_enable(struct drm_encoder *encoder)
> value &= ~DITHER_CONTROL_MASK;
> value &= ~BASE_COLOR_SIZE_MASK;
>
> + if (dc->soc->has_nvdisplay) {
> + sor->cmu_output_lut =
> + dma_alloc_coherent(dc->dev, ARRAY_SIZE(default_srgb_lut) * sizeof(u64),
> + &sor->cmu_output_phys, GFP_KERNEL);
You need to check for failure, otherwise you might NULL dereference the
pointer below. But then it's probably even better to allocate this at
probe time so that we can guarantee that the LUT can always be set.
> +
> + for (i = 0; i < ARRAY_SIZE(default_srgb_lut); i++) {
> + r = default_srgb_lut[i];
> + sor->cmu_output_lut[i] = (r << 32) | (r << 16) | r;
> + }
Given that this was taken from the downstream driver, this is probably
correct, but I'm not sure I understand why the same value is written to
the LUT thrice. Do you happen to know?
> + tegra_dc_writel(dc, (u32)(sor->cmu_output_phys & 0xffffffff),
> + DC_DISP_COREPVT_HEAD_SET_OUTPUT_LUT_BASE);
> + tegra_dc_writel(dc, (u32)(sor->cmu_output_phys >> 32),
> + DC_DISP_COREPVT_HEAD_SET_OUTPUT_LUT_BASE_HI);
You'll want to use the lower_32_bits() and upper_32_bits() functions
like we do for other address values (see hub.c, for example).
Thierry
On Mon, Nov 3, 2025 at 5:54 AM Thierry Reding <thierry.reding@gmail.com> wrote:
>
> On Sat, Nov 01, 2025 at 06:15:17PM -0500, Aaron Kling via B4 Relay wrote:
> > 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.
> >
> > Signed-off-by: Aaron Kling <webgeek1234@gmail.com>
> > ---
> > drivers/gpu/drm/tegra/dc.h | 13 +++
> > drivers/gpu/drm/tegra/sor.c | 206 ++++++++++++++++++++++++++++++++++++++++++++
> > 2 files changed, 219 insertions(+)
>
> What does "darker than intended" mean? Who defines the intention? How do
> we know what the intention is? What this patch ultimately seems to be
> doing is define sRGB to be the default colorspace. Is that always the
> right default choice? What if people want to specify a different
> colorspace?
I reported this issue almost a month ago. See kernel lore [0] and
freedesktop issue [1]. The pictures in the latter show what nvdisplay
looks like right now. It's nigh unusably dark. When booted into
Android with a tv launcher that has a black background, as is default
for LineageOS, it is really hard to read anything. Is it correct as a
default? Well, cboot hardcodes this, so... presumably? It would be
more ideal to expose this and csc to userspace, but I'm not sure if
drm has a standardized interface for that or if tegra would have to
make something vendor specific. I think that would be a separate
change concept compared to setting this default, though.
> Looking at the enum dp_colorimetry it seems like sRGB is the default for
> DP at least. But then it says the default is sRGB or ITU-R BT.601, but
> if I compare that to the Wikipedia article for sRGB that says sRGB is
> closer to ITU-R BT.709 than BT.601. Can we narrow in what exactly the
> LUT in this patch corresponds to?
I really don't know. While trying to fix the broken colors, I came
across the same table in cboot [2] and the downstream tegradc driver.
Cboot was released as a tarball with no commit history. And the
tegradc commit history did not have any further clarification beyond
'sRGB'.
> > diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h
> > index 0559fa6b1bf70416e51d5067cc04a6ae6572de23..286eddd89a28f7ea9e64c00f03af76f6c68ae9d8 100644
> > --- a/drivers/gpu/drm/tegra/dc.h
> > +++ b/drivers/gpu/drm/tegra/dc.h
> > @@ -447,11 +447,24 @@ 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_MASK (1 << 20)
> > +#define CMU_ENABLE_DISABLE (0 << 20)
> > +#define CMU_ENABLE_ENABLE (1 << 20)
>
> _MASK and _DISABLE are unused (and also quite useless in this case).
Fair. I was trying to match the style of the rest of the header, but I
can drop the unused defines.
>
> >
> > #define DC_DISP_SHIFT_CLOCK_OPTIONS 0x431
> > #define SC1_H_QUALIFIER_NONE (1 << 16)
> > #define SC0_H_QUALIFIER_NONE (1 << 0)
> >
> > +/* Nvdisplay */
> > +#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
> > +
>
> There's a section in this header titled "Tegra186 and later", where
> these new definitions should go. Anything in this section is part of the
> old registers (or the emulated ones for backwards compatibility).
I figured there had to be a section for that somewhere, but my
searches failed me. I see it now and will move.
> > #define DC_DISP_DATA_ENABLE_OPTIONS 0x432
> > #define DE_SELECT_ACTIVE_BLANK (0 << 0)
> > #define DE_SELECT_ACTIVE (1 << 0)
> > diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c
> > index 21f3dfdcc5c9576580b9aa9990dd1bedcdeb4482..a381cb35113c0f3191d7204302f4024f33141622 100644
> > --- a/drivers/gpu/drm/tegra/sor.c
> > +++ b/drivers/gpu/drm/tegra/sor.c
> > @@ -443,6 +443,9 @@ struct tegra_sor {
> > bool scdc_enabled;
> >
> > struct tegra_hda_format format;
> > +
> > + u64 *cmu_output_lut;
> > + dma_addr_t cmu_output_phys;
> > };
> >
> > struct tegra_sor_state {
> > @@ -483,6 +486,180 @@ static inline struct tegra_sor *to_sor(struct tegra_output *output)
> > return container_of(output, struct tegra_sor, output);
> > }
> >
> > +static u16 default_srgb_lut[] = {
> > + 0x6000, 0x60CE, 0x619D, 0x626C, 0x632D, 0x63D4,
> [...]
> > + 0x9FE2, 0x9FE9, 0x9FF0, 0x9FF7, 0x9FFF,
> > +};
>
> I don't take it there's a way to generate this table? And these are not
> standard values that could be shared among different drivers?
I don't know of a way to generate it. As mentioned above, this was
copied from downstream.
As for sharing, I don't know. If I read the tx2 trm correctly, the
display pipeline goes through a input LUT, which is not currently
enabled by tegra-drm, then into csc, which expects some 'linear
colorspace'. Then that outputs into the output LUT, which is labelled
as the cmu, which is expected to translate from that linear colorspace
into the colorspace expected by the display. Given that this LUT
generates expected colors on my displays, I assume that the pixels in
the pipeline are in that 'linear colorspace'. I'm not sure if that's a
standardized thing or something nvdisplay specific. If it is the
latter, then the table wouldn't be useful anywhere else.
> You could probably make this a bit more compact by indenting the data
> with a single tab and squeeze in 2 or 3 more values per line.
Ack.
> > static inline u32 tegra_sor_readl(struct tegra_sor *sor, unsigned int offset)
> > {
> > u32 value = readl(sor->regs + (offset << 2));
> > @@ -2241,6 +2418,13 @@ static void tegra_sor_hdmi_disable(struct drm_encoder *encoder)
> > dev_err(sor->dev, "failed to power off I/O pad: %d\n", err);
> >
> > host1x_client_suspend(&sor->client);
> > +
> > + if (sor->soc->has_nvdisplay) {
> > + dma_free_coherent(dc->dev, ARRAY_SIZE(default_srgb_lut) * sizeof(u64),
> > + sor->cmu_output_lut, sor->cmu_output_phys);
> > + sor->cmu_output_lut = NULL;
> > + sor->cmu_output_phys = 0;
> > + }
> > }
> >
> > static void tegra_sor_hdmi_enable(struct drm_encoder *encoder)
> > @@ -2255,6 +2439,7 @@ static void tegra_sor_hdmi_enable(struct drm_encoder *encoder)
> > unsigned long rate, pclk;
> > unsigned int div, i;
> > u32 value;
> > + u64 r;
>
> This can be moved into the branch to narrow the scope.
Ack.
>
> > int err;
> >
> > state = to_sor_state(output->connector.state);
> > @@ -2557,6 +2742,27 @@ static void tegra_sor_hdmi_enable(struct drm_encoder *encoder)
> > value &= ~DITHER_CONTROL_MASK;
> > value &= ~BASE_COLOR_SIZE_MASK;
> >
> > + if (dc->soc->has_nvdisplay) {
> > + sor->cmu_output_lut =
> > + dma_alloc_coherent(dc->dev, ARRAY_SIZE(default_srgb_lut) * sizeof(u64),
> > + &sor->cmu_output_phys, GFP_KERNEL);
>
> You need to check for failure, otherwise you might NULL dereference the
> pointer below. But then it's probably even better to allocate this at
> probe time so that we can guarantee that the LUT can always be set.
Moving alloc to probe and free to remove makes sense. Less thrashing
that way too. Will do.
> > +
> > + for (i = 0; i < ARRAY_SIZE(default_srgb_lut); i++) {
> > + r = default_srgb_lut[i];
> > + sor->cmu_output_lut[i] = (r << 32) | (r << 16) | r;
> > + }
>
> Given that this was taken from the downstream driver, this is probably
> correct, but I'm not sure I understand why the same value is written to
> the LUT thrice. Do you happen to know?
I do not, no. I wondered at that too.
>
> > + tegra_dc_writel(dc, (u32)(sor->cmu_output_phys & 0xffffffff),
> > + DC_DISP_COREPVT_HEAD_SET_OUTPUT_LUT_BASE);
> > + tegra_dc_writel(dc, (u32)(sor->cmu_output_phys >> 32),
> > + DC_DISP_COREPVT_HEAD_SET_OUTPUT_LUT_BASE_HI);
>
> You'll want to use the lower_32_bits() and upper_32_bits() functions
> like we do for other address values (see hub.c, for example).
Ack.
I will stage the code review changes, but will hold off on sending a
new revision. Pending any additional changes coming from the
discussion of the concept in general.
Aaron
[0] https://lore.kernel.org/all/CALHNRZ_vMy1CTosZ=ymOhAyMNRh+oBOU9NJ8Gvr8EkqQ5XjFDw@mail.gmail.com/
[1] https://gitlab.freedesktop.org/drm/tegra/-/issues/8
[2] https://github.com/LineageOS/android_bootable_cboot_common/blob/034b04d3ac7f2f80d72e3b894d97da4f6e2cd591/drivers/display/nvdisp/tegrabl_nvdisp_cmu.c#L24
On Mon, Nov 03, 2025 at 12:39:57PM -0600, Aaron Kling wrote: > On Mon, Nov 3, 2025 at 5:54 AM Thierry Reding <thierry.reding@gmail.com> wrote: > > > > On Sat, Nov 01, 2025 at 06:15:17PM -0500, Aaron Kling via B4 Relay wrote: > > > 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. > > > > > > Signed-off-by: Aaron Kling <webgeek1234@gmail.com> > > > --- > > > drivers/gpu/drm/tegra/dc.h | 13 +++ > > > drivers/gpu/drm/tegra/sor.c | 206 ++++++++++++++++++++++++++++++++++++++++++++ > > > 2 files changed, 219 insertions(+) > > > > What does "darker than intended" mean? Who defines the intention? How do > > we know what the intention is? What this patch ultimately seems to be > > doing is define sRGB to be the default colorspace. Is that always the > > right default choice? What if people want to specify a different > > colorspace? > > I reported this issue almost a month ago. See kernel lore [0] and > freedesktop issue [1]. The pictures in the latter show what nvdisplay > looks like right now. It's nigh unusably dark. When booted into > Android with a tv launcher that has a black background, as is default > for LineageOS, it is really hard to read anything. Is it correct as a > default? Well, cboot hardcodes this, so... presumably? It would be > more ideal to expose this and csc to userspace, but I'm not sure if > drm has a standardized interface for that or if tegra would have to > make something vendor specific. I think that would be a separate > change concept compared to setting this default, though. The reason I'm asking is because I don't recall ever seeing "broken" colors like you do. So I suspect that this may also be related to what display is connected, or the mode that we're setting. It could perhaps also be related to what infoframes we're sending and how these are supported/interpreted by the attached display. All of that is to say that maybe this looks broken on the particular setup that you have but may works fine on other setups. Changing the default may fix your setup and break others. Thierry
On Tue, Nov 4, 2025 at 3:14 AM Thierry Reding <thierry.reding@gmail.com> wrote: > > On Mon, Nov 03, 2025 at 12:39:57PM -0600, Aaron Kling wrote: > > On Mon, Nov 3, 2025 at 5:54 AM Thierry Reding <thierry.reding@gmail.com> wrote: > > > > > > On Sat, Nov 01, 2025 at 06:15:17PM -0500, Aaron Kling via B4 Relay wrote: > > > > 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. > > > > > > > > Signed-off-by: Aaron Kling <webgeek1234@gmail.com> > > > > --- > > > > drivers/gpu/drm/tegra/dc.h | 13 +++ > > > > drivers/gpu/drm/tegra/sor.c | 206 ++++++++++++++++++++++++++++++++++++++++++++ > > > > 2 files changed, 219 insertions(+) > > > > > > What does "darker than intended" mean? Who defines the intention? How do > > > we know what the intention is? What this patch ultimately seems to be > > > doing is define sRGB to be the default colorspace. Is that always the > > > right default choice? What if people want to specify a different > > > colorspace? > > > > I reported this issue almost a month ago. See kernel lore [0] and > > freedesktop issue [1]. The pictures in the latter show what nvdisplay > > looks like right now. It's nigh unusably dark. When booted into > > Android with a tv launcher that has a black background, as is default > > for LineageOS, it is really hard to read anything. Is it correct as a > > default? Well, cboot hardcodes this, so... presumably? It would be > > more ideal to expose this and csc to userspace, but I'm not sure if > > drm has a standardized interface for that or if tegra would have to > > make something vendor specific. I think that would be a separate > > change concept compared to setting this default, though. > > The reason I'm asking is because I don't recall ever seeing "broken" > colors like you do. So I suspect that this may also be related to what > display is connected, or the mode that we're setting. It could perhaps > also be related to what infoframes we're sending and how these are > supported/interpreted by the attached display. > > All of that is to say that maybe this looks broken on the particular > setup that you have but may works fine on other setups. Changing the > default may fix your setup and break others. Do you have a device set up so you can check? Or does the regression test bench have a display that can be forwarded? My current setup is a rack of units plugged via hdmi to a kvm which is then plugged to a pikvm. I also observed this issue before I had this setup, plugged directly to a 1080p monitor. I have not checked displayport. I can cycle through a couple other displays without this patch to see if I get any other result. I am fairly certain I have consistently seen this issue since I started trying to work with tegra-drm on kernel 6.1 or maybe even 5.15. I've never seen it work to allow for a bisect. I am in contact with one other person with a tx2 devkit, who replicated the issue when I asked. Who plans to reply to this thread with setup info later. Aaron
Hi all, On 11/4/25 19:12, Aaron Kling wrote: > On Tue, Nov 4, 2025 at 3:14 AM Thierry Reding <thierry.reding@gmail.com> wrote: >> On Mon, Nov 03, 2025 at 12:39:57PM -0600, Aaron Kling wrote: >>> On Mon, Nov 3, 2025 at 5:54 AM Thierry Reding <thierry.reding@gmail.com> wrote: >>>> On Sat, Nov 01, 2025 at 06:15:17PM -0500, Aaron Kling via B4 Relay wrote: >>>>> 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. >>>>> >>>>> Signed-off-by: Aaron Kling <webgeek1234@gmail.com> >>>>> --- >>>>> drivers/gpu/drm/tegra/dc.h | 13 +++ >>>>> drivers/gpu/drm/tegra/sor.c | 206 ++++++++++++++++++++++++++++++++++++++++++++ >>>>> 2 files changed, 219 insertions(+) >>>> What does "darker than intended" mean? Who defines the intention? How do >>>> we know what the intention is? What this patch ultimately seems to be >>>> doing is define sRGB to be the default colorspace. Is that always the >>>> right default choice? What if people want to specify a different >>>> colorspace? >>> I reported this issue almost a month ago. See kernel lore [0] and >>> freedesktop issue [1]. The pictures in the latter show what nvdisplay >>> looks like right now. It's nigh unusably dark. When booted into >>> Android with a tv launcher that has a black background, as is default >>> for LineageOS, it is really hard to read anything. Is it correct as a >>> default? Well, cboot hardcodes this, so... presumably? It would be >>> more ideal to expose this and csc to userspace, but I'm not sure if >>> drm has a standardized interface for that or if tegra would have to >>> make something vendor specific. I think that would be a separate >>> change concept compared to setting this default, though. >> The reason I'm asking is because I don't recall ever seeing "broken" >> colors like you do. So I suspect that this may also be related to what >> display is connected, or the mode that we're setting. I have tried it on both a MacroSilicon HDMI capture card and an Arzopa Z1FC 1080p portable monitor and run into the same darker colors. Both have in common that they use HDMI which seems to line up with what Aaron is reporting. I do not have an eDP display to test or another carrier board with a different display out to test. >> It could perhaps >> also be related to what infoframes we're sending and how these are >> supported/interpreted by the attached display. >> >> All of that is to say that maybe this looks broken on the particular >> setup that you have but may works fine on other setups. Changing the >> default may fix your setup and break others. > Do you have a device set up so you can check? Or does the regression > test bench have a display that can be forwarded? > > My current setup is a rack of units plugged via hdmi to a kvm which is > then plugged to a pikvm. I also observed this issue before I had this > setup, plugged directly to a 1080p monitor. I have not checked > displayport. I can cycle through a couple other displays without this > patch to see if I get any other result. I am fairly certain I have > consistently seen this issue since I started trying to work with > tegra-drm on kernel 6.1 or maybe even 5.15. I've never seen it work to > allow for a bisect. > > I am in contact with one other person with a tx2 devkit, who > replicated the issue when I asked. Who plans to reply to this thread > with setup info later. For reference, I am said person. I have a Jetson TX2 Devkit that uses the P2771 Device Tree. I'm running a Fedora distrokernel with no additional patches applied by myself. I have personally noticed the issue to at least be present on 6.14.5 and 6.17.4. I'm currently not at home to take screenshots with and without the submitted patch, but will be able to do it tomorrownight or friday. Kindest regards, Jasper > > Aaron >
On Wed, Nov 5, 2025 at 3:28 PM Jasper Korten <jja2000@gmail.com> wrote: > > Hi all, > > On 11/4/25 19:12, Aaron Kling wrote: > > On Tue, Nov 4, 2025 at 3:14 AM Thierry Reding <thierry.reding@gmail.com> wrote: > >> On Mon, Nov 03, 2025 at 12:39:57PM -0600, Aaron Kling wrote: > >>> On Mon, Nov 3, 2025 at 5:54 AM Thierry Reding <thierry.reding@gmail.com> wrote: > >>>> On Sat, Nov 01, 2025 at 06:15:17PM -0500, Aaron Kling via B4 Relay wrote: > >>>>> 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. > >>>>> > >>>>> Signed-off-by: Aaron Kling <webgeek1234@gmail.com> > >>>>> --- > >>>>> drivers/gpu/drm/tegra/dc.h | 13 +++ > >>>>> drivers/gpu/drm/tegra/sor.c | 206 ++++++++++++++++++++++++++++++++++++++++++++ > >>>>> 2 files changed, 219 insertions(+) > >>>> What does "darker than intended" mean? Who defines the intention? How do > >>>> we know what the intention is? What this patch ultimately seems to be > >>>> doing is define sRGB to be the default colorspace. Is that always the > >>>> right default choice? What if people want to specify a different > >>>> colorspace? > >>> I reported this issue almost a month ago. See kernel lore [0] and > >>> freedesktop issue [1]. The pictures in the latter show what nvdisplay > >>> looks like right now. It's nigh unusably dark. When booted into > >>> Android with a tv launcher that has a black background, as is default > >>> for LineageOS, it is really hard to read anything. Is it correct as a > >>> default? Well, cboot hardcodes this, so... presumably? It would be > >>> more ideal to expose this and csc to userspace, but I'm not sure if > >>> drm has a standardized interface for that or if tegra would have to > >>> make something vendor specific. I think that would be a separate > >>> change concept compared to setting this default, though. > >> The reason I'm asking is because I don't recall ever seeing "broken" > >> colors like you do. So I suspect that this may also be related to what > >> display is connected, or the mode that we're setting. > I have tried it on both a MacroSilicon HDMI capture card and an Arzopa > Z1FC 1080p portable monitor and run into the same darker colors. Both > have in common that they use HDMI which seems to line up with what Aaron > is reporting. I do not have an eDP display to test or another carrier > board with a different display out to test. > >> It could perhaps > >> also be related to what infoframes we're sending and how these are > >> supported/interpreted by the attached display. > >> > >> All of that is to say that maybe this looks broken on the particular > >> setup that you have but may works fine on other setups. Changing the > >> default may fix your setup and break others. > > Do you have a device set up so you can check? Or does the regression > > test bench have a display that can be forwarded? > > > > My current setup is a rack of units plugged via hdmi to a kvm which is > > then plugged to a pikvm. I also observed this issue before I had this > > setup, plugged directly to a 1080p monitor. I have not checked > > displayport. I can cycle through a couple other displays without this > > patch to see if I get any other result. I am fairly certain I have > > consistently seen this issue since I started trying to work with > > tegra-drm on kernel 6.1 or maybe even 5.15. I've never seen it work to > > allow for a bisect. > > > > I am in contact with one other person with a tx2 devkit, who > > replicated the issue when I asked. Who plans to reply to this thread > > with setup info later. > > For reference, I am said person. I have a Jetson TX2 Devkit that uses > the P2771 Device Tree. I'm running a Fedora distrokernel with no > additional patches applied by myself. I have personally noticed the > issue to at least be present on 6.14.5 and 6.17.4. > > > I'm currently not at home to take screenshots with and without the > submitted patch, but will be able to do it tomorrownight or friday. Any further thoughts from the maintainers on this patch? As far as I know, this is an issue for all users, at the very least on hdmi. Aaron
> On Dec 8, 2025, at 8:23 PM, Aaron Kling <webgeek1234@gmail.com> wrote: > > On Wed, Nov 5, 2025 at 3:28 PM Jasper Korten <jja2000@gmail.com> wrote: >> >> Hi all, >> >> On 11/4/25 19:12, Aaron Kling wrote: >>> On Tue, Nov 4, 2025 at 3:14 AM Thierry Reding <thierry.reding@gmail.com> wrote: >>>> On Mon, Nov 03, 2025 at 12:39:57PM -0600, Aaron Kling wrote: >>>>> On Mon, Nov 3, 2025 at 5:54 AM Thierry Reding <thierry.reding@gmail.com> wrote: >>>>>> On Sat, Nov 01, 2025 at 06:15:17PM -0500, Aaron Kling via B4 Relay wrote: >>>>>>> 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. >>>>>>> >>>>>>> Signed-off-by: Aaron Kling <webgeek1234@gmail.com> >>>>>>> --- >>>>>>> drivers/gpu/drm/tegra/dc.h | 13 +++ >>>>>>> drivers/gpu/drm/tegra/sor.c | 206 ++++++++++++++++++++++++++++++++++++++++++++ >>>>>>> 2 files changed, 219 insertions(+) >>>>>> What does "darker than intended" mean? Who defines the intention? How do >>>>>> we know what the intention is? What this patch ultimately seems to be >>>>>> doing is define sRGB to be the default colorspace. Is that always the >>>>>> right default choice? What if people want to specify a different >>>>>> colorspace? >>>>> I reported this issue almost a month ago. See kernel lore [0] and >>>>> freedesktop issue [1]. The pictures in the latter show what nvdisplay >>>>> looks like right now. It's nigh unusably dark. When booted into >>>>> Android with a tv launcher that has a black background, as is default >>>>> for LineageOS, it is really hard to read anything. Is it correct as a >>>>> default? Well, cboot hardcodes this, so... presumably? It would be >>>>> more ideal to expose this and csc to userspace, but I'm not sure if >>>>> drm has a standardized interface for that or if tegra would have to >>>>> make something vendor specific. I think that would be a separate >>>>> change concept compared to setting this default, though. >>>> The reason I'm asking is because I don't recall ever seeing "broken" >>>> colors like you do. So I suspect that this may also be related to what >>>> display is connected, or the mode that we're setting. >> I have tried it on both a MacroSilicon HDMI capture card and an Arzopa >> Z1FC 1080p portable monitor and run into the same darker colors. Both >> have in common that they use HDMI which seems to line up with what Aaron >> is reporting. I do not have an eDP display to test or another carrier >> board with a different display out to test. >>>> It could perhaps >>>> also be related to what infoframes we're sending and how these are >>>> supported/interpreted by the attached display. >>>> >>>> All of that is to say that maybe this looks broken on the particular >>>> setup that you have but may works fine on other setups. Changing the >>>> default may fix your setup and break others. >>> Do you have a device set up so you can check? Or does the regression >>> test bench have a display that can be forwarded? >>> >>> My current setup is a rack of units plugged via hdmi to a kvm which is >>> then plugged to a pikvm. I also observed this issue before I had this >>> setup, plugged directly to a 1080p monitor. I have not checked >>> displayport. I can cycle through a couple other displays without this >>> patch to see if I get any other result. I am fairly certain I have >>> consistently seen this issue since I started trying to work with >>> tegra-drm on kernel 6.1 or maybe even 5.15. I've never seen it work to >>> allow for a bisect. >>> >>> I am in contact with one other person with a tx2 devkit, who >>> replicated the issue when I asked. Who plans to reply to this thread >>> with setup info later. >> >> For reference, I am said person. I have a Jetson TX2 Devkit that uses >> the P2771 Device Tree. I'm running a Fedora distrokernel with no >> additional patches applied by myself. I have personally noticed the >> issue to at least be present on 6.14.5 and 6.17.4. >> >> >> I'm currently not at home to take screenshots with and without the >> submitted patch, but will be able to do it tomorrownight or friday. > > Any further thoughts from the maintainers on this patch? As far as I > know, this is an issue for all users, at the very least on hdmi. > > Aaron > I can confirm that I have the same issue on a DisplayPort output of t194. IMO, this patch will need to be reworked a bit to enable the CMU for this output as well. I hacked this change in for DisplayPort, and then it functioned as intended there as well. I've traced back to the reason this is necessary. The DC hub driver is applying an sRGB degamma for every RGB plane (presumably for blending), and then nothing reapplies the EOTF later on. Without gamma correction in places where it is expected, images are going to look "too dark". Which does raise the point that there is an alternative implementation where we do not degamma RGB planes in the first place. But this may have unintended consequences when it comes to composition. The SOR does not appear to handle YCbCr outputs at this time, so enabling the CMU assuming an sRGB EOTF seems like a reasonable path here, to me. Kurt
On Thursday, January 22, 2026 2:08 AM Kurt Kiefer wrote: > > > On Dec 8, 2025, at 8:23 PM, Aaron Kling <webgeek1234@gmail.com> wrote: > > > > On Wed, Nov 5, 2025 at 3:28 PM Jasper Korten <jja2000@gmail.com> wrote: > >> > >> Hi all, > >> > >> On 11/4/25 19:12, Aaron Kling wrote: > >>> On Tue, Nov 4, 2025 at 3:14 AM Thierry Reding <thierry.reding@gmail.com> wrote: > >>>> On Mon, Nov 03, 2025 at 12:39:57PM -0600, Aaron Kling wrote: > >>>>> On Mon, Nov 3, 2025 at 5:54 AM Thierry Reding <thierry.reding@gmail.com> wrote: > >>>>>> On Sat, Nov 01, 2025 at 06:15:17PM -0500, Aaron Kling via B4 Relay wrote: > >>>>>>> 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. > >>>>>>> > >>>>>>> Signed-off-by: Aaron Kling <webgeek1234@gmail.com> > >>>>>>> --- > >>>>>>> drivers/gpu/drm/tegra/dc.h | 13 +++ > >>>>>>> drivers/gpu/drm/tegra/sor.c | 206 ++++++++++++++++++++++++++++++++++++++++++++ > >>>>>>> 2 files changed, 219 insertions(+) > >>>>>> What does "darker than intended" mean? Who defines the intention? How do > >>>>>> we know what the intention is? What this patch ultimately seems to be > >>>>>> doing is define sRGB to be the default colorspace. Is that always the > >>>>>> right default choice? What if people want to specify a different > >>>>>> colorspace? > >>>>> I reported this issue almost a month ago. See kernel lore [0] and > >>>>> freedesktop issue [1]. The pictures in the latter show what nvdisplay > >>>>> looks like right now. It's nigh unusably dark. When booted into > >>>>> Android with a tv launcher that has a black background, as is default > >>>>> for LineageOS, it is really hard to read anything. Is it correct as a > >>>>> default? Well, cboot hardcodes this, so... presumably? It would be > >>>>> more ideal to expose this and csc to userspace, but I'm not sure if > >>>>> drm has a standardized interface for that or if tegra would have to > >>>>> make something vendor specific. I think that would be a separate > >>>>> change concept compared to setting this default, though. > >>>> The reason I'm asking is because I don't recall ever seeing "broken" > >>>> colors like you do. So I suspect that this may also be related to what > >>>> display is connected, or the mode that we're setting. > >> I have tried it on both a MacroSilicon HDMI capture card and an Arzopa > >> Z1FC 1080p portable monitor and run into the same darker colors. Both > >> have in common that they use HDMI which seems to line up with what Aaron > >> is reporting. I do not have an eDP display to test or another carrier > >> board with a different display out to test. > >>>> It could perhaps > >>>> also be related to what infoframes we're sending and how these are > >>>> supported/interpreted by the attached display. > >>>> > >>>> All of that is to say that maybe this looks broken on the particular > >>>> setup that you have but may works fine on other setups. Changing the > >>>> default may fix your setup and break others. > >>> Do you have a device set up so you can check? Or does the regression > >>> test bench have a display that can be forwarded? > >>> > >>> My current setup is a rack of units plugged via hdmi to a kvm which is > >>> then plugged to a pikvm. I also observed this issue before I had this > >>> setup, plugged directly to a 1080p monitor. I have not checked > >>> displayport. I can cycle through a couple other displays without this > >>> patch to see if I get any other result. I am fairly certain I have > >>> consistently seen this issue since I started trying to work with > >>> tegra-drm on kernel 6.1 or maybe even 5.15. I've never seen it work to > >>> allow for a bisect. > >>> > >>> I am in contact with one other person with a tx2 devkit, who > >>> replicated the issue when I asked. Who plans to reply to this thread > >>> with setup info later. > >> > >> For reference, I am said person. I have a Jetson TX2 Devkit that uses > >> the P2771 Device Tree. I'm running a Fedora distrokernel with no > >> additional patches applied by myself. I have personally noticed the > >> issue to at least be present on 6.14.5 and 6.17.4. > >> > >> > >> I'm currently not at home to take screenshots with and without the > >> submitted patch, but will be able to do it tomorrownight or friday. > > > > Any further thoughts from the maintainers on this patch? As far as I > > know, this is an issue for all users, at the very least on hdmi. > > > > Aaron > > > > I can confirm that I have the same issue on a DisplayPort output of t194. > IMO, this patch will need to be reworked a bit to enable the CMU for this > output as well. I hacked this change in for DisplayPort, and then it > functioned as intended there as well. > > I've traced back to the reason this is necessary. The DC hub driver is > applying an sRGB degamma for every RGB plane (presumably for blending), > and then nothing reapplies the EOTF later on. Without gamma correction > in places where it is expected, images are going to look "too dark". > > Which does raise the point that there is an alternative implementation > where we do not degamma RGB planes in the first place. But this may have > unintended consequences when it comes to composition. > > The SOR does not appear to handle YCbCr outputs at this time, so enabling > the CMU assuming an sRGB EOTF seems like a reasonable path here, to me. > > Kurt I tested this patch locally and did some investigation. Can confirm that on my Jetson AGX Xavier, this patch (or disabling degamma) fixes the color output. The colorspace the display expects from the incoming data is specified in the AVI infoframe. This is generated in tegra_sor_hdmi_setup_avi_infoframe, which calls into drm_hdmi_avi_infoframe_from_display_mode, which leaves a lot of fields set at the default. Currently we're advertising: * colorimetry = no data -> for HD resolutions, use Rec. 709 primaries. These are the same as sRGB. * itc = false -> NOT IT content. My understanding (based on some LLM research and otherwise) is that this is likely to result in the display expecting Rec. 709 colors with Rec. 709 gamma. sRGB gamma is slightly different, and setting itc = true would hint the display towards using sRGB gamma. However, what seems clear to me is that the display would be expecting nonlinear data, so enabling gamma conversion at the output LUT seems correct to me. So this patch would be a clear improvement (with the fixes already discussed). Mikko
On Tue, Jan 27, 2026 at 01:12:54PM +0900, Mikko Perttunen wrote: > On Thursday, January 22, 2026 2:08 AM Kurt Kiefer wrote: > > > > > On Dec 8, 2025, at 8:23 PM, Aaron Kling <webgeek1234@gmail.com> wrote: > > > > > > On Wed, Nov 5, 2025 at 3:28 PM Jasper Korten <jja2000@gmail.com> wrote: > > >> > > >> Hi all, > > >> > > >> On 11/4/25 19:12, Aaron Kling wrote: > > >>> On Tue, Nov 4, 2025 at 3:14 AM Thierry Reding <thierry.reding@gmail.com> wrote: > > >>>> On Mon, Nov 03, 2025 at 12:39:57PM -0600, Aaron Kling wrote: > > >>>>> On Mon, Nov 3, 2025 at 5:54 AM Thierry Reding <thierry.reding@gmail.com> wrote: > > >>>>>> On Sat, Nov 01, 2025 at 06:15:17PM -0500, Aaron Kling via B4 Relay wrote: > > >>>>>>> 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. > > >>>>>>> > > >>>>>>> Signed-off-by: Aaron Kling <webgeek1234@gmail.com> > > >>>>>>> --- > > >>>>>>> drivers/gpu/drm/tegra/dc.h | 13 +++ > > >>>>>>> drivers/gpu/drm/tegra/sor.c | 206 ++++++++++++++++++++++++++++++++++++++++++++ > > >>>>>>> 2 files changed, 219 insertions(+) > > >>>>>> What does "darker than intended" mean? Who defines the intention? How do > > >>>>>> we know what the intention is? What this patch ultimately seems to be > > >>>>>> doing is define sRGB to be the default colorspace. Is that always the > > >>>>>> right default choice? What if people want to specify a different > > >>>>>> colorspace? > > >>>>> I reported this issue almost a month ago. See kernel lore [0] and > > >>>>> freedesktop issue [1]. The pictures in the latter show what nvdisplay > > >>>>> looks like right now. It's nigh unusably dark. When booted into > > >>>>> Android with a tv launcher that has a black background, as is default > > >>>>> for LineageOS, it is really hard to read anything. Is it correct as a > > >>>>> default? Well, cboot hardcodes this, so... presumably? It would be > > >>>>> more ideal to expose this and csc to userspace, but I'm not sure if > > >>>>> drm has a standardized interface for that or if tegra would have to > > >>>>> make something vendor specific. I think that would be a separate > > >>>>> change concept compared to setting this default, though. > > >>>> The reason I'm asking is because I don't recall ever seeing "broken" > > >>>> colors like you do. So I suspect that this may also be related to what > > >>>> display is connected, or the mode that we're setting. > > >> I have tried it on both a MacroSilicon HDMI capture card and an Arzopa > > >> Z1FC 1080p portable monitor and run into the same darker colors. Both > > >> have in common that they use HDMI which seems to line up with what Aaron > > >> is reporting. I do not have an eDP display to test or another carrier > > >> board with a different display out to test. > > >>>> It could perhaps > > >>>> also be related to what infoframes we're sending and how these are > > >>>> supported/interpreted by the attached display. > > >>>> > > >>>> All of that is to say that maybe this looks broken on the particular > > >>>> setup that you have but may works fine on other setups. Changing the > > >>>> default may fix your setup and break others. > > >>> Do you have a device set up so you can check? Or does the regression > > >>> test bench have a display that can be forwarded? > > >>> > > >>> My current setup is a rack of units plugged via hdmi to a kvm which is > > >>> then plugged to a pikvm. I also observed this issue before I had this > > >>> setup, plugged directly to a 1080p monitor. I have not checked > > >>> displayport. I can cycle through a couple other displays without this > > >>> patch to see if I get any other result. I am fairly certain I have > > >>> consistently seen this issue since I started trying to work with > > >>> tegra-drm on kernel 6.1 or maybe even 5.15. I've never seen it work to > > >>> allow for a bisect. > > >>> > > >>> I am in contact with one other person with a tx2 devkit, who > > >>> replicated the issue when I asked. Who plans to reply to this thread > > >>> with setup info later. > > >> > > >> For reference, I am said person. I have a Jetson TX2 Devkit that uses > > >> the P2771 Device Tree. I'm running a Fedora distrokernel with no > > >> additional patches applied by myself. I have personally noticed the > > >> issue to at least be present on 6.14.5 and 6.17.4. > > >> > > >> > > >> I'm currently not at home to take screenshots with and without the > > >> submitted patch, but will be able to do it tomorrownight or friday. > > > > > > Any further thoughts from the maintainers on this patch? As far as I > > > know, this is an issue for all users, at the very least on hdmi. > > > > > > Aaron > > > > > > > I can confirm that I have the same issue on a DisplayPort output of t194. > > IMO, this patch will need to be reworked a bit to enable the CMU for this > > output as well. I hacked this change in for DisplayPort, and then it > > functioned as intended there as well. > > > > I've traced back to the reason this is necessary. The DC hub driver is > > applying an sRGB degamma for every RGB plane (presumably for blending), > > and then nothing reapplies the EOTF later on. Without gamma correction > > in places where it is expected, images are going to look "too dark". > > > > Which does raise the point that there is an alternative implementation > > where we do not degamma RGB planes in the first place. But this may have > > unintended consequences when it comes to composition. > > > > The SOR does not appear to handle YCbCr outputs at this time, so enabling > > the CMU assuming an sRGB EOTF seems like a reasonable path here, to me. > > > > Kurt > > I tested this patch locally and did some investigation. Can confirm > that on my Jetson AGX Xavier, this patch (or disabling degamma) fixes > the color output. > > The colorspace the display expects from the incoming data is specified > in the AVI infoframe. This is generated in > tegra_sor_hdmi_setup_avi_infoframe, which calls into > drm_hdmi_avi_infoframe_from_display_mode, which leaves a lot of fields > set at the default. > > Currently we're advertising: > * colorimetry = no data -> for HD resolutions, use Rec. 709 primaries. > These are the same as sRGB. > * itc = false -> NOT IT content. > > My understanding (based on some LLM research and otherwise) is that > this is likely to result in the display expecting Rec. 709 colors with > Rec. 709 gamma. sRGB gamma is slightly different, and setting itc = > true would hint the display towards using sRGB gamma. > > However, what seems clear to me is that the display would be expecting > nonlinear data, so enabling gamma conversion at the output LUT seems > correct to me. So this patch would be a clear improvement (with the > fixes already discussed). I think ideally we want to hook this up to the DRM color management facilities, so that it can both be properly reported and configured at runtime. Obviously we also want to make sure that the output pixels match what is advertised via the AVI infoframe. Looks like there's concensus that enabling the output LUT is the correct way to do that. Thierry
On Tue, Jan 27, 2026 at 4:32 AM Thierry Reding <thierry.reding@kernel.org> wrote: > > On Tue, Jan 27, 2026 at 01:12:54PM +0900, Mikko Perttunen wrote: > > On Thursday, January 22, 2026 2:08 AM Kurt Kiefer wrote: > > > > > > > On Dec 8, 2025, at 8:23 PM, Aaron Kling <webgeek1234@gmail.com> wrote: > > > > > > > > On Wed, Nov 5, 2025 at 3:28 PM Jasper Korten <jja2000@gmail.com> wrote: > > > >> > > > >> Hi all, > > > >> > > > >> On 11/4/25 19:12, Aaron Kling wrote: > > > >>> On Tue, Nov 4, 2025 at 3:14 AM Thierry Reding <thierry.reding@gmail.com> wrote: > > > >>>> On Mon, Nov 03, 2025 at 12:39:57PM -0600, Aaron Kling wrote: > > > >>>>> On Mon, Nov 3, 2025 at 5:54 AM Thierry Reding <thierry.reding@gmail.com> wrote: > > > >>>>>> On Sat, Nov 01, 2025 at 06:15:17PM -0500, Aaron Kling via B4 Relay wrote: > > > >>>>>>> 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. > > > >>>>>>> > > > >>>>>>> Signed-off-by: Aaron Kling <webgeek1234@gmail.com> > > > >>>>>>> --- > > > >>>>>>> drivers/gpu/drm/tegra/dc.h | 13 +++ > > > >>>>>>> drivers/gpu/drm/tegra/sor.c | 206 ++++++++++++++++++++++++++++++++++++++++++++ > > > >>>>>>> 2 files changed, 219 insertions(+) > > > >>>>>> What does "darker than intended" mean? Who defines the intention? How do > > > >>>>>> we know what the intention is? What this patch ultimately seems to be > > > >>>>>> doing is define sRGB to be the default colorspace. Is that always the > > > >>>>>> right default choice? What if people want to specify a different > > > >>>>>> colorspace? > > > >>>>> I reported this issue almost a month ago. See kernel lore [0] and > > > >>>>> freedesktop issue [1]. The pictures in the latter show what nvdisplay > > > >>>>> looks like right now. It's nigh unusably dark. When booted into > > > >>>>> Android with a tv launcher that has a black background, as is default > > > >>>>> for LineageOS, it is really hard to read anything. Is it correct as a > > > >>>>> default? Well, cboot hardcodes this, so... presumably? It would be > > > >>>>> more ideal to expose this and csc to userspace, but I'm not sure if > > > >>>>> drm has a standardized interface for that or if tegra would have to > > > >>>>> make something vendor specific. I think that would be a separate > > > >>>>> change concept compared to setting this default, though. > > > >>>> The reason I'm asking is because I don't recall ever seeing "broken" > > > >>>> colors like you do. So I suspect that this may also be related to what > > > >>>> display is connected, or the mode that we're setting. > > > >> I have tried it on both a MacroSilicon HDMI capture card and an Arzopa > > > >> Z1FC 1080p portable monitor and run into the same darker colors. Both > > > >> have in common that they use HDMI which seems to line up with what Aaron > > > >> is reporting. I do not have an eDP display to test or another carrier > > > >> board with a different display out to test. > > > >>>> It could perhaps > > > >>>> also be related to what infoframes we're sending and how these are > > > >>>> supported/interpreted by the attached display. > > > >>>> > > > >>>> All of that is to say that maybe this looks broken on the particular > > > >>>> setup that you have but may works fine on other setups. Changing the > > > >>>> default may fix your setup and break others. > > > >>> Do you have a device set up so you can check? Or does the regression > > > >>> test bench have a display that can be forwarded? > > > >>> > > > >>> My current setup is a rack of units plugged via hdmi to a kvm which is > > > >>> then plugged to a pikvm. I also observed this issue before I had this > > > >>> setup, plugged directly to a 1080p monitor. I have not checked > > > >>> displayport. I can cycle through a couple other displays without this > > > >>> patch to see if I get any other result. I am fairly certain I have > > > >>> consistently seen this issue since I started trying to work with > > > >>> tegra-drm on kernel 6.1 or maybe even 5.15. I've never seen it work to > > > >>> allow for a bisect. > > > >>> > > > >>> I am in contact with one other person with a tx2 devkit, who > > > >>> replicated the issue when I asked. Who plans to reply to this thread > > > >>> with setup info later. > > > >> > > > >> For reference, I am said person. I have a Jetson TX2 Devkit that uses > > > >> the P2771 Device Tree. I'm running a Fedora distrokernel with no > > > >> additional patches applied by myself. I have personally noticed the > > > >> issue to at least be present on 6.14.5 and 6.17.4. > > > >> > > > >> > > > >> I'm currently not at home to take screenshots with and without the > > > >> submitted patch, but will be able to do it tomorrownight or friday. > > > > > > > > Any further thoughts from the maintainers on this patch? As far as I > > > > know, this is an issue for all users, at the very least on hdmi. > > > > > > > > Aaron > > > > > > > > > > I can confirm that I have the same issue on a DisplayPort output of t194. > > > IMO, this patch will need to be reworked a bit to enable the CMU for this > > > output as well. I hacked this change in for DisplayPort, and then it > > > functioned as intended there as well. > > > > > > I've traced back to the reason this is necessary. The DC hub driver is > > > applying an sRGB degamma for every RGB plane (presumably for blending), > > > and then nothing reapplies the EOTF later on. Without gamma correction > > > in places where it is expected, images are going to look "too dark". > > > > > > Which does raise the point that there is an alternative implementation > > > where we do not degamma RGB planes in the first place. But this may have > > > unintended consequences when it comes to composition. > > > > > > The SOR does not appear to handle YCbCr outputs at this time, so enabling > > > the CMU assuming an sRGB EOTF seems like a reasonable path here, to me. > > > > > > Kurt > > > > I tested this patch locally and did some investigation. Can confirm > > that on my Jetson AGX Xavier, this patch (or disabling degamma) fixes > > the color output. > > > > The colorspace the display expects from the incoming data is specified > > in the AVI infoframe. This is generated in > > tegra_sor_hdmi_setup_avi_infoframe, which calls into > > drm_hdmi_avi_infoframe_from_display_mode, which leaves a lot of fields > > set at the default. > > > > Currently we're advertising: > > * colorimetry = no data -> for HD resolutions, use Rec. 709 primaries. > > These are the same as sRGB. > > * itc = false -> NOT IT content. > > > > My understanding (based on some LLM research and otherwise) is that > > this is likely to result in the display expecting Rec. 709 colors with > > Rec. 709 gamma. sRGB gamma is slightly different, and setting itc = > > true would hint the display towards using sRGB gamma. > > > > However, what seems clear to me is that the display would be expecting > > nonlinear data, so enabling gamma conversion at the output LUT seems > > correct to me. So this patch would be a clear improvement (with the > > fixes already discussed). > > I think ideally we want to hook this up to the DRM color management > facilities, so that it can both be properly reported and configured > at runtime. That would be ideal yes. But I don't have nearly the knowledge of DRM or nvdisplay to wire this up. Is there someone at Nvidia that can make time to do so? > Obviously we also want to make sure that the output pixels match what > is advertised via the AVI infoframe. Looks like there's concensus that > enabling the output LUT is the correct way to do that. If more fully featured CMU support can't be done in a reasonable timeframe, I can address the earlier review comments and coordinate with Kurt to replicate this for DP, then send a v2. Aaron
On 09/12/2025 05:23, Aaron Kling wrote: > On Wed, Nov 5, 2025 at 3:28 PM Jasper Korten <jja2000@gmail.com> wrote: >> Hi all, >> >> On 11/4/25 19:12, Aaron Kling wrote: >>> On Tue, Nov 4, 2025 at 3:14 AM Thierry Reding <thierry.reding@gmail.com> wrote: >>>> On Mon, Nov 03, 2025 at 12:39:57PM -0600, Aaron Kling wrote: >>>>> On Mon, Nov 3, 2025 at 5:54 AM Thierry Reding <thierry.reding@gmail.com> wrote: >>>>>> On Sat, Nov 01, 2025 at 06:15:17PM -0500, Aaron Kling via B4 Relay wrote: >>>>>>> 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. >>>>>>> >>>>>>> Signed-off-by: Aaron Kling <webgeek1234@gmail.com> >>>>>>> --- >>>>>>> drivers/gpu/drm/tegra/dc.h | 13 +++ >>>>>>> drivers/gpu/drm/tegra/sor.c | 206 ++++++++++++++++++++++++++++++++++++++++++++ >>>>>>> 2 files changed, 219 insertions(+) >>>>>> What does "darker than intended" mean? Who defines the intention? How do >>>>>> we know what the intention is? What this patch ultimately seems to be >>>>>> doing is define sRGB to be the default colorspace. Is that always the >>>>>> right default choice? What if people want to specify a different >>>>>> colorspace? >>>>> I reported this issue almost a month ago. See kernel lore [0] and >>>>> freedesktop issue [1]. The pictures in the latter show what nvdisplay >>>>> looks like right now. It's nigh unusably dark. When booted into >>>>> Android with a tv launcher that has a black background, as is default >>>>> for LineageOS, it is really hard to read anything. Is it correct as a >>>>> default? Well, cboot hardcodes this, so... presumably? It would be >>>>> more ideal to expose this and csc to userspace, but I'm not sure if >>>>> drm has a standardized interface for that or if tegra would have to >>>>> make something vendor specific. I think that would be a separate >>>>> change concept compared to setting this default, though. >>>> The reason I'm asking is because I don't recall ever seeing "broken" >>>> colors like you do. So I suspect that this may also be related to what >>>> display is connected, or the mode that we're setting. >> I have tried it on both a MacroSilicon HDMI capture card and an Arzopa >> Z1FC 1080p portable monitor and run into the same darker colors. Both >> have in common that they use HDMI which seems to line up with what Aaron >> is reporting. I do not have an eDP display to test or another carrier >> board with a different display out to test. >>>> It could perhaps >>>> also be related to what infoframes we're sending and how these are >>>> supported/interpreted by the attached display. >>>> >>>> All of that is to say that maybe this looks broken on the particular >>>> setup that you have but may works fine on other setups. Changing the >>>> default may fix your setup and break others. >>> Do you have a device set up so you can check? Or does the regression >>> test bench have a display that can be forwarded? >>> >>> My current setup is a rack of units plugged via hdmi to a kvm which is >>> then plugged to a pikvm. I also observed this issue before I had this >>> setup, plugged directly to a 1080p monitor. I have not checked >>> displayport. I can cycle through a couple other displays without this >>> patch to see if I get any other result. I am fairly certain I have >>> consistently seen this issue since I started trying to work with >>> tegra-drm on kernel 6.1 or maybe even 5.15. I've never seen it work to >>> allow for a bisect. >>> >>> I am in contact with one other person with a tx2 devkit, who >>> replicated the issue when I asked. Who plans to reply to this thread >>> with setup info later. >> For reference, I am said person. I have a Jetson TX2 Devkit that uses >> the P2771 Device Tree. I'm running a Fedora distrokernel with no >> additional patches applied by myself. I have personally noticed the >> issue to at least be present on 6.14.5 and 6.17.4. >> >> >> I'm currently not at home to take screenshots with and without the >> submitted patch, but will be able to do it tomorrownight or friday. > Any further thoughts from the maintainers on this patch? As far as I > know, this is an issue for all users, at the very least on hdmi. > > Aaron I've finally captured some footage of the colors of my TX2 within tty. I've also added a reference in the form of my X13s doing the same thing.[1] I will at a later date try the patch and update the MR comment, but at least this shows the difference while recording using the same setup. Kindest regards, Jasper [1]: https://gitlab.freedesktop.org/drm/tegra/-/issues/8#note_3242611
On 18/12/2025 00:18, Jasper Korten wrote: > On 09/12/2025 05:23, Aaron Kling wrote: > >> On Wed, Nov 5, 2025 at 3:28 PM Jasper Korten <jja2000@gmail.com> wrote: >>> Hi all, >>> >>> On 11/4/25 19:12, Aaron Kling wrote: >>>> On Tue, Nov 4, 2025 at 3:14 AM Thierry Reding >>>> <thierry.reding@gmail.com> wrote: >>>>> On Mon, Nov 03, 2025 at 12:39:57PM -0600, Aaron Kling wrote: >>>>>> On Mon, Nov 3, 2025 at 5:54 AM Thierry Reding >>>>>> <thierry.reding@gmail.com> wrote: >>>>>>> On Sat, Nov 01, 2025 at 06:15:17PM -0500, Aaron Kling via B4 >>>>>>> Relay wrote: >>>>>>>> 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. >>>>>>>> >>>>>>>> Signed-off-by: Aaron Kling <webgeek1234@gmail.com> >>>>>>>> --- >>>>>>>> drivers/gpu/drm/tegra/dc.h | 13 +++ >>>>>>>> drivers/gpu/drm/tegra/sor.c | 206 >>>>>>>> ++++++++++++++++++++++++++++++++++++++++++++ >>>>>>>> 2 files changed, 219 insertions(+) >>>>>>> What does "darker than intended" mean? Who defines the >>>>>>> intention? How do >>>>>>> we know what the intention is? What this patch ultimately seems >>>>>>> to be >>>>>>> doing is define sRGB to be the default colorspace. Is that >>>>>>> always the >>>>>>> right default choice? What if people want to specify a different >>>>>>> colorspace? >>>>>> I reported this issue almost a month ago. See kernel lore [0] and >>>>>> freedesktop issue [1]. The pictures in the latter show what >>>>>> nvdisplay >>>>>> looks like right now. It's nigh unusably dark. When booted into >>>>>> Android with a tv launcher that has a black background, as is >>>>>> default >>>>>> for LineageOS, it is really hard to read anything. Is it correct >>>>>> as a >>>>>> default? Well, cboot hardcodes this, so... presumably? It would be >>>>>> more ideal to expose this and csc to userspace, but I'm not sure if >>>>>> drm has a standardized interface for that or if tegra would have to >>>>>> make something vendor specific. I think that would be a separate >>>>>> change concept compared to setting this default, though. >>>>> The reason I'm asking is because I don't recall ever seeing "broken" >>>>> colors like you do. So I suspect that this may also be related to >>>>> what >>>>> display is connected, or the mode that we're setting. >>> I have tried it on both a MacroSilicon HDMI capture card and an Arzopa >>> Z1FC 1080p portable monitor and run into the same darker colors. Both >>> have in common that they use HDMI which seems to line up with what >>> Aaron >>> is reporting. I do not have an eDP display to test or another carrier >>> board with a different display out to test. >>>>> It could perhaps >>>>> also be related to what infoframes we're sending and how these are >>>>> supported/interpreted by the attached display. >>>>> >>>>> All of that is to say that maybe this looks broken on the particular >>>>> setup that you have but may works fine on other setups. Changing the >>>>> default may fix your setup and break others. >>>> Do you have a device set up so you can check? Or does the regression >>>> test bench have a display that can be forwarded? >>>> >>>> My current setup is a rack of units plugged via hdmi to a kvm which is >>>> then plugged to a pikvm. I also observed this issue before I had this >>>> setup, plugged directly to a 1080p monitor. I have not checked >>>> displayport. I can cycle through a couple other displays without this >>>> patch to see if I get any other result. I am fairly certain I have >>>> consistently seen this issue since I started trying to work with >>>> tegra-drm on kernel 6.1 or maybe even 5.15. I've never seen it work to >>>> allow for a bisect. >>>> >>>> I am in contact with one other person with a tx2 devkit, who >>>> replicated the issue when I asked. Who plans to reply to this thread >>>> with setup info later. >>> For reference, I am said person. I have a Jetson TX2 Devkit that uses >>> the P2771 Device Tree. I'm running a Fedora distrokernel with no >>> additional patches applied by myself. I have personally noticed the >>> issue to at least be present on 6.14.5 and 6.17.4. >>> >>> >>> I'm currently not at home to take screenshots with and without the >>> submitted patch, but will be able to do it tomorrownight or friday. >> Any further thoughts from the maintainers on this patch? As far as I >> know, this is an issue for all users, at the very least on hdmi. >> >> Aaron > > I've finally captured some footage of the colors of my TX2 within tty. > I've also added a reference in the form of my X13s doing the same > thing.[1] > > I will at a later date try the patch and update the MR comment, > but at least this shows the difference while recording using the same > setup. > > Kindest regards, > > Jasper > > [1]: https://gitlab.freedesktop.org/drm/tegra/-/issues/8#note_3242611 > As promised, I've added my test results to the Issue[1]. It seems to improve colors a lot more, haven't ran into any other issues. The patch seems to work therefore: Tested-by: Jasper Korten <jja2000@gmail.com> Kindest regards, Jasper Korten [1]: https://gitlab.freedesktop.org/drm/tegra/-/issues/8#note_3246713
Hi Aaron,
kernel test robot noticed the following build warnings:
[auto build test WARNING on dcb6fa37fd7bc9c3d2b066329b0d27dedf8becaa]
url: https://github.com/intel-lab-lkp/linux/commits/Aaron-Kling-via-B4-Relay/drm-tegra-Enable-cmu-for-Tegra186-and-Tegra194/20251102-071726
base: dcb6fa37fd7bc9c3d2b066329b0d27dedf8becaa
patch link: https://lore.kernel.org/r/20251101-tegra-drm-cmu-v1-1-211799755ab8%40gmail.com
patch subject: [PATCH] drm/tegra: Enable cmu for Tegra186 and Tegra194
config: arm-defconfig (https://download.01.org/0day-ci/archive/20251103/202511030131.AADiEKfQ-lkp@intel.com/config)
compiler: clang version 22.0.0git (https://github.com/llvm/llvm-project d2625a438020ad35330cda29c3def102c1687b1b)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251103/202511030131.AADiEKfQ-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202511030131.AADiEKfQ-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> drivers/gpu/drm/tegra/sor.c:2757:50: warning: shift count >= width of type [-Wshift-count-overflow]
2757 | tegra_dc_writel(dc, (u32)(sor->cmu_output_phys >> 32),
| ^ ~~
1 warning generated.
vim +2757 drivers/gpu/drm/tegra/sor.c
2590
2591 /* switch the SOR clock to the pad clock */
2592 err = tegra_sor_set_parent_clock(sor, sor->clk_pad);
2593 if (err < 0) {
2594 dev_err(sor->dev, "failed to select SOR parent clock: %d\n",
2595 err);
2596 return;
2597 }
2598
2599 /* switch the output clock to the parent pixel clock */
2600 err = clk_set_parent(sor->clk, sor->clk_parent);
2601 if (err < 0) {
2602 dev_err(sor->dev, "failed to select output parent clock: %d\n",
2603 err);
2604 return;
2605 }
2606
2607 /* adjust clock rate for HDMI 2.0 modes */
2608 rate = clk_get_rate(sor->clk_parent);
2609
2610 if (mode->clock >= 340000)
2611 rate /= 2;
2612
2613 DRM_DEBUG_KMS("setting clock to %lu Hz, mode: %lu Hz\n", rate, pclk);
2614
2615 clk_set_rate(sor->clk, rate);
2616
2617 if (!sor->soc->has_nvdisplay) {
2618 value = SOR_INPUT_CONTROL_HDMI_SRC_SELECT(dc->pipe);
2619
2620 /* XXX is this the proper check? */
2621 if (mode->clock < 75000)
2622 value |= SOR_INPUT_CONTROL_ARM_VIDEO_RANGE_LIMITED;
2623
2624 tegra_sor_writel(sor, value, SOR_INPUT_CONTROL);
2625 }
2626
2627 max_ac = ((mode->htotal - mode->hdisplay) - SOR_REKEY - 18) / 32;
2628
2629 value = SOR_HDMI_CTRL_ENABLE | SOR_HDMI_CTRL_MAX_AC_PACKET(max_ac) |
2630 SOR_HDMI_CTRL_AUDIO_LAYOUT | SOR_HDMI_CTRL_REKEY(SOR_REKEY);
2631 tegra_sor_writel(sor, value, SOR_HDMI_CTRL);
2632
2633 if (!dc->soc->has_nvdisplay) {
2634 /* H_PULSE2 setup */
2635 pulse_start = h_ref_to_sync +
2636 (mode->hsync_end - mode->hsync_start) +
2637 (mode->htotal - mode->hsync_end) - 10;
2638
2639 value = PULSE_LAST_END_A | PULSE_QUAL_VACTIVE |
2640 PULSE_POLARITY_HIGH | PULSE_MODE_NORMAL;
2641 tegra_dc_writel(dc, value, DC_DISP_H_PULSE2_CONTROL);
2642
2643 value = PULSE_END(pulse_start + 8) | PULSE_START(pulse_start);
2644 tegra_dc_writel(dc, value, DC_DISP_H_PULSE2_POSITION_A);
2645
2646 value = tegra_dc_readl(dc, DC_DISP_DISP_SIGNAL_OPTIONS0);
2647 value |= H_PULSE2_ENABLE;
2648 tegra_dc_writel(dc, value, DC_DISP_DISP_SIGNAL_OPTIONS0);
2649 }
2650
2651 /* infoframe setup */
2652 err = tegra_sor_hdmi_setup_avi_infoframe(sor, mode);
2653 if (err < 0)
2654 dev_err(sor->dev, "failed to setup AVI infoframe: %d\n", err);
2655
2656 /* XXX HDMI audio support not implemented yet */
2657 tegra_sor_hdmi_disable_audio_infoframe(sor);
2658
2659 /* use single TMDS protocol */
2660 value = tegra_sor_readl(sor, SOR_STATE1);
2661 value &= ~SOR_STATE_ASY_PROTOCOL_MASK;
2662 value |= SOR_STATE_ASY_PROTOCOL_SINGLE_TMDS_A;
2663 tegra_sor_writel(sor, value, SOR_STATE1);
2664
2665 /* power up pad calibration */
2666 value = tegra_sor_readl(sor, sor->soc->regs->dp_padctl0);
2667 value &= ~SOR_DP_PADCTL_PAD_CAL_PD;
2668 tegra_sor_writel(sor, value, sor->soc->regs->dp_padctl0);
2669
2670 /* production settings */
2671 settings = tegra_sor_hdmi_find_settings(sor, mode->clock * 1000);
2672 if (!settings) {
2673 dev_err(sor->dev, "no settings for pixel clock %d Hz\n",
2674 mode->clock * 1000);
2675 return;
2676 }
2677
2678 value = tegra_sor_readl(sor, sor->soc->regs->pll0);
2679 value &= ~SOR_PLL0_ICHPMP_MASK;
2680 value &= ~SOR_PLL0_FILTER_MASK;
2681 value &= ~SOR_PLL0_VCOCAP_MASK;
2682 value |= SOR_PLL0_ICHPMP(settings->ichpmp);
2683 value |= SOR_PLL0_FILTER(settings->filter);
2684 value |= SOR_PLL0_VCOCAP(settings->vcocap);
2685 tegra_sor_writel(sor, value, sor->soc->regs->pll0);
2686
2687 /* XXX not in TRM */
2688 value = tegra_sor_readl(sor, sor->soc->regs->pll1);
2689 value &= ~SOR_PLL1_LOADADJ_MASK;
2690 value &= ~SOR_PLL1_TMDS_TERMADJ_MASK;
2691 value |= SOR_PLL1_LOADADJ(settings->loadadj);
2692 value |= SOR_PLL1_TMDS_TERMADJ(settings->tmds_termadj);
2693 value |= SOR_PLL1_TMDS_TERM;
2694 tegra_sor_writel(sor, value, sor->soc->regs->pll1);
2695
2696 value = tegra_sor_readl(sor, sor->soc->regs->pll3);
2697 value &= ~SOR_PLL3_BG_TEMP_COEF_MASK;
2698 value &= ~SOR_PLL3_BG_VREF_LEVEL_MASK;
2699 value &= ~SOR_PLL3_AVDD10_LEVEL_MASK;
2700 value &= ~SOR_PLL3_AVDD14_LEVEL_MASK;
2701 value |= SOR_PLL3_BG_TEMP_COEF(settings->bg_temp_coef);
2702 value |= SOR_PLL3_BG_VREF_LEVEL(settings->bg_vref_level);
2703 value |= SOR_PLL3_AVDD10_LEVEL(settings->avdd10_level);
2704 value |= SOR_PLL3_AVDD14_LEVEL(settings->avdd14_level);
2705 tegra_sor_writel(sor, value, sor->soc->regs->pll3);
2706
2707 value = settings->drive_current[3] << 24 |
2708 settings->drive_current[2] << 16 |
2709 settings->drive_current[1] << 8 |
2710 settings->drive_current[0] << 0;
2711 tegra_sor_writel(sor, value, SOR_LANE_DRIVE_CURRENT0);
2712
2713 value = settings->preemphasis[3] << 24 |
2714 settings->preemphasis[2] << 16 |
2715 settings->preemphasis[1] << 8 |
2716 settings->preemphasis[0] << 0;
2717 tegra_sor_writel(sor, value, SOR_LANE_PREEMPHASIS0);
2718
2719 value = tegra_sor_readl(sor, sor->soc->regs->dp_padctl0);
2720 value &= ~SOR_DP_PADCTL_TX_PU_MASK;
2721 value |= SOR_DP_PADCTL_TX_PU_ENABLE;
2722 value |= SOR_DP_PADCTL_TX_PU(settings->tx_pu_value);
2723 tegra_sor_writel(sor, value, sor->soc->regs->dp_padctl0);
2724
2725 value = tegra_sor_readl(sor, sor->soc->regs->dp_padctl2);
2726 value &= ~SOR_DP_PADCTL_SPAREPLL_MASK;
2727 value |= SOR_DP_PADCTL_SPAREPLL(settings->sparepll);
2728 tegra_sor_writel(sor, value, sor->soc->regs->dp_padctl2);
2729
2730 /* power down pad calibration */
2731 value = tegra_sor_readl(sor, sor->soc->regs->dp_padctl0);
2732 value |= SOR_DP_PADCTL_PAD_CAL_PD;
2733 tegra_sor_writel(sor, value, sor->soc->regs->dp_padctl0);
2734
2735 if (!dc->soc->has_nvdisplay) {
2736 /* miscellaneous display controller settings */
2737 value = VSYNC_H_POSITION(1);
2738 tegra_dc_writel(dc, value, DC_DISP_DISP_TIMING_OPTIONS);
2739 }
2740
2741 value = tegra_dc_readl(dc, DC_DISP_DISP_COLOR_CONTROL);
2742 value &= ~DITHER_CONTROL_MASK;
2743 value &= ~BASE_COLOR_SIZE_MASK;
2744
2745 if (dc->soc->has_nvdisplay) {
2746 sor->cmu_output_lut =
2747 dma_alloc_coherent(dc->dev, ARRAY_SIZE(default_srgb_lut) * sizeof(u64),
2748 &sor->cmu_output_phys, GFP_KERNEL);
2749
2750 for (i = 0; i < ARRAY_SIZE(default_srgb_lut); i++) {
2751 r = default_srgb_lut[i];
2752 sor->cmu_output_lut[i] = (r << 32) | (r << 16) | r;
2753 }
2754
2755 tegra_dc_writel(dc, (u32)(sor->cmu_output_phys & 0xffffffff),
2756 DC_DISP_COREPVT_HEAD_SET_OUTPUT_LUT_BASE);
> 2757 tegra_dc_writel(dc, (u32)(sor->cmu_output_phys >> 32),
2758 DC_DISP_COREPVT_HEAD_SET_OUTPUT_LUT_BASE_HI);
2759
2760 tegra_dc_writel(dc, OUTPUT_LUT_MODE_INTERPOLATE | OUTPUT_LUT_SIZE_SIZE_1025,
2761 DC_DISP_CORE_HEAD_SET_CONTROL_OUTPUT_LUT);
2762
2763 value |= CMU_ENABLE_ENABLE;
2764 }
2765
2766 switch (state->bpc) {
2767 case 6:
2768 value |= BASE_COLOR_SIZE_666;
2769 break;
2770
2771 case 8:
2772 value |= BASE_COLOR_SIZE_888;
2773 break;
2774
2775 case 10:
2776 value |= BASE_COLOR_SIZE_101010;
2777 break;
2778
2779 case 12:
2780 value |= BASE_COLOR_SIZE_121212;
2781 break;
2782
2783 default:
2784 WARN(1, "%u bits-per-color not supported\n", state->bpc);
2785 value |= BASE_COLOR_SIZE_888;
2786 break;
2787 }
2788
2789 tegra_dc_writel(dc, value, DC_DISP_DISP_COLOR_CONTROL);
2790
2791 /* XXX set display head owner */
2792 value = tegra_sor_readl(sor, SOR_STATE1);
2793 value &= ~SOR_STATE_ASY_OWNER_MASK;
2794 value |= SOR_STATE_ASY_OWNER(1 + dc->pipe);
2795 tegra_sor_writel(sor, value, SOR_STATE1);
2796
2797 err = tegra_sor_power_up(sor, 250);
2798 if (err < 0)
2799 dev_err(sor->dev, "failed to power up SOR: %d\n", err);
2800
2801 /* configure dynamic range of output */
2802 value = tegra_sor_readl(sor, sor->soc->regs->head_state0 + dc->pipe);
2803 value &= ~SOR_HEAD_STATE_RANGECOMPRESS_MASK;
2804 value &= ~SOR_HEAD_STATE_DYNRANGE_MASK;
2805 tegra_sor_writel(sor, value, sor->soc->regs->head_state0 + dc->pipe);
2806
2807 /* configure colorspace */
2808 value = tegra_sor_readl(sor, sor->soc->regs->head_state0 + dc->pipe);
2809 value &= ~SOR_HEAD_STATE_COLORSPACE_MASK;
2810 value |= SOR_HEAD_STATE_COLORSPACE_RGB;
2811 tegra_sor_writel(sor, value, sor->soc->regs->head_state0 + dc->pipe);
2812
2813 tegra_sor_mode_set(sor, mode, state);
2814
2815 tegra_sor_update(sor);
2816
2817 /* program preamble timing in SOR (XXX) */
2818 value = tegra_sor_readl(sor, SOR_DP_SPARE0);
2819 value &= ~SOR_DP_SPARE_DISP_VIDEO_PREAMBLE;
2820 tegra_sor_writel(sor, value, SOR_DP_SPARE0);
2821
2822 err = tegra_sor_attach(sor);
2823 if (err < 0)
2824 dev_err(sor->dev, "failed to attach SOR: %d\n", err);
2825
2826 /* enable display to SOR clock and generate HDMI preamble */
2827 value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
2828
2829 if (!sor->soc->has_nvdisplay)
2830 value |= SOR1_TIMING_CYA;
2831
2832 value |= SOR_ENABLE(sor->index);
2833
2834 tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);
2835
2836 if (dc->soc->has_nvdisplay) {
2837 value = tegra_dc_readl(dc, DC_DISP_CORE_SOR_SET_CONTROL(sor->index));
2838 value &= ~PROTOCOL_MASK;
2839 value |= PROTOCOL_SINGLE_TMDS_A;
2840 tegra_dc_writel(dc, value, DC_DISP_CORE_SOR_SET_CONTROL(sor->index));
2841 }
2842
2843 tegra_dc_commit(dc);
2844
2845 err = tegra_sor_wakeup(sor);
2846 if (err < 0)
2847 dev_err(sor->dev, "failed to wakeup SOR: %d\n", err);
2848
2849 tegra_sor_hdmi_scdc_start(sor);
2850 tegra_sor_audio_prepare(sor);
2851 }
2852
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Hi Aaron,
kernel test robot noticed the following build warnings:
[auto build test WARNING on dcb6fa37fd7bc9c3d2b066329b0d27dedf8becaa]
url: https://github.com/intel-lab-lkp/linux/commits/Aaron-Kling-via-B4-Relay/drm-tegra-Enable-cmu-for-Tegra186-and-Tegra194/20251102-071726
base: dcb6fa37fd7bc9c3d2b066329b0d27dedf8becaa
patch link: https://lore.kernel.org/r/20251101-tegra-drm-cmu-v1-1-211799755ab8%40gmail.com
patch subject: [PATCH] drm/tegra: Enable cmu for Tegra186 and Tegra194
config: arm-randconfig-002-20251102 (https://download.01.org/0day-ci/archive/20251103/202511030007.5ksWfboC-lkp@intel.com/config)
compiler: arm-linux-gnueabi-gcc (GCC) 10.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251103/202511030007.5ksWfboC-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202511030007.5ksWfboC-lkp@intel.com/
All warnings (new ones prefixed by >>):
drivers/gpu/drm/tegra/sor.c: In function 'tegra_sor_hdmi_enable':
>> drivers/gpu/drm/tegra/sor.c:2757:50: warning: right shift count >= width of type [-Wshift-count-overflow]
2757 | tegra_dc_writel(dc, (u32)(sor->cmu_output_phys >> 32),
| ^~
vim +2757 drivers/gpu/drm/tegra/sor.c
2590
2591 /* switch the SOR clock to the pad clock */
2592 err = tegra_sor_set_parent_clock(sor, sor->clk_pad);
2593 if (err < 0) {
2594 dev_err(sor->dev, "failed to select SOR parent clock: %d\n",
2595 err);
2596 return;
2597 }
2598
2599 /* switch the output clock to the parent pixel clock */
2600 err = clk_set_parent(sor->clk, sor->clk_parent);
2601 if (err < 0) {
2602 dev_err(sor->dev, "failed to select output parent clock: %d\n",
2603 err);
2604 return;
2605 }
2606
2607 /* adjust clock rate for HDMI 2.0 modes */
2608 rate = clk_get_rate(sor->clk_parent);
2609
2610 if (mode->clock >= 340000)
2611 rate /= 2;
2612
2613 DRM_DEBUG_KMS("setting clock to %lu Hz, mode: %lu Hz\n", rate, pclk);
2614
2615 clk_set_rate(sor->clk, rate);
2616
2617 if (!sor->soc->has_nvdisplay) {
2618 value = SOR_INPUT_CONTROL_HDMI_SRC_SELECT(dc->pipe);
2619
2620 /* XXX is this the proper check? */
2621 if (mode->clock < 75000)
2622 value |= SOR_INPUT_CONTROL_ARM_VIDEO_RANGE_LIMITED;
2623
2624 tegra_sor_writel(sor, value, SOR_INPUT_CONTROL);
2625 }
2626
2627 max_ac = ((mode->htotal - mode->hdisplay) - SOR_REKEY - 18) / 32;
2628
2629 value = SOR_HDMI_CTRL_ENABLE | SOR_HDMI_CTRL_MAX_AC_PACKET(max_ac) |
2630 SOR_HDMI_CTRL_AUDIO_LAYOUT | SOR_HDMI_CTRL_REKEY(SOR_REKEY);
2631 tegra_sor_writel(sor, value, SOR_HDMI_CTRL);
2632
2633 if (!dc->soc->has_nvdisplay) {
2634 /* H_PULSE2 setup */
2635 pulse_start = h_ref_to_sync +
2636 (mode->hsync_end - mode->hsync_start) +
2637 (mode->htotal - mode->hsync_end) - 10;
2638
2639 value = PULSE_LAST_END_A | PULSE_QUAL_VACTIVE |
2640 PULSE_POLARITY_HIGH | PULSE_MODE_NORMAL;
2641 tegra_dc_writel(dc, value, DC_DISP_H_PULSE2_CONTROL);
2642
2643 value = PULSE_END(pulse_start + 8) | PULSE_START(pulse_start);
2644 tegra_dc_writel(dc, value, DC_DISP_H_PULSE2_POSITION_A);
2645
2646 value = tegra_dc_readl(dc, DC_DISP_DISP_SIGNAL_OPTIONS0);
2647 value |= H_PULSE2_ENABLE;
2648 tegra_dc_writel(dc, value, DC_DISP_DISP_SIGNAL_OPTIONS0);
2649 }
2650
2651 /* infoframe setup */
2652 err = tegra_sor_hdmi_setup_avi_infoframe(sor, mode);
2653 if (err < 0)
2654 dev_err(sor->dev, "failed to setup AVI infoframe: %d\n", err);
2655
2656 /* XXX HDMI audio support not implemented yet */
2657 tegra_sor_hdmi_disable_audio_infoframe(sor);
2658
2659 /* use single TMDS protocol */
2660 value = tegra_sor_readl(sor, SOR_STATE1);
2661 value &= ~SOR_STATE_ASY_PROTOCOL_MASK;
2662 value |= SOR_STATE_ASY_PROTOCOL_SINGLE_TMDS_A;
2663 tegra_sor_writel(sor, value, SOR_STATE1);
2664
2665 /* power up pad calibration */
2666 value = tegra_sor_readl(sor, sor->soc->regs->dp_padctl0);
2667 value &= ~SOR_DP_PADCTL_PAD_CAL_PD;
2668 tegra_sor_writel(sor, value, sor->soc->regs->dp_padctl0);
2669
2670 /* production settings */
2671 settings = tegra_sor_hdmi_find_settings(sor, mode->clock * 1000);
2672 if (!settings) {
2673 dev_err(sor->dev, "no settings for pixel clock %d Hz\n",
2674 mode->clock * 1000);
2675 return;
2676 }
2677
2678 value = tegra_sor_readl(sor, sor->soc->regs->pll0);
2679 value &= ~SOR_PLL0_ICHPMP_MASK;
2680 value &= ~SOR_PLL0_FILTER_MASK;
2681 value &= ~SOR_PLL0_VCOCAP_MASK;
2682 value |= SOR_PLL0_ICHPMP(settings->ichpmp);
2683 value |= SOR_PLL0_FILTER(settings->filter);
2684 value |= SOR_PLL0_VCOCAP(settings->vcocap);
2685 tegra_sor_writel(sor, value, sor->soc->regs->pll0);
2686
2687 /* XXX not in TRM */
2688 value = tegra_sor_readl(sor, sor->soc->regs->pll1);
2689 value &= ~SOR_PLL1_LOADADJ_MASK;
2690 value &= ~SOR_PLL1_TMDS_TERMADJ_MASK;
2691 value |= SOR_PLL1_LOADADJ(settings->loadadj);
2692 value |= SOR_PLL1_TMDS_TERMADJ(settings->tmds_termadj);
2693 value |= SOR_PLL1_TMDS_TERM;
2694 tegra_sor_writel(sor, value, sor->soc->regs->pll1);
2695
2696 value = tegra_sor_readl(sor, sor->soc->regs->pll3);
2697 value &= ~SOR_PLL3_BG_TEMP_COEF_MASK;
2698 value &= ~SOR_PLL3_BG_VREF_LEVEL_MASK;
2699 value &= ~SOR_PLL3_AVDD10_LEVEL_MASK;
2700 value &= ~SOR_PLL3_AVDD14_LEVEL_MASK;
2701 value |= SOR_PLL3_BG_TEMP_COEF(settings->bg_temp_coef);
2702 value |= SOR_PLL3_BG_VREF_LEVEL(settings->bg_vref_level);
2703 value |= SOR_PLL3_AVDD10_LEVEL(settings->avdd10_level);
2704 value |= SOR_PLL3_AVDD14_LEVEL(settings->avdd14_level);
2705 tegra_sor_writel(sor, value, sor->soc->regs->pll3);
2706
2707 value = settings->drive_current[3] << 24 |
2708 settings->drive_current[2] << 16 |
2709 settings->drive_current[1] << 8 |
2710 settings->drive_current[0] << 0;
2711 tegra_sor_writel(sor, value, SOR_LANE_DRIVE_CURRENT0);
2712
2713 value = settings->preemphasis[3] << 24 |
2714 settings->preemphasis[2] << 16 |
2715 settings->preemphasis[1] << 8 |
2716 settings->preemphasis[0] << 0;
2717 tegra_sor_writel(sor, value, SOR_LANE_PREEMPHASIS0);
2718
2719 value = tegra_sor_readl(sor, sor->soc->regs->dp_padctl0);
2720 value &= ~SOR_DP_PADCTL_TX_PU_MASK;
2721 value |= SOR_DP_PADCTL_TX_PU_ENABLE;
2722 value |= SOR_DP_PADCTL_TX_PU(settings->tx_pu_value);
2723 tegra_sor_writel(sor, value, sor->soc->regs->dp_padctl0);
2724
2725 value = tegra_sor_readl(sor, sor->soc->regs->dp_padctl2);
2726 value &= ~SOR_DP_PADCTL_SPAREPLL_MASK;
2727 value |= SOR_DP_PADCTL_SPAREPLL(settings->sparepll);
2728 tegra_sor_writel(sor, value, sor->soc->regs->dp_padctl2);
2729
2730 /* power down pad calibration */
2731 value = tegra_sor_readl(sor, sor->soc->regs->dp_padctl0);
2732 value |= SOR_DP_PADCTL_PAD_CAL_PD;
2733 tegra_sor_writel(sor, value, sor->soc->regs->dp_padctl0);
2734
2735 if (!dc->soc->has_nvdisplay) {
2736 /* miscellaneous display controller settings */
2737 value = VSYNC_H_POSITION(1);
2738 tegra_dc_writel(dc, value, DC_DISP_DISP_TIMING_OPTIONS);
2739 }
2740
2741 value = tegra_dc_readl(dc, DC_DISP_DISP_COLOR_CONTROL);
2742 value &= ~DITHER_CONTROL_MASK;
2743 value &= ~BASE_COLOR_SIZE_MASK;
2744
2745 if (dc->soc->has_nvdisplay) {
2746 sor->cmu_output_lut =
2747 dma_alloc_coherent(dc->dev, ARRAY_SIZE(default_srgb_lut) * sizeof(u64),
2748 &sor->cmu_output_phys, GFP_KERNEL);
2749
2750 for (i = 0; i < ARRAY_SIZE(default_srgb_lut); i++) {
2751 r = default_srgb_lut[i];
2752 sor->cmu_output_lut[i] = (r << 32) | (r << 16) | r;
2753 }
2754
2755 tegra_dc_writel(dc, (u32)(sor->cmu_output_phys & 0xffffffff),
2756 DC_DISP_COREPVT_HEAD_SET_OUTPUT_LUT_BASE);
> 2757 tegra_dc_writel(dc, (u32)(sor->cmu_output_phys >> 32),
2758 DC_DISP_COREPVT_HEAD_SET_OUTPUT_LUT_BASE_HI);
2759
2760 tegra_dc_writel(dc, OUTPUT_LUT_MODE_INTERPOLATE | OUTPUT_LUT_SIZE_SIZE_1025,
2761 DC_DISP_CORE_HEAD_SET_CONTROL_OUTPUT_LUT);
2762
2763 value |= CMU_ENABLE_ENABLE;
2764 }
2765
2766 switch (state->bpc) {
2767 case 6:
2768 value |= BASE_COLOR_SIZE_666;
2769 break;
2770
2771 case 8:
2772 value |= BASE_COLOR_SIZE_888;
2773 break;
2774
2775 case 10:
2776 value |= BASE_COLOR_SIZE_101010;
2777 break;
2778
2779 case 12:
2780 value |= BASE_COLOR_SIZE_121212;
2781 break;
2782
2783 default:
2784 WARN(1, "%u bits-per-color not supported\n", state->bpc);
2785 value |= BASE_COLOR_SIZE_888;
2786 break;
2787 }
2788
2789 tegra_dc_writel(dc, value, DC_DISP_DISP_COLOR_CONTROL);
2790
2791 /* XXX set display head owner */
2792 value = tegra_sor_readl(sor, SOR_STATE1);
2793 value &= ~SOR_STATE_ASY_OWNER_MASK;
2794 value |= SOR_STATE_ASY_OWNER(1 + dc->pipe);
2795 tegra_sor_writel(sor, value, SOR_STATE1);
2796
2797 err = tegra_sor_power_up(sor, 250);
2798 if (err < 0)
2799 dev_err(sor->dev, "failed to power up SOR: %d\n", err);
2800
2801 /* configure dynamic range of output */
2802 value = tegra_sor_readl(sor, sor->soc->regs->head_state0 + dc->pipe);
2803 value &= ~SOR_HEAD_STATE_RANGECOMPRESS_MASK;
2804 value &= ~SOR_HEAD_STATE_DYNRANGE_MASK;
2805 tegra_sor_writel(sor, value, sor->soc->regs->head_state0 + dc->pipe);
2806
2807 /* configure colorspace */
2808 value = tegra_sor_readl(sor, sor->soc->regs->head_state0 + dc->pipe);
2809 value &= ~SOR_HEAD_STATE_COLORSPACE_MASK;
2810 value |= SOR_HEAD_STATE_COLORSPACE_RGB;
2811 tegra_sor_writel(sor, value, sor->soc->regs->head_state0 + dc->pipe);
2812
2813 tegra_sor_mode_set(sor, mode, state);
2814
2815 tegra_sor_update(sor);
2816
2817 /* program preamble timing in SOR (XXX) */
2818 value = tegra_sor_readl(sor, SOR_DP_SPARE0);
2819 value &= ~SOR_DP_SPARE_DISP_VIDEO_PREAMBLE;
2820 tegra_sor_writel(sor, value, SOR_DP_SPARE0);
2821
2822 err = tegra_sor_attach(sor);
2823 if (err < 0)
2824 dev_err(sor->dev, "failed to attach SOR: %d\n", err);
2825
2826 /* enable display to SOR clock and generate HDMI preamble */
2827 value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
2828
2829 if (!sor->soc->has_nvdisplay)
2830 value |= SOR1_TIMING_CYA;
2831
2832 value |= SOR_ENABLE(sor->index);
2833
2834 tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);
2835
2836 if (dc->soc->has_nvdisplay) {
2837 value = tegra_dc_readl(dc, DC_DISP_CORE_SOR_SET_CONTROL(sor->index));
2838 value &= ~PROTOCOL_MASK;
2839 value |= PROTOCOL_SINGLE_TMDS_A;
2840 tegra_dc_writel(dc, value, DC_DISP_CORE_SOR_SET_CONTROL(sor->index));
2841 }
2842
2843 tegra_dc_commit(dc);
2844
2845 err = tegra_sor_wakeup(sor);
2846 if (err < 0)
2847 dev_err(sor->dev, "failed to wakeup SOR: %d\n", err);
2848
2849 tegra_sor_hdmi_scdc_start(sor);
2850 tegra_sor_audio_prepare(sor);
2851 }
2852
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
© 2016 - 2026 Red Hat, Inc.