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

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/i915/display/intel_bw.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/display/intel_bw.c
Extension
.c
Size
41696 bytes
Lines
1521
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct intel_bw_state {
	struct intel_global_state base;

	/*
	 * Contains a bit mask, used to determine, whether correspondent
	 * pipe allows SAGV or not.
	 */
	u8 pipe_sagv_reject;

	/*
	 * From MTL onwards, to lock a QGV point, punit expects the peak BW of
	 * the selected QGV point as the parameter in multiples of 100MB/s
	 */
	u16 qgv_point_peakbw;

	/*
	 * Current QGV points mask, which restricts
	 * some particular SAGV states, not to confuse
	 * with pipe_sagv_mask.
	 */
	u16 qgv_points_mask;

	unsigned int data_rate[I915_MAX_PIPES];
	u8 num_active_planes[I915_MAX_PIPES];
};

/* Parameters for Qclk Geyserville (QGV) */
struct intel_qgv_point {
	u16 dclk, t_rp, t_rdpre, t_rc, t_ras, t_rcd;
};

#define DEPROGBWPCLIMIT		60

struct intel_psf_gv_point {
	u8 clk; /* clock in multiples of 16.6666 MHz */
};

struct intel_qgv_info {
	struct intel_qgv_point points[I915_NUM_QGV_POINTS];
	struct intel_psf_gv_point psf_points[I915_NUM_PSF_GV_POINTS];
	u8 num_points;
	u8 num_psf_points;
	u8 t_bl;
	u8 max_numchannels;
	u8 channel_width;
	u8 deinterleave;
};

static int dclk_freq_mhz(int ratio)
{
	/* multiple of 16.666 MHz (100/6) */
	return DIV_ROUND_CLOSEST(ratio * 100, 6);
}

static int dg1_mchbar_read_qgv_point_info(struct intel_display *display,
					  struct intel_qgv_point *sp,
					  int point)
{
	u32 dclk_ratio;
	u32 val;

	val = intel_mchbar_read(display, SA_PERF_STATUS_0_0_0_MCHBAR_PC);
	dclk_ratio = REG_FIELD_GET(DG1_QCLK_RATIO_MASK, val);
	if (val & DG1_QCLK_REFERENCE)
		dclk_ratio *= 6; /* 6 * 16.666 MHz = 100 MHz */
	else
		dclk_ratio *= 8; /* 8 * 16.666 MHz = 133 MHz */

	val = intel_mchbar_read(display, SKL_MC_BIOS_DATA_0_0_0_MCHBAR_PCU);
	if (val & DG1_GEAR_TYPE)
		dclk_ratio *= 2;

	sp->dclk = dclk_freq_mhz(dclk_ratio);
	if (sp->dclk == 0)
		return -EINVAL;

	val = intel_mchbar_read(display, MCHBAR_CH0_CR_TC_PRE_0_0_0_MCHBAR);
	sp->t_rp = REG_FIELD_GET(DG1_DRAM_T_RP_MASK, val);
	sp->t_rdpre = REG_FIELD_GET(DG1_DRAM_T_RDPRE_MASK, val);

	val = intel_mchbar_read(display, MCHBAR_CH0_CR_TC_PRE_0_0_0_MCHBAR_HIGH);
	sp->t_rcd = REG_FIELD_GET(DG1_DRAM_T_RCD_MASK, val);
	sp->t_ras = REG_FIELD_GET(DG1_DRAM_T_RAS_MASK, val);

	sp->t_rc = sp->t_rp + sp->t_ras;

	return 0;
}

static int icl_pcode_read_qgv_point_info(struct intel_display *display,

Annotation

Implementation Notes