* [PATCHv5 2/8] drm/i915/histogram: Add support for histogram
@ 2024-11-21 14:39 Arun R Murthy
2024-11-21 14:39 ` [PATCHv3 6/8] drm/i915/histogram: histogram delay counter doesnt reset Arun R Murthy
2024-11-21 14:39 ` [PATCHv6 7/8] drm/i915/histogram: Histogram changes for Display 20+ Arun R Murthy
0 siblings, 2 replies; 6+ messages in thread
From: Arun R Murthy @ 2024-11-21 14:39 UTC (permalink / raw)
To: intel-xe, intel-gfx, dri-devel; +Cc: Arun R Murthy, Suraj Kandpal
Statistics is generated from the image frame that is coming to display
and an event is sent to user after reading this histogram data.
This statistics/histogram is then shared with the user upon getting a
request from user. User can then use this histogram and generate an
enhancement factor. This enhancement factor can be multiplied/added with
the incoming pixel data frame.
v2: forward declaration in header file along with error handling (Jani)
v3: Replaced i915 with intel_display (Suraj)
v4: Removed dithering enable/disable (Vandita)
New patch for histogram register definitions (Suraj)
v5: IET LUT pgm follow the seq in spec and removed change to TC at end
(Suraj)
Signed-off-by: Arun R Murthy <arun.r.murthy@intel.com>
Reviewed-by: Suraj Kandpal <suraj.kandpal@intel.com>
---
drivers/gpu/drm/i915/Makefile | 1 +
.../drm/i915/display/intel_display_types.h | 2 +
.../gpu/drm/i915/display/intel_histogram.c | 187 ++++++++++++++++++
.../gpu/drm/i915/display/intel_histogram.h | 35 ++++
4 files changed, 225 insertions(+)
create mode 100644 drivers/gpu/drm/i915/display/intel_histogram.c
create mode 100644 drivers/gpu/drm/i915/display/intel_histogram.h
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index e465828d748f..97141b4def3b 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -267,6 +267,7 @@ i915-y += \
display/intel_hdcp.o \
display/intel_hdcp_gsc.o \
display/intel_hdcp_gsc_message.o \
+ display/intel_histogram.o \
display/intel_hotplug.o \
display/intel_hotplug_irq.o \
display/intel_hti.o \
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 339e4b0f7698..351441efd10a 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1414,6 +1414,8 @@ struct intel_crtc {
/* for loading single buffered registers during vblank */
struct pm_qos_request vblank_pm_qos;
+ struct intel_histogram *histogram;
+
#ifdef CONFIG_DEBUG_FS
struct intel_pipe_crc pipe_crc;
#endif
diff --git a/drivers/gpu/drm/i915/display/intel_histogram.c b/drivers/gpu/drm/i915/display/intel_histogram.c
new file mode 100644
index 000000000000..12b70936c91c
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_histogram.c
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#include <drm/drm_device.h>
+#include <drm/drm_file.h>
+#include <drm/drm_vblank.h>
+
+#include "i915_reg.h"
+#include "i915_drv.h"
+#include "intel_de.h"
+#include "intel_display.h"
+#include "intel_display_types.h"
+#include "intel_histogram.h"
+#include "intel_histogram_regs.h"
+
+/* 3.0% of the pipe's current pixel count, hw does x4 */
+#define HISTOGRAM_GUARDBAND_THRESHOLD_DEFAULT 300
+/* Precision factor for threshold guardband */
+#define HISTOGRAM_GUARDBAND_PRECISION_FACTOR 10000
+#define HISTOGRAM_DEFAULT_GUARDBAND_DELAY 0x04
+
+struct intel_histogram {
+ struct intel_crtc *crtc;
+ struct delayed_work work;
+ bool enable;
+ bool can_enable;
+ u32 bin_data[HISTOGRAM_BIN_COUNT];
+};
+
+int intel_histogram_atomic_check(struct intel_crtc *intel_crtc)
+{
+ struct intel_histogram *histogram = intel_crtc->histogram;
+
+ /* TODO: Restrictions for enabling histogram */
+ histogram->can_enable = true;
+
+ return 0;
+}
+
+static int intel_histogram_enable(struct intel_crtc *intel_crtc)
+{
+ struct intel_display *display = to_intel_display(intel_crtc);
+ struct intel_histogram *histogram = intel_crtc->histogram;
+ int pipe = intel_crtc->pipe;
+ u64 res;
+ u32 gbandthreshold;
+
+ if (!histogram || !histogram->can_enable)
+ return -EINVAL;
+
+ if (histogram->enable)
+ return 0;
+
+ /* enable histogram, clear DPST_CTL bin reg func select to TC */
+ intel_de_rmw(display, DPST_CTL(pipe),
+ DPST_CTL_BIN_REG_FUNC_SEL | DPST_CTL_IE_HIST_EN |
+ DPST_CTL_HIST_MODE | DPST_CTL_IE_TABLE_VALUE_FORMAT |
+ DPST_CTL_ENHANCEMENT_MODE_MASK | DPST_CTL_IE_MODI_TABLE_EN,
+ DPST_CTL_BIN_REG_FUNC_TC | DPST_CTL_IE_HIST_EN |
+ DPST_CTL_HIST_MODE_HSV |
+ DPST_CTL_IE_TABLE_VALUE_FORMAT_1INT_9FRAC |
+ DPST_CTL_EN_MULTIPLICATIVE | DPST_CTL_IE_MODI_TABLE_EN);
+
+ /* Re-Visit: check if wait for one vblank is required */
+ drm_crtc_wait_one_vblank(&intel_crtc->base);
+
+ /* TODO: Program GuardBand Threshold needs to be moved to modeset path */
+ res = (intel_crtc->config->hw.adjusted_mode.vtotal *
+ intel_crtc->config->hw.adjusted_mode.htotal);
+
+ gbandthreshold = (res * HISTOGRAM_GUARDBAND_THRESHOLD_DEFAULT) /
+ HISTOGRAM_GUARDBAND_PRECISION_FACTOR;
+
+ /* Enable histogram interrupt mode */
+ intel_de_rmw(display, DPST_GUARD(pipe),
+ DPST_GUARD_THRESHOLD_GB_MASK |
+ DPST_GUARD_INTERRUPT_DELAY_MASK | DPST_GUARD_HIST_INT_EN,
+ DPST_GUARD_THRESHOLD_GB(gbandthreshold) |
+ DPST_GUARD_INTERRUPT_DELAY(HISTOGRAM_DEFAULT_GUARDBAND_DELAY) |
+ DPST_GUARD_HIST_INT_EN);
+
+ /* Clear pending interrupts has to be done on separate write */
+ intel_de_rmw(display, DPST_GUARD(pipe),
+ DPST_GUARD_HIST_EVENT_STATUS, 1);
+
+ histogram->enable = true;
+
+ return 0;
+}
+
+static void intel_histogram_disable(struct intel_crtc *intel_crtc)
+{
+ struct intel_display *display = to_intel_display(intel_crtc);
+ struct intel_histogram *histogram = intel_crtc->histogram;
+ int pipe = intel_crtc->pipe;
+
+ if (!histogram)
+ return;
+
+ /* If already disabled return */
+ if (histogram->enable)
+ return;
+
+ /* Clear pending interrupts and disable interrupts */
+ intel_de_rmw(display, DPST_GUARD(pipe),
+ DPST_GUARD_HIST_INT_EN | DPST_GUARD_HIST_EVENT_STATUS, 0);
+
+ /* disable DPST_CTL Histogram mode */
+ intel_de_rmw(display, DPST_CTL(pipe),
+ DPST_CTL_IE_HIST_EN, 0);
+
+ histogram->enable = false;
+}
+
+int intel_histogram_update(struct intel_crtc *intel_crtc, bool enable)
+{
+ if (enable)
+ return intel_histogram_enable(intel_crtc);
+
+ intel_histogram_disable(intel_crtc);
+ return 0;
+}
+
+int intel_histogram_set_iet_lut(struct intel_crtc *intel_crtc, u32 *data)
+{
+ struct intel_histogram *histogram = intel_crtc->histogram;
+ struct intel_display *display = to_intel_display(intel_crtc);
+ int pipe = intel_crtc->pipe;
+ int i = 0;
+
+ if (!histogram)
+ return -EINVAL;
+
+ if (!histogram->enable) {
+ drm_err(display->drm, "histogram not enabled");
+ return -EINVAL;
+ }
+
+ if (!data) {
+ drm_err(display->drm, "enhancement LUT data is NULL");
+ return -EINVAL;
+ }
+
+ /* Set DPST_CTL Bin Reg function select to IE & wait for a vblabk */
+ intel_de_rmw(display, DPST_CTL(pipe),
+ DPST_CTL_BIN_REG_FUNC_SEL, DPST_CTL_BIN_REG_FUNC_IE);
+
+ drm_crtc_wait_one_vblank(&intel_crtc->base);
+
+ /* Set DPST_CTL Bin Register Index to 0 */
+ intel_de_rmw(display, DPST_CTL(pipe),
+ DPST_CTL_BIN_REG_MASK, DPST_CTL_BIN_REG_CLEAR);
+
+ for (i = 0; i < HISTOGRAM_IET_LENGTH; i++) {
+ intel_de_rmw(display, DPST_BIN(pipe),
+ DPST_BIN_DATA_MASK, data[i]);
+ drm_dbg_atomic(display->drm, "iet_lut[%d]=%x\n", i, data[i]);
+ }
+
+ return 0;
+}
+
+void intel_histogram_finish(struct intel_crtc *intel_crtc)
+{
+ struct intel_histogram *histogram = intel_crtc->histogram;
+
+ kfree(histogram);
+}
+
+int intel_histogram_init(struct intel_crtc *intel_crtc)
+{
+ struct intel_histogram *histogram;
+
+ /* Allocate histogram internal struct */
+ histogram = kzalloc(sizeof(*histogram), GFP_KERNEL);
+ if (!histogram) {
+ return -ENOMEM;
+ }
+
+ intel_crtc->histogram = histogram;
+ histogram->crtc = intel_crtc;
+ histogram->can_enable = false;
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/i915/display/intel_histogram.h b/drivers/gpu/drm/i915/display/intel_histogram.h
new file mode 100644
index 000000000000..9d66724f9c53
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_histogram.h
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#ifndef __INTEL_HISTOGRAM_H__
+#define __INTEL_HISTOGRAM_H__
+
+#include <linux/types.h>
+
+struct intel_crtc;
+
+#define HISTOGRAM_BIN_COUNT 32
+#define HISTOGRAM_IET_LENGTH 33
+
+enum intel_global_hist_status {
+ INTEL_HISTOGRAM_ENABLE,
+ INTEL_HISTOGRAM_DISABLE,
+};
+
+enum intel_global_histogram {
+ INTEL_HISTOGRAM,
+};
+
+enum intel_global_hist_lut {
+ INTEL_HISTOGRAM_PIXEL_FACTOR,
+};
+
+int intel_histogram_atomic_check(struct intel_crtc *intel_crtc);
+int intel_histogram_update(struct intel_crtc *intel_crtc, bool enable);
+int intel_histogram_set_iet_lut(struct intel_crtc *intel_crtc, u32 *data);
+int intel_histogram_init(struct intel_crtc *intel_crtc);
+void intel_histogram_finish(struct intel_crtc *intel_crtc);
+
+#endif /* __INTEL_HISTOGRAM_H__ */
--
2.25.1
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCHv3 6/8] drm/i915/histogram: histogram delay counter doesnt reset 2024-11-21 14:39 [PATCHv5 2/8] drm/i915/histogram: Add support for histogram Arun R Murthy @ 2024-11-21 14:39 ` Arun R Murthy 2024-11-21 14:39 ` [PATCHv6 7/8] drm/i915/histogram: Histogram changes for Display 20+ Arun R Murthy 1 sibling, 0 replies; 6+ messages in thread From: Arun R Murthy @ 2024-11-21 14:39 UTC (permalink / raw) To: intel-xe, intel-gfx, dri-devel; +Cc: Arun R Murthy The delay counter for histogram does not reset and as a result the histogram bin never gets updated. Workaround would be to use save and restore histogram register. v2: Follow the seq in interrupt handler Restore DPST bit 0 read/write dpst ctl rg Restore DPST bit 1 and Guardband Delay Interrupt counter = 0 (Suraj) v3: updated wa version for display 13 and 14 Wa: 14014889975 Signed-off-by: Arun R Murthy <arun.r.murthy@intel.com> --- drivers/gpu/drm/i915/display/intel_histogram.c | 14 ++++++++++++++ .../gpu/drm/i915/display/intel_histogram_regs.h | 2 ++ 2 files changed, 16 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_histogram.c b/drivers/gpu/drm/i915/display/intel_histogram.c index add303df21d5..7b27c7227a8a 100644 --- a/drivers/gpu/drm/i915/display/intel_histogram.c +++ b/drivers/gpu/drm/i915/display/intel_histogram.c @@ -59,6 +59,11 @@ static void intel_histogram_handle_int_work(struct work_struct *work) snprintf(pipe_id, sizeof(pipe_id), "PIPE=%u", intel_crtc->base.base.id); + /* Wa: 14014889975 */ + if (IS_DISPLAY_VER(display, 13, 14)) + intel_de_rmw(display, DPST_CTL(intel_crtc->pipe), + DPST_CTL_RESTORE, 0); + /* * TODO: PSR to be exited while reading the Histogram data * Set DPST_CTL Bin Reg function select to TC @@ -86,6 +91,15 @@ static void intel_histogram_handle_int_work(struct work_struct *work) return; } + /* Wa: 14014889975 */ + if (IS_DISPLAY_VER(display, 13, 14)) + /* Write the value read from DPST_CTL to DPST_CTL.Interrupt Delay Counter(bit 23:16) */ + intel_de_rmw(display, DPST_CTL(intel_crtc->pipe), + DPST_CTL_GUARDBAND_INTERRUPT_DELAY_CNT | + DPST_CTL_RESTORE, + DPST_CTL_GUARDBAND_INTERRUPT_DELAY(0x0) | + DPST_CTL_RESTORE); + /* Enable histogram interrupt */ intel_de_rmw(display, DPST_GUARD(intel_crtc->pipe), DPST_GUARD_HIST_INT_EN, DPST_GUARD_HIST_INT_EN); diff --git a/drivers/gpu/drm/i915/display/intel_histogram_regs.h b/drivers/gpu/drm/i915/display/intel_histogram_regs.h index 1252b4f339a6..213c9f483567 100644 --- a/drivers/gpu/drm/i915/display/intel_histogram_regs.h +++ b/drivers/gpu/drm/i915/display/intel_histogram_regs.h @@ -16,6 +16,8 @@ #define DPST_CTL_RESTORE REG_BIT(28) #define DPST_CTL_IE_MODI_TABLE_EN REG_BIT(27) #define DPST_CTL_HIST_MODE REG_BIT(24) +#define DPST_CTL_GUARDBAND_INTERRUPT_DELAY_CNT REG_GENMASK(23, 16) +#define DPST_CTL_GUARDBAND_INTERRUPT_DELAY(val) REG_FIELD_PREP(DPST_CTL_GUARDBAND_INTERRUPT_DELAY_CNT, val) #define DPST_CTL_ENHANCEMENT_MODE_MASK REG_GENMASK(14, 13) #define DPST_CTL_EN_MULTIPLICATIVE REG_FIELD_PREP(DPST_CTL_ENHANCEMENT_MODE_MASK, 2) #define DPST_CTL_IE_TABLE_VALUE_FORMAT REG_BIT(15) -- 2.25.1 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCHv6 7/8] drm/i915/histogram: Histogram changes for Display 20+ 2024-11-21 14:39 [PATCHv5 2/8] drm/i915/histogram: Add support for histogram Arun R Murthy 2024-11-21 14:39 ` [PATCHv3 6/8] drm/i915/histogram: histogram delay counter doesnt reset Arun R Murthy @ 2024-11-21 14:39 ` Arun R Murthy 1 sibling, 0 replies; 6+ messages in thread From: Arun R Murthy @ 2024-11-21 14:39 UTC (permalink / raw) To: intel-xe, intel-gfx, dri-devel; +Cc: Arun R Murthy In Display 20+, new registers are added for setting index, reading histogram and writing the IET. v2: Removed duplicate code (Jani) v3: Moved histogram core changes to earlier patches (Jani/Suraj) v4: Rebased after addressing comments on patch 1 v5: Added the retry logic from patch3 and rebased the patch series v6: optimize wite_iet() (Suraj) Bspec: 68895 Signed-off-by: Arun R Murthy <arun.r.murthy@intel.com> --- .../gpu/drm/i915/display/intel_histogram.c | 105 +++++++++++++----- .../drm/i915/display/intel_histogram_regs.h | 25 +++++ 2 files changed, 103 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_histogram.c b/drivers/gpu/drm/i915/display/intel_histogram.c index 7b27c7227a8a..475d29441612 100644 --- a/drivers/gpu/drm/i915/display/intel_histogram.c +++ b/drivers/gpu/drm/i915/display/intel_histogram.c @@ -29,6 +29,37 @@ struct intel_histogram { u32 bin_data[HISTOGRAM_BIN_COUNT]; }; +static void set_bin_index_0(struct intel_display *display, enum pipe pipe) +{ + if (DISPLAY_VER(display) >= 20) + intel_de_rmw(display, DPST_IE_INDEX(pipe), + DPST_IE_BIN_INDEX_MASK, DPST_IE_BIN_INDEX(0)); + else + intel_de_rmw(display, DPST_CTL(pipe), + DPST_CTL_BIN_REG_MASK, + DPST_CTL_BIN_REG_CLEAR); +} + +static void write_iet(struct intel_display *display, enum pipe pipe, + u32 *data) +{ + int i; + + for (i = 0; i < HISTOGRAM_IET_LENGTH; i++) { + if (DISPLAY_VER(display) >= 20) + intel_de_rmw(display, DPST_IE_BIN(pipe), + DPST_IE_BIN_DATA_MASK, + DPST_IE_BIN_DATA(data[i])); + else + intel_de_rmw(display, DPST_BIN(pipe), + DPST_BIN_DATA_MASK, + DPST_BIN_DATA(data[i])); + + drm_dbg_atomic(display->drm, "iet_lut[%d]=%x\n", + i, data[i]); + } +} + static bool intel_histogram_get_data(struct intel_crtc *intel_crtc) { struct intel_display *display = to_intel_display(intel_crtc); @@ -36,12 +67,27 @@ static bool intel_histogram_get_data(struct intel_crtc *intel_crtc) int index; u32 dpstbin; + if (DISPLAY_VER(display) >= 20) + intel_de_rmw(display, DPST_HIST_INDEX(intel_crtc->pipe), + DPST_HIST_BIN_INDEX_MASK, + DPST_HIST_BIN_INDEX(0)); + else + intel_de_rmw(display, DPST_CTL(intel_crtc->pipe), + DPST_CTL_BIN_REG_FUNC_SEL | DPST_CTL_BIN_REG_MASK, 0); + for (index = 0; index < ARRAY_SIZE(histogram->bin_data); index++) { - dpstbin = intel_de_read(display, DPST_BIN(intel_crtc->pipe)); + dpstbin = intel_de_read(display, (DISPLAY_VER(display) >= 20 ? + DPST_HIST_BIN(intel_crtc->pipe) : + DPST_BIN(intel_crtc->pipe))); if (!(dpstbin & DPST_BIN_BUSY)) { - histogram->bin_data[index] = dpstbin & DPST_BIN_DATA_MASK; - } else + histogram->bin_data[index] = dpstbin & (DISPLAY_VER(display) >= 20 ? + DPST_HIST_BIN_DATA_MASK : + DPST_BIN_DATA_MASK); + } else { + drm_err(display->drm, "Histogram bin busy, retyring\n"); + fsleep(2); return false; + } } return true; } @@ -69,8 +115,6 @@ static void intel_histogram_handle_int_work(struct work_struct *work) * Set DPST_CTL Bin Reg function select to TC * Set DPST_CTL Bin Register Index to 0 */ - intel_de_rmw(display, DPST_CTL(intel_crtc->pipe), - DPST_CTL_BIN_REG_FUNC_SEL | DPST_CTL_BIN_REG_MASK, 0); for (retry = 0; retry < HISTOGRAM_BIN_READ_RETRY_COUNT; retry++) { if (intel_histogram_get_data(intel_crtc)) { drm_property_replace_global_blob(display->drm, @@ -150,15 +194,26 @@ static int intel_histogram_enable(struct intel_crtc *intel_crtc) if (histogram->enable) return 0; - /* enable histogram, clear DPST_CTL bin reg func select to TC */ - intel_de_rmw(display, DPST_CTL(pipe), - DPST_CTL_BIN_REG_FUNC_SEL | DPST_CTL_IE_HIST_EN | - DPST_CTL_HIST_MODE | DPST_CTL_IE_TABLE_VALUE_FORMAT | - DPST_CTL_ENHANCEMENT_MODE_MASK | DPST_CTL_IE_MODI_TABLE_EN, - DPST_CTL_BIN_REG_FUNC_TC | DPST_CTL_IE_HIST_EN | - DPST_CTL_HIST_MODE_HSV | - DPST_CTL_IE_TABLE_VALUE_FORMAT_1INT_9FRAC | - DPST_CTL_EN_MULTIPLICATIVE | DPST_CTL_IE_MODI_TABLE_EN); + /* enable histogram, clear DPST_BIN reg and select TC function */ + if (DISPLAY_VER(display) >= 20) + intel_de_rmw(display, DPST_CTL(pipe), + DPST_CTL_IE_HIST_EN | + DPST_CTL_HIST_MODE, + DPST_CTL_IE_HIST_EN | + DPST_CTL_HIST_MODE_HSV); + else + /* enable histogram, clear DPST_BIN reg and select TC function */ + intel_de_rmw(display, DPST_CTL(pipe), + DPST_CTL_BIN_REG_FUNC_SEL | DPST_CTL_IE_HIST_EN | + DPST_CTL_HIST_MODE | + DPST_CTL_IE_TABLE_VALUE_FORMAT | + DPST_CTL_ENHANCEMENT_MODE_MASK | + DPST_CTL_IE_MODI_TABLE_EN, + DPST_CTL_BIN_REG_FUNC_TC | DPST_CTL_IE_HIST_EN | + DPST_CTL_HIST_MODE_HSV | + DPST_CTL_IE_TABLE_VALUE_FORMAT_1INT_9FRAC | + DPST_CTL_EN_MULTIPLICATIVE | + DPST_CTL_IE_MODI_TABLE_EN); /* Re-Visit: check if wait for one vblank is required */ drm_crtc_wait_one_vblank(&intel_crtc->base); @@ -227,7 +282,6 @@ int intel_histogram_set_iet_lut(struct intel_crtc *intel_crtc, u32 *data) struct intel_histogram *histogram = intel_crtc->histogram; struct intel_display *display = to_intel_display(intel_crtc); int pipe = intel_crtc->pipe; - int i = 0; if (!histogram) return -EINVAL; @@ -242,22 +296,19 @@ int intel_histogram_set_iet_lut(struct intel_crtc *intel_crtc, u32 *data) return -EINVAL; } - /* Set DPST_CTL Bin Reg function select to IE & wait for a vblabk */ - intel_de_rmw(display, DPST_CTL(pipe), - DPST_CTL_BIN_REG_FUNC_SEL, DPST_CTL_BIN_REG_FUNC_IE); - drm_crtc_wait_one_vblank(&intel_crtc->base); + if (DISPLAY_VER(display) < 20) { + /* Set DPST_CTL Bin Reg function select to IE & wait for a vblabk */ + intel_de_rmw(display, DPST_CTL(pipe), + DPST_CTL_BIN_REG_FUNC_SEL, + DPST_CTL_BIN_REG_FUNC_IE); - /* Set DPST_CTL Bin Register Index to 0 */ - intel_de_rmw(display, DPST_CTL(pipe), - DPST_CTL_BIN_REG_MASK, DPST_CTL_BIN_REG_CLEAR); - - for (i = 0; i < HISTOGRAM_IET_LENGTH; i++) { - intel_de_rmw(display, DPST_BIN(pipe), - DPST_BIN_DATA_MASK, data[i]); - drm_dbg_atomic(display->drm, "iet_lut[%d]=%x\n", i, data[i]); + drm_crtc_wait_one_vblank(&intel_crtc->base); } + set_bin_index_0(display, pipe); + write_iet(display, pipe, data); + return 0; } diff --git a/drivers/gpu/drm/i915/display/intel_histogram_regs.h b/drivers/gpu/drm/i915/display/intel_histogram_regs.h index 213c9f483567..3fbb9c2deaae 100644 --- a/drivers/gpu/drm/i915/display/intel_histogram_regs.h +++ b/drivers/gpu/drm/i915/display/intel_histogram_regs.h @@ -45,6 +45,31 @@ #define _DPST_BIN_B 0x491C4 #define DPST_BIN(pipe) _MMIO_PIPE(pipe, _DPST_BIN_A, _DPST_BIN_B) #define DPST_BIN_DATA_MASK REG_GENMASK(23, 0) +#define DPST_BIN_DATA(val) REG_FIELD_PREP(DPST_BIN_DATA_MASK, val) #define DPST_BIN_BUSY REG_BIT(31) +#define _DPST_HIST_INDEX_A 0x490D8 +#define _DPST_HIST_INDEX_B 0x491D8 +#define DPST_HIST_INDEX(pipe) _MMIO_PIPE(pipe, _DPST_HIST_INDEX_A, _DPST_HIST_INDEX_B) +#define DPST_HIST_BIN_INDEX_MASK REG_GENMASK(4, 0) +#define DPST_HIST_BIN_INDEX(val) REG_FIELD_PREP(DPST_HIST_BIN_INDEX_MASK, val) + +#define _DPST_HIST_BIN_A 0x490C4 +#define _DPST_HIST_BIN_B 0x491C4 +#define DPST_HIST_BIN(pipe) _MMIO_PIPE(pipe, _DPST_HIST_BIN_A, _DPST_HIST_BIN_B) +#define DPST_HIST_BIN_BUSY REG_BIT(31) +#define DPST_HIST_BIN_DATA_MASK REG_GENMASK(30, 0) + +#define _DPST_IE_BIN_A 0x490CC +#define _DPST_IE_BIN_B 0x491CC +#define DPST_IE_BIN(pipe) _MMIO_PIPE(pipe, _DPST_IE_BIN_A, _DPST_IE_BIN_B) +#define DPST_IE_BIN_DATA_MASK REG_GENMASK(9, 0) +#define DPST_IE_BIN_DATA(val) REG_FIELD_PREP(DPST_IE_BIN_DATA_MASK, val) + +#define _DPST_IE_INDEX_A 0x490DC +#define _DPST_IE_INDEX_B 0x491DC +#define DPST_IE_INDEX(pipe) _MMIO_PIPE(pipe, _DPST_IE_INDEX_A, _DPST_IE_INDEX_B) +#define DPST_IE_BIN_INDEX_MASK REG_GENMASK(6, 0) +#define DPST_IE_BIN_INDEX(val) REG_FIELD_PREP(DPST_IE_BIN_INDEX_MASK, val) + #endif /* __INTEL_HISTOGRAM_REGS_H__ */ -- 2.25.1 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 0/8] Display Global Histogram @ 2024-11-21 12:25 Arun R Murthy 2024-11-21 12:25 ` [PATCHv5 2/8] drm/i915/histogram: Add support for histogram Arun R Murthy 0 siblings, 1 reply; 6+ messages in thread From: Arun R Murthy @ 2024-11-21 12:25 UTC (permalink / raw) To: intel-xe, intel-gfx, dri-devel; +Cc: Arun R Murthy Display histogram is a hardware functionality where a statistics for 'x' number of frames is generated to form a histogram data. This is notified to the user via histogram event. Compositor will then upon sensing the histogram event will read the histogram data from KMD via crtc property. A library can be developed to take this generated histogram as an input and apply some algorithm to generate an Image EnhancemenT(IET). This is further fed back to the KMD via crtc property. KMD will use this IET as a multiplicand factor to multiply with the incoming pixels at the end of the pipe which is then pushed onto the display. One such library Global Histogram Enhancement(GHE) will take the histogram as input and applied the algorithm to enhance the density and then return the enhanced factor. This library can be located @ https://github.com/intel/ghe The corresponding mutter changes to enable/disable histogram, read the histogram data, communicate with the library and write the enhanced data back to the KMD is also pushed for review at https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3873 The IGT changes for validating the histogram event and reading the histogram is also pushed for review at https://patchwork.freedesktop.org/series/135789/ Test-with: 20240705091333.328322-1-mohammed.thasleem@intel.com Arun R Murthy (8): drm/i915/histogram: Define registers for histogram drm/i915/histogram: Add support for histogram drm/xe: Add histogram support to Xe builds drm/i915/histogram: histogram interrupt handling drm/i915/histogram: Add crtc properties for global histogram drm/i915/histogram: histogram delay counter doesnt reset drm/i915/histogram: Histogram changes for Display 20+ drm/i915/histogram: Enable pipe dithering drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/display/intel_atomic.c | 5 + drivers/gpu/drm/i915/display/intel_crtc.c | 166 +++++++- drivers/gpu/drm/i915/display/intel_crtc.h | 5 + drivers/gpu/drm/i915/display/intel_display.c | 16 + .../gpu/drm/i915/display/intel_display_irq.c | 6 +- .../drm/i915/display/intel_display_types.h | 15 + .../gpu/drm/i915/display/intel_histogram.c | 354 ++++++++++++++++++ .../gpu/drm/i915/display/intel_histogram.h | 38 ++ .../drm/i915/display/intel_histogram_regs.h | 75 ++++ drivers/gpu/drm/i915/i915_reg.h | 5 +- drivers/gpu/drm/xe/Makefile | 1 + 12 files changed, 683 insertions(+), 4 deletions(-) create mode 100644 drivers/gpu/drm/i915/display/intel_histogram.c create mode 100644 drivers/gpu/drm/i915/display/intel_histogram.h create mode 100644 drivers/gpu/drm/i915/display/intel_histogram_regs.h -- 2.25.1 ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCHv5 2/8] drm/i915/histogram: Add support for histogram 2024-11-21 12:25 [PATCH 0/8] Display Global Histogram Arun R Murthy @ 2024-11-21 12:25 ` Arun R Murthy 2024-11-21 13:44 ` Kandpal, Suraj 0 siblings, 1 reply; 6+ messages in thread From: Arun R Murthy @ 2024-11-21 12:25 UTC (permalink / raw) To: intel-xe, intel-gfx, dri-devel; +Cc: Arun R Murthy Statistics is generated from the image frame that is coming to display and an event is sent to user after reading this histogram data. This statistics/histogram is then shared with the user upon getting a request from user. User can then use this histogram and generate an enhancement factor. This enhancement factor can be multiplied/added with the incoming pixel data frame. v2: forward declaration in header file along with error handling (Jani) v3: Replaced i915 with intel_display (Suraj) v4: Removed dithering enable/disable (Vandita) New patch for histogram register definitions (Suraj) v5: IET LUT pgm follow the seq in spec and removed change to TC at end (Suraj) Signed-off-by: Arun R Murthy <arun.r.murthy@intel.com> --- drivers/gpu/drm/i915/Makefile | 1 + .../drm/i915/display/intel_display_types.h | 2 + .../gpu/drm/i915/display/intel_histogram.c | 190 ++++++++++++++++++ .../gpu/drm/i915/display/intel_histogram.h | 35 ++++ 4 files changed, 228 insertions(+) create mode 100644 drivers/gpu/drm/i915/display/intel_histogram.c create mode 100644 drivers/gpu/drm/i915/display/intel_histogram.h diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index e465828d748f..97141b4def3b 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -267,6 +267,7 @@ i915-y += \ display/intel_hdcp.o \ display/intel_hdcp_gsc.o \ display/intel_hdcp_gsc_message.o \ + display/intel_histogram.o \ display/intel_hotplug.o \ display/intel_hotplug_irq.o \ display/intel_hti.o \ diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 339e4b0f7698..351441efd10a 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1414,6 +1414,8 @@ struct intel_crtc { /* for loading single buffered registers during vblank */ struct pm_qos_request vblank_pm_qos; + struct intel_histogram *histogram; + #ifdef CONFIG_DEBUG_FS struct intel_pipe_crc pipe_crc; #endif diff --git a/drivers/gpu/drm/i915/display/intel_histogram.c b/drivers/gpu/drm/i915/display/intel_histogram.c new file mode 100644 index 000000000000..b2dda88a8093 --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_histogram.c @@ -0,0 +1,190 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright © 2024 Intel Corporation + */ + +#include <drm/drm_device.h> +#include <drm/drm_file.h> +#include <drm/drm_vblank.h> + +#include "i915_reg.h" +#include "i915_drv.h" +#include "intel_de.h" +#include "intel_display.h" +#include "intel_display_types.h" +#include "intel_histogram.h" +#include "intel_histogram_regs.h" + +/* 3.0% of the pipe's current pixel count, hw does x4 */ +#define HISTOGRAM_GUARDBAND_THRESHOLD_DEFAULT 300 +/* Precision factor for threshold guardband */ +#define HISTOGRAM_GUARDBAND_PRECISION_FACTOR 10000 +#define HISTOGRAM_DEFAULT_GUARDBAND_DELAY 0x04 + +struct intel_histogram { + struct intel_crtc *crtc; + struct delayed_work work; + bool enable; + bool can_enable; + u32 bin_data[HISTOGRAM_BIN_COUNT]; +}; + +int intel_histogram_atomic_check(struct intel_crtc *intel_crtc) +{ + struct intel_histogram *histogram = intel_crtc->histogram; + + /* TODO: Restrictions for enabling histogram */ + histogram->can_enable = true; + + return 0; +} + +static int intel_histogram_enable(struct intel_crtc *intel_crtc) +{ + struct intel_display *display = to_intel_display(intel_crtc); + struct intel_histogram *histogram = intel_crtc->histogram; + int pipe = intel_crtc->pipe; + u64 res; + u32 gbandthreshold; + + if (!histogram) + return -EINVAL; + + if (!histogram->can_enable) + return -EINVAL; + + if (histogram->enable) + return 0; + + /* enable histogram, clear DPST_CTL bin reg func select to TC */ + intel_de_rmw(display, DPST_CTL(pipe), + DPST_CTL_BIN_REG_FUNC_SEL | DPST_CTL_IE_HIST_EN | + DPST_CTL_HIST_MODE | DPST_CTL_IE_TABLE_VALUE_FORMAT | + DPST_CTL_ENHANCEMENT_MODE_MASK | DPST_CTL_IE_MODI_TABLE_EN, + DPST_CTL_BIN_REG_FUNC_TC | DPST_CTL_IE_HIST_EN | + DPST_CTL_HIST_MODE_HSV | + DPST_CTL_IE_TABLE_VALUE_FORMAT_1INT_9FRAC | + DPST_CTL_EN_MULTIPLICATIVE | DPST_CTL_IE_MODI_TABLE_EN); + + /* Re-Visit: check if wait for one vblank is required */ + drm_crtc_wait_one_vblank(&intel_crtc->base); + + /* TODO: Program GuardBand Threshold: To be moved to modeset path */ + res = (intel_crtc->config->hw.adjusted_mode.vtotal * + intel_crtc->config->hw.adjusted_mode.htotal); + + gbandthreshold = (res * HISTOGRAM_GUARDBAND_THRESHOLD_DEFAULT) / + HISTOGRAM_GUARDBAND_PRECISION_FACTOR; + + /* Enable histogram interrupt mode */ + intel_de_rmw(display, DPST_GUARD(pipe), + DPST_GUARD_THRESHOLD_GB_MASK | + DPST_GUARD_INTERRUPT_DELAY_MASK | DPST_GUARD_HIST_INT_EN, + DPST_GUARD_THRESHOLD_GB(gbandthreshold) | + DPST_GUARD_INTERRUPT_DELAY(HISTOGRAM_DEFAULT_GUARDBAND_DELAY) | + DPST_GUARD_HIST_INT_EN); + + /* Clear pending interrupts has to be done on separate write */ + intel_de_rmw(display, DPST_GUARD(pipe), + DPST_GUARD_HIST_EVENT_STATUS, 1); + + histogram->enable = true; + + return 0; +} + +static void intel_histogram_disable(struct intel_crtc *intel_crtc) +{ + struct intel_display *display = to_intel_display(intel_crtc); + struct intel_histogram *histogram = intel_crtc->histogram; + int pipe = intel_crtc->pipe; + + if (!histogram) + return; + + /* If already disabled return */ + if (histogram->enable) + return; + + /* Clear pending interrupts and disable interrupts */ + intel_de_rmw(display, DPST_GUARD(pipe), + DPST_GUARD_HIST_INT_EN | DPST_GUARD_HIST_EVENT_STATUS, 0); + + /* disable DPST_CTL Histogram mode */ + intel_de_rmw(display, DPST_CTL(pipe), + DPST_CTL_IE_HIST_EN, 0); + + histogram->enable = false; +} + +int intel_histogram_update(struct intel_crtc *intel_crtc, bool enable) +{ + if (enable) + return intel_histogram_enable(intel_crtc); + + intel_histogram_disable(intel_crtc); + return 0; +} + +int intel_histogram_set_iet_lut(struct intel_crtc *intel_crtc, u32 *data) +{ + struct intel_histogram *histogram = intel_crtc->histogram; + struct intel_display *display = to_intel_display(intel_crtc); + int pipe = intel_crtc->pipe; + int i = 0; + + if (!histogram) + return -EINVAL; + + if (!histogram->enable) { + drm_err(display->drm, "histogram not enabled"); + return -EINVAL; + } + + if (!data) { + drm_err(display->drm, "enhancement LUT data is NULL"); + return -EINVAL; + } + + /* Set DPST_CTL Bin Reg function select to IE & wait for a vblabk */ + intel_de_rmw(display, DPST_CTL(pipe), + DPST_CTL_BIN_REG_FUNC_SEL, DPST_CTL_BIN_REG_FUNC_IE); + + drm_crtc_wait_one_vblank(&intel_crtc->base); + + /* Set DPST_CTL Bin Register Index to 0 */ + intel_de_rmw(display, DPST_CTL(pipe), + DPST_CTL_BIN_REG_MASK, DPST_CTL_BIN_REG_CLEAR); + + for (i = 0; i < HISTOGRAM_IET_LENGTH; i++) { + intel_de_rmw(display, DPST_BIN(pipe), + DPST_BIN_DATA_MASK, data[i]); + drm_dbg_atomic(display->drm, "iet_lut[%d]=%x\n", i, data[i]); + } + + return 0; +} + +void intel_histogram_finish(struct intel_crtc *intel_crtc) +{ + struct intel_histogram *histogram = intel_crtc->histogram; + + kfree(histogram); +} + +int intel_histogram_init(struct intel_crtc *intel_crtc) +{ + struct intel_histogram *histogram; + + /* Allocate histogram internal struct */ + histogram = kzalloc(sizeof(*histogram), GFP_KERNEL); + if (!histogram) { + return -ENOMEM; + } + + intel_crtc->histogram = histogram; + histogram->crtc = intel_crtc; + histogram->can_enable = false; + + return 0; +} diff --git a/drivers/gpu/drm/i915/display/intel_histogram.h b/drivers/gpu/drm/i915/display/intel_histogram.h new file mode 100644 index 000000000000..9d66724f9c53 --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_histogram.h @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright © 2024 Intel Corporation + */ + +#ifndef __INTEL_HISTOGRAM_H__ +#define __INTEL_HISTOGRAM_H__ + +#include <linux/types.h> + +struct intel_crtc; + +#define HISTOGRAM_BIN_COUNT 32 +#define HISTOGRAM_IET_LENGTH 33 + +enum intel_global_hist_status { + INTEL_HISTOGRAM_ENABLE, + INTEL_HISTOGRAM_DISABLE, +}; + +enum intel_global_histogram { + INTEL_HISTOGRAM, +}; + +enum intel_global_hist_lut { + INTEL_HISTOGRAM_PIXEL_FACTOR, +}; + +int intel_histogram_atomic_check(struct intel_crtc *intel_crtc); +int intel_histogram_update(struct intel_crtc *intel_crtc, bool enable); +int intel_histogram_set_iet_lut(struct intel_crtc *intel_crtc, u32 *data); +int intel_histogram_init(struct intel_crtc *intel_crtc); +void intel_histogram_finish(struct intel_crtc *intel_crtc); + +#endif /* __INTEL_HISTOGRAM_H__ */ -- 2.25.1 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* RE: [PATCHv5 2/8] drm/i915/histogram: Add support for histogram 2024-11-21 12:25 ` [PATCHv5 2/8] drm/i915/histogram: Add support for histogram Arun R Murthy @ 2024-11-21 13:44 ` Kandpal, Suraj 2024-11-21 14:22 ` Murthy, Arun R 0 siblings, 1 reply; 6+ messages in thread From: Kandpal, Suraj @ 2024-11-21 13:44 UTC (permalink / raw) To: Murthy, Arun R, intel-xe@lists.freedesktop.org, intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org Cc: Murthy, Arun R > -----Original Message----- > From: Intel-xe <intel-xe-bounces@lists.freedesktop.org> On Behalf Of Arun R > Murthy > Sent: Thursday, November 21, 2024 5:56 PM > To: intel-xe@lists.freedesktop.org; intel-gfx@lists.freedesktop.org; dri- > devel@lists.freedesktop.org > Cc: Murthy, Arun R <arun.r.murthy@intel.com> > Subject: [PATCHv5 2/8] drm/i915/histogram: Add support for histogram > > Statistics is generated from the image frame that is coming to display and an > event is sent to user after reading this histogram data. > This statistics/histogram is then shared with the user upon getting a request > from user. User can then use this histogram and generate an enhancement > factor. This enhancement factor can be multiplied/added with the incoming > pixel data frame. > > v2: forward declaration in header file along with error handling (Jani) > v3: Replaced i915 with intel_display (Suraj) > v4: Removed dithering enable/disable (Vandita) > New patch for histogram register definitions (Suraj) > v5: IET LUT pgm follow the seq in spec and removed change to TC at end > (Suraj) > I think some comments were missed need to address them but nothing major > Signed-off-by: Arun R Murthy <arun.r.murthy@intel.com> > --- > drivers/gpu/drm/i915/Makefile | 1 + > .../drm/i915/display/intel_display_types.h | 2 + > .../gpu/drm/i915/display/intel_histogram.c | 190 ++++++++++++++++++ > .../gpu/drm/i915/display/intel_histogram.h | 35 ++++ > 4 files changed, 228 insertions(+) > create mode 100644 drivers/gpu/drm/i915/display/intel_histogram.c > create mode 100644 drivers/gpu/drm/i915/display/intel_histogram.h > > diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile > index e465828d748f..97141b4def3b 100644 > --- a/drivers/gpu/drm/i915/Makefile > +++ b/drivers/gpu/drm/i915/Makefile > @@ -267,6 +267,7 @@ i915-y += \ > display/intel_hdcp.o \ > display/intel_hdcp_gsc.o \ > display/intel_hdcp_gsc_message.o \ > + display/intel_histogram.o \ > display/intel_hotplug.o \ > display/intel_hotplug_irq.o \ > display/intel_hti.o \ > diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h > b/drivers/gpu/drm/i915/display/intel_display_types.h > index 339e4b0f7698..351441efd10a 100644 > --- a/drivers/gpu/drm/i915/display/intel_display_types.h > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h > @@ -1414,6 +1414,8 @@ struct intel_crtc { > /* for loading single buffered registers during vblank */ > struct pm_qos_request vblank_pm_qos; > > + struct intel_histogram *histogram; > + > #ifdef CONFIG_DEBUG_FS > struct intel_pipe_crc pipe_crc; > #endif > diff --git a/drivers/gpu/drm/i915/display/intel_histogram.c > b/drivers/gpu/drm/i915/display/intel_histogram.c > new file mode 100644 > index 000000000000..b2dda88a8093 > --- /dev/null > +++ b/drivers/gpu/drm/i915/display/intel_histogram.c > @@ -0,0 +1,190 @@ > +// SPDX-License-Identifier: MIT > +/* > + * Copyright © 2024 Intel Corporation > + */ > + > +#include <drm/drm_device.h> > +#include <drm/drm_file.h> > +#include <drm/drm_vblank.h> > + > +#include "i915_reg.h" > +#include "i915_drv.h" > +#include "intel_de.h" > +#include "intel_display.h" > +#include "intel_display_types.h" > +#include "intel_histogram.h" > +#include "intel_histogram_regs.h" > + > +/* 3.0% of the pipe's current pixel count, hw does x4 */ #define > +HISTOGRAM_GUARDBAND_THRESHOLD_DEFAULT 300 > +/* Precision factor for threshold guardband */ #define > +HISTOGRAM_GUARDBAND_PRECISION_FACTOR 10000 #define > +HISTOGRAM_DEFAULT_GUARDBAND_DELAY 0x04 > + > +struct intel_histogram { > + struct intel_crtc *crtc; > + struct delayed_work work; > + bool enable; > + bool can_enable; > + u32 bin_data[HISTOGRAM_BIN_COUNT]; > +}; > + > +int intel_histogram_atomic_check(struct intel_crtc *intel_crtc) { > + struct intel_histogram *histogram = intel_crtc->histogram; > + > + /* TODO: Restrictions for enabling histogram */ > + histogram->can_enable = true; > + > + return 0; > +} > + > +static int intel_histogram_enable(struct intel_crtc *intel_crtc) { > + struct intel_display *display = to_intel_display(intel_crtc); > + struct intel_histogram *histogram = intel_crtc->histogram; > + int pipe = intel_crtc->pipe; > + u64 res; > + u32 gbandthreshold; > + > + if (!histogram) > + return -EINVAL; > + > + if (!histogram->can_enable) > + return -EINVAL; Nit: the above two conditions can be combined with && > + > + if (histogram->enable) > + return 0; > + > + /* enable histogram, clear DPST_CTL bin reg func select to TC */ > + intel_de_rmw(display, DPST_CTL(pipe), > + DPST_CTL_BIN_REG_FUNC_SEL | DPST_CTL_IE_HIST_EN | > + DPST_CTL_HIST_MODE | > DPST_CTL_IE_TABLE_VALUE_FORMAT | > + DPST_CTL_ENHANCEMENT_MODE_MASK | > DPST_CTL_IE_MODI_TABLE_EN, > + DPST_CTL_BIN_REG_FUNC_TC | DPST_CTL_IE_HIST_EN | > + DPST_CTL_HIST_MODE_HSV | > + DPST_CTL_IE_TABLE_VALUE_FORMAT_1INT_9FRAC | > + DPST_CTL_EN_MULTIPLICATIVE | > DPST_CTL_IE_MODI_TABLE_EN); > + > + /* Re-Visit: check if wait for one vblank is required */ > + drm_crtc_wait_one_vblank(&intel_crtc->base); > + > + /* TODO: Program GuardBand Threshold: To be moved to modeset > path */ I wanted this to be something like this /* TODO: Program GuardBand Threshold needs to be moved to modeset path */ > + res = (intel_crtc->config->hw.adjusted_mode.vtotal * > + intel_crtc->config->hw.adjusted_mode.htotal); > + > + gbandthreshold = (res * > HISTOGRAM_GUARDBAND_THRESHOLD_DEFAULT) / > + HISTOGRAM_GUARDBAND_PRECISION_FACTOR; > + > + /* Enable histogram interrupt mode */ > + intel_de_rmw(display, DPST_GUARD(pipe), > + DPST_GUARD_THRESHOLD_GB_MASK | > + DPST_GUARD_INTERRUPT_DELAY_MASK | > DPST_GUARD_HIST_INT_EN, > + DPST_GUARD_THRESHOLD_GB(gbandthreshold) | > + > DPST_GUARD_INTERRUPT_DELAY(HISTOGRAM_DEFAULT_GUARDBAND_DELA > Y) | > + DPST_GUARD_HIST_INT_EN); > + > + /* Clear pending interrupts has to be done on separate write */ > + intel_de_rmw(display, DPST_GUARD(pipe), > + DPST_GUARD_HIST_EVENT_STATUS, 1); > + > + histogram->enable = true; > + > + return 0; > +} > + > +static void intel_histogram_disable(struct intel_crtc *intel_crtc) { > + struct intel_display *display = to_intel_display(intel_crtc); > + struct intel_histogram *histogram = intel_crtc->histogram; > + int pipe = intel_crtc->pipe; > + > + if (!histogram) > + return; > + > + /* If already disabled return */ > + if (histogram->enable) > + return; > + > + /* Clear pending interrupts and disable interrupts */ > + intel_de_rmw(display, DPST_GUARD(pipe), > + DPST_GUARD_HIST_INT_EN | > DPST_GUARD_HIST_EVENT_STATUS, 0); > + > + /* disable DPST_CTL Histogram mode */ > + intel_de_rmw(display, DPST_CTL(pipe), > + DPST_CTL_IE_HIST_EN, 0); > + > + histogram->enable = false; > +} > + > +int intel_histogram_update(struct intel_crtc *intel_crtc, bool enable) > +{ > + if (enable) > + return intel_histogram_enable(intel_crtc); > + > + intel_histogram_disable(intel_crtc); > + return 0; > +} > + > +int intel_histogram_set_iet_lut(struct intel_crtc *intel_crtc, u32 > +*data) { > + struct intel_histogram *histogram = intel_crtc->histogram; > + struct intel_display *display = to_intel_display(intel_crtc); > + int pipe = intel_crtc->pipe; > + int i = 0; > + > + if (!histogram) > + return -EINVAL; > + > + if (!histogram->enable) { > + drm_err(display->drm, "histogram not enabled"); > + return -EINVAL; > + } > + > + if (!data) { > + drm_err(display->drm, "enhancement LUT data is NULL"); > + return -EINVAL; > + } > + > + /* Set DPST_CTL Bin Reg function select to IE & wait for a vblabk */ > + intel_de_rmw(display, DPST_CTL(pipe), > + DPST_CTL_BIN_REG_FUNC_SEL, > DPST_CTL_BIN_REG_FUNC_IE); > + > + drm_crtc_wait_one_vblank(&intel_crtc->base); > + > + /* Set DPST_CTL Bin Register Index to 0 */ > + intel_de_rmw(display, DPST_CTL(pipe), > + DPST_CTL_BIN_REG_MASK, DPST_CTL_BIN_REG_CLEAR); > + > + for (i = 0; i < HISTOGRAM_IET_LENGTH; i++) { > + intel_de_rmw(display, DPST_BIN(pipe), > + DPST_BIN_DATA_MASK, data[i]); > + drm_dbg_atomic(display->drm, "iet_lut[%d]=%x\n", i, > data[i]); > + } > + > + return 0; > +} > + > +void intel_histogram_finish(struct intel_crtc *intel_crtc) { > + struct intel_histogram *histogram = intel_crtc->histogram; > + > + kfree(histogram); > +} > + > +int intel_histogram_init(struct intel_crtc *intel_crtc) { > + struct intel_histogram *histogram; > + > + /* Allocate histogram internal struct */ > + histogram = kzalloc(sizeof(*histogram), GFP_KERNEL); > + if (!histogram) { > + return -ENOMEM; > + } You don’t need the {} brackets here for if With the above fixed LGTM Reviewed-by: Suraj Kandpal <suraj.kandpal@intel.com> > + > + intel_crtc->histogram = histogram; > + histogram->crtc = intel_crtc; > + histogram->can_enable = false; > + > + return 0; > +} > diff --git a/drivers/gpu/drm/i915/display/intel_histogram.h > b/drivers/gpu/drm/i915/display/intel_histogram.h > new file mode 100644 > index 000000000000..9d66724f9c53 > --- /dev/null > +++ b/drivers/gpu/drm/i915/display/intel_histogram.h > @@ -0,0 +1,35 @@ > +// SPDX-License-Identifier: MIT > +/* > + * Copyright © 2024 Intel Corporation > + */ > + > +#ifndef __INTEL_HISTOGRAM_H__ > +#define __INTEL_HISTOGRAM_H__ > + > +#include <linux/types.h> > + > +struct intel_crtc; > + > +#define HISTOGRAM_BIN_COUNT 32 > +#define HISTOGRAM_IET_LENGTH 33 > + > +enum intel_global_hist_status { > + INTEL_HISTOGRAM_ENABLE, > + INTEL_HISTOGRAM_DISABLE, > +}; > + > +enum intel_global_histogram { > + INTEL_HISTOGRAM, > +}; > + > +enum intel_global_hist_lut { > + INTEL_HISTOGRAM_PIXEL_FACTOR, > +}; > + > +int intel_histogram_atomic_check(struct intel_crtc *intel_crtc); int > +intel_histogram_update(struct intel_crtc *intel_crtc, bool enable); int > +intel_histogram_set_iet_lut(struct intel_crtc *intel_crtc, u32 *data); > +int intel_histogram_init(struct intel_crtc *intel_crtc); void > +intel_histogram_finish(struct intel_crtc *intel_crtc); > + > +#endif /* __INTEL_HISTOGRAM_H__ */ > -- > 2.25.1 ^ permalink raw reply [flat|nested] 6+ messages in thread
* RE: [PATCHv5 2/8] drm/i915/histogram: Add support for histogram 2024-11-21 13:44 ` Kandpal, Suraj @ 2024-11-21 14:22 ` Murthy, Arun R 0 siblings, 0 replies; 6+ messages in thread From: Murthy, Arun R @ 2024-11-21 14:22 UTC (permalink / raw) To: Kandpal, Suraj, intel-xe@lists.freedesktop.org, intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org > > -----Original Message----- > > From: Intel-xe <intel-xe-bounces@lists.freedesktop.org> On Behalf Of > > Arun R Murthy > > Sent: Thursday, November 21, 2024 5:56 PM > > To: intel-xe@lists.freedesktop.org; intel-gfx@lists.freedesktop.org; > > dri- devel@lists.freedesktop.org > > Cc: Murthy, Arun R <arun.r.murthy@intel.com> > > Subject: [PATCHv5 2/8] drm/i915/histogram: Add support for histogram > > > > Statistics is generated from the image frame that is coming to display > > and an event is sent to user after reading this histogram data. > > This statistics/histogram is then shared with the user upon getting a > > request from user. User can then use this histogram and generate an > > enhancement factor. This enhancement factor can be multiplied/added > > with the incoming pixel data frame. > > > > v2: forward declaration in header file along with error handling > > (Jani) > > v3: Replaced i915 with intel_display (Suraj) > > v4: Removed dithering enable/disable (Vandita) > > New patch for histogram register definitions (Suraj) > > v5: IET LUT pgm follow the seq in spec and removed change to TC at end > > (Suraj) > > > > I think some comments were missed need to address them but nothing major > > > Signed-off-by: Arun R Murthy <arun.r.murthy@intel.com> > > --- > > drivers/gpu/drm/i915/Makefile | 1 + > > .../drm/i915/display/intel_display_types.h | 2 + > > .../gpu/drm/i915/display/intel_histogram.c | 190 ++++++++++++++++++ > > .../gpu/drm/i915/display/intel_histogram.h | 35 ++++ > > 4 files changed, 228 insertions(+) > > create mode 100644 drivers/gpu/drm/i915/display/intel_histogram.c > > create mode 100644 drivers/gpu/drm/i915/display/intel_histogram.h > > > > diff --git a/drivers/gpu/drm/i915/Makefile > > b/drivers/gpu/drm/i915/Makefile index e465828d748f..97141b4def3b > > 100644 > > --- a/drivers/gpu/drm/i915/Makefile > > +++ b/drivers/gpu/drm/i915/Makefile > > @@ -267,6 +267,7 @@ i915-y += \ > > display/intel_hdcp.o \ > > display/intel_hdcp_gsc.o \ > > display/intel_hdcp_gsc_message.o \ > > + display/intel_histogram.o \ > > display/intel_hotplug.o \ > > display/intel_hotplug_irq.o \ > > display/intel_hti.o \ > > diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h > > b/drivers/gpu/drm/i915/display/intel_display_types.h > > index 339e4b0f7698..351441efd10a 100644 > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h > > @@ -1414,6 +1414,8 @@ struct intel_crtc { > > /* for loading single buffered registers during vblank */ > > struct pm_qos_request vblank_pm_qos; > > > > + struct intel_histogram *histogram; > > + > > #ifdef CONFIG_DEBUG_FS > > struct intel_pipe_crc pipe_crc; > > #endif > > diff --git a/drivers/gpu/drm/i915/display/intel_histogram.c > > b/drivers/gpu/drm/i915/display/intel_histogram.c > > new file mode 100644 > > index 000000000000..b2dda88a8093 > > --- /dev/null > > +++ b/drivers/gpu/drm/i915/display/intel_histogram.c > > @@ -0,0 +1,190 @@ > > +// SPDX-License-Identifier: MIT > > +/* > > + * Copyright © 2024 Intel Corporation */ > > + > > +#include <drm/drm_device.h> > > +#include <drm/drm_file.h> > > +#include <drm/drm_vblank.h> > > + > > +#include "i915_reg.h" > > +#include "i915_drv.h" > > +#include "intel_de.h" > > +#include "intel_display.h" > > +#include "intel_display_types.h" > > +#include "intel_histogram.h" > > +#include "intel_histogram_regs.h" > > + > > +/* 3.0% of the pipe's current pixel count, hw does x4 */ #define > > +HISTOGRAM_GUARDBAND_THRESHOLD_DEFAULT 300 > > +/* Precision factor for threshold guardband */ #define > > +HISTOGRAM_GUARDBAND_PRECISION_FACTOR 10000 #define > > +HISTOGRAM_DEFAULT_GUARDBAND_DELAY 0x04 > > + > > +struct intel_histogram { > > + struct intel_crtc *crtc; > > + struct delayed_work work; > > + bool enable; > > + bool can_enable; > > + u32 bin_data[HISTOGRAM_BIN_COUNT]; > > +}; > > + > > +int intel_histogram_atomic_check(struct intel_crtc *intel_crtc) { > > + struct intel_histogram *histogram = intel_crtc->histogram; > > + > > + /* TODO: Restrictions for enabling histogram */ > > + histogram->can_enable = true; > > + > > + return 0; > > +} > > + > > +static int intel_histogram_enable(struct intel_crtc *intel_crtc) { > > + struct intel_display *display = to_intel_display(intel_crtc); > > + struct intel_histogram *histogram = intel_crtc->histogram; > > + int pipe = intel_crtc->pipe; > > + u64 res; > > + u32 gbandthreshold; > > + > > + if (!histogram) > > + return -EINVAL; > > + > > + if (!histogram->can_enable) > > + return -EINVAL; > > Nit: the above two conditions can be combined with && > Done > > + > > + if (histogram->enable) > > + return 0; > > + > > + /* enable histogram, clear DPST_CTL bin reg func select to TC */ > > + intel_de_rmw(display, DPST_CTL(pipe), > > + DPST_CTL_BIN_REG_FUNC_SEL | DPST_CTL_IE_HIST_EN | > > + DPST_CTL_HIST_MODE | > > DPST_CTL_IE_TABLE_VALUE_FORMAT | > > + DPST_CTL_ENHANCEMENT_MODE_MASK | > > DPST_CTL_IE_MODI_TABLE_EN, > > + DPST_CTL_BIN_REG_FUNC_TC | DPST_CTL_IE_HIST_EN | > > + DPST_CTL_HIST_MODE_HSV | > > + DPST_CTL_IE_TABLE_VALUE_FORMAT_1INT_9FRAC | > > + DPST_CTL_EN_MULTIPLICATIVE | > > DPST_CTL_IE_MODI_TABLE_EN); > > + > > + /* Re-Visit: check if wait for one vblank is required */ > > + drm_crtc_wait_one_vblank(&intel_crtc->base); > > + > > + /* TODO: Program GuardBand Threshold: To be moved to modeset > > path */ > > I wanted this to be something like this > /* TODO: Program GuardBand Threshold needs to be moved to modeset path > */ > > Done > > + res = (intel_crtc->config->hw.adjusted_mode.vtotal * > > + intel_crtc->config->hw.adjusted_mode.htotal); > > + > > + gbandthreshold = (res * > > HISTOGRAM_GUARDBAND_THRESHOLD_DEFAULT) / > > + HISTOGRAM_GUARDBAND_PRECISION_FACTOR; > > + > > + /* Enable histogram interrupt mode */ > > + intel_de_rmw(display, DPST_GUARD(pipe), > > + DPST_GUARD_THRESHOLD_GB_MASK | > > + DPST_GUARD_INTERRUPT_DELAY_MASK | > > DPST_GUARD_HIST_INT_EN, > > + DPST_GUARD_THRESHOLD_GB(gbandthreshold) | > > + > > DPST_GUARD_INTERRUPT_DELAY(HISTOGRAM_DEFAULT_GUARDBAND_DELA > > Y) | > > + DPST_GUARD_HIST_INT_EN); > > + > > + /* Clear pending interrupts has to be done on separate write */ > > + intel_de_rmw(display, DPST_GUARD(pipe), > > + DPST_GUARD_HIST_EVENT_STATUS, 1); > > + > > + histogram->enable = true; > > + > > + return 0; > > +} > > + > > +static void intel_histogram_disable(struct intel_crtc *intel_crtc) { > > + struct intel_display *display = to_intel_display(intel_crtc); > > + struct intel_histogram *histogram = intel_crtc->histogram; > > + int pipe = intel_crtc->pipe; > > + > > + if (!histogram) > > + return; > > + > > + /* If already disabled return */ > > + if (histogram->enable) > > + return; > > + > > + /* Clear pending interrupts and disable interrupts */ > > + intel_de_rmw(display, DPST_GUARD(pipe), > > + DPST_GUARD_HIST_INT_EN | > > DPST_GUARD_HIST_EVENT_STATUS, 0); > > + > > + /* disable DPST_CTL Histogram mode */ > > + intel_de_rmw(display, DPST_CTL(pipe), > > + DPST_CTL_IE_HIST_EN, 0); > > + > > + histogram->enable = false; > > +} > > + > > +int intel_histogram_update(struct intel_crtc *intel_crtc, bool > > +enable) { > > + if (enable) > > + return intel_histogram_enable(intel_crtc); > > + > > + intel_histogram_disable(intel_crtc); > > + return 0; > > +} > > + > > +int intel_histogram_set_iet_lut(struct intel_crtc *intel_crtc, u32 > > +*data) { > > + struct intel_histogram *histogram = intel_crtc->histogram; > > + struct intel_display *display = to_intel_display(intel_crtc); > > + int pipe = intel_crtc->pipe; > > + int i = 0; > > + > > + if (!histogram) > > + return -EINVAL; > > + > > + if (!histogram->enable) { > > + drm_err(display->drm, "histogram not enabled"); > > + return -EINVAL; > > + } > > + > > + if (!data) { > > + drm_err(display->drm, "enhancement LUT data is NULL"); > > + return -EINVAL; > > + } > > + > > + /* Set DPST_CTL Bin Reg function select to IE & wait for a vblabk */ > > + intel_de_rmw(display, DPST_CTL(pipe), > > + DPST_CTL_BIN_REG_FUNC_SEL, > > DPST_CTL_BIN_REG_FUNC_IE); > > + > > + drm_crtc_wait_one_vblank(&intel_crtc->base); > > + > > + /* Set DPST_CTL Bin Register Index to 0 */ > > + intel_de_rmw(display, DPST_CTL(pipe), > > + DPST_CTL_BIN_REG_MASK, DPST_CTL_BIN_REG_CLEAR); > > + > > + for (i = 0; i < HISTOGRAM_IET_LENGTH; i++) { > > + intel_de_rmw(display, DPST_BIN(pipe), > > + DPST_BIN_DATA_MASK, data[i]); > > + drm_dbg_atomic(display->drm, "iet_lut[%d]=%x\n", i, > > data[i]); > > + } > > + > > + return 0; > > +} > > + > > +void intel_histogram_finish(struct intel_crtc *intel_crtc) { > > + struct intel_histogram *histogram = intel_crtc->histogram; > > + > > + kfree(histogram); > > +} > > + > > +int intel_histogram_init(struct intel_crtc *intel_crtc) { > > + struct intel_histogram *histogram; > > + > > + /* Allocate histogram internal struct */ > > + histogram = kzalloc(sizeof(*histogram), GFP_KERNEL); > > + if (!histogram) { > > + return -ENOMEM; > > + } > > You don’t need the {} brackets here for if > Done Thanks and Regards, Arun R Murthy -------------------- ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2024-11-21 14:49 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2024-11-21 14:39 [PATCHv5 2/8] drm/i915/histogram: Add support for histogram Arun R Murthy 2024-11-21 14:39 ` [PATCHv3 6/8] drm/i915/histogram: histogram delay counter doesnt reset Arun R Murthy 2024-11-21 14:39 ` [PATCHv6 7/8] drm/i915/histogram: Histogram changes for Display 20+ Arun R Murthy -- strict thread matches above, loose matches on Subject: below -- 2024-11-21 12:25 [PATCH 0/8] Display Global Histogram Arun R Murthy 2024-11-21 12:25 ` [PATCHv5 2/8] drm/i915/histogram: Add support for histogram Arun R Murthy 2024-11-21 13:44 ` Kandpal, Suraj 2024-11-21 14:22 ` Murthy, Arun R
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox