Commit 74ad9ec9 authored by Nemesa Garg's avatar Nemesa Garg Committed by Jani Nikula
Browse files

drm/i915/display: Add CASF strength and winsize



Add register definitions for sharpness strength and
filter window size used by CASF. Provide functions to
read and write these fields.

The sharpness strength value is determined by user input,
while the winsize is based on the resolution. The casf_enable
flag should be set if the platform supports sharpness adjustments
and the user API strength is not zero. Once sharpness is
enabled, update the strength bit of the register whenever
the user changes the strength value, as the enable bit and
winsize bit remain constant.

Introduce helper to enable, disable and update strength.
Add relavant strength and winsize in both enable and disable.

v2: Introduce get_config for casf[Ankit]
v3: Replace 0 with FILTER_STRENGTH_MASK[Ankit]
v4: After updating strength add win_sz register
v5: Replace u16 with u32 for total_pixel
v6: Add casf logging
v7: Add helper for enable and disable casf

Signed-off-by: default avatarNemesa Garg <nemesa.garg@intel.com>
Reviewed-by: default avatarAnkit Nautiyal <ankit.k.nautiyal@intel.com>
Link: https://patch.msgid.link/20251028120747.3027332-4-ankit.k.nautiyal@intel.com


Signed-off-by: default avatarJani Nikula <jani.nikula@intel.com>
parent 72a583c2
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -234,6 +234,7 @@ i915-y += \
	display/intel_bios.o \
	display/intel_bo.o \
	display/intel_bw.o \
	display/intel_casf.o \
	display/intel_cdclk.o \
	display/intel_cmtg.o \
	display/intel_color.o \
+128 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: MIT
/* Copyright © 2025 Intel Corporation */

#include <drm/drm_print.h>

#include "i915_reg.h"
#include "intel_casf.h"
#include "intel_casf_regs.h"
#include "intel_de.h"
#include "intel_display_regs.h"
#include "intel_display_types.h"

#define MAX_PIXELS_FOR_3_TAP_FILTER (1920 * 1080)
#define MAX_PIXELS_FOR_5_TAP_FILTER (3840 * 2160)

/**
 * DOC: Content Adaptive Sharpness Filter (CASF)
 *
 * Starting from LNL the display engine supports an
 * adaptive sharpening filter, enhancing the image
 * quality. The display hardware utilizes the second
 * pipe scaler for implementing CASF.
 * If sharpness is being enabled then pipe scaling
 * cannot be used.
 * This filter operates on a region of pixels based
 * on the tap size. Coefficients are used to generate
 * an alpha value which blends the sharpened image to
 * original image.
 */

void intel_casf_update_strength(struct intel_crtc_state *crtc_state)
{
	struct intel_display *display = to_intel_display(crtc_state);
	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
	int win_size;

	intel_de_rmw(display, SHARPNESS_CTL(crtc->pipe), FILTER_STRENGTH_MASK,
		     FILTER_STRENGTH(crtc_state->hw.casf_params.strength));

	win_size = intel_de_read(display, SKL_PS_WIN_SZ(crtc->pipe, 1));

	intel_de_write_fw(display, SKL_PS_WIN_SZ(crtc->pipe, 1), win_size);
}

static void intel_casf_compute_win_size(struct intel_crtc_state *crtc_state)
{
	const struct drm_display_mode *mode = &crtc_state->hw.adjusted_mode;
	u32 total_pixels = mode->hdisplay * mode->vdisplay;

	if (total_pixels <= MAX_PIXELS_FOR_3_TAP_FILTER)
		crtc_state->hw.casf_params.win_size = SHARPNESS_FILTER_SIZE_3X3;
	else if (total_pixels <= MAX_PIXELS_FOR_5_TAP_FILTER)
		crtc_state->hw.casf_params.win_size = SHARPNESS_FILTER_SIZE_5X5;
	else
		crtc_state->hw.casf_params.win_size = SHARPNESS_FILTER_SIZE_7X7;
}

int intel_casf_compute_config(struct intel_crtc_state *crtc_state)
{
	struct intel_display *display = to_intel_display(crtc_state);

	if (!HAS_CASF(display))
		return 0;

	if (crtc_state->uapi.sharpness_strength == 0) {
		crtc_state->hw.casf_params.casf_enable = false;
		crtc_state->hw.casf_params.strength = 0;
		return 0;
	}

	crtc_state->hw.casf_params.casf_enable = true;

	/*
	 * HW takes a value in form (1.0 + strength) in 4.4 fixed format.
	 * Strength is from 0.0-14.9375 ie from 0-239.
	 * User can give value from 0-255 but is clamped to 239.
	 * Ex. User gives 85 which is 5.3125 and adding 1.0 gives 6.3125.
	 * 6.3125 in 4.4 format is b01100101 which is equal to 101.
	 * Also 85 + 16 = 101.
	 */
	crtc_state->hw.casf_params.strength =
		min(crtc_state->uapi.sharpness_strength, 0xEF) + 0x10;

	intel_casf_compute_win_size(crtc_state);

	return 0;
}

void intel_casf_sharpness_get_config(struct intel_crtc_state *crtc_state)
{
	struct intel_display *display = to_intel_display(crtc_state);
	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
	u32 sharp;

	sharp = intel_de_read(display, SHARPNESS_CTL(crtc->pipe));
	if (sharp & FILTER_EN) {
		if (drm_WARN_ON(display->drm,
				REG_FIELD_GET(FILTER_STRENGTH_MASK, sharp) < 16))
			crtc_state->hw.casf_params.strength = 0;
		else
			crtc_state->hw.casf_params.strength =
				REG_FIELD_GET(FILTER_STRENGTH_MASK, sharp);
		crtc_state->hw.casf_params.casf_enable = true;
		crtc_state->hw.casf_params.win_size =
			REG_FIELD_GET(FILTER_SIZE_MASK, sharp);
	}
}

void intel_casf_enable(struct intel_crtc_state *crtc_state)
{
	struct intel_display *display = to_intel_display(crtc_state);
	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
	u32 sharpness_ctl;

	sharpness_ctl = FILTER_EN | FILTER_STRENGTH(crtc_state->hw.casf_params.strength);

	sharpness_ctl |= crtc_state->hw.casf_params.win_size;

	intel_de_write(display, SHARPNESS_CTL(crtc->pipe), sharpness_ctl);
}

void intel_casf_disable(const struct intel_crtc_state *crtc_state)
{
	struct intel_display *display = to_intel_display(crtc_state);
	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);

	intel_de_write(display, SHARPNESS_CTL(crtc->pipe), 0);
}
+19 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: MIT */
/*
 * Copyright © 2025 Intel Corporation
 */

#ifndef __INTEL_CASF_H__
#define __INTEL_CASF_H__

#include <linux/types.h>

struct intel_crtc_state;

int intel_casf_compute_config(struct intel_crtc_state *crtc_state);
void intel_casf_update_strength(struct intel_crtc_state *new_crtc_state);
void intel_casf_sharpness_get_config(struct intel_crtc_state *crtc_state);
void intel_casf_enable(struct intel_crtc_state *crtc_state);
void intel_casf_disable(const struct intel_crtc_state *crtc_state);

#endif /* __INTEL_CASF_H__ */
+22 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: MIT */
/*
 * Copyright © 2025 Intel Corporation
 */

#ifndef __INTEL_CASF_REGS_H__
#define __INTEL_CASF_REGS_H__

#include "intel_display_reg_defs.h"

#define _SHARPNESS_CTL_A		0x682B0
#define _SHARPNESS_CTL_B		0x68AB0
#define SHARPNESS_CTL(pipe)		_MMIO_PIPE(pipe, _SHARPNESS_CTL_A, _SHARPNESS_CTL_B)
#define   FILTER_EN			REG_BIT(31)
#define   FILTER_STRENGTH_MASK		REG_GENMASK(15, 8)
#define   FILTER_STRENGTH(x)		REG_FIELD_PREP(FILTER_STRENGTH_MASK, (x))
#define   FILTER_SIZE_MASK		REG_GENMASK(1, 0)
#define   SHARPNESS_FILTER_SIZE_3X3	REG_FIELD_PREP(FILTER_SIZE_MASK, 0)
#define   SHARPNESS_FILTER_SIZE_5X5	REG_FIELD_PREP(FILTER_SIZE_MASK, 1)
#define   SHARPNESS_FILTER_SIZE_7X7	REG_FIELD_PREP(FILTER_SIZE_MASK, 2)

#endif /* __INTEL_CASF_REGS__ */
+5 −0
Original line number Diff line number Diff line
@@ -372,6 +372,11 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config,

	intel_vdsc_state_dump(&p, 0, pipe_config);

	drm_printf(&p, "sharpness strength: %d, sharpness tap size: %d, sharpness enable: %d\n",
		   pipe_config->hw.casf_params.strength,
		   pipe_config->hw.casf_params.win_size,
		   pipe_config->hw.casf_params.casf_enable);

dump_planes:
	if (!state)
		return;
Loading