File Index
Files and directories
Sign in
FILE

intel_display_device.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/i915/display/intel_display_device.c C
   1// SPDX-License-Identifier: MIT
   2/*
   3 * Copyright © 2023 Intel Corporation
   4 */
   5
   6#include <linux/pci.h>
   7
   8#include <drm/drm_color_mgmt.h>
   9#include <drm/drm_drv.h>
  10#include <drm/drm_print.h>
  11#include <drm/intel/pciids.h>
  12
  13#include "i915_reg.h"
  14#include "intel_cx0_phy_regs.h"
  15#include "intel_de.h"
  16#include "intel_display.h"
  17#include "intel_display_device.h"
  18#include "intel_display_params.h"
  19#include "intel_display_power.h"
  20#include "intel_display_reg_defs.h"
  21#include "intel_display_regs.h"
  22#include "intel_display_types.h"
  23#include "intel_fbc.h"
  24#include "intel_step.h"
  25
  26__diag_push();
  27__diag_ignore_all("-Woverride-init", "Allow field initialization overrides for display info");
  28
  29struct stepping_desc {
  30	const enum intel_step *map; /* revid to step map */
  31	size_t size; /* map size */
  32};
  33
  34#define STEP_INFO(_map)				\
  35	.step_info.map = _map,			\
  36	.step_info.size = ARRAY_SIZE(_map)
  37
  38struct subplatform_desc {
  39	struct intel_display_platforms platforms;
  40	const char *name;
  41	const u16 *pciidlist;
  42	struct stepping_desc step_info;
  43};
  44
  45#define SUBPLATFORM(_platform, _subplatform)				\
  46	.platforms._platform##_##_subplatform = 1,			\
  47	.name = #_subplatform
  48
  49/*
  50 * Group subplatform alias that matches multiple subplatforms. For making ult
  51 * cover both ult and ulx on HSW/BDW.
  52 */
  53#define SUBPLATFORM_GROUP(_platform, _subplatform)			\
  54	.platforms._platform##_##_subplatform = 1
  55
  56struct platform_desc {
  57	struct intel_display_platforms platforms;
  58	const char *name;
  59	const struct subplatform_desc *subplatforms;
  60	const struct intel_display_device_info *info; /* NULL for GMD ID */
  61	struct stepping_desc step_info;
  62};
  63
  64#define PLATFORM(_platform)			 \
  65	.platforms._platform = 1,		 \
  66	.name = #_platform
  67
  68/*
  69 * Group platform alias that matches multiple platforms. For aliases such as g4x
  70 * that covers both g45 and gm45.
  71 */
  72#define PLATFORM_GROUP(_platform)		\
  73	.platforms._platform = 1
  74
  75#define ID(id) (id)
  76
  77static const struct intel_display_device_info no_display = {};
  78
  79#define PIPE_A_OFFSET		0x70000
  80#define PIPE_B_OFFSET		0x71000
  81#define PIPE_C_OFFSET		0x72000
  82#define PIPE_D_OFFSET		0x73000
  83#define CHV_PIPE_C_OFFSET	0x74000
  84/*
  85 * There's actually no pipe EDP. Some pipe registers have
  86 * simply shifted from the pipe to the transcoder, while
  87 * keeping their original offset. Thus we need PIPE_EDP_OFFSET
  88 * to access such registers in transcoder EDP.
  89 */
  90#define PIPE_EDP_OFFSET	0x7f000
  91
  92/* ICL DSI 0 and 1 */
  93#define PIPE_DSI0_OFFSET	0x7b000
  94#define PIPE_DSI1_OFFSET	0x7b800
  95
  96#define TRANSCODER_A_OFFSET 0x60000
  97#define TRANSCODER_B_OFFSET 0x61000
  98#define TRANSCODER_C_OFFSET 0x62000
  99#define CHV_TRANSCODER_C_OFFSET 0x63000
 100#define TRANSCODER_D_OFFSET 0x63000
 101#define TRANSCODER_EDP_OFFSET 0x6f000
 102#define TRANSCODER_DSI0_OFFSET	0x6b000
 103#define TRANSCODER_DSI1_OFFSET	0x6b800
 104
 105#define CURSOR_A_OFFSET 0x70080
 106#define CURSOR_B_OFFSET 0x700c0
 107#define CHV_CURSOR_C_OFFSET 0x700e0
 108#define IVB_CURSOR_B_OFFSET 0x71080
 109#define IVB_CURSOR_C_OFFSET 0x72080
 110#define TGL_CURSOR_D_OFFSET 0x73080
 111
 112#define I845_PIPE_OFFSETS \
 113	.pipe_offsets = { \
 114		[TRANSCODER_A] = PIPE_A_OFFSET,	\
 115	}, \
 116	.trans_offsets = { \
 117		[TRANSCODER_A] = TRANSCODER_A_OFFSET, \
 118	}
 119
 120#define I9XX_PIPE_OFFSETS \
 121	.pipe_offsets = { \
 122		[TRANSCODER_A] = PIPE_A_OFFSET,	\
 123		[TRANSCODER_B] = PIPE_B_OFFSET, \
 124	}, \
 125	.trans_offsets = { \
 126		[TRANSCODER_A] = TRANSCODER_A_OFFSET, \
 127		[TRANSCODER_B] = TRANSCODER_B_OFFSET, \
 128	}
 129
 130#define IVB_PIPE_OFFSETS \
 131	.pipe_offsets = { \
 132		[TRANSCODER_A] = PIPE_A_OFFSET,	\
 133		[TRANSCODER_B] = PIPE_B_OFFSET, \
 134		[TRANSCODER_C] = PIPE_C_OFFSET, \
 135	}, \
 136	.trans_offsets = { \
 137		[TRANSCODER_A] = TRANSCODER_A_OFFSET, \
 138		[TRANSCODER_B] = TRANSCODER_B_OFFSET, \
 139		[TRANSCODER_C] = TRANSCODER_C_OFFSET, \
 140	}
 141
 142#define HSW_PIPE_OFFSETS \
 143	.pipe_offsets = { \
 144		[TRANSCODER_A] = PIPE_A_OFFSET,	\
 145		[TRANSCODER_B] = PIPE_B_OFFSET, \
 146		[TRANSCODER_C] = PIPE_C_OFFSET, \
 147		[TRANSCODER_EDP] = PIPE_EDP_OFFSET, \
 148	}, \
 149	.trans_offsets = { \
 150		[TRANSCODER_A] = TRANSCODER_A_OFFSET, \
 151		[TRANSCODER_B] = TRANSCODER_B_OFFSET, \
 152		[TRANSCODER_C] = TRANSCODER_C_OFFSET, \
 153		[TRANSCODER_EDP] = TRANSCODER_EDP_OFFSET, \
 154	}
 155
 156#define CHV_PIPE_OFFSETS \
 157	.pipe_offsets = { \
 158		[TRANSCODER_A] = PIPE_A_OFFSET, \
 159		[TRANSCODER_B] = PIPE_B_OFFSET, \
 160		[TRANSCODER_C] = CHV_PIPE_C_OFFSET, \
 161	}, \
 162	.trans_offsets = { \
 163		[TRANSCODER_A] = TRANSCODER_A_OFFSET, \
 164		[TRANSCODER_B] = TRANSCODER_B_OFFSET, \
 165		[TRANSCODER_C] = CHV_TRANSCODER_C_OFFSET, \
 166	}
 167
 168#define I845_CURSOR_OFFSETS \
 169	.cursor_offsets = { \
 170		[PIPE_A] = CURSOR_A_OFFSET, \
 171	}
 172
 173#define I9XX_CURSOR_OFFSETS \
 174	.cursor_offsets = { \
 175		[PIPE_A] = CURSOR_A_OFFSET, \
 176		[PIPE_B] = CURSOR_B_OFFSET, \
 177	}
 178
 179#define CHV_CURSOR_OFFSETS \
 180	.cursor_offsets = { \
 181		[PIPE_A] = CURSOR_A_OFFSET, \
 182		[PIPE_B] = CURSOR_B_OFFSET, \
 183		[PIPE_C] = CHV_CURSOR_C_OFFSET, \
 184	}
 185
 186#define IVB_CURSOR_OFFSETS \
 187	.cursor_offsets = { \
 188		[PIPE_A] = CURSOR_A_OFFSET, \
 189		[PIPE_B] = IVB_CURSOR_B_OFFSET, \
 190		[PIPE_C] = IVB_CURSOR_C_OFFSET, \
 191	}
 192
 193#define TGL_CURSOR_OFFSETS \
 194	.cursor_offsets = { \
 195		[PIPE_A] = CURSOR_A_OFFSET, \
 196		[PIPE_B] = IVB_CURSOR_B_OFFSET, \
 197		[PIPE_C] = IVB_CURSOR_C_OFFSET, \
 198		[PIPE_D] = TGL_CURSOR_D_OFFSET, \
 199	}
 200
 201#define I845_COLORS \
 202	.color = { .gamma_lut_size = 256 }
 203#define I9XX_COLORS \
 204	.color = { .gamma_lut_size = 129, \
 205		   .gamma_lut_tests = DRM_COLOR_LUT_NON_DECREASING, \
 206	}
 207#define ILK_COLORS \
 208	.color = { .gamma_lut_size = 1024 }
 209#define IVB_COLORS \
 210	.color = { .degamma_lut_size = 1024, .gamma_lut_size = 1024 }
 211#define CHV_COLORS \
 212	.color = { \
 213		.degamma_lut_size = 65, .gamma_lut_size = 257, \
 214		.degamma_lut_tests = DRM_COLOR_LUT_NON_DECREASING, \
 215		.gamma_lut_tests = DRM_COLOR_LUT_NON_DECREASING, \
 216	}
 217#define GLK_COLORS \
 218	.color = { \
 219		.degamma_lut_size = 33, .gamma_lut_size = 1024, \
 220		.degamma_lut_tests = DRM_COLOR_LUT_NON_DECREASING | \
 221				     DRM_COLOR_LUT_EQUAL_CHANNELS, \
 222	}
 223#define ICL_COLORS \
 224	.color = { \
 225		.degamma_lut_size = 33, .gamma_lut_size = 262145, \
 226		.degamma_lut_tests = DRM_COLOR_LUT_NON_DECREASING | \
 227				     DRM_COLOR_LUT_EQUAL_CHANNELS, \
 228		.gamma_lut_tests = DRM_COLOR_LUT_NON_DECREASING, \
 229	}
 230
 231#define I830_DISPLAY \
 232	.has_overlay = 1, \
 233	.cursor_needs_physical = 1, \
 234	.overlay_needs_physical = 1, \
 235	.has_gmch = 1, \
 236	I9XX_PIPE_OFFSETS, \
 237	I9XX_CURSOR_OFFSETS, \
 238	I9XX_COLORS, \
 239	\
 240	.__runtime_defaults.ip.ver = 2, \
 241	.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \
 242	.__runtime_defaults.cpu_transcoder_mask = \
 243		BIT(TRANSCODER_A) | BIT(TRANSCODER_B)
 244
 245#define I845_DISPLAY \
 246	.has_overlay = 1, \
 247	.overlay_needs_physical = 1, \
 248	.has_gmch = 1, \
 249	I845_PIPE_OFFSETS, \
 250	I845_CURSOR_OFFSETS, \
 251	I845_COLORS, \
 252	\
 253	.__runtime_defaults.ip.ver = 2, \
 254	.__runtime_defaults.pipe_mask = BIT(PIPE_A), \
 255	.__runtime_defaults.cpu_transcoder_mask = BIT(TRANSCODER_A)
 256
 257static const struct platform_desc i830_desc = {
 258	PLATFORM(i830),
 259	PLATFORM_GROUP(mobile),
 260	.info = &(const struct intel_display_device_info) {
 261		I830_DISPLAY,
 262
 263		.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C), /* DVO A/B/C */
 264	},
 265};
 266
 267static const struct platform_desc i845_desc = {
 268	PLATFORM(i845g),
 269	.info = &(const struct intel_display_device_info) {
 270		I845_DISPLAY,
 271
 272		.__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* DVO B/C */
 273	},
 274};
 275
 276static const struct platform_desc i85x_desc = {
 277	PLATFORM(i85x),
 278	PLATFORM_GROUP(mobile),
 279	.info = &(const struct intel_display_device_info) {
 280		I830_DISPLAY,
 281
 282		.__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* DVO B/C */
 283		.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
 284	},
 285};
 286
 287static const struct platform_desc i865g_desc = {
 288	PLATFORM(i865g),
 289	.info = &(const struct intel_display_device_info) {
 290		I845_DISPLAY,
 291
 292		.__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* DVO B/C */
 293		.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
 294	},
 295};
 296
 297#define GEN3_DISPLAY   \
 298	.has_gmch = 1, \
 299	.has_overlay = 1, \
 300	I9XX_PIPE_OFFSETS, \
 301	I9XX_CURSOR_OFFSETS, \
 302	\
 303	.__runtime_defaults.ip.ver = 3, \
 304	.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \
 305	.__runtime_defaults.cpu_transcoder_mask = \
 306		BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \
 307	.__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C) /* SDVO B/C */
 308
 309static const struct platform_desc i915g_desc = {
 310	PLATFORM(i915g),
 311	.info = &(const struct intel_display_device_info) {
 312		GEN3_DISPLAY,
 313		I845_COLORS,
 314		.cursor_needs_physical = 1,
 315		.overlay_needs_physical = 1,
 316	},
 317};
 318
 319static const struct platform_desc i915gm_desc = {
 320	PLATFORM(i915gm),
 321	PLATFORM_GROUP(mobile),
 322	.info = &(const struct intel_display_device_info) {
 323		GEN3_DISPLAY,
 324		I9XX_COLORS,
 325		.cursor_needs_physical = 1,
 326		.overlay_needs_physical = 1,
 327		.supports_tv = 1,
 328
 329		.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
 330	},
 331};
 332
 333static const struct platform_desc i945g_desc = {
 334	PLATFORM(i945g),
 335	.info = &(const struct intel_display_device_info) {
 336		GEN3_DISPLAY,
 337		I845_COLORS,
 338		.has_hotplug = 1,
 339		.cursor_needs_physical = 1,
 340		.overlay_needs_physical = 1,
 341	},
 342};
 343
 344static const struct platform_desc i945gm_desc = {
 345	PLATFORM(i915gm),
 346	PLATFORM_GROUP(mobile),
 347	.info = &(const struct intel_display_device_info) {
 348		GEN3_DISPLAY,
 349		I9XX_COLORS,
 350		.has_hotplug = 1,
 351		.cursor_needs_physical = 1,
 352		.overlay_needs_physical = 1,
 353		.supports_tv = 1,
 354
 355		.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
 356	},
 357};
 358
 359static const struct platform_desc g33_desc = {
 360	PLATFORM(g33),
 361	.info = &(const struct intel_display_device_info) {
 362		GEN3_DISPLAY,
 363		I845_COLORS,
 364		.has_hotplug = 1,
 365	},
 366};
 367
 368static const struct intel_display_device_info pnv_display = {
 369	GEN3_DISPLAY,
 370	I9XX_COLORS,
 371	.has_hotplug = 1,
 372};
 373
 374static const struct platform_desc pnv_g_desc = {
 375	PLATFORM(pineview),
 376	.info = &pnv_display,
 377};
 378
 379static const struct platform_desc pnv_m_desc = {
 380	PLATFORM(pineview),
 381	PLATFORM_GROUP(mobile),
 382	.info = &pnv_display,
 383};
 384
 385#define GEN4_DISPLAY \
 386	.has_hotplug = 1, \
 387	.has_gmch = 1, \
 388	I9XX_PIPE_OFFSETS, \
 389	I9XX_CURSOR_OFFSETS, \
 390	I9XX_COLORS, \
 391	\
 392	.__runtime_defaults.ip.ver = 4, \
 393	.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \
 394	.__runtime_defaults.cpu_transcoder_mask = \
 395		BIT(TRANSCODER_A) | BIT(TRANSCODER_B)
 396
 397static const struct platform_desc i965g_desc = {
 398	PLATFORM(i965g),
 399	.info = &(const struct intel_display_device_info) {
 400		GEN4_DISPLAY,
 401		.has_overlay = 1,
 402
 403		.__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* SDVO B/C */
 404	},
 405};
 406
 407static const struct platform_desc i965gm_desc = {
 408	PLATFORM(i965gm),
 409	PLATFORM_GROUP(mobile),
 410	.info = &(const struct intel_display_device_info) {
 411		GEN4_DISPLAY,
 412		.has_overlay = 1,
 413		.supports_tv = 1,
 414
 415		.__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* SDVO B/C */
 416		.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
 417	},
 418};
 419
 420static const struct platform_desc g45_desc = {
 421	PLATFORM(g45),
 422	PLATFORM_GROUP(g4x),
 423	.info = &(const struct intel_display_device_info) {
 424		GEN4_DISPLAY,
 425
 426		.__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* SDVO/HDMI/DP B/C, DP D */
 427	},
 428};
 429
 430static const struct platform_desc gm45_desc = {
 431	PLATFORM(gm45),
 432	PLATFORM_GROUP(g4x),
 433	PLATFORM_GROUP(mobile),
 434	.info = &(const struct intel_display_device_info) {
 435		GEN4_DISPLAY,
 436		.supports_tv = 1,
 437
 438		.__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* SDVO/HDMI/DP B/C, DP D */
 439		.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
 440	},
 441};
 442
 443#define ILK_DISPLAY \
 444	.has_hotplug = 1, \
 445	I9XX_PIPE_OFFSETS, \
 446	I9XX_CURSOR_OFFSETS, \
 447	ILK_COLORS, \
 448	\
 449	.__runtime_defaults.ip.ver = 5, \
 450	.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \
 451	.__runtime_defaults.cpu_transcoder_mask = \
 452		BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \
 453	.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D) /* DP A, SDVO/HDMI/DP B, HDMI/DP C/D */
 454
 455static const struct platform_desc ilk_d_desc = {
 456	PLATFORM(ironlake),
 457	.info = &(const struct intel_display_device_info) {
 458		ILK_DISPLAY,
 459	},
 460};
 461
 462static const struct platform_desc ilk_m_desc = {
 463	PLATFORM(ironlake),
 464	PLATFORM_GROUP(mobile),
 465	.info = &(const struct intel_display_device_info) {
 466		ILK_DISPLAY,
 467
 468		.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
 469	},
 470};
 471
 472static const struct intel_display_device_info snb_display = {
 473	.has_hotplug = 1,
 474	I9XX_PIPE_OFFSETS,
 475	I9XX_CURSOR_OFFSETS,
 476	ILK_COLORS,
 477
 478	.__runtime_defaults.ip.ver = 6,
 479	.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B),
 480	.__runtime_defaults.cpu_transcoder_mask =
 481	BIT(TRANSCODER_A) | BIT(TRANSCODER_B),
 482	.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* DP A, SDVO/HDMI/DP B, HDMI/DP C/D */
 483	.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
 484};
 485
 486static const struct platform_desc snb_d_desc = {
 487	PLATFORM(sandybridge),
 488	.info = &snb_display,
 489};
 490
 491static const struct platform_desc snb_m_desc = {
 492	PLATFORM(sandybridge),
 493	PLATFORM_GROUP(mobile),
 494	.info = &snb_display,
 495};
 496
 497static const struct intel_display_device_info ivb_display = {
 498	.has_hotplug = 1,
 499	IVB_PIPE_OFFSETS,
 500	IVB_CURSOR_OFFSETS,
 501	IVB_COLORS,
 502
 503	.__runtime_defaults.ip.ver = 7,
 504	.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
 505	.__runtime_defaults.cpu_transcoder_mask =
 506	BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C),
 507	.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* DP A, SDVO/HDMI/DP B, HDMI/DP C/D */
 508	.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
 509};
 510
 511static const struct platform_desc ivb_d_desc = {
 512	PLATFORM(ivybridge),
 513	.info = &ivb_display,
 514};
 515
 516static const struct platform_desc ivb_m_desc = {
 517	PLATFORM(ivybridge),
 518	PLATFORM_GROUP(mobile),
 519	.info = &ivb_display,
 520};
 521
 522static const struct platform_desc vlv_desc = {
 523	PLATFORM(valleyview),
 524	.info = &(const struct intel_display_device_info) {
 525		.has_gmch = 1,
 526		.has_hotplug = 1,
 527		.mmio_offset = VLV_DISPLAY_BASE,
 528		I9XX_PIPE_OFFSETS,
 529		I9XX_CURSOR_OFFSETS,
 530		I9XX_COLORS,
 531
 532		.__runtime_defaults.ip.ver = 7,
 533		.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B),
 534		.__runtime_defaults.cpu_transcoder_mask =
 535		BIT(TRANSCODER_A) | BIT(TRANSCODER_B),
 536		.__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* HDMI/DP B/C */
 537	},
 538};
 539
 540static const u16 hsw_ult_ids[] = {
 541	INTEL_HSW_ULT_GT1_IDS(ID),
 542	INTEL_HSW_ULT_GT2_IDS(ID),
 543	INTEL_HSW_ULT_GT3_IDS(ID),
 544	0
 545};
 546
 547static const u16 hsw_ulx_ids[] = {
 548	INTEL_HSW_ULX_GT1_IDS(ID),
 549	INTEL_HSW_ULX_GT2_IDS(ID),
 550	0
 551};
 552
 553static const struct platform_desc hsw_desc = {
 554	PLATFORM(haswell),
 555	.subplatforms = (const struct subplatform_desc[]) {
 556		/* Special case: Use ult both as group and subplatform. */
 557		{
 558			SUBPLATFORM(haswell, ult),
 559			SUBPLATFORM_GROUP(haswell, ult),
 560			.pciidlist = hsw_ult_ids,
 561		},
 562		{
 563			SUBPLATFORM(haswell, ulx),
 564			SUBPLATFORM_GROUP(haswell, ult),
 565			.pciidlist = hsw_ulx_ids,
 566		},
 567		{},
 568	},
 569	.info = &(const struct intel_display_device_info) {
 570		.has_ddi = 1,
 571		.has_dp_mst = 1,
 572		.has_fpga_dbg = 1,
 573		.has_hotplug = 1,
 574		.has_psr = 1,
 575		.has_psr_hw_tracking = 1,
 576		HSW_PIPE_OFFSETS,
 577		IVB_CURSOR_OFFSETS,
 578		IVB_COLORS,
 579
 580		.__runtime_defaults.ip.ver = 7,
 581		.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
 582		.__runtime_defaults.cpu_transcoder_mask =
 583		BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
 584		BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP),
 585		.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D) | BIT(PORT_E),
 586		.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
 587	},
 588};
 589
 590static const u16 bdw_ult_ids[] = {
 591	INTEL_BDW_ULT_GT1_IDS(ID),
 592	INTEL_BDW_ULT_GT2_IDS(ID),
 593	INTEL_BDW_ULT_GT3_IDS(ID),
 594	INTEL_BDW_ULT_RSVD_IDS(ID),
 595	0
 596};
 597
 598static const u16 bdw_ulx_ids[] = {
 599	INTEL_BDW_ULX_GT1_IDS(ID),
 600	INTEL_BDW_ULX_GT2_IDS(ID),
 601	INTEL_BDW_ULX_GT3_IDS(ID),
 602	INTEL_BDW_ULX_RSVD_IDS(ID),
 603	0
 604};
 605
 606static const struct platform_desc bdw_desc = {
 607	PLATFORM(broadwell),
 608	.subplatforms = (const struct subplatform_desc[]) {
 609		/* Special case: Use ult both as group and subplatform. */
 610		{
 611			SUBPLATFORM(broadwell, ult),
 612			SUBPLATFORM_GROUP(broadwell, ult),
 613			.pciidlist = bdw_ult_ids,
 614		},
 615		{
 616			SUBPLATFORM(broadwell, ulx),
 617			SUBPLATFORM_GROUP(broadwell, ult),
 618			.pciidlist = bdw_ulx_ids,
 619		},
 620		{},
 621	},
 622	.info = &(const struct intel_display_device_info) {
 623		.has_ddi = 1,
 624		.has_dp_mst = 1,
 625		.has_fpga_dbg = 1,
 626		.has_hotplug = 1,
 627		.has_psr = 1,
 628		.has_psr_hw_tracking = 1,
 629		HSW_PIPE_OFFSETS,
 630		IVB_CURSOR_OFFSETS,
 631		IVB_COLORS,
 632
 633		.__runtime_defaults.ip.ver = 8,
 634		.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
 635		.__runtime_defaults.cpu_transcoder_mask =
 636		BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
 637		BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP),
 638		.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D) | BIT(PORT_E),
 639		.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
 640	},
 641};
 642
 643static const struct platform_desc chv_desc = {
 644	PLATFORM(cherryview),
 645	.info = &(const struct intel_display_device_info) {
 646		.has_hotplug = 1,
 647		.has_gmch = 1,
 648		.mmio_offset = VLV_DISPLAY_BASE,
 649		CHV_PIPE_OFFSETS,
 650		CHV_CURSOR_OFFSETS,
 651		CHV_COLORS,
 652
 653		.__runtime_defaults.ip.ver = 8,
 654		.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
 655		.__runtime_defaults.cpu_transcoder_mask =
 656		BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C),
 657		.__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* HDMI/DP B/C/D */
 658	},
 659};
 660
 661static const struct intel_display_device_info skl_display = {
 662	.dbuf.size = 896 - 4, /* 4 blocks for bypass path allocation */
 663	.dbuf.slice_mask = BIT(DBUF_S1),
 664	.has_ddi = 1,
 665	.has_dp_mst = 1,
 666	.has_fpga_dbg = 1,
 667	.has_hotplug = 1,
 668	.has_ipc = 1,
 669	.has_psr = 1,
 670	.has_psr_hw_tracking = 1,
 671	HSW_PIPE_OFFSETS,
 672	IVB_CURSOR_OFFSETS,
 673	IVB_COLORS,
 674
 675	.__runtime_defaults.ip.ver = 9,
 676	.__runtime_defaults.has_dmc = 1,
 677	.__runtime_defaults.has_hdcp = 1,
 678	.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
 679	.__runtime_defaults.cpu_transcoder_mask =
 680	BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
 681	BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP),
 682	.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D) | BIT(PORT_E),
 683	.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
 684};
 685
 686static const u16 skl_ult_ids[] = {
 687	INTEL_SKL_ULT_GT1_IDS(ID),
 688	INTEL_SKL_ULT_GT2_IDS(ID),
 689	INTEL_SKL_ULT_GT3_IDS(ID),
 690	0
 691};
 692
 693static const u16 skl_ulx_ids[] = {
 694	INTEL_SKL_ULX_GT1_IDS(ID),
 695	INTEL_SKL_ULX_GT2_IDS(ID),
 696	0
 697};
 698
 699static const enum intel_step skl_steppings[] = {
 700	[0x6] = STEP_G0,
 701	[0x7] = STEP_H0,
 702	[0x9] = STEP_J0,
 703	[0xA] = STEP_I1,
 704};
 705
 706static const struct platform_desc skl_desc = {
 707	PLATFORM(skylake),
 708	.subplatforms = (const struct subplatform_desc[]) {
 709		{
 710			SUBPLATFORM(skylake, ult),
 711			.pciidlist = skl_ult_ids,
 712		},
 713		{
 714			SUBPLATFORM(skylake, ulx),
 715			.pciidlist = skl_ulx_ids,
 716		},
 717		{},
 718	},
 719	.info = &skl_display,
 720	STEP_INFO(skl_steppings),
 721};
 722
 723static const u16 kbl_ult_ids[] = {
 724	INTEL_KBL_ULT_GT1_IDS(ID),
 725	INTEL_KBL_ULT_GT2_IDS(ID),
 726	INTEL_KBL_ULT_GT3_IDS(ID),
 727	0
 728};
 729
 730static const u16 kbl_ulx_ids[] = {
 731	INTEL_KBL_ULX_GT1_IDS(ID),
 732	INTEL_KBL_ULX_GT2_IDS(ID),
 733	INTEL_AML_KBL_GT2_IDS(ID),
 734	0
 735};
 736
 737static const enum intel_step kbl_steppings[] = {
 738	[1] = STEP_B0,
 739	[2] = STEP_B0,
 740	[3] = STEP_B0,
 741	[4] = STEP_C0,
 742	[5] = STEP_B1,
 743	[6] = STEP_B1,
 744	[7] = STEP_C0,
 745};
 746
 747static const struct platform_desc kbl_desc = {
 748	PLATFORM(kabylake),
 749	.subplatforms = (const struct subplatform_desc[]) {
 750		{
 751			SUBPLATFORM(kabylake, ult),
 752			.pciidlist = kbl_ult_ids,
 753		},
 754		{
 755			SUBPLATFORM(kabylake, ulx),
 756			.pciidlist = kbl_ulx_ids,
 757		},
 758		{},
 759	},
 760	.info = &skl_display,
 761	STEP_INFO(kbl_steppings),
 762};
 763
 764static const u16 cfl_ult_ids[] = {
 765	INTEL_CFL_U_GT2_IDS(ID),
 766	INTEL_CFL_U_GT3_IDS(ID),
 767	INTEL_WHL_U_GT1_IDS(ID),
 768	INTEL_WHL_U_GT2_IDS(ID),
 769	INTEL_WHL_U_GT3_IDS(ID),
 770	0
 771};
 772
 773static const u16 cfl_ulx_ids[] = {
 774	INTEL_AML_CFL_GT2_IDS(ID),
 775	0
 776};
 777
 778static const struct platform_desc cfl_desc = {
 779	PLATFORM(coffeelake),
 780	.subplatforms = (const struct subplatform_desc[]) {
 781		{
 782			SUBPLATFORM(coffeelake, ult),
 783			.pciidlist = cfl_ult_ids,
 784		},
 785		{
 786			SUBPLATFORM(coffeelake, ulx),
 787			.pciidlist = cfl_ulx_ids,
 788		},
 789		{},
 790	},
 791	.info = &skl_display,
 792};
 793
 794static const u16 cml_ult_ids[] = {
 795	INTEL_CML_U_GT1_IDS(ID),
 796	INTEL_CML_U_GT2_IDS(ID),
 797	0
 798};
 799
 800static const struct platform_desc cml_desc = {
 801	PLATFORM(cometlake),
 802	.subplatforms = (const struct subplatform_desc[]) {
 803		{
 804			SUBPLATFORM(cometlake, ult),
 805			.pciidlist = cml_ult_ids,
 806		},
 807		{},
 808	},
 809	.info = &skl_display,
 810};
 811
 812#define GEN9_LP_DISPLAY			 \
 813	.dbuf.slice_mask = BIT(DBUF_S1), \
 814	.has_dp_mst = 1, \
 815	.has_ddi = 1, \
 816	.has_fpga_dbg = 1, \
 817	.has_hotplug = 1, \
 818	.has_ipc = 1, \
 819	.has_psr = 1, \
 820	.has_psr_hw_tracking = 1, \
 821	HSW_PIPE_OFFSETS, \
 822	IVB_CURSOR_OFFSETS, \
 823	IVB_COLORS, \
 824	\
 825	.__runtime_defaults.has_dmc = 1, \
 826	.__runtime_defaults.has_hdcp = 1, \
 827	.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A), \
 828	.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C), \
 829	.__runtime_defaults.cpu_transcoder_mask = \
 830		BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | \
 831		BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP) | \
 832		BIT(TRANSCODER_DSI_A) | BIT(TRANSCODER_DSI_C), \
 833	.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C)
 834
 835static const enum intel_step bxt_steppings[] = {
 836	[0xA] = STEP_C0,
 837	[0xB] = STEP_C0,
 838	[0xC] = STEP_D0,
 839	[0xD] = STEP_E0,
 840};
 841
 842static const struct platform_desc bxt_desc = {
 843	PLATFORM(broxton),
 844	.info = &(const struct intel_display_device_info) {
 845		GEN9_LP_DISPLAY,
 846		.dbuf.size = 512 - 4, /* 4 blocks for bypass path allocation */
 847
 848		.__runtime_defaults.ip.ver = 9,
 849	},
 850	STEP_INFO(bxt_steppings),
 851};
 852
 853static const enum intel_step glk_steppings[] = {
 854	[3] = STEP_B0,
 855};
 856
 857static const struct platform_desc glk_desc = {
 858	PLATFORM(geminilake),
 859	.info = &(const struct intel_display_device_info) {
 860		GEN9_LP_DISPLAY,
 861		.dbuf.size = 1024 - 4, /* 4 blocks for bypass path allocation */
 862		GLK_COLORS,
 863
 864		.__runtime_defaults.ip.ver = 10,
 865	},
 866	STEP_INFO(glk_steppings),
 867};
 868
 869#define ICL_DISPLAY \
 870	.abox_mask = BIT(0), \
 871	.dbuf.size = 2048, \
 872	.dbuf.slice_mask = BIT(DBUF_S1) | BIT(DBUF_S2), \
 873	.has_ddi = 1, \
 874	.has_dp_mst = 1, \
 875	.has_fpga_dbg = 1, \
 876	.has_hotplug = 1, \
 877	.has_ipc = 1, \
 878	.has_psr = 1, \
 879	.has_psr_hw_tracking = 1, \
 880	.pipe_offsets = { \
 881		[TRANSCODER_A] = PIPE_A_OFFSET, \
 882		[TRANSCODER_B] = PIPE_B_OFFSET, \
 883		[TRANSCODER_C] = PIPE_C_OFFSET, \
 884		[TRANSCODER_EDP] = PIPE_EDP_OFFSET, \
 885		[TRANSCODER_DSI_0] = PIPE_DSI0_OFFSET, \
 886		[TRANSCODER_DSI_1] = PIPE_DSI1_OFFSET, \
 887	}, \
 888	.trans_offsets = { \
 889		[TRANSCODER_A] = TRANSCODER_A_OFFSET, \
 890		[TRANSCODER_B] = TRANSCODER_B_OFFSET, \
 891		[TRANSCODER_C] = TRANSCODER_C_OFFSET, \
 892		[TRANSCODER_EDP] = TRANSCODER_EDP_OFFSET, \
 893		[TRANSCODER_DSI_0] = TRANSCODER_DSI0_OFFSET, \
 894		[TRANSCODER_DSI_1] = TRANSCODER_DSI1_OFFSET, \
 895	}, \
 896	IVB_CURSOR_OFFSETS, \
 897	ICL_COLORS, \
 898	\
 899	.__runtime_defaults.ip.ver = 11, \
 900	.__runtime_defaults.has_dmc = 1, \
 901	.__runtime_defaults.has_dsc = 1, \
 902	.__runtime_defaults.has_hdcp = 1, \
 903	.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C), \
 904	.__runtime_defaults.cpu_transcoder_mask = \
 905		BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | \
 906		BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP) | \
 907		BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1), \
 908	.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A)
 909
 910static const u16 icl_port_f_ids[] = {
 911	INTEL_ICL_PORT_F_IDS(ID),
 912	0
 913};
 914
 915static const enum intel_step icl_steppings[] = {
 916	[7] = STEP_D0,
 917};
 918
 919static const struct platform_desc icl_desc = {
 920	PLATFORM(icelake),
 921	.subplatforms = (const struct subplatform_desc[]) {
 922		{
 923			SUBPLATFORM(icelake, port_f),
 924			.pciidlist = icl_port_f_ids,
 925		},
 926		{},
 927	},
 928	.info = &(const struct intel_display_device_info) {
 929		ICL_DISPLAY,
 930
 931		.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D) | BIT(PORT_E),
 932	},
 933	STEP_INFO(icl_steppings),
 934};
 935
 936static const struct intel_display_device_info jsl_ehl_display = {
 937	ICL_DISPLAY,
 938
 939	.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D),
 940};
 941
 942static const enum intel_step jsl_ehl_steppings[] = {
 943	[0] = STEP_A0,
 944	[1] = STEP_B0,
 945};
 946
 947static const struct platform_desc jsl_desc = {
 948	PLATFORM(jasperlake),
 949	.info = &jsl_ehl_display,
 950	STEP_INFO(jsl_ehl_steppings),
 951};
 952
 953static const struct platform_desc ehl_desc = {
 954	PLATFORM(elkhartlake),
 955	.info = &jsl_ehl_display,
 956	STEP_INFO(jsl_ehl_steppings),
 957};
 958
 959#define XE_D_DISPLAY \
 960	.abox_mask = GENMASK(2, 1), \
 961	.dbuf.size = 2048, \
 962	.dbuf.slice_mask = BIT(DBUF_S1) | BIT(DBUF_S2), \
 963	.has_ddi = 1, \
 964	.has_dp_mst = 1, \
 965	.has_dsb = 1, \
 966	.has_fpga_dbg = 1, \
 967	.has_hotplug = 1, \
 968	.has_ipc = 1, \
 969	.has_psr = 1, \
 970	.has_psr_hw_tracking = 1, \
 971	.pipe_offsets = { \
 972		[TRANSCODER_A] = PIPE_A_OFFSET, \
 973		[TRANSCODER_B] = PIPE_B_OFFSET, \
 974		[TRANSCODER_C] = PIPE_C_OFFSET, \
 975		[TRANSCODER_D] = PIPE_D_OFFSET, \
 976		[TRANSCODER_DSI_0] = PIPE_DSI0_OFFSET, \
 977		[TRANSCODER_DSI_1] = PIPE_DSI1_OFFSET, \
 978	}, \
 979	.trans_offsets = { \
 980		[TRANSCODER_A] = TRANSCODER_A_OFFSET, \
 981		[TRANSCODER_B] = TRANSCODER_B_OFFSET, \
 982		[TRANSCODER_C] = TRANSCODER_C_OFFSET, \
 983		[TRANSCODER_D] = TRANSCODER_D_OFFSET, \
 984		[TRANSCODER_DSI_0] = TRANSCODER_DSI0_OFFSET, \
 985		[TRANSCODER_DSI_1] = TRANSCODER_DSI1_OFFSET, \
 986	}, \
 987	TGL_CURSOR_OFFSETS, \
 988	ICL_COLORS, \
 989	\
 990	.__runtime_defaults.ip.ver = 12, \
 991	.__runtime_defaults.has_dmc = 1, \
 992	.__runtime_defaults.has_dsc = 1, \
 993	.__runtime_defaults.has_hdcp = 1, \
 994	.__runtime_defaults.pipe_mask = \
 995		BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D), \
 996	.__runtime_defaults.cpu_transcoder_mask = \
 997		BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | \
 998		BIT(TRANSCODER_C) | BIT(TRANSCODER_D) | \
 999		BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1), \
1000	.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A)
1001
1002static const u16 tgl_uy_ids[] = {
1003	INTEL_TGL_GT2_IDS(ID),
1004	0
1005};
1006
1007static const enum intel_step tgl_steppings[] = {
1008	[0] = STEP_B0,
1009	[1] = STEP_D0,
1010};
1011
1012static const enum intel_step tgl_uy_steppings[] = {
1013	[0] = STEP_A0,
1014	[1] = STEP_C0,
1015	[2] = STEP_C0,
1016	[3] = STEP_D0,
1017};
1018
1019static const struct platform_desc tgl_desc = {
1020	PLATFORM(tigerlake),
1021	.subplatforms = (const struct subplatform_desc[]) {
1022		{
1023			SUBPLATFORM(tigerlake, uy),
1024			.pciidlist = tgl_uy_ids,
1025			STEP_INFO(tgl_uy_steppings),
1026		},
1027		{},
1028	},
1029	.info = &(const struct intel_display_device_info) {
1030		XE_D_DISPLAY,
1031
1032		/*
1033		 * FIXME DDI C/combo PHY C missing due to combo PHY
1034		 * code making a mess on SKUs where the PHY is missing.
1035		 */
1036		.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) |
1037		BIT(PORT_TC1) | BIT(PORT_TC2) | BIT(PORT_TC3) | BIT(PORT_TC4) | BIT(PORT_TC5) | BIT(PORT_TC6),
1038	},
1039	STEP_INFO(tgl_steppings),
1040};
1041
1042static const enum intel_step dg1_steppings[] = {
1043	[0] = STEP_A0,
1044	[1] = STEP_B0,
1045};
1046
1047static const struct platform_desc dg1_desc = {
1048	PLATFORM(dg1),
1049	PLATFORM_GROUP(dgfx),
1050	.info = &(const struct intel_display_device_info) {
1051		XE_D_DISPLAY,
1052
1053		.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) |
1054		BIT(PORT_TC1) | BIT(PORT_TC2),
1055	},
1056	STEP_INFO(dg1_steppings),
1057};
1058
1059static const enum intel_step rkl_steppings[] = {
1060	[0] = STEP_A0,
1061	[1] = STEP_B0,
1062	[4] = STEP_C0,
1063};
1064
1065static const struct platform_desc rkl_desc = {
1066	PLATFORM(rocketlake),
1067	.info = &(const struct intel_display_device_info) {
1068		XE_D_DISPLAY,
1069		.abox_mask = BIT(0),
1070		.has_hti = 1,
1071		.has_psr_hw_tracking = 0,
1072
1073		.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
1074		.__runtime_defaults.cpu_transcoder_mask =
1075		BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C),
1076		.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) |
1077		BIT(PORT_TC1) | BIT(PORT_TC2),
1078	},
1079	STEP_INFO(rkl_steppings),
1080};
1081
1082static const u16 adls_rpls_ids[] = {
1083	INTEL_RPLS_IDS(ID),
1084	0
1085};
1086
1087static const enum intel_step adl_s_steppings[] = {
1088	[0x0] = STEP_A0,
1089	[0x1] = STEP_A2,
1090	[0x4] = STEP_B0,
1091	[0x8] = STEP_B0,
1092	[0xC] = STEP_C0,
1093};
1094
1095static const enum intel_step adl_s_rpl_s_steppings[] = {
1096	[0x4] = STEP_D0,
1097	[0xC] = STEP_C0,
1098};
1099
1100static const struct platform_desc adl_s_desc = {
1101	PLATFORM(alderlake_s),
1102	.subplatforms = (const struct subplatform_desc[]) {
1103		{
1104			SUBPLATFORM(alderlake_s, raptorlake_s),
1105			.pciidlist = adls_rpls_ids,
1106			STEP_INFO(adl_s_rpl_s_steppings),
1107		},
1108		{},
1109	},
1110	.info = &(const struct intel_display_device_info) {
1111		XE_D_DISPLAY,
1112		.has_hti = 1,
1113		.has_psr_hw_tracking = 0,
1114
1115		.__runtime_defaults.port_mask = BIT(PORT_A) |
1116		BIT(PORT_TC1) | BIT(PORT_TC2) | BIT(PORT_TC3) | BIT(PORT_TC4),
1117	},
1118	STEP_INFO(adl_s_steppings),
1119};
1120
1121#define XE_LPD_FEATURES \
1122	.abox_mask = GENMASK(1, 0),						\
1123	.color = {								\
1124		.degamma_lut_size = 129, .gamma_lut_size = 1024,		\
1125		.degamma_lut_tests = DRM_COLOR_LUT_NON_DECREASING |		\
1126		DRM_COLOR_LUT_EQUAL_CHANNELS,					\
1127	},									\
1128	.dbuf.size = 4096,							\
1129	.dbuf.slice_mask = BIT(DBUF_S1) | BIT(DBUF_S2) | BIT(DBUF_S3) |		\
1130		BIT(DBUF_S4),							\
1131	.has_ddi = 1,								\
1132	.has_dp_mst = 1,							\
1133	.has_dsb = 1,								\
1134	.has_fpga_dbg = 1,							\
1135	.has_hotplug = 1,							\
1136	.has_ipc = 1,								\
1137	.has_psr = 1,								\
1138	.pipe_offsets = {							\
1139		[TRANSCODER_A] = PIPE_A_OFFSET,					\
1140		[TRANSCODER_B] = PIPE_B_OFFSET,					\
1141		[TRANSCODER_C] = PIPE_C_OFFSET,					\
1142		[TRANSCODER_D] = PIPE_D_OFFSET,					\
1143		[TRANSCODER_DSI_0] = PIPE_DSI0_OFFSET,				\
1144		[TRANSCODER_DSI_1] = PIPE_DSI1_OFFSET,				\
1145	},									\
1146	.trans_offsets = {							\
1147		[TRANSCODER_A] = TRANSCODER_A_OFFSET,				\
1148		[TRANSCODER_B] = TRANSCODER_B_OFFSET,				\
1149		[TRANSCODER_C] = TRANSCODER_C_OFFSET,				\
1150		[TRANSCODER_D] = TRANSCODER_D_OFFSET,				\
1151		[TRANSCODER_DSI_0] = TRANSCODER_DSI0_OFFSET,			\
1152		[TRANSCODER_DSI_1] = TRANSCODER_DSI1_OFFSET,			\
1153	},									\
1154	TGL_CURSOR_OFFSETS,							\
1155										\
1156	.__runtime_defaults.ip.ver = 13,					\
1157	.__runtime_defaults.has_dmc = 1,					\
1158	.__runtime_defaults.has_dsc = 1,					\
1159	.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),			\
1160	.__runtime_defaults.has_hdcp = 1,					\
1161	.__runtime_defaults.pipe_mask =						\
1162		BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D)
1163
1164static const struct intel_display_device_info xe_lpd_display = {
1165	XE_LPD_FEATURES,
1166	.has_cdclk_crawl = 1,
1167	.has_psr_hw_tracking = 0,
1168
1169	.__runtime_defaults.cpu_transcoder_mask =
1170		BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
1171		BIT(TRANSCODER_C) | BIT(TRANSCODER_D) |
1172		BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1),
1173	.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) |
1174		BIT(PORT_TC1) | BIT(PORT_TC2) | BIT(PORT_TC3) | BIT(PORT_TC4),
1175};
1176
1177static const u16 adlp_adln_ids[] = {
1178	INTEL_ADLN_IDS(ID),
1179	0
1180};
1181
1182static const u16 adlp_rplu_ids[] = {
1183	INTEL_RPLU_IDS(ID),
1184	0
1185};
1186
1187static const u16 adlp_rplp_ids[] = {
1188	INTEL_RPLP_IDS(ID),
1189	0
1190};
1191
1192static const enum intel_step adl_p_steppings[] = {
1193	[0x0] = STEP_A0,
1194	[0x4] = STEP_B0,
1195	[0x8] = STEP_C0,
1196	[0xC] = STEP_D0,
1197};
1198
1199static const enum intel_step adl_p_adl_n_steppings[] = {
1200	[0x0] = STEP_D0,
1201};
1202
1203static const enum intel_step adl_p_rpl_pu_steppings[] = {
1204	[0x4] = STEP_E0,
1205};
1206
1207static const struct platform_desc adl_p_desc = {
1208	PLATFORM(alderlake_p),
1209	.subplatforms = (const struct subplatform_desc[]) {
1210		{
1211			SUBPLATFORM(alderlake_p, alderlake_n),
1212			.pciidlist = adlp_adln_ids,
1213			STEP_INFO(adl_p_adl_n_steppings),
1214		},
1215		{
1216			SUBPLATFORM(alderlake_p, raptorlake_p),
1217			.pciidlist = adlp_rplp_ids,
1218			STEP_INFO(adl_p_rpl_pu_steppings),
1219		},
1220		{
1221			SUBPLATFORM(alderlake_p, raptorlake_u),
1222			.pciidlist = adlp_rplu_ids,
1223			STEP_INFO(adl_p_rpl_pu_steppings),
1224		},
1225		{},
1226	},
1227	.info = &xe_lpd_display,
1228	STEP_INFO(adl_p_steppings),
1229};
1230
1231static const struct intel_display_device_info xe_hpd_display = {
1232	XE_LPD_FEATURES,
1233	.has_cdclk_squash = 1,
1234
1235	.__runtime_defaults.cpu_transcoder_mask =
1236		BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
1237		BIT(TRANSCODER_C) | BIT(TRANSCODER_D),
1238	.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D_XELPD) |
1239		BIT(PORT_TC1),
1240};
1241
1242static const u16 dg2_g10_ids[] = {
1243	INTEL_DG2_G10_IDS(ID),
1244	0
1245};
1246
1247static const u16 dg2_g11_ids[] = {
1248	INTEL_DG2_G11_IDS(ID),
1249	0
1250};
1251
1252static const u16 dg2_g12_ids[] = {
1253	INTEL_DG2_G12_IDS(ID),
1254	0
1255};
1256
1257static const enum intel_step dg2_g10_steppings[] = {
1258	[0x0] = STEP_A0,
1259	[0x1] = STEP_A0,
1260	[0x4] = STEP_B0,
1261	[0x8] = STEP_C0,
1262};
1263
1264static const enum intel_step dg2_g11_steppings[] = {
1265	[0x0] = STEP_B0,
1266	[0x4] = STEP_C0,
1267	[0x5] = STEP_C0,
1268};
1269
1270static const enum intel_step dg2_g12_steppings[] = {
1271	[0x0] = STEP_C0,
1272	[0x1] = STEP_C0,
1273};
1274
1275static const struct platform_desc dg2_desc = {
1276	PLATFORM(dg2),
1277	PLATFORM_GROUP(dgfx),
1278	.subplatforms = (const struct subplatform_desc[]) {
1279		{
1280			SUBPLATFORM(dg2, g10),
1281			.pciidlist = dg2_g10_ids,
1282			STEP_INFO(dg2_g10_steppings),
1283		},
1284		{
1285			SUBPLATFORM(dg2, g11),
1286			.pciidlist = dg2_g11_ids,
1287			STEP_INFO(dg2_g11_steppings),
1288		},
1289		{
1290			SUBPLATFORM(dg2, g12),
1291			.pciidlist = dg2_g12_ids,
1292			STEP_INFO(dg2_g12_steppings),
1293		},
1294		{},
1295	},
1296	.info = &xe_hpd_display,
1297};
1298
1299#define XE_LPDP_FEATURES							\
1300	.abox_mask = GENMASK(1, 0),						\
1301	.color = {								\
1302		.degamma_lut_size = 129, .gamma_lut_size = 1024,		\
1303		.degamma_lut_tests = DRM_COLOR_LUT_NON_DECREASING |		\
1304		DRM_COLOR_LUT_EQUAL_CHANNELS,					\
1305	},									\
1306	.dbuf.size = 4096,							\
1307	.dbuf.slice_mask = BIT(DBUF_S1) | BIT(DBUF_S2) | BIT(DBUF_S3) |		\
1308		BIT(DBUF_S4),							\
1309	.has_cdclk_crawl = 1,							\
1310	.has_cdclk_squash = 1,							\
1311	.has_ddi = 1,								\
1312	.has_dp_mst = 1,							\
1313	.has_dsb = 1,								\
1314	.has_fpga_dbg = 1,							\
1315	.has_hotplug = 1,							\
1316	.has_ipc = 1,								\
1317	.has_psr = 1,								\
1318	.pipe_offsets = {							\
1319		[TRANSCODER_A] = PIPE_A_OFFSET,					\
1320		[TRANSCODER_B] = PIPE_B_OFFSET,					\
1321		[TRANSCODER_C] = PIPE_C_OFFSET,					\
1322		[TRANSCODER_D] = PIPE_D_OFFSET,					\
1323	},									\
1324	.trans_offsets = {							\
1325		[TRANSCODER_A] = TRANSCODER_A_OFFSET,				\
1326		[TRANSCODER_B] = TRANSCODER_B_OFFSET,				\
1327		[TRANSCODER_C] = TRANSCODER_C_OFFSET,				\
1328		[TRANSCODER_D] = TRANSCODER_D_OFFSET,				\
1329	},									\
1330	TGL_CURSOR_OFFSETS,							\
1331										\
1332	.__runtime_defaults.cpu_transcoder_mask =				\
1333		BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |				\
1334		BIT(TRANSCODER_C) | BIT(TRANSCODER_D),				\
1335	.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A) | BIT(INTEL_FBC_B),	\
1336	.__runtime_defaults.has_dmc = 1,					\
1337	.__runtime_defaults.has_dsc = 1,					\
1338	.__runtime_defaults.has_hdcp = 1,					\
1339	.__runtime_defaults.pipe_mask =						\
1340		BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D),		\
1341	.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) |		\
1342		BIT(PORT_TC1) | BIT(PORT_TC2) | BIT(PORT_TC3) | BIT(PORT_TC4)
1343
1344static const struct intel_display_device_info xe_lpdp_display = {
1345	XE_LPDP_FEATURES,
1346};
1347
1348static const struct intel_display_device_info xe2_lpd_display = {
1349	XE_LPDP_FEATURES,
1350
1351	.__runtime_defaults.fbc_mask =
1352		BIT(INTEL_FBC_A) | BIT(INTEL_FBC_B) |
1353		BIT(INTEL_FBC_C) | BIT(INTEL_FBC_D),
1354	.__runtime_defaults.has_dbuf_overlap_detection = true,
1355};
1356
1357static const struct intel_display_device_info wcl_display = {
1358	XE_LPDP_FEATURES,
1359
1360	.__runtime_defaults.cpu_transcoder_mask =
1361		BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C),
1362	.__runtime_defaults.pipe_mask =
1363		BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
1364	.__runtime_defaults.fbc_mask =
1365		BIT(INTEL_FBC_A) | BIT(INTEL_FBC_B) | BIT(INTEL_FBC_C),
1366	.__runtime_defaults.port_mask =
1367		BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_TC1) | BIT(PORT_TC2),
1368};
1369
1370static const struct intel_display_device_info xe2_hpd_display = {
1371	XE_LPDP_FEATURES,
1372	.__runtime_defaults.port_mask = BIT(PORT_A) |
1373		BIT(PORT_TC1) | BIT(PORT_TC2) | BIT(PORT_TC3) | BIT(PORT_TC4),
1374};
1375
1376static const u16 mtl_u_ids[] = {
1377	INTEL_MTL_U_IDS(ID),
1378	INTEL_ARL_U_IDS(ID),
1379	0
1380};
1381
1382/*
1383 * Do not initialize the .info member of the platform desc for GMD ID based
1384 * platforms. Their display will be probed automatically based on the IP version
1385 * reported by the hardware.
1386 */
1387static const struct platform_desc mtl_desc = {
1388	PLATFORM(meteorlake),
1389	.subplatforms = (const struct subplatform_desc[]) {
1390		{
1391			SUBPLATFORM(meteorlake, u),
1392			.pciidlist = mtl_u_ids,
1393		},
1394		{},
1395	}
1396};
1397
1398static const struct platform_desc lnl_desc = {
1399	PLATFORM(lunarlake),
1400};
1401
1402static const struct platform_desc bmg_desc = {
1403	PLATFORM(battlemage),
1404	PLATFORM_GROUP(dgfx),
1405};
1406
1407static const u16 wcl_ids[] = {
1408	INTEL_WCL_IDS(ID),
1409	0
1410};
1411
1412static const struct platform_desc ptl_desc = {
1413	PLATFORM(pantherlake),
1414	.subplatforms = (const struct subplatform_desc[]) {
1415		{
1416			SUBPLATFORM(pantherlake, wildcatlake),
1417			.pciidlist = wcl_ids,
1418		},
1419		{},
1420	}
1421};
1422
1423__diag_pop();
1424
1425/*
1426 * Separate detection for no display cases to keep the display id array simple.
1427 *
1428 * IVB Q requires subvendor and subdevice matching to differentiate from IVB D
1429 * GT2 server.
1430 */
1431static bool has_no_display(struct pci_dev *pdev)
1432{
1433	static const struct pci_device_id ids[] = {
1434		INTEL_IVB_Q_IDS(INTEL_VGA_DEVICE, 0),
1435		{}
1436	};
1437
1438	return pci_match_id(ids, pdev);
1439}
1440
1441#define INTEL_DISPLAY_DEVICE(_id, _desc) { .devid = (_id), .desc = (_desc) }
1442
1443static const struct {
1444	u32 devid;
1445	const struct platform_desc *desc;
1446} intel_display_ids[] = {
1447	INTEL_I830_IDS(INTEL_DISPLAY_DEVICE, &i830_desc),
1448	INTEL_I845G_IDS(INTEL_DISPLAY_DEVICE, &i845_desc),
1449	INTEL_I85X_IDS(INTEL_DISPLAY_DEVICE, &i85x_desc),
1450	INTEL_I865G_IDS(INTEL_DISPLAY_DEVICE, &i865g_desc),
1451	INTEL_I915G_IDS(INTEL_DISPLAY_DEVICE, &i915g_desc),
1452	INTEL_I915GM_IDS(INTEL_DISPLAY_DEVICE, &i915gm_desc),
1453	INTEL_I945G_IDS(INTEL_DISPLAY_DEVICE, &i945g_desc),
1454	INTEL_I945GM_IDS(INTEL_DISPLAY_DEVICE, &i945gm_desc),
1455	INTEL_I965G_IDS(INTEL_DISPLAY_DEVICE, &i965g_desc),
1456	INTEL_G33_IDS(INTEL_DISPLAY_DEVICE, &g33_desc),
1457	INTEL_I965GM_IDS(INTEL_DISPLAY_DEVICE, &i965gm_desc),
1458	INTEL_GM45_IDS(INTEL_DISPLAY_DEVICE, &gm45_desc),
1459	INTEL_G45_IDS(INTEL_DISPLAY_DEVICE, &g45_desc),
1460	INTEL_PNV_G_IDS(INTEL_DISPLAY_DEVICE, &pnv_g_desc),
1461	INTEL_PNV_M_IDS(INTEL_DISPLAY_DEVICE, &pnv_m_desc),
1462	INTEL_ILK_D_IDS(INTEL_DISPLAY_DEVICE, &ilk_d_desc),
1463	INTEL_ILK_M_IDS(INTEL_DISPLAY_DEVICE, &ilk_m_desc),
1464	INTEL_SNB_D_IDS(INTEL_DISPLAY_DEVICE, &snb_d_desc),
1465	INTEL_SNB_M_IDS(INTEL_DISPLAY_DEVICE, &snb_m_desc),
1466	INTEL_IVB_D_IDS(INTEL_DISPLAY_DEVICE, &ivb_d_desc),
1467	INTEL_IVB_M_IDS(INTEL_DISPLAY_DEVICE, &ivb_m_desc),
1468	INTEL_HSW_IDS(INTEL_DISPLAY_DEVICE, &hsw_desc),
1469	INTEL_VLV_IDS(INTEL_DISPLAY_DEVICE, &vlv_desc),
1470	INTEL_BDW_IDS(INTEL_DISPLAY_DEVICE, &bdw_desc),
1471	INTEL_CHV_IDS(INTEL_DISPLAY_DEVICE, &chv_desc),
1472	INTEL_SKL_IDS(INTEL_DISPLAY_DEVICE, &skl_desc),
1473	INTEL_BXT_IDS(INTEL_DISPLAY_DEVICE, &bxt_desc),
1474	INTEL_GLK_IDS(INTEL_DISPLAY_DEVICE, &glk_desc),
1475	INTEL_KBL_IDS(INTEL_DISPLAY_DEVICE, &kbl_desc),
1476	INTEL_CFL_IDS(INTEL_DISPLAY_DEVICE, &cfl_desc),
1477	INTEL_WHL_IDS(INTEL_DISPLAY_DEVICE, &cfl_desc),
1478	INTEL_CML_IDS(INTEL_DISPLAY_DEVICE, &cml_desc),
1479	INTEL_ICL_IDS(INTEL_DISPLAY_DEVICE, &icl_desc),
1480	INTEL_EHL_IDS(INTEL_DISPLAY_DEVICE, &ehl_desc),
1481	INTEL_JSL_IDS(INTEL_DISPLAY_DEVICE, &jsl_desc),
1482	INTEL_TGL_IDS(INTEL_DISPLAY_DEVICE, &tgl_desc),
1483	INTEL_DG1_IDS(INTEL_DISPLAY_DEVICE, &dg1_desc),
1484	INTEL_RKL_IDS(INTEL_DISPLAY_DEVICE, &rkl_desc),
1485	INTEL_ADLS_IDS(INTEL_DISPLAY_DEVICE, &adl_s_desc),
1486	INTEL_RPLS_IDS(INTEL_DISPLAY_DEVICE, &adl_s_desc),
1487	INTEL_ADLP_IDS(INTEL_DISPLAY_DEVICE, &adl_p_desc),
1488	INTEL_ADLN_IDS(INTEL_DISPLAY_DEVICE, &adl_p_desc),
1489	INTEL_RPLU_IDS(INTEL_DISPLAY_DEVICE, &adl_p_desc),
1490	INTEL_RPLP_IDS(INTEL_DISPLAY_DEVICE, &adl_p_desc),
1491	INTEL_DG2_IDS(INTEL_DISPLAY_DEVICE, &dg2_desc),
1492	INTEL_ARL_IDS(INTEL_DISPLAY_DEVICE, &mtl_desc),
1493	INTEL_MTL_IDS(INTEL_DISPLAY_DEVICE, &mtl_desc),
1494	INTEL_LNL_IDS(INTEL_DISPLAY_DEVICE, &lnl_desc),
1495	INTEL_BMG_IDS(INTEL_DISPLAY_DEVICE, &bmg_desc),
1496	INTEL_PTL_IDS(INTEL_DISPLAY_DEVICE, &ptl_desc),
1497	INTEL_WCL_IDS(INTEL_DISPLAY_DEVICE, &ptl_desc),
1498};
1499
1500static const struct {
1501	u16 ver;
1502	u16 rel;
1503	const struct intel_display_device_info *display;
1504} gmdid_display_map[] = {
1505	{ 14,  0, &xe_lpdp_display },
1506	{ 14,  1, &xe2_hpd_display },
1507	{ 20,  0, &xe2_lpd_display },
1508	{ 30,  0, &xe2_lpd_display },
1509	{ 30,  2, &wcl_display },
1510	{ 35,  0, &xe2_lpd_display },
1511};
1512
1513static const struct intel_display_device_info *
1514probe_gmdid_display(struct intel_display *display, struct intel_display_ip_ver *ip_ver)
1515{
1516	struct pci_dev *pdev = to_pci_dev(display->drm->dev);
1517	struct intel_display_ip_ver gmd_id;
1518	void __iomem *addr;
1519	u32 val;
1520	int i;
1521
1522	addr = pci_iomap_range(pdev, 0, i915_mmio_reg_offset(GMD_ID_DISPLAY), sizeof(u32));
1523	if (!addr) {
1524		drm_err(display->drm,
1525			"Cannot map MMIO BAR to read display GMD_ID\n");
1526		return NULL;
1527	}
1528
1529	val = ioread32(addr);
1530	pci_iounmap(pdev, addr);
1531
1532	if (val == 0) {
1533		drm_dbg_kms(display->drm, "Device doesn't have display\n");
1534		return NULL;
1535	}
1536
1537	gmd_id.ver = REG_FIELD_GET(GMD_ID_ARCH_MASK, val);
1538	gmd_id.rel = REG_FIELD_GET(GMD_ID_RELEASE_MASK, val);
1539	gmd_id.step = REG_FIELD_GET(GMD_ID_STEP, val);
1540
1541	for (i = 0; i < ARRAY_SIZE(gmdid_display_map); i++) {
1542		if (gmd_id.ver == gmdid_display_map[i].ver &&
1543		    gmd_id.rel == gmdid_display_map[i].rel) {
1544			*ip_ver = gmd_id;
1545			return gmdid_display_map[i].display;
1546		}
1547	}
1548
1549	drm_err(display->drm,
1550		"Unrecognized display IP version %d.%02d; disabling display.\n",
1551		gmd_id.ver, gmd_id.rel);
1552	return NULL;
1553}
1554
1555static const struct platform_desc *find_platform_desc(struct pci_dev *pdev)
1556{
1557	int i;
1558
1559	for (i = 0; i < ARRAY_SIZE(intel_display_ids); i++) {
1560		if (intel_display_ids[i].devid == pdev->device)
1561			return intel_display_ids[i].desc;
1562	}
1563
1564	return NULL;
1565}
1566
1567static const struct subplatform_desc *
1568find_subplatform_desc(struct pci_dev *pdev, const struct platform_desc *desc)
1569{
1570	const struct subplatform_desc *sp;
1571	const u16 *id;
1572
1573	for (sp = desc->subplatforms; sp && sp->pciidlist; sp++)
1574		for (id = sp->pciidlist; *id; id++)
1575			if (*id == pdev->device)
1576				return sp;
1577
1578	return NULL;
1579}
1580
1581static enum intel_step get_pre_gmdid_step(struct intel_display *display,
1582					  const struct stepping_desc *main,
1583					  const struct stepping_desc *sub)
1584{
1585	struct pci_dev *pdev = to_pci_dev(display->drm->dev);
1586	const enum intel_step *map = main->map;
1587	int size = main->size;
1588	int revision = pdev->revision;
1589	enum intel_step step;
1590
1591	/* subplatform stepping info trumps main platform info */
1592	if (sub && sub->map && sub->size) {
1593		map = sub->map;
1594		size = sub->size;
1595	}
1596
1597	/* not all platforms define steppings, and it's fine */
1598	if (!map || !size)
1599		return STEP_NONE;
1600
1601	if (revision < size && map[revision] != STEP_NONE) {
1602		step = map[revision];
1603	} else {
1604		drm_warn(display->drm, "Unknown revision 0x%02x\n", revision);
1605
1606		/*
1607		 * If we hit a gap in the revision to step map, use the information
1608		 * for the next revision.
1609		 *
1610		 * This may be wrong in all sorts of ways, especially if the
1611		 * steppings in the array are not monotonically increasing, but
1612		 * it's better than defaulting to 0.
1613		 */
1614		while (revision < size && map[revision] == STEP_NONE)
1615			revision++;
1616
1617		if (revision < size) {
1618			drm_dbg_kms(display->drm, "Using display stepping for revision 0x%02x\n",
1619				    revision);
1620			step = map[revision];
1621		} else {
1622			drm_dbg_kms(display->drm, "Using future display stepping\n");
1623			step = STEP_FUTURE;
1624		}
1625	}
1626
1627	drm_WARN_ON(display->drm, step == STEP_NONE);
1628
1629	return step;
1630}
1631
1632/* Size of the entire bitmap, not the number of platforms */
1633static unsigned int display_platforms_num_bits(void)
1634{
1635	return sizeof(((struct intel_display_platforms *)0)->bitmap) * BITS_PER_BYTE;
1636}
1637
1638/* Number of platform bits set */
1639static unsigned int display_platforms_weight(const struct intel_display_platforms *p)
1640{
1641	return bitmap_weight(p->bitmap, display_platforms_num_bits());
1642}
1643
1644/* Merge the subplatform information from src to dst */
1645static void display_platforms_or(struct intel_display_platforms *dst,
1646				 const struct intel_display_platforms *src)
1647{
1648	bitmap_or(dst->bitmap, dst->bitmap, src->bitmap, display_platforms_num_bits());
1649}
1650
1651struct intel_display *intel_display_device_probe(struct pci_dev *pdev,
1652						 const struct intel_display_parent_interface *parent)
1653{
1654	struct intel_display *display;
1655	const struct intel_display_device_info *info;
1656	struct intel_display_ip_ver ip_ver = {};
1657	const struct platform_desc *desc;
1658	const struct subplatform_desc *subdesc;
1659	enum intel_step step;
1660
1661	display = kzalloc(sizeof(*display), GFP_KERNEL);
1662	if (!display)
1663		return ERR_PTR(-ENOMEM);
1664
1665	/* Add drm device backpointer as early as possible. */
1666	display->drm = pci_get_drvdata(pdev);
1667
1668	display->parent = parent;
1669
1670	intel_display_params_copy(&display->params);
1671
1672	if (has_no_display(pdev)) {
1673		drm_dbg_kms(display->drm, "Device doesn't have display\n");
1674		goto no_display;
1675	}
1676
1677	desc = find_platform_desc(pdev);
1678	if (!desc) {
1679		drm_dbg_kms(display->drm,
1680			    "Unknown device ID %04x; disabling display.\n",
1681			    pdev->device);
1682		goto no_display;
1683	}
1684
1685	info = desc->info;
1686	if (!info)
1687		info = probe_gmdid_display(display, &ip_ver);
1688	if (!info)
1689		goto no_display;
1690
1691	DISPLAY_INFO(display) = info;
1692
1693	memcpy(DISPLAY_RUNTIME_INFO(display),
1694	       &DISPLAY_INFO(display)->__runtime_defaults,
1695	       sizeof(*DISPLAY_RUNTIME_INFO(display)));
1696
1697	drm_WARN_ON(display->drm, !desc->name ||
1698		    !display_platforms_weight(&desc->platforms));
1699
1700	display->platform = desc->platforms;
1701
1702	subdesc = find_subplatform_desc(pdev, desc);
1703	if (subdesc) {
1704		drm_WARN_ON(display->drm, !subdesc->name ||
1705			    !display_platforms_weight(&subdesc->platforms));
1706
1707		display_platforms_or(&display->platform, &subdesc->platforms);
1708
1709		/* Ensure platform and subplatform are distinct */
1710		drm_WARN_ON(display->drm,
1711			    display_platforms_weight(&display->platform) !=
1712			    display_platforms_weight(&desc->platforms) +
1713			    display_platforms_weight(&subdesc->platforms));
1714	}
1715
1716	if (ip_ver.ver || ip_ver.rel || ip_ver.step) {
1717		DISPLAY_RUNTIME_INFO(display)->ip = ip_ver;
1718		step = STEP_A0 + ip_ver.step;
1719		if (step > STEP_FUTURE) {
1720			drm_dbg_kms(display->drm, "Using future display stepping\n");
1721			step = STEP_FUTURE;
1722		}
1723	} else {
1724		step = get_pre_gmdid_step(display, &desc->step_info,
1725					  subdesc ? &subdesc->step_info : NULL);
1726	}
1727
1728	DISPLAY_RUNTIME_INFO(display)->step = step;
1729
1730	drm_info(display->drm, "Found %s%s%s (device ID %04x) %s display version %u.%02u stepping %s\n",
1731		 desc->name, subdesc ? "/" : "", subdesc ? subdesc->name : "",
1732		 pdev->device, display->platform.dgfx ? "discrete" : "integrated",
1733		 DISPLAY_RUNTIME_INFO(display)->ip.ver,
1734		 DISPLAY_RUNTIME_INFO(display)->ip.rel,
1735		 step != STEP_NONE ? intel_step_name(step) : "N/A");
1736
1737	return display;
1738
1739no_display:
1740	DISPLAY_INFO(display) = &no_display;
1741
1742	return display;
1743}
1744
1745void intel_display_device_remove(struct intel_display *display)
1746{
1747	if (!display)
1748		return;
1749
1750	intel_display_params_free(&display->params);
1751	kfree(display);
1752}
1753
1754static void __intel_display_device_info_runtime_init(struct intel_display *display)
1755{
1756	struct intel_display_runtime_info *display_runtime = DISPLAY_RUNTIME_INFO(display);
1757	enum pipe pipe;
1758
1759	BUILD_BUG_ON(BITS_PER_TYPE(display_runtime->pipe_mask) < I915_MAX_PIPES);
1760	BUILD_BUG_ON(BITS_PER_TYPE(display_runtime->cpu_transcoder_mask) < I915_MAX_TRANSCODERS);
1761	BUILD_BUG_ON(BITS_PER_TYPE(display_runtime->port_mask) < I915_MAX_PORTS);
1762
1763	/* This covers both ULT and ULX */
1764	if (display->platform.haswell_ult || display->platform.broadwell_ult)
1765		display_runtime->port_mask &= ~BIT(PORT_D);
1766
1767	if (display->platform.icelake_port_f)
1768		display_runtime->port_mask |= BIT(PORT_F);
1769
1770	/* Wa_14011765242: adl-s A0,A1 */
1771	if (display->platform.alderlake_s && IS_DISPLAY_STEP(display, STEP_A0, STEP_A2))
1772		for_each_pipe(display, pipe)
1773			display_runtime->num_scalers[pipe] = 0;
1774	else if (DISPLAY_VER(display) >= 11) {
1775		for_each_pipe(display, pipe)
1776			display_runtime->num_scalers[pipe] = 2;
1777	} else if (DISPLAY_VER(display) >= 9) {
1778		display_runtime->num_scalers[PIPE_A] = 2;
1779		display_runtime->num_scalers[PIPE_B] = 2;
1780		display_runtime->num_scalers[PIPE_C] = 1;
1781	}
1782
1783	if (DISPLAY_VER(display) >= 13 || HAS_D12_PLANE_MINIMIZATION(display))
1784		for_each_pipe(display, pipe)
1785			display_runtime->num_sprites[pipe] = 4;
1786	else if (DISPLAY_VER(display) >= 11)
1787		for_each_pipe(display, pipe)
1788			display_runtime->num_sprites[pipe] = 6;
1789	else if (DISPLAY_VER(display) == 10)
1790		for_each_pipe(display, pipe)
1791			display_runtime->num_sprites[pipe] = 3;
1792	else if (display->platform.broxton) {
1793		/*
1794		 * Skylake and Broxton currently don't expose the topmost plane as its
1795		 * use is exclusive with the legacy cursor and we only want to expose
1796		 * one of those, not both. Until we can safely expose the topmost plane
1797		 * as a DRM_PLANE_TYPE_CURSOR with all the features exposed/supported,
1798		 * we don't expose the topmost plane at all to prevent ABI breakage
1799		 * down the line.
1800		 */
1801
1802		display_runtime->num_sprites[PIPE_A] = 2;
1803		display_runtime->num_sprites[PIPE_B] = 2;
1804		display_runtime->num_sprites[PIPE_C] = 1;
1805	} else if (display->platform.valleyview || display->platform.cherryview) {
1806		for_each_pipe(display, pipe)
1807			display_runtime->num_sprites[pipe] = 2;
1808	} else if (DISPLAY_VER(display) >= 5 || display->platform.g4x) {
1809		for_each_pipe(display, pipe)
1810			display_runtime->num_sprites[pipe] = 1;
1811	}
1812
1813	if ((display->platform.dgfx || DISPLAY_VER(display) >= 14) &&
1814	    !(intel_de_read(display, GU_CNTL_PROTECTED) & DEPRESENT)) {
1815		drm_info(display->drm, "Display not present, disabling\n");
1816		goto display_fused_off;
1817	}
1818
1819	if (IS_DISPLAY_VER(display, 7, 8) && HAS_PCH_SPLIT(display)) {
1820		u32 fuse_strap = intel_de_read(display, FUSE_STRAP);
1821		u32 sfuse_strap = intel_de_read(display, SFUSE_STRAP);
1822
1823		/*
1824		 * SFUSE_STRAP is supposed to have a bit signalling the display
1825		 * is fused off. Unfortunately it seems that, at least in
1826		 * certain cases, fused off display means that PCH display
1827		 * reads don't land anywhere. In that case, we read 0s.
1828		 *
1829		 * On CPT/PPT, we can detect this case as SFUSE_STRAP_FUSE_LOCK
1830		 * should be set when taking over after the firmware.
1831		 */
1832		if (fuse_strap & ILK_INTERNAL_DISPLAY_DISABLE ||
1833		    sfuse_strap & SFUSE_STRAP_DISPLAY_DISABLED ||
1834		    (HAS_PCH_CPT(display) &&
1835		     !(sfuse_strap & SFUSE_STRAP_FUSE_LOCK))) {
1836			drm_info(display->drm,
1837				 "Display fused off, disabling\n");
1838			goto display_fused_off;
1839		} else if (fuse_strap & IVB_PIPE_C_DISABLE) {
1840			drm_info(display->drm, "PipeC fused off\n");
1841			display_runtime->pipe_mask &= ~BIT(PIPE_C);
1842			display_runtime->cpu_transcoder_mask &= ~BIT(TRANSCODER_C);
1843		}
1844	} else if (DISPLAY_VER(display) >= 9) {
1845		u32 dfsm = intel_de_read(display, SKL_DFSM);
1846
1847		if (dfsm & SKL_DFSM_PIPE_A_DISABLE) {
1848			display_runtime->pipe_mask &= ~BIT(PIPE_A);
1849			display_runtime->cpu_transcoder_mask &= ~BIT(TRANSCODER_A);
1850			display_runtime->fbc_mask &= ~BIT(INTEL_FBC_A);
1851		}
1852		if (dfsm & SKL_DFSM_PIPE_B_DISABLE) {
1853			display_runtime->pipe_mask &= ~BIT(PIPE_B);
1854			display_runtime->cpu_transcoder_mask &= ~BIT(TRANSCODER_B);
1855			display_runtime->fbc_mask &= ~BIT(INTEL_FBC_B);
1856		}
1857		if (dfsm & SKL_DFSM_PIPE_C_DISABLE) {
1858			display_runtime->pipe_mask &= ~BIT(PIPE_C);
1859			display_runtime->cpu_transcoder_mask &= ~BIT(TRANSCODER_C);
1860			display_runtime->fbc_mask &= ~BIT(INTEL_FBC_C);
1861		}
1862
1863		if (DISPLAY_VER(display) >= 12 &&
1864		    (dfsm & TGL_DFSM_PIPE_D_DISABLE)) {
1865			display_runtime->pipe_mask &= ~BIT(PIPE_D);
1866			display_runtime->cpu_transcoder_mask &= ~BIT(TRANSCODER_D);
1867			display_runtime->fbc_mask &= ~BIT(INTEL_FBC_D);
1868		}
1869
1870		if (!display_runtime->pipe_mask)
1871			goto display_fused_off;
1872
1873		if (dfsm & SKL_DFSM_DISPLAY_HDCP_DISABLE)
1874			display_runtime->has_hdcp = 0;
1875
1876		if (display->platform.dg2 || DISPLAY_VER(display) < 13) {
1877			if (dfsm & SKL_DFSM_DISPLAY_PM_DISABLE)
1878				display_runtime->fbc_mask = 0;
1879		}
1880
1881		if (DISPLAY_VER(display) >= 11 && (dfsm & ICL_DFSM_DMC_DISABLE))
1882			display_runtime->has_dmc = 0;
1883
1884		if (IS_DISPLAY_VER(display, 10, 12) &&
1885		    (dfsm & GLK_DFSM_DISPLAY_DSC_DISABLE))
1886			display_runtime->has_dsc = 0;
1887
1888		if (DISPLAY_VER(display) >= 20 &&
1889		    (dfsm & XE2LPD_DFSM_DBUF_OVERLAP_DISABLE))
1890			display_runtime->has_dbuf_overlap_detection = false;
1891	}
1892
1893	if (DISPLAY_VER(display) >= 20) {
1894		u32 cap = intel_de_read(display, XE2LPD_DE_CAP);
1895
1896		if (REG_FIELD_GET(XE2LPD_DE_CAP_DSC_MASK, cap) ==
1897		    XE2LPD_DE_CAP_DSC_REMOVED)
1898			display_runtime->has_dsc = 0;
1899
1900		if (REG_FIELD_GET(XE2LPD_DE_CAP_SCALER_MASK, cap) ==
1901		    XE2LPD_DE_CAP_SCALER_SINGLE) {
1902			for_each_pipe(display, pipe)
1903				if (display_runtime->num_scalers[pipe])
1904					display_runtime->num_scalers[pipe] = 1;
1905		}
1906	}
1907
1908	if (DISPLAY_VER(display) >= 30)
1909		display_runtime->edp_typec_support =
1910			intel_de_read(display, PICA_PHY_CONFIG_CONTROL) & EDP_ON_TYPEC;
1911
1912	display_runtime->rawclk_freq = intel_read_rawclk(display);
1913	drm_dbg_kms(display->drm, "rawclk rate: %d kHz\n",
1914		    display_runtime->rawclk_freq);
1915
1916	return;
1917
1918display_fused_off:
1919	memset(display_runtime, 0, sizeof(*display_runtime));
1920}
1921
1922void intel_display_device_info_runtime_init(struct intel_display *display)
1923{
1924	if (HAS_DISPLAY(display))
1925		__intel_display_device_info_runtime_init(display);
1926
1927	/* Display may have been disabled by runtime init */
1928	if (!HAS_DISPLAY(display)) {
1929		display->drm->driver_features &= ~(DRIVER_MODESET | DRIVER_ATOMIC);
1930		display->info.__device_info = &no_display;
1931	}
1932
1933	/* Disable nuclear pageflip by default on pre-g4x */
1934	if (!display->params.nuclear_pageflip &&
1935	    DISPLAY_VER(display) < 5 && !display->platform.g4x)
1936		display->drm->driver_features &= ~DRIVER_ATOMIC;
1937}
1938
1939void intel_display_device_info_print(const struct intel_display_device_info *info,
1940				     const struct intel_display_runtime_info *runtime,
1941				     struct drm_printer *p)
1942{
1943	if (runtime->ip.rel)
1944		drm_printf(p, "display version: %u.%02u\n",
1945			   runtime->ip.ver,
1946			   runtime->ip.rel);
1947	else
1948		drm_printf(p, "display version: %u\n",
1949			   runtime->ip.ver);
1950
1951	drm_printf(p, "display stepping: %s\n", intel_step_name(runtime->step));
1952
1953#define PRINT_FLAG(name) drm_printf(p, "%s: %s\n", #name, str_yes_no(info->name))
1954	DEV_INFO_DISPLAY_FOR_EACH_FLAG(PRINT_FLAG);
1955#undef PRINT_FLAG
1956
1957	drm_printf(p, "has_hdcp: %s\n", str_yes_no(runtime->has_hdcp));
1958	drm_printf(p, "has_dmc: %s\n", str_yes_no(runtime->has_dmc));
1959	drm_printf(p, "has_dsc: %s\n", str_yes_no(runtime->has_dsc));
1960
1961	drm_printf(p, "rawclk rate: %u kHz\n", runtime->rawclk_freq);
1962}
1963
1964bool intel_display_device_present(struct intel_display *display)
1965{
1966	return display && HAS_DISPLAY(display);
1967}
1968
1969/*
1970 * Assuming the device has display hardware, should it be enabled?
1971 *
1972 * It's an error to call this function if the device does not have display
1973 * hardware.
1974 *
1975 * Disabling display means taking over the display hardware, putting it to
1976 * sleep, and preventing connectors from being connected via any means.
1977 */
1978bool intel_display_device_enabled(struct intel_display *display)
1979{
1980	/* Only valid when HAS_DISPLAY() is true */
1981	drm_WARN_ON(display->drm, !HAS_DISPLAY(display));
1982
1983	return !display->params.disable_display &&
1984		!intel_opregion_headless_sku(display);
1985}
~/ Read-only file preview.