diff mbox series

[v2,1/2] drm/i915/display: Add support for darskscreen detection

Message ID 20231027095336.3059445-2-nemesa.garg@intel.com (mailing list archive)
State New, archived
Headers show
Series Enable Darkscreen Feature | expand

Commit Message

Garg, Nemesa Oct. 27, 2023, 9:53 a.m. UTC
Darkscreen detection checks if all the pixels of the frame are less then
or equal to the comparision value. The comparision value is set to 256
i.e black. So upon getting black pixels from the pipe, the dark screen
detect bit is set and an error message will be printed.

v2: Addressed review comments (Jani)

Signed-off-by: Nemesa Garg <nemesa.garg@intel.com>
---
 drivers/gpu/drm/i915/Makefile                 |  1 +
 .../gpu/drm/i915/display/intel_darkscreen.c   | 87 +++++++++++++++++++
 .../gpu/drm/i915/display/intel_darkscreen.h   | 26 ++++++
 .../drm/i915/display/intel_display_types.h    |  2 +
 drivers/gpu/drm/i915/i915_reg.h               |  8 ++
 5 files changed, 124 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/display/intel_darkscreen.c
 create mode 100644 drivers/gpu/drm/i915/display/intel_darkscreen.h

Comments

Jani Nikula Oct. 27, 2023, 11:10 a.m. UTC | #1
On Fri, 27 Oct 2023, Nemesa Garg <nemesa.garg@intel.com> wrote:
> Darkscreen detection checks if all the pixels of the frame are less then
> or equal to the comparision value. The comparision value is set to 256
> i.e black. So upon getting black pixels from the pipe, the dark screen
> detect bit is set and an error message will be printed.

Okay, this still describes *what* the patch does, but not *why*. Why do
we need this? What for?

(Please just reply here for starters, instead of resending.)


BR,
Jani.
Garg, Nemesa Oct. 30, 2023, 9:37 a.m. UTC | #2
Hi Jani,

Sometimes there is an issue of black screen on the display due to number of errors like invalid input buffers (black), some issue with display programming (no planes enabled, LUTs zeroed) which means some problem with DE. Upon detection following steps can be taken:
1.Print in dmesg so user can be aware of this issue upon checking the logs
2. Correction steps can be taken and the design is in progress and will come up with follow up patches.

Thanks and Regards,
Nemesa

> -----Original Message-----
> From: Jani Nikula <jani.nikula@linux.intel.com>
> Sent: Friday, October 27, 2023 4:40 PM
> To: Garg, Nemesa <nemesa.garg@intel.com>; intel-gfx@lists.freedesktop.org
> Subject: Re: [Intel-gfx] [v2 1/2] drm/i915/display: Add support for darskscreen
> detection
> 
> On Fri, 27 Oct 2023, Nemesa Garg <nemesa.garg@intel.com> wrote:
> > Darkscreen detection checks if all the pixels of the frame are less
> > then or equal to the comparision value. The comparision value is set
> > to 256 i.e black. So upon getting black pixels from the pipe, the dark
> > screen detect bit is set and an error message will be printed.
> 
> Okay, this still describes *what* the patch does, but not *why*. Why do we need
> this? What for?
> 
> (Please just reply here for starters, instead of resending.)
> 
> 
> BR,
> Jani.
> 
> 
> --
> Jani Nikula, Intel
Jani Nikula Oct. 30, 2023, 10:19 a.m. UTC | #3
On Mon, 30 Oct 2023, "Garg, Nemesa" <nemesa.garg@intel.com> wrote:
> Hi Jani,
>
> Sometimes there is an issue of black screen on the display due to number of errors like invalid input buffers (black), some issue with display programming (no planes enabled, LUTs zeroed) which means some problem with DE. Upon detection following steps can be taken:
> 1.Print in dmesg so user can be aware of this issue upon checking the logs
> 2. Correction steps can be taken and the design is in progress and will come up with follow up patches.

And if the user wants to show a black screen? Does this feature flag an
error?

BR,
Jani.


>
> Thanks and Regards,
> Nemesa
>
>> -----Original Message-----
>> From: Jani Nikula <jani.nikula@linux.intel.com>
>> Sent: Friday, October 27, 2023 4:40 PM
>> To: Garg, Nemesa <nemesa.garg@intel.com>; intel-gfx@lists.freedesktop.org
>> Subject: Re: [Intel-gfx] [v2 1/2] drm/i915/display: Add support for darskscreen
>> detection
>> 
>> On Fri, 27 Oct 2023, Nemesa Garg <nemesa.garg@intel.com> wrote:
>> > Darkscreen detection checks if all the pixels of the frame are less
>> > then or equal to the comparision value. The comparision value is set
>> > to 256 i.e black. So upon getting black pixels from the pipe, the dark
>> > screen detect bit is set and an error message will be printed.
>> 
>> Okay, this still describes *what* the patch does, but not *why*. Why do we need
>> this? What for?
>> 
>> (Please just reply here for starters, instead of resending.)
>> 
>> 
>> BR,
>> Jani.
>> 
>> 
>> --
>> Jani Nikula, Intel
Garg, Nemesa Oct. 31, 2023, 10:18 a.m. UTC | #4
This is will also be caught as dark screen.

Regards,
Nemesa

> -----Original Message-----
> From: Jani Nikula <jani.nikula@linux.intel.com>
> Sent: Monday, October 30, 2023 3:50 PM
> To: Garg, Nemesa <nemesa.garg@intel.com>; intel-gfx@lists.freedesktop.org
> Subject: RE: [Intel-gfx] [v2 1/2] drm/i915/display: Add support for darskscreen
> detection
> 
> On Mon, 30 Oct 2023, "Garg, Nemesa" <nemesa.garg@intel.com> wrote:
> > Hi Jani,
> >
> > Sometimes there is an issue of black screen on the display due to number of
> errors like invalid input buffers (black), some issue with display programming (no
> planes enabled, LUTs zeroed) which means some problem with DE. Upon
> detection following steps can be taken:
> > 1.Print in dmesg so user can be aware of this issue upon checking the
> > logs 2. Correction steps can be taken and the design is in progress and will come
> up with follow up patches.
> 
> And if the user wants to show a black screen? Does this feature flag an error?
> 
> BR,
> Jani.
> 
> 
> >
> > Thanks and Regards,
> > Nemesa
> >
> >> -----Original Message-----
> >> From: Jani Nikula <jani.nikula@linux.intel.com>
> >> Sent: Friday, October 27, 2023 4:40 PM
> >> To: Garg, Nemesa <nemesa.garg@intel.com>;
> >> intel-gfx@lists.freedesktop.org
> >> Subject: Re: [Intel-gfx] [v2 1/2] drm/i915/display: Add support for
> >> darskscreen detection
> >>
> >> On Fri, 27 Oct 2023, Nemesa Garg <nemesa.garg@intel.com> wrote:
> >> > Darkscreen detection checks if all the pixels of the frame are less
> >> > then or equal to the comparision value. The comparision value is
> >> > set to 256 i.e black. So upon getting black pixels from the pipe,
> >> > the dark screen detect bit is set and an error message will be printed.
> >>
> >> Okay, this still describes *what* the patch does, but not *why*. Why
> >> do we need this? What for?
> >>
> >> (Please just reply here for starters, instead of resending.)
> >>
> >>
> >> BR,
> >> Jani.
> >>
> >>
> >> --
> >> Jani Nikula, Intel
> 
> --
> Jani Nikula, Intel
Arun R Murthy Dec. 12, 2023, 6:09 a.m. UTC | #5
> -----Original Message-----
> From: Intel-gfx <intel-gfx-bounces@lists.freedesktop.org> On Behalf Of Nemesa
> Garg
> Sent: Friday, October 27, 2023 3:24 PM
> To: intel-gfx@lists.freedesktop.org
> Subject: [Intel-gfx] [v2 1/2] drm/i915/display: Add support for darskscreen
> detection
> 
> Darkscreen detection checks if all the pixels of the frame are less then or equal
> to the comparision value. The comparision value is set to 256 i.e black. So upon
> getting black pixels from the pipe, the dark screen detect bit is set and an error
> message will be printed.
> 
> v2: Addressed review comments (Jani)
> 
> Signed-off-by: Nemesa Garg <nemesa.garg@intel.com>
> ---
>  drivers/gpu/drm/i915/Makefile                 |  1 +
>  .../gpu/drm/i915/display/intel_darkscreen.c   | 87 +++++++++++++++++++
>  .../gpu/drm/i915/display/intel_darkscreen.h   | 26 ++++++
>  .../drm/i915/display/intel_display_types.h    |  2 +
>  drivers/gpu/drm/i915/i915_reg.h               |  8 ++
>  5 files changed, 124 insertions(+)
>  create mode 100644 drivers/gpu/drm/i915/display/intel_darkscreen.c
>  create mode 100644 drivers/gpu/drm/i915/display/intel_darkscreen.h
> 
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index 88b2bb005014..538d5a42f9e3 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -254,6 +254,7 @@ i915-y += \
>  	display/intel_crtc.o \
>  	display/intel_crtc_state_dump.o \
>  	display/intel_cursor.o \
> +	display/intel_darkscreen.o \
>  	display/intel_display.o \
>  	display/intel_display_driver.o \
>  	display/intel_display_irq.o \
> diff --git a/drivers/gpu/drm/i915/display/intel_darkscreen.c
> b/drivers/gpu/drm/i915/display/intel_darkscreen.c
> new file mode 100644
> index 000000000000..0be719c76c4e
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/display/intel_darkscreen.c
> @@ -0,0 +1,87 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright © 2023 Intel Corporation
> + *
> + */
> +
> +#include "i915_reg.h"
> +#include "intel_de.h"
> +#include "intel_display_types.h"
> +
> +#define COLOR_DEPTH_6BPC 6
> +#define COLOR_DEPTH_8BPC 8
> +#define COLOR_DEPTH_10BPC 10
> +#define COLOR_DEPTH_12BPC 12
> +
> +#define COMPARE_VALUE_6_BPC 4
> +#define COMPARE_VALUE_8_BPC 16
> +#define COMPARE_VALUE_10_BPC 64
> +#define COMPARE_VALUE_12_BPC 256
> +
> +#define COMPARE_VALUE_CALCULATION_FACTOR 12
> +
> +/*
> + * Checks the color format and compute the comapre value based on bpc.
> + */
Can we have this in proper kernel doc format?

> +void intel_dark_screen_enable(struct intel_crtc_state *crtc_state) {
> +	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> +	u32 comparevalue;
> +
> +	if (!crtc->dark_screen.enable)
> +		return;
> +
> +	if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB)
> +		return;
Better to have an error print saying not supported.

Thanks and Regards,
Arun R Murthy
-------------------
> +
> +	switch (crtc_state->pipe_bpp / 3) {
> +	case COLOR_DEPTH_6BPC:
> +		comparevalue = COMPARE_VALUE_6_BPC;
> +		break;
> +	case COLOR_DEPTH_8BPC:
> +		comparevalue = COMPARE_VALUE_8_BPC;
> +		break;
> +	case COLOR_DEPTH_10BPC:
> +		comparevalue = COMPARE_VALUE_10_BPC;
> +		break;
> +	case COLOR_DEPTH_12BPC:
> +		comparevalue = COMPARE_VALUE_12_BPC;
> +		break;
> +	default:
> +		drm_dbg(&dev_priv->drm,
> +			"Bpc value is incorrect:%d\n",
> +			crtc_state->pipe_bpp / 3);
> +		return;
> +	}
> +
> +	comparevalue = comparevalue <<
> +		(COMPARE_VALUE_CALCULATION_FACTOR - crtc_state-
> >pipe_bpp / 3);
> +
> +	intel_de_write(dev_priv, DARK_SCREEN(cpu_transcoder),
> +		       DARK_SCREEN_ENABLE | DARK_SCREEN_DETECT |
> +		       DARK_SCREEN_DONE |
> DARK_SCREEN_COMPARE_VAL(comparevalue));
> +
> +	intel_de_wait_for_set(dev_priv,
> +			      DARK_SCREEN(crtc->config->cpu_transcoder),
> DARK_SCREEN_DONE,
> +1);
> +
> +	if (intel_de_read(dev_priv, DARK_SCREEN(crtc->config-
> >cpu_transcoder)) &
> +			  DARK_SCREEN_DETECT) {
> +		drm_err(&dev_priv->drm,
> +			"Dark Screen detected:%c\n",
> +			pipe_name(crtc->pipe));
> +	}
> +
> +	intel_de_rmw(dev_priv, DARK_SCREEN(crtc->config->cpu_transcoder),
> 1, DARK_SCREEN_DETECT |
> +		     DARK_SCREEN_DONE);
> +}
> +
> +void intel_dark_screen_disable(struct intel_crtc_state *crtc_state) {
> +	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> +
> +	intel_de_write(dev_priv, DARK_SCREEN(cpu_transcoder), 0); }
> diff --git a/drivers/gpu/drm/i915/display/intel_darkscreen.h
> b/drivers/gpu/drm/i915/display/intel_darkscreen.h
> new file mode 100644
> index 000000000000..366e43499fc4
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/display/intel_darkscreen.h
> @@ -0,0 +1,26 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright © 2023 Intel Corporation
> + *
> + */
> +
> +#ifndef __INTEL_DARKSCREEN_H__
> +#define __INTEL_DARKSCREEN_H__
> +
> +#include <linux/types.h>
> +
> +struct intel_crtc_state;
> +struct intel_crtc;
> +
> +struct intel_darkscreen {
> +	bool enable;
> +};
> +
> +#ifdef CONFIG_DEBUG_FS
> +void intel_dark_screen_enable(struct intel_crtc_state *crtc_state);
> +void intel_dark_screen_disable(struct intel_crtc_state *crtc_state);
> +void intel_darkscreen_crtc_debugfs_add(struct intel_crtc *crtc);
> +
> +#endif
> +
> +#endif /* __INTEL_DARKSCREEN_H_ */
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
> b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 65ea37fe8cff..bd0306e9318f 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -49,6 +49,7 @@
>  #include "i915_vma.h"
>  #include "i915_vma_types.h"
>  #include "intel_bios.h"
> +#include "intel_darkscreen.h"
>  #include "intel_display.h"
>  #include "intel_display_limits.h"
>  #include "intel_display_power.h"
> @@ -1517,6 +1518,7 @@ struct intel_crtc {
> 
>  #ifdef CONFIG_DEBUG_FS
>  	struct intel_pipe_crc pipe_crc;
> +	struct intel_darkscreen dark_screen;
>  #endif
>  };
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h
> b/drivers/gpu/drm/i915/i915_reg.h index 135e8d8dbdf0..a9f7b80a56cf
> 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -2097,6 +2097,14 @@
>  #define   TRANS_PUSH_EN			REG_BIT(31)
>  #define   TRANS_PUSH_SEND		REG_BIT(30)
> 
> +#define _DARK_SCREEN_PIPE_A		0x60120
> +#define DARK_SCREEN(trans)		_MMIO_TRANS2(trans,
> _DARK_SCREEN_PIPE_A)
> +#define   DARK_SCREEN_ENABLE		REG_BIT(31)
> +#define   DARK_SCREEN_DETECT		REG_BIT(29)
> +#define   DARK_SCREEN_DONE		REG_BIT(28)
> +#define DARK_SCREEN_COMPARE_MASK	REG_GENMASK(9, 0)
> +#define DARK_SCREEN_COMPARE_VAL(x)
> 	REG_FIELD_PREP(DARK_SCREEN_COMPARE_MASK, (x))
> +
>  /* VGA port control */
>  #define ADPA			_MMIO(0x61100)
>  #define PCH_ADPA                _MMIO(0xe1100)
> --
> 2.25.1
Jani Nikula Dec. 12, 2023, 9:04 a.m. UTC | #6
On Tue, 12 Dec 2023, "Murthy, Arun R" <arun.r.murthy@intel.com> wrote:
>> -----Original Message-----
>> From: Intel-gfx <intel-gfx-bounces@lists.freedesktop.org> On Behalf Of Nemesa
>> Garg
>> Sent: Friday, October 27, 2023 3:24 PM
>> To: intel-gfx@lists.freedesktop.org
>> Subject: [Intel-gfx] [v2 1/2] drm/i915/display: Add support for darskscreen
>> detection
>> 
>> Darkscreen detection checks if all the pixels of the frame are less then or equal
>> to the comparision value. The comparision value is set to 256 i.e black. So upon
>> getting black pixels from the pipe, the dark screen detect bit is set and an error
>> message will be printed.
>> 
>> v2: Addressed review comments (Jani)
>> 
>> Signed-off-by: Nemesa Garg <nemesa.garg@intel.com>
>> ---
>>  drivers/gpu/drm/i915/Makefile                 |  1 +
>>  .../gpu/drm/i915/display/intel_darkscreen.c   | 87 +++++++++++++++++++
>>  .../gpu/drm/i915/display/intel_darkscreen.h   | 26 ++++++
>>  .../drm/i915/display/intel_display_types.h    |  2 +
>>  drivers/gpu/drm/i915/i915_reg.h               |  8 ++
>>  5 files changed, 124 insertions(+)
>>  create mode 100644 drivers/gpu/drm/i915/display/intel_darkscreen.c
>>  create mode 100644 drivers/gpu/drm/i915/display/intel_darkscreen.h
>> 
>> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
>> index 88b2bb005014..538d5a42f9e3 100644
>> --- a/drivers/gpu/drm/i915/Makefile
>> +++ b/drivers/gpu/drm/i915/Makefile
>> @@ -254,6 +254,7 @@ i915-y += \
>>  	display/intel_crtc.o \
>>  	display/intel_crtc_state_dump.o \
>>  	display/intel_cursor.o \
>> +	display/intel_darkscreen.o \
>>  	display/intel_display.o \
>>  	display/intel_display_driver.o \
>>  	display/intel_display_irq.o \
>> diff --git a/drivers/gpu/drm/i915/display/intel_darkscreen.c
>> b/drivers/gpu/drm/i915/display/intel_darkscreen.c
>> new file mode 100644
>> index 000000000000..0be719c76c4e
>> --- /dev/null
>> +++ b/drivers/gpu/drm/i915/display/intel_darkscreen.c
>> @@ -0,0 +1,87 @@
>> +// SPDX-License-Identifier: MIT
>> +/*
>> + * Copyright © 2023 Intel Corporation
>> + *
>> + */
>> +
>> +#include "i915_reg.h"
>> +#include "intel_de.h"
>> +#include "intel_display_types.h"
>> +
>> +#define COLOR_DEPTH_6BPC 6
>> +#define COLOR_DEPTH_8BPC 8
>> +#define COLOR_DEPTH_10BPC 10
>> +#define COLOR_DEPTH_12BPC 12
>> +
>> +#define COMPARE_VALUE_6_BPC 4
>> +#define COMPARE_VALUE_8_BPC 16
>> +#define COMPARE_VALUE_10_BPC 64
>> +#define COMPARE_VALUE_12_BPC 256
>> +
>> +#define COMPARE_VALUE_CALCULATION_FACTOR 12
>> +
>> +/*
>> + * Checks the color format and compute the comapre value based on bpc.
>> + */
> Can we have this in proper kernel doc format?

IMO it's not necessary for rather simple internal functions like this.

But please use the imperative mood ("check", not "checks") and fix the
typos though.

>
>> +void intel_dark_screen_enable(struct intel_crtc_state *crtc_state) {
>> +	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>> +	u32 comparevalue;
>> +
>> +	if (!crtc->dark_screen.enable)
>> +		return;
>> +
>> +	if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB)
>> +		return;
> Better to have an error print saying not supported.
>
> Thanks and Regards,
> Arun R Murthy
> -------------------
>> +
>> +	switch (crtc_state->pipe_bpp / 3) {
>> +	case COLOR_DEPTH_6BPC:
>> +		comparevalue = COMPARE_VALUE_6_BPC;
>> +		break;
>> +	case COLOR_DEPTH_8BPC:
>> +		comparevalue = COMPARE_VALUE_8_BPC;
>> +		break;
>> +	case COLOR_DEPTH_10BPC:
>> +		comparevalue = COMPARE_VALUE_10_BPC;
>> +		break;
>> +	case COLOR_DEPTH_12BPC:
>> +		comparevalue = COMPARE_VALUE_12_BPC;
>> +		break;
>> +	default:
>> +		drm_dbg(&dev_priv->drm,
>> +			"Bpc value is incorrect:%d\n",
>> +			crtc_state->pipe_bpp / 3);
>> +		return;
>> +	}
>> +
>> +	comparevalue = comparevalue <<
>> +		(COMPARE_VALUE_CALCULATION_FACTOR - crtc_state-
>> >pipe_bpp / 3);
>> +
>> +	intel_de_write(dev_priv, DARK_SCREEN(cpu_transcoder),
>> +		       DARK_SCREEN_ENABLE | DARK_SCREEN_DETECT |
>> +		       DARK_SCREEN_DONE |
>> DARK_SCREEN_COMPARE_VAL(comparevalue));
>> +
>> +	intel_de_wait_for_set(dev_priv,
>> +			      DARK_SCREEN(crtc->config->cpu_transcoder),
>> DARK_SCREEN_DONE,
>> +1);
>> +
>> +	if (intel_de_read(dev_priv, DARK_SCREEN(crtc->config-
>> >cpu_transcoder)) &
>> +			  DARK_SCREEN_DETECT) {
>> +		drm_err(&dev_priv->drm,
>> +			"Dark Screen detected:%c\n",
>> +			pipe_name(crtc->pipe));
>> +	}
>> +
>> +	intel_de_rmw(dev_priv, DARK_SCREEN(crtc->config->cpu_transcoder),
>> 1, DARK_SCREEN_DETECT |
>> +		     DARK_SCREEN_DONE);
>> +}
>> +
>> +void intel_dark_screen_disable(struct intel_crtc_state *crtc_state) {
>> +	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>> +
>> +	intel_de_write(dev_priv, DARK_SCREEN(cpu_transcoder), 0); }
>> diff --git a/drivers/gpu/drm/i915/display/intel_darkscreen.h
>> b/drivers/gpu/drm/i915/display/intel_darkscreen.h
>> new file mode 100644
>> index 000000000000..366e43499fc4
>> --- /dev/null
>> +++ b/drivers/gpu/drm/i915/display/intel_darkscreen.h
>> @@ -0,0 +1,26 @@
>> +/* SPDX-License-Identifier: MIT */
>> +/*
>> + * Copyright © 2023 Intel Corporation
>> + *
>> + */
>> +
>> +#ifndef __INTEL_DARKSCREEN_H__
>> +#define __INTEL_DARKSCREEN_H__
>> +
>> +#include <linux/types.h>
>> +
>> +struct intel_crtc_state;
>> +struct intel_crtc;
>> +
>> +struct intel_darkscreen {
>> +	bool enable;
>> +};
>> +
>> +#ifdef CONFIG_DEBUG_FS
>> +void intel_dark_screen_enable(struct intel_crtc_state *crtc_state);
>> +void intel_dark_screen_disable(struct intel_crtc_state *crtc_state);
>> +void intel_darkscreen_crtc_debugfs_add(struct intel_crtc *crtc);
>> +
>> +#endif
>> +
>> +#endif /* __INTEL_DARKSCREEN_H_ */
>> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
>> b/drivers/gpu/drm/i915/display/intel_display_types.h
>> index 65ea37fe8cff..bd0306e9318f 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
>> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
>> @@ -49,6 +49,7 @@
>>  #include "i915_vma.h"
>>  #include "i915_vma_types.h"
>>  #include "intel_bios.h"
>> +#include "intel_darkscreen.h"
>>  #include "intel_display.h"
>>  #include "intel_display_limits.h"
>>  #include "intel_display_power.h"
>> @@ -1517,6 +1518,7 @@ struct intel_crtc {
>> 
>>  #ifdef CONFIG_DEBUG_FS
>>  	struct intel_pipe_crc pipe_crc;
>> +	struct intel_darkscreen dark_screen;
>>  #endif
>>  };
>> 
>> diff --git a/drivers/gpu/drm/i915/i915_reg.h
>> b/drivers/gpu/drm/i915/i915_reg.h index 135e8d8dbdf0..a9f7b80a56cf
>> 100644
>> --- a/drivers/gpu/drm/i915/i915_reg.h
>> +++ b/drivers/gpu/drm/i915/i915_reg.h
>> @@ -2097,6 +2097,14 @@
>>  #define   TRANS_PUSH_EN			REG_BIT(31)
>>  #define   TRANS_PUSH_SEND		REG_BIT(30)
>> 
>> +#define _DARK_SCREEN_PIPE_A		0x60120
>> +#define DARK_SCREEN(trans)		_MMIO_TRANS2(trans,
>> _DARK_SCREEN_PIPE_A)
>> +#define   DARK_SCREEN_ENABLE		REG_BIT(31)
>> +#define   DARK_SCREEN_DETECT		REG_BIT(29)
>> +#define   DARK_SCREEN_DONE		REG_BIT(28)
>> +#define DARK_SCREEN_COMPARE_MASK	REG_GENMASK(9, 0)
>> +#define DARK_SCREEN_COMPARE_VAL(x)
>> 	REG_FIELD_PREP(DARK_SCREEN_COMPARE_MASK, (x))
>> +
>>  /* VGA port control */
>>  #define ADPA			_MMIO(0x61100)
>>  #define PCH_ADPA                _MMIO(0xe1100)
>> --
>> 2.25.1
>
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 88b2bb005014..538d5a42f9e3 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -254,6 +254,7 @@  i915-y += \
 	display/intel_crtc.o \
 	display/intel_crtc_state_dump.o \
 	display/intel_cursor.o \
+	display/intel_darkscreen.o \
 	display/intel_display.o \
 	display/intel_display_driver.o \
 	display/intel_display_irq.o \
diff --git a/drivers/gpu/drm/i915/display/intel_darkscreen.c b/drivers/gpu/drm/i915/display/intel_darkscreen.c
new file mode 100644
index 000000000000..0be719c76c4e
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_darkscreen.c
@@ -0,0 +1,87 @@ 
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2023 Intel Corporation
+ *
+ */
+
+#include "i915_reg.h"
+#include "intel_de.h"
+#include "intel_display_types.h"
+
+#define COLOR_DEPTH_6BPC 6
+#define COLOR_DEPTH_8BPC 8
+#define COLOR_DEPTH_10BPC 10
+#define COLOR_DEPTH_12BPC 12
+
+#define COMPARE_VALUE_6_BPC 4
+#define COMPARE_VALUE_8_BPC 16
+#define COMPARE_VALUE_10_BPC 64
+#define COMPARE_VALUE_12_BPC 256
+
+#define COMPARE_VALUE_CALCULATION_FACTOR 12
+
+/*
+ * Checks the color format and compute the comapre value based on bpc.
+ */
+void intel_dark_screen_enable(struct intel_crtc_state *crtc_state)
+{
+	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	u32 comparevalue;
+
+	if (!crtc->dark_screen.enable)
+		return;
+
+	if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB)
+		return;
+
+	switch (crtc_state->pipe_bpp / 3) {
+	case COLOR_DEPTH_6BPC:
+		comparevalue = COMPARE_VALUE_6_BPC;
+		break;
+	case COLOR_DEPTH_8BPC:
+		comparevalue = COMPARE_VALUE_8_BPC;
+		break;
+	case COLOR_DEPTH_10BPC:
+		comparevalue = COMPARE_VALUE_10_BPC;
+		break;
+	case COLOR_DEPTH_12BPC:
+		comparevalue = COMPARE_VALUE_12_BPC;
+		break;
+	default:
+		drm_dbg(&dev_priv->drm,
+			"Bpc value is incorrect:%d\n",
+			crtc_state->pipe_bpp / 3);
+		return;
+	}
+
+	comparevalue = comparevalue <<
+		(COMPARE_VALUE_CALCULATION_FACTOR - crtc_state->pipe_bpp / 3);
+
+	intel_de_write(dev_priv, DARK_SCREEN(cpu_transcoder),
+		       DARK_SCREEN_ENABLE | DARK_SCREEN_DETECT |
+		       DARK_SCREEN_DONE | DARK_SCREEN_COMPARE_VAL(comparevalue));
+
+	intel_de_wait_for_set(dev_priv,
+			      DARK_SCREEN(crtc->config->cpu_transcoder), DARK_SCREEN_DONE, 1);
+
+	if (intel_de_read(dev_priv, DARK_SCREEN(crtc->config->cpu_transcoder)) &
+			  DARK_SCREEN_DETECT) {
+		drm_err(&dev_priv->drm,
+			"Dark Screen detected:%c\n",
+			pipe_name(crtc->pipe));
+	}
+
+	intel_de_rmw(dev_priv, DARK_SCREEN(crtc->config->cpu_transcoder), 1, DARK_SCREEN_DETECT |
+		     DARK_SCREEN_DONE);
+}
+
+void intel_dark_screen_disable(struct intel_crtc_state *crtc_state)
+{
+	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+
+	intel_de_write(dev_priv, DARK_SCREEN(cpu_transcoder), 0);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_darkscreen.h b/drivers/gpu/drm/i915/display/intel_darkscreen.h
new file mode 100644
index 000000000000..366e43499fc4
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_darkscreen.h
@@ -0,0 +1,26 @@ 
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2023 Intel Corporation
+ *
+ */
+
+#ifndef __INTEL_DARKSCREEN_H__
+#define __INTEL_DARKSCREEN_H__
+
+#include <linux/types.h>
+
+struct intel_crtc_state;
+struct intel_crtc;
+
+struct intel_darkscreen {
+	bool enable;
+};
+
+#ifdef CONFIG_DEBUG_FS
+void intel_dark_screen_enable(struct intel_crtc_state *crtc_state);
+void intel_dark_screen_disable(struct intel_crtc_state *crtc_state);
+void intel_darkscreen_crtc_debugfs_add(struct intel_crtc *crtc);
+
+#endif
+
+#endif /* __INTEL_DARKSCREEN_H_ */
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 65ea37fe8cff..bd0306e9318f 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -49,6 +49,7 @@ 
 #include "i915_vma.h"
 #include "i915_vma_types.h"
 #include "intel_bios.h"
+#include "intel_darkscreen.h"
 #include "intel_display.h"
 #include "intel_display_limits.h"
 #include "intel_display_power.h"
@@ -1517,6 +1518,7 @@  struct intel_crtc {
 
 #ifdef CONFIG_DEBUG_FS
 	struct intel_pipe_crc pipe_crc;
+	struct intel_darkscreen dark_screen;
 #endif
 };
 
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 135e8d8dbdf0..a9f7b80a56cf 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2097,6 +2097,14 @@ 
 #define   TRANS_PUSH_EN			REG_BIT(31)
 #define   TRANS_PUSH_SEND		REG_BIT(30)
 
+#define _DARK_SCREEN_PIPE_A		0x60120
+#define DARK_SCREEN(trans)		_MMIO_TRANS2(trans, _DARK_SCREEN_PIPE_A)
+#define   DARK_SCREEN_ENABLE		REG_BIT(31)
+#define   DARK_SCREEN_DETECT		REG_BIT(29)
+#define   DARK_SCREEN_DONE		REG_BIT(28)
+#define DARK_SCREEN_COMPARE_MASK	REG_GENMASK(9, 0)
+#define DARK_SCREEN_COMPARE_VAL(x)	REG_FIELD_PREP(DARK_SCREEN_COMPARE_MASK, (x))
+
 /* VGA port control */
 #define ADPA			_MMIO(0x61100)
 #define PCH_ADPA                _MMIO(0xe1100)