Skip to content

Commit 2d0cdf6

Browse files
committed
drm/i915/display: Extract display init from intel_device_info_runtime_init
Moving display-specific runtime info initialization into display/ makes the display code more self-contained and also makes it easier to call from the Xe driver. v2: - Drop unnecessary display/ prefix from #includes. (Jani) - Clear runtime info if fusing leaves no pipes remaining, the same as we do when fusing indicates the entire display controller is unavailable. (Jani) - Move adjustment of DRIVER_MODESET / DRIVER_ATOMIC after call to intel_display_device_info_runtime_init(); HAS_DISPLAY may have changed to false during the runtime init. (Jani) Cc: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20230602181450.1151368-1-matthew.d.roper@intel.com
1 parent 19db206 commit 2d0cdf6

3 files changed

Lines changed: 141 additions & 135 deletions

File tree

drivers/gpu/drm/i915/display/intel_display_device.c

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
#include "i915_drv.h"
1111
#include "i915_reg.h"
12+
#include "intel_de.h"
13+
#include "intel_display.h"
1214
#include "intel_display_device.h"
1315
#include "intel_display_power.h"
1416
#include "intel_display_reg_defs.h"
@@ -788,3 +790,128 @@ intel_display_device_probe(struct drm_i915_private *i915, bool has_gmdid,
788790

789791
return &no_display;
790792
}
793+
794+
void intel_display_device_info_runtime_init(struct drm_i915_private *i915)
795+
{
796+
struct intel_display_runtime_info *display_runtime = DISPLAY_RUNTIME_INFO(i915);
797+
enum pipe pipe;
798+
799+
/* Wa_14011765242: adl-s A0,A1 */
800+
if (IS_ADLS_DISPLAY_STEP(i915, STEP_A0, STEP_A2))
801+
for_each_pipe(i915, pipe)
802+
display_runtime->num_scalers[pipe] = 0;
803+
else if (DISPLAY_VER(i915) >= 11) {
804+
for_each_pipe(i915, pipe)
805+
display_runtime->num_scalers[pipe] = 2;
806+
} else if (DISPLAY_VER(i915) >= 9) {
807+
display_runtime->num_scalers[PIPE_A] = 2;
808+
display_runtime->num_scalers[PIPE_B] = 2;
809+
display_runtime->num_scalers[PIPE_C] = 1;
810+
}
811+
812+
if (DISPLAY_VER(i915) >= 13 || HAS_D12_PLANE_MINIMIZATION(i915))
813+
for_each_pipe(i915, pipe)
814+
display_runtime->num_sprites[pipe] = 4;
815+
else if (DISPLAY_VER(i915) >= 11)
816+
for_each_pipe(i915, pipe)
817+
display_runtime->num_sprites[pipe] = 6;
818+
else if (DISPLAY_VER(i915) == 10)
819+
for_each_pipe(i915, pipe)
820+
display_runtime->num_sprites[pipe] = 3;
821+
else if (IS_BROXTON(i915)) {
822+
/*
823+
* Skylake and Broxton currently don't expose the topmost plane as its
824+
* use is exclusive with the legacy cursor and we only want to expose
825+
* one of those, not both. Until we can safely expose the topmost plane
826+
* as a DRM_PLANE_TYPE_CURSOR with all the features exposed/supported,
827+
* we don't expose the topmost plane at all to prevent ABI breakage
828+
* down the line.
829+
*/
830+
831+
display_runtime->num_sprites[PIPE_A] = 2;
832+
display_runtime->num_sprites[PIPE_B] = 2;
833+
display_runtime->num_sprites[PIPE_C] = 1;
834+
} else if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) {
835+
for_each_pipe(i915, pipe)
836+
display_runtime->num_sprites[pipe] = 2;
837+
} else if (DISPLAY_VER(i915) >= 5 || IS_G4X(i915)) {
838+
for_each_pipe(i915, pipe)
839+
display_runtime->num_sprites[pipe] = 1;
840+
}
841+
842+
if ((IS_DGFX(i915) || DISPLAY_VER(i915) >= 14) &&
843+
!(intel_de_read(i915, GU_CNTL_PROTECTED) & DEPRESENT)) {
844+
drm_info(&i915->drm, "Display not present, disabling\n");
845+
goto display_fused_off;
846+
}
847+
848+
if (IS_GRAPHICS_VER(i915, 7, 8) && HAS_PCH_SPLIT(i915)) {
849+
u32 fuse_strap = intel_de_read(i915, FUSE_STRAP);
850+
u32 sfuse_strap = intel_de_read(i915, SFUSE_STRAP);
851+
852+
/*
853+
* SFUSE_STRAP is supposed to have a bit signalling the display
854+
* is fused off. Unfortunately it seems that, at least in
855+
* certain cases, fused off display means that PCH display
856+
* reads don't land anywhere. In that case, we read 0s.
857+
*
858+
* On CPT/PPT, we can detect this case as SFUSE_STRAP_FUSE_LOCK
859+
* should be set when taking over after the firmware.
860+
*/
861+
if (fuse_strap & ILK_INTERNAL_DISPLAY_DISABLE ||
862+
sfuse_strap & SFUSE_STRAP_DISPLAY_DISABLED ||
863+
(HAS_PCH_CPT(i915) &&
864+
!(sfuse_strap & SFUSE_STRAP_FUSE_LOCK))) {
865+
drm_info(&i915->drm,
866+
"Display fused off, disabling\n");
867+
goto display_fused_off;
868+
} else if (fuse_strap & IVB_PIPE_C_DISABLE) {
869+
drm_info(&i915->drm, "PipeC fused off\n");
870+
display_runtime->pipe_mask &= ~BIT(PIPE_C);
871+
display_runtime->cpu_transcoder_mask &= ~BIT(TRANSCODER_C);
872+
}
873+
} else if (DISPLAY_VER(i915) >= 9) {
874+
u32 dfsm = intel_de_read(i915, SKL_DFSM);
875+
876+
if (dfsm & SKL_DFSM_PIPE_A_DISABLE) {
877+
display_runtime->pipe_mask &= ~BIT(PIPE_A);
878+
display_runtime->cpu_transcoder_mask &= ~BIT(TRANSCODER_A);
879+
display_runtime->fbc_mask &= ~BIT(INTEL_FBC_A);
880+
}
881+
if (dfsm & SKL_DFSM_PIPE_B_DISABLE) {
882+
display_runtime->pipe_mask &= ~BIT(PIPE_B);
883+
display_runtime->cpu_transcoder_mask &= ~BIT(TRANSCODER_B);
884+
}
885+
if (dfsm & SKL_DFSM_PIPE_C_DISABLE) {
886+
display_runtime->pipe_mask &= ~BIT(PIPE_C);
887+
display_runtime->cpu_transcoder_mask &= ~BIT(TRANSCODER_C);
888+
}
889+
890+
if (DISPLAY_VER(i915) >= 12 &&
891+
(dfsm & TGL_DFSM_PIPE_D_DISABLE)) {
892+
display_runtime->pipe_mask &= ~BIT(PIPE_D);
893+
display_runtime->cpu_transcoder_mask &= ~BIT(TRANSCODER_D);
894+
}
895+
896+
if (!display_runtime->pipe_mask)
897+
goto display_fused_off;
898+
899+
if (dfsm & SKL_DFSM_DISPLAY_HDCP_DISABLE)
900+
display_runtime->has_hdcp = 0;
901+
902+
if (dfsm & SKL_DFSM_DISPLAY_PM_DISABLE)
903+
display_runtime->fbc_mask = 0;
904+
905+
if (DISPLAY_VER(i915) >= 11 && (dfsm & ICL_DFSM_DMC_DISABLE))
906+
display_runtime->has_dmc = 0;
907+
908+
if (IS_DISPLAY_VER(i915, 10, 12) &&
909+
(dfsm & GLK_DFSM_DISPLAY_DSC_DISABLE))
910+
display_runtime->has_dsc = 0;
911+
}
912+
913+
return;
914+
915+
display_fused_off:
916+
memset(display_runtime, 0, sizeof(*display_runtime));
917+
}

drivers/gpu/drm/i915/display/intel_display_device.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,5 +124,6 @@ struct intel_display_device_info {
124124
const struct intel_display_device_info *
125125
intel_display_device_probe(struct drm_i915_private *i915, bool has_gmdid,
126126
u16 *ver, u16 *rel, u16 *step);
127+
void intel_display_device_info_runtime_init(struct drm_i915_private *i915);
127128

128129
#endif

drivers/gpu/drm/i915/intel_device_info.c

Lines changed: 13 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,7 @@
2727
#include <drm/drm_print.h>
2828
#include <drm/i915_pciids.h>
2929

30-
#include "display/intel_cdclk.h"
31-
#include "display/intel_de.h"
32-
#include "display/intel_display.h"
30+
#include "display/intel_display_device.h"
3331
#include "gt/intel_gt_regs.h"
3432
#include "i915_drv.h"
3533
#include "i915_reg.h"
@@ -411,125 +409,23 @@ void intel_device_info_runtime_init(struct drm_i915_private *dev_priv)
411409
{
412410
struct intel_device_info *info = mkwrite_device_info(dev_priv);
413411
struct intel_runtime_info *runtime = RUNTIME_INFO(dev_priv);
414-
struct intel_display_runtime_info *display_runtime =
415-
DISPLAY_RUNTIME_INFO(dev_priv);
416-
enum pipe pipe;
417-
418-
/* Wa_14011765242: adl-s A0,A1 */
419-
if (IS_ADLS_DISPLAY_STEP(dev_priv, STEP_A0, STEP_A2))
420-
for_each_pipe(dev_priv, pipe)
421-
display_runtime->num_scalers[pipe] = 0;
422-
else if (DISPLAY_VER(dev_priv) >= 11) {
423-
for_each_pipe(dev_priv, pipe)
424-
display_runtime->num_scalers[pipe] = 2;
425-
} else if (DISPLAY_VER(dev_priv) >= 9) {
426-
display_runtime->num_scalers[PIPE_A] = 2;
427-
display_runtime->num_scalers[PIPE_B] = 2;
428-
display_runtime->num_scalers[PIPE_C] = 1;
429-
}
430-
431-
BUILD_BUG_ON(BITS_PER_TYPE(intel_engine_mask_t) < I915_NUM_ENGINES);
432412

433-
if (DISPLAY_VER(dev_priv) >= 13 || HAS_D12_PLANE_MINIMIZATION(dev_priv))
434-
for_each_pipe(dev_priv, pipe)
435-
display_runtime->num_sprites[pipe] = 4;
436-
else if (DISPLAY_VER(dev_priv) >= 11)
437-
for_each_pipe(dev_priv, pipe)
438-
display_runtime->num_sprites[pipe] = 6;
439-
else if (DISPLAY_VER(dev_priv) == 10)
440-
for_each_pipe(dev_priv, pipe)
441-
display_runtime->num_sprites[pipe] = 3;
442-
else if (IS_BROXTON(dev_priv)) {
443-
/*
444-
* Skylake and Broxton currently don't expose the topmost plane as its
445-
* use is exclusive with the legacy cursor and we only want to expose
446-
* one of those, not both. Until we can safely expose the topmost plane
447-
* as a DRM_PLANE_TYPE_CURSOR with all the features exposed/supported,
448-
* we don't expose the topmost plane at all to prevent ABI breakage
449-
* down the line.
450-
*/
413+
if (HAS_DISPLAY(dev_priv))
414+
intel_display_device_info_runtime_init(dev_priv);
451415

452-
display_runtime->num_sprites[PIPE_A] = 2;
453-
display_runtime->num_sprites[PIPE_B] = 2;
454-
display_runtime->num_sprites[PIPE_C] = 1;
455-
} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
456-
for_each_pipe(dev_priv, pipe)
457-
display_runtime->num_sprites[pipe] = 2;
458-
} else if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv)) {
459-
for_each_pipe(dev_priv, pipe)
460-
display_runtime->num_sprites[pipe] = 1;
461-
}
462-
463-
if (HAS_DISPLAY(dev_priv) &&
464-
(IS_DGFX(dev_priv) || DISPLAY_VER(dev_priv) >= 14) &&
465-
!(intel_de_read(dev_priv, GU_CNTL_PROTECTED) & DEPRESENT)) {
466-
drm_info(&dev_priv->drm, "Display not present, disabling\n");
467-
468-
display_runtime->pipe_mask = 0;
416+
/* Display may have been disabled by runtime init */
417+
if (!HAS_DISPLAY(dev_priv)) {
418+
dev_priv->drm.driver_features &= ~(DRIVER_MODESET |
419+
DRIVER_ATOMIC);
420+
info->display = &no_display;
469421
}
470422

471-
if (HAS_DISPLAY(dev_priv) && IS_GRAPHICS_VER(dev_priv, 7, 8) &&
472-
HAS_PCH_SPLIT(dev_priv)) {
473-
u32 fuse_strap = intel_de_read(dev_priv, FUSE_STRAP);
474-
u32 sfuse_strap = intel_de_read(dev_priv, SFUSE_STRAP);
475-
476-
/*
477-
* SFUSE_STRAP is supposed to have a bit signalling the display
478-
* is fused off. Unfortunately it seems that, at least in
479-
* certain cases, fused off display means that PCH display
480-
* reads don't land anywhere. In that case, we read 0s.
481-
*
482-
* On CPT/PPT, we can detect this case as SFUSE_STRAP_FUSE_LOCK
483-
* should be set when taking over after the firmware.
484-
*/
485-
if (fuse_strap & ILK_INTERNAL_DISPLAY_DISABLE ||
486-
sfuse_strap & SFUSE_STRAP_DISPLAY_DISABLED ||
487-
(HAS_PCH_CPT(dev_priv) &&
488-
!(sfuse_strap & SFUSE_STRAP_FUSE_LOCK))) {
489-
drm_info(&dev_priv->drm,
490-
"Display fused off, disabling\n");
491-
display_runtime->pipe_mask = 0;
492-
} else if (fuse_strap & IVB_PIPE_C_DISABLE) {
493-
drm_info(&dev_priv->drm, "PipeC fused off\n");
494-
display_runtime->pipe_mask &= ~BIT(PIPE_C);
495-
display_runtime->cpu_transcoder_mask &= ~BIT(TRANSCODER_C);
496-
}
497-
} else if (HAS_DISPLAY(dev_priv) && DISPLAY_VER(dev_priv) >= 9) {
498-
u32 dfsm = intel_de_read(dev_priv, SKL_DFSM);
499-
500-
if (dfsm & SKL_DFSM_PIPE_A_DISABLE) {
501-
display_runtime->pipe_mask &= ~BIT(PIPE_A);
502-
display_runtime->cpu_transcoder_mask &= ~BIT(TRANSCODER_A);
503-
display_runtime->fbc_mask &= ~BIT(INTEL_FBC_A);
504-
}
505-
if (dfsm & SKL_DFSM_PIPE_B_DISABLE) {
506-
display_runtime->pipe_mask &= ~BIT(PIPE_B);
507-
display_runtime->cpu_transcoder_mask &= ~BIT(TRANSCODER_B);
508-
}
509-
if (dfsm & SKL_DFSM_PIPE_C_DISABLE) {
510-
display_runtime->pipe_mask &= ~BIT(PIPE_C);
511-
display_runtime->cpu_transcoder_mask &= ~BIT(TRANSCODER_C);
512-
}
513-
514-
if (DISPLAY_VER(dev_priv) >= 12 &&
515-
(dfsm & TGL_DFSM_PIPE_D_DISABLE)) {
516-
display_runtime->pipe_mask &= ~BIT(PIPE_D);
517-
display_runtime->cpu_transcoder_mask &= ~BIT(TRANSCODER_D);
518-
}
519-
520-
if (dfsm & SKL_DFSM_DISPLAY_HDCP_DISABLE)
521-
display_runtime->has_hdcp = 0;
522-
523-
if (dfsm & SKL_DFSM_DISPLAY_PM_DISABLE)
524-
display_runtime->fbc_mask = 0;
525-
526-
if (DISPLAY_VER(dev_priv) >= 11 && (dfsm & ICL_DFSM_DMC_DISABLE))
527-
display_runtime->has_dmc = 0;
423+
/* Disable nuclear pageflip by default on pre-g4x */
424+
if (!dev_priv->params.nuclear_pageflip &&
425+
DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv))
426+
dev_priv->drm.driver_features &= ~DRIVER_ATOMIC;
528427

529-
if (IS_DISPLAY_VER(dev_priv, 10, 12) &&
530-
(dfsm & GLK_DFSM_DISPLAY_DSC_DISABLE))
531-
display_runtime->has_dsc = 0;
532-
}
428+
BUILD_BUG_ON(BITS_PER_TYPE(intel_engine_mask_t) < I915_NUM_ENGINES);
533429

534430
if (GRAPHICS_VER(dev_priv) == 6 && i915_vtd_active(dev_priv)) {
535431
drm_info(&dev_priv->drm,
@@ -540,24 +436,6 @@ void intel_device_info_runtime_init(struct drm_i915_private *dev_priv)
540436
runtime->rawclk_freq = intel_read_rawclk(dev_priv);
541437
drm_dbg(&dev_priv->drm, "rawclk rate: %d kHz\n", runtime->rawclk_freq);
542438

543-
if (!HAS_DISPLAY(dev_priv)) {
544-
dev_priv->drm.driver_features &= ~(DRIVER_MODESET |
545-
DRIVER_ATOMIC);
546-
info->display = &no_display;
547-
548-
display_runtime->cpu_transcoder_mask = 0;
549-
memset(display_runtime->num_sprites, 0, sizeof(display_runtime->num_sprites));
550-
memset(display_runtime->num_scalers, 0, sizeof(display_runtime->num_scalers));
551-
display_runtime->fbc_mask = 0;
552-
display_runtime->has_hdcp = false;
553-
display_runtime->has_dmc = false;
554-
display_runtime->has_dsc = false;
555-
}
556-
557-
/* Disable nuclear pageflip by default on pre-g4x */
558-
if (!dev_priv->params.nuclear_pageflip &&
559-
DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv))
560-
dev_priv->drm.driver_features &= ~DRIVER_ATOMIC;
561439
}
562440

563441
/*

0 commit comments

Comments
 (0)