File Index
Files and directories
Sign in
FILE

skl_prefill.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/i915/display/skl_prefill.c C
  1// SPDX-License-Identifier: MIT
  2/*
  3 * Copyright © 2025 Intel Corporation
  4 */
  5
  6#include <linux/debugfs.h>
  7
  8#include <drm/drm_print.h>
  9
 10#include "intel_cdclk.h"
 11#include "intel_display_core.h"
 12#include "intel_display_types.h"
 13#include "intel_vblank.h"
 14#include "intel_vdsc.h"
 15#include "skl_prefill.h"
 16#include "skl_scaler.h"
 17#include "skl_watermark.h"
 18
 19static unsigned int prefill_usecs_to_lines(const struct intel_crtc_state *crtc_state,
 20					   unsigned int usecs)
 21{
 22	const struct drm_display_mode *pipe_mode = &crtc_state->hw.pipe_mode;
 23
 24	return DIV_ROUND_UP_ULL(mul_u32_u32(pipe_mode->crtc_clock, usecs << 16),
 25				pipe_mode->crtc_htotal * 1000);
 26}
 27
 28static void prefill_init(struct skl_prefill_ctx *ctx,
 29			 const struct intel_crtc_state *crtc_state)
 30{
 31	memset(ctx, 0, sizeof(*ctx));
 32
 33	ctx->prefill.fixed = crtc_state->framestart_delay << 16;
 34
 35	/* 20 usec for translation walks/etc. */
 36	ctx->prefill.fixed += prefill_usecs_to_lines(crtc_state, 20);
 37
 38	ctx->prefill.dsc = intel_vdsc_prefill_lines(crtc_state);
 39}
 40
 41static void prefill_init_nocdclk_worst(struct skl_prefill_ctx *ctx,
 42				       const struct intel_crtc_state *crtc_state)
 43{
 44	prefill_init(ctx, crtc_state);
 45
 46	ctx->prefill.wm0 = skl_wm0_prefill_lines_worst(crtc_state);
 47	ctx->prefill.scaler_1st = skl_scaler_1st_prefill_lines_worst(crtc_state);
 48	ctx->prefill.scaler_2nd = skl_scaler_2nd_prefill_lines_worst(crtc_state);
 49
 50	ctx->adj.scaler_1st = skl_scaler_1st_prefill_adjustment_worst(crtc_state);
 51	ctx->adj.scaler_2nd = skl_scaler_2nd_prefill_adjustment_worst(crtc_state);
 52}
 53
 54static void prefill_init_nocdclk(struct skl_prefill_ctx *ctx,
 55				 const struct intel_crtc_state *crtc_state)
 56{
 57	prefill_init(ctx, crtc_state);
 58
 59	ctx->prefill.wm0 = skl_wm0_prefill_lines(crtc_state);
 60	ctx->prefill.scaler_1st = skl_scaler_1st_prefill_lines(crtc_state);
 61	ctx->prefill.scaler_2nd = skl_scaler_2nd_prefill_lines(crtc_state);
 62
 63	ctx->adj.scaler_1st = skl_scaler_1st_prefill_adjustment(crtc_state);
 64	ctx->adj.scaler_2nd = skl_scaler_2nd_prefill_adjustment(crtc_state);
 65}
 66
 67static unsigned int prefill_adjust(unsigned int value, unsigned int factor)
 68{
 69	return DIV_ROUND_UP_ULL(mul_u32_u32(value, factor), 0x10000);
 70}
 71
 72static unsigned int prefill_lines_nocdclk(const struct skl_prefill_ctx *ctx)
 73{
 74	unsigned int prefill = 0;
 75
 76	prefill += ctx->prefill.dsc;
 77	prefill = prefill_adjust(prefill, ctx->adj.scaler_2nd);
 78
 79	prefill += ctx->prefill.scaler_2nd;
 80	prefill = prefill_adjust(prefill, ctx->adj.scaler_1st);
 81
 82	prefill += ctx->prefill.scaler_1st;
 83	prefill += ctx->prefill.wm0;
 84
 85	return prefill;
 86}
 87
 88static unsigned int prefill_lines_cdclk(const struct skl_prefill_ctx *ctx)
 89{
 90	return prefill_adjust(prefill_lines_nocdclk(ctx), ctx->adj.cdclk);
 91}
 92
 93static unsigned int prefill_lines_full(const struct skl_prefill_ctx *ctx)
 94{
 95	return ctx->prefill.fixed + prefill_lines_cdclk(ctx);
 96}
 97
 98void skl_prefill_init_worst(struct skl_prefill_ctx *ctx,
 99			    const struct intel_crtc_state *crtc_state)
100{
101	prefill_init_nocdclk_worst(ctx, crtc_state);
102
103	ctx->adj.cdclk = intel_cdclk_prefill_adjustment_worst(crtc_state);
104
105	ctx->prefill.full = prefill_lines_full(ctx);
106}
107
108void skl_prefill_init(struct skl_prefill_ctx *ctx,
109		      const struct intel_crtc_state *crtc_state)
110{
111	prefill_init_nocdclk(ctx, crtc_state);
112
113	ctx->adj.cdclk = intel_cdclk_prefill_adjustment(crtc_state);
114
115	ctx->prefill.full = prefill_lines_full(ctx);
116}
117
118static unsigned int prefill_lines_with_latency(const struct skl_prefill_ctx *ctx,
119					       const struct intel_crtc_state *crtc_state,
120					       unsigned int latency_us)
121{
122	return ctx->prefill.full + prefill_usecs_to_lines(crtc_state, latency_us);
123}
124
125int skl_prefill_min_guardband(const struct skl_prefill_ctx *ctx,
126			      const struct intel_crtc_state *crtc_state,
127			      unsigned int latency_us)
128{
129	unsigned int prefill = prefill_lines_with_latency(ctx, crtc_state, latency_us);
130
131	return DIV_ROUND_UP(prefill, 0x10000);
132}
133
134static unsigned int prefill_guardband(const struct intel_crtc_state *crtc_state)
135{
136	return intel_crtc_vblank_length(crtc_state) << 16;
137}
138
139bool skl_prefill_vblank_too_short(const struct skl_prefill_ctx *ctx,
140				  const struct intel_crtc_state *crtc_state,
141				  unsigned int latency_us)
142{
143	unsigned int guardband = prefill_guardband(crtc_state);
144	unsigned int prefill = prefill_lines_with_latency(ctx, crtc_state, latency_us);
145
146	return guardband < prefill;
147}
148
149int skl_prefill_min_cdclk(const struct skl_prefill_ctx *ctx,
150			  const struct intel_crtc_state *crtc_state)
151{
152	unsigned int prefill_unadjusted = prefill_lines_nocdclk(ctx);
153	unsigned int prefill_available = prefill_guardband(crtc_state) - ctx->prefill.fixed;
154
155	return intel_cdclk_min_cdclk_for_prefill(crtc_state, prefill_unadjusted,
156						 prefill_available);
157}
~/ Read-only file preview.