@@ -1343,6 +1343,17 @@ static void ilk_lut_write(const struct intel_crtc_state *crtc_state,
13431343 intel_de_write_fw (display , reg , val );
13441344}
13451345
1346+ static void ilk_lut_write_indexed (const struct intel_crtc_state * crtc_state ,
1347+ i915_reg_t reg , u32 val )
1348+ {
1349+ struct intel_display * display = to_intel_display (crtc_state );
1350+
1351+ if (crtc_state -> dsb_color_vblank )
1352+ intel_dsb_reg_write_indexed (crtc_state -> dsb_color_vblank , reg , val );
1353+ else
1354+ intel_de_write_fw (display , reg , val );
1355+ }
1356+
13461357static void ilk_load_lut_8 (const struct intel_crtc_state * crtc_state ,
13471358 const struct drm_property_blob * blob )
13481359{
@@ -1357,19 +1368,29 @@ static void ilk_load_lut_8(const struct intel_crtc_state *crtc_state,
13571368 lut = blob -> data ;
13581369
13591370 /*
1360- * DSB fails to correctly load the legacy LUT
1361- * unless we either write each entry twice,
1362- * or use non-posted writes
1371+ * DSB fails to correctly load the legacy LUT unless
1372+ * we either write each entry twice when using posted
1373+ * writes, or we use non-posted writes.
1374+ *
1375+ * If palette anti-collision is active during LUT
1376+ * register writes:
1377+ * - posted writes simply get dropped and thus the LUT
1378+ * contents may not be correctly updated
1379+ * - non-posted writes are blocked and thus the LUT
1380+ * contents are always correct, but simultaneous CPU
1381+ * MMIO access will start to fail
1382+ *
1383+ * Choose the lesser of two evils and use posted writes.
1384+ * Using posted writes is also faster, even when having
1385+ * to write each register twice.
13631386 */
1364- if (crtc_state -> dsb_color_vblank )
1365- intel_dsb_nonpost_start (crtc_state -> dsb_color_vblank );
1366-
1367- for (i = 0 ; i < 256 ; i ++ )
1387+ for (i = 0 ; i < 256 ; i ++ ) {
13681388 ilk_lut_write (crtc_state , LGC_PALETTE (pipe , i ),
13691389 i9xx_lut_8 (& lut [i ]));
1370-
1371- if (crtc_state -> dsb_color_vblank )
1372- intel_dsb_nonpost_end (crtc_state -> dsb_color_vblank );
1390+ if (crtc_state -> dsb_color_vblank )
1391+ ilk_lut_write (crtc_state , LGC_PALETTE (pipe , i ),
1392+ i9xx_lut_8 (& lut [i ]));
1393+ }
13731394}
13741395
13751396static void ilk_load_lut_10 (const struct intel_crtc_state * crtc_state ,
@@ -1458,8 +1479,8 @@ static void bdw_load_lut_10(const struct intel_crtc_state *crtc_state,
14581479 prec_index );
14591480
14601481 for (i = 0 ; i < lut_size ; i ++ )
1461- ilk_lut_write (crtc_state , PREC_PAL_DATA (pipe ),
1462- ilk_lut_10 (& lut [i ]));
1482+ ilk_lut_write_indexed (crtc_state , PREC_PAL_DATA (pipe ),
1483+ ilk_lut_10 (& lut [i ]));
14631484
14641485 /*
14651486 * Reset the index, otherwise it prevents the legacy palette to be
@@ -1612,16 +1633,16 @@ static void glk_load_degamma_lut(const struct intel_crtc_state *crtc_state,
16121633 * ToDo: Extend to max 7.0. Enable 32 bit input value
16131634 * as compared to just 16 to achieve this.
16141635 */
1615- ilk_lut_write (crtc_state , PRE_CSC_GAMC_DATA (pipe ),
1616- DISPLAY_VER (display ) >= 14 ?
1617- mtl_degamma_lut (& lut [i ]) : glk_degamma_lut (& lut [i ]));
1636+ ilk_lut_write_indexed (crtc_state , PRE_CSC_GAMC_DATA (pipe ),
1637+ DISPLAY_VER (display ) >= 14 ?
1638+ mtl_degamma_lut (& lut [i ]) : glk_degamma_lut (& lut [i ]));
16181639 }
16191640
16201641 /* Clamp values > 1.0. */
16211642 while (i ++ < glk_degamma_lut_size (display ))
1622- ilk_lut_write (crtc_state , PRE_CSC_GAMC_DATA (pipe ),
1623- DISPLAY_VER (display ) >= 14 ?
1624- 1 << 24 : 1 << 16 );
1643+ ilk_lut_write_indexed (crtc_state , PRE_CSC_GAMC_DATA (pipe ),
1644+ DISPLAY_VER (display ) >= 14 ?
1645+ 1 << 24 : 1 << 16 );
16251646
16261647 ilk_lut_write (crtc_state , PRE_CSC_GAMC_INDEX (pipe ), 0 );
16271648}
@@ -1687,10 +1708,10 @@ icl_program_gamma_superfine_segment(const struct intel_crtc_state *crtc_state)
16871708 for (i = 0 ; i < 9 ; i ++ ) {
16881709 const struct drm_color_lut * entry = & lut [i ];
16891710
1690- ilk_lut_write (crtc_state , PREC_PAL_MULTI_SEG_DATA (pipe ),
1691- ilk_lut_12p4_ldw (entry ));
1692- ilk_lut_write (crtc_state , PREC_PAL_MULTI_SEG_DATA (pipe ),
1693- ilk_lut_12p4_udw (entry ));
1711+ ilk_lut_write_indexed (crtc_state , PREC_PAL_MULTI_SEG_DATA (pipe ),
1712+ ilk_lut_12p4_ldw (entry ));
1713+ ilk_lut_write_indexed (crtc_state , PREC_PAL_MULTI_SEG_DATA (pipe ),
1714+ ilk_lut_12p4_udw (entry ));
16941715 }
16951716
16961717 ilk_lut_write (crtc_state , PREC_PAL_MULTI_SEG_INDEX (pipe ),
@@ -1726,10 +1747,10 @@ icl_program_gamma_multi_segment(const struct intel_crtc_state *crtc_state)
17261747 for (i = 1 ; i < 257 ; i ++ ) {
17271748 entry = & lut [i * 8 ];
17281749
1729- ilk_lut_write (crtc_state , PREC_PAL_DATA (pipe ),
1730- ilk_lut_12p4_ldw (entry ));
1731- ilk_lut_write (crtc_state , PREC_PAL_DATA (pipe ),
1732- ilk_lut_12p4_udw (entry ));
1750+ ilk_lut_write_indexed (crtc_state , PREC_PAL_DATA (pipe ),
1751+ ilk_lut_12p4_ldw (entry ));
1752+ ilk_lut_write_indexed (crtc_state , PREC_PAL_DATA (pipe ),
1753+ ilk_lut_12p4_udw (entry ));
17331754 }
17341755
17351756 /*
@@ -1747,10 +1768,10 @@ icl_program_gamma_multi_segment(const struct intel_crtc_state *crtc_state)
17471768 for (i = 0 ; i < 256 ; i ++ ) {
17481769 entry = & lut [i * 8 * 128 ];
17491770
1750- ilk_lut_write (crtc_state , PREC_PAL_DATA (pipe ),
1751- ilk_lut_12p4_ldw (entry ));
1752- ilk_lut_write (crtc_state , PREC_PAL_DATA (pipe ),
1753- ilk_lut_12p4_udw (entry ));
1771+ ilk_lut_write_indexed (crtc_state , PREC_PAL_DATA (pipe ),
1772+ ilk_lut_12p4_ldw (entry ));
1773+ ilk_lut_write_indexed (crtc_state , PREC_PAL_DATA (pipe ),
1774+ ilk_lut_12p4_udw (entry ));
17541775 }
17551776
17561777 ilk_lut_write (crtc_state , PREC_PAL_INDEX (pipe ),
0 commit comments