[Intel-gfx] [PATCH] tests: save GPU engine information more properly

2023-10-12 Thread Lee Shawn C
We encounter a unexpected error on chrome book device while
running kms_busy test. It will restore GPU engine's timeout
value but open incorrect file name (XR24 in below).

openat(AT_FDCWD, "/sys/dev/char/226:0", O_RDONLY) = 12
openat(12, "dev", O_RDONLY) = 13
read(13, "226:0\n", 1023)   = 6
close(13)   = 0
openat(12, "engine", O_RDONLY)  = 13
close(12)   = 0
openat(13, "XR24", O_RDONLY)= -1 ENOENT (No such file or directory)

Test code did not save engine data properly to cause this problem.
So modify the code to save GPU engine information into a globla variable
to avoid test deamon to open incorrect file again.

Issue: https://gitlab.freedesktop.org/drm/igt-gpu-tools/-/issues/147
Fixes: 9e635a1c5029 ("tests/kms_busy: Ensure GPU reset when waiting
for a new FB during modeset")
Cc: Tvrtko Ursulin 
Cc: Imre Deak 
Cc: Vidya Srinivas 
Signed-off-by: Lee Shawn C 
---
 lib/i915/gem_engine_topology.c | 12 ++--
 lib/i915/gem_engine_topology.h |  2 +-
 tests/intel/gem_exec_capture.c |  2 +-
 tests/intel/gem_reset_stats.c  |  2 +-
 tests/intel/i915_hangman.c |  2 +-
 tests/intel/kms_busy.c |  2 +-
 6 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/lib/i915/gem_engine_topology.c b/lib/i915/gem_engine_topology.c
index 7c6cd9ba97db..afb576afb2dc 100644
--- a/lib/i915/gem_engine_topology.c
+++ b/lib/i915/gem_engine_topology.c
@@ -571,23 +571,23 @@ void gem_engine_properties_configure(int fd, struct 
gem_engine_properties *param
int ret;
struct gem_engine_properties write = *params;
 
-   ret = gem_engine_property_scanf(fd, write.engine->name,
+   ret = gem_engine_property_scanf(fd, write.engine.name,
"heartbeat_interval_ms",
"%d", >heartbeat_interval);
igt_assert_eq(ret, 1);
 
-   ret = gem_engine_property_printf(fd, write.engine->name,
+   ret = gem_engine_property_printf(fd, write.engine.name,
 "heartbeat_interval_ms", "%d",
 write.heartbeat_interval);
igt_assert_lt(0, ret);
 
if (gem_scheduler_has_preemption(fd)) {
-   ret = gem_engine_property_scanf(fd, write.engine->name,
+   ret = gem_engine_property_scanf(fd, write.engine.name,
"preempt_timeout_ms",
"%d", >preempt_timeout);
igt_assert_eq(ret, 1);
 
-   ret = gem_engine_property_printf(fd, write.engine->name,
+   ret = gem_engine_property_printf(fd, write.engine.name,
 "preempt_timeout_ms", "%d",
 write.preempt_timeout);
igt_assert_lt(0, ret);
@@ -598,13 +598,13 @@ void gem_engine_properties_restore(int fd, const struct 
gem_engine_properties *s
 {
int ret;
 
-   ret = gem_engine_property_printf(fd, saved->engine->name,
+   ret = gem_engine_property_printf(fd, saved->engine.name,
 "heartbeat_interval_ms", "%d",
 saved->heartbeat_interval);
igt_assert_lt(0, ret);
 
if (gem_scheduler_has_preemption(fd)) {
-   ret = gem_engine_property_printf(fd, saved->engine->name,
+   ret = gem_engine_property_printf(fd, saved->engine.name,
 "preempt_timeout_ms", "%d",
 saved->preempt_timeout);
igt_assert_lt(0, ret);
diff --git a/lib/i915/gem_engine_topology.h b/lib/i915/gem_engine_topology.h
index 89642c31721c..9eb9d5ddc888 100644
--- a/lib/i915/gem_engine_topology.h
+++ b/lib/i915/gem_engine_topology.h
@@ -122,7 +122,7 @@ struct intel_execution_engine2 
gem_eb_flags_to_engine(unsigned int flags);
 intel_next_engine(__##e__))
 
 struct gem_engine_properties {
-   const struct intel_execution_engine2 *engine;
+   struct intel_execution_engine2 engine;
int preempt_timeout;
int heartbeat_interval;
 };
diff --git a/tests/intel/gem_exec_capture.c b/tests/intel/gem_exec_capture.c
index ab8305e4dfaf..d231c53b98e1 100644
--- a/tests/intel/gem_exec_capture.c
+++ b/tests/intel/gem_exec_capture.c
@@ -258,7 +258,7 @@ configure_hangs(int fd, const struct 
intel_execution_engine2 *e, int ctxt_id)
struct gem_engine_properties props;
 
/* Ensure fast hang detection */
-   props.engine = e;
+   props.engine = *e;
props.preempt_timeout = 25

Re: [Intel-gfx] drm/i915/mtl: Remove the 'force_probe' requirement for Meteor Lake

2023-10-11 Thread Lee, Shawn C
> From: Radhakrishna Sripada 
> 
> Meteor Lake has demonstrated consistent stability for some time.
> All user-space API modifications tide to its core platform
> functions are operational.
> 
> The necessary firmware components are set up and comprehensive
> testing has been condused over a period.
> 
> Given the recent faborable CI results, as well, we believe it's
> time to eliminate the 'force_probe' prerequisite and activate the
> platform by default.
> 
> Signed-off-by: Aditya Chauhan 
> Signed-off-by: Andrzej Hajda 
> Signed-off-by: Chris Wilson 
> Signed-off-by: Janusz Krzysztofik 
> Signed-off-by: Jonathan Cavitt 
> Signed-off-by: Nirmoy Das 
> Signed-off-by: Radhakrishna Sripada 
> Signed-off-by: Andi Shyti 
> Cc: Jani Nikula 
> Cc: Joonas Lahtinen 
> Cc: Rodrigo Vivi 
> Cc: Tvrtko Ursulin 
> ---
> Hello,
> 
> This patch eliminates the 'force probe' for the MTL platforms. Over the recent
> weeks, MTL has demonstrated stability, consistently passing BAT tests with
> success rates ranging from 98% to 100%.
> 
> There's a single issue hindering us from achieving a 100% BAT test coverage.
> Fortunately, we've identified the issue, and the proposed solution can be 
> found
> here[*]. The CI results are encouraging.
> 
> Once all reviews are addressed, we plan to submit this series with the 
> "Fixes:"
> tag.
> 
> Thank you and best regards,
> Andi and Radhakrishna
> 
> [*] https://patchwork.freedesktop.org/series/124744/
> 
>  drivers/gpu/drm/i915/i915_pci.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
> index df7c261410f7..fe748906c06f 100644
> --- a/drivers/gpu/drm/i915/i915_pci.c
> +++ b/drivers/gpu/drm/i915/i915_pci.c
> @@ -836,7 +836,6 @@  static const struct intel_device_info mtl_info = {
>   .has_pxp = 1,
>   .memory_regions = REGION_SMEM | REGION_STOLEN_LMEM,
>   .platform_engine_mask = BIT(RCS0) | BIT(BCS0) | BIT(CCS0),
> - .require_force_probe = 1,
>   MTL_CACHELEVEL,
>  };
>  

Test on my MTL device and it works properly.

Acked-by: Lee Shawn C 
Tested-by: Lee Shawn C 


Re: [Intel-gfx] [PATCH 3/3] drm/i915/uncore: optimize CONFIG_DRM_I915_DEBUG_MMIO=n more

2023-07-24 Thread Lee, Shawn C
>On 06/07/2023 13:06, Jani Nikula wrote:
>> On Thu, 06 Jul 2023, Tvrtko Ursulin  wrote:
>>> On 04/07/2023 10:48, Jani Nikula wrote:
>>>> While the default for the mmio_debug parameter depends on 
>>>> CONFIG_DRM_I915_DEBUG_MMIO, we look it up and include all the code 
>>>> for unclaimed reg debugging even when CONFIG_DRM_I915_DEBUG_MMIO=n. Fix it.
>>>>
>>>> Cc: Lee Shawn C 
>>>> Signed-off-by: Jani Nikula 
>>>> ---
>>>>drivers/gpu/drm/i915/intel_uncore.c | 3 ++-
>>>>1 file changed, 2 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/i915/intel_uncore.c 
>>>> b/drivers/gpu/drm/i915/intel_uncore.c
>>>> index dfefad5a5fec..da2edde4b6f6 100644
>>>> --- a/drivers/gpu/drm/i915/intel_uncore.c
>>>> +++ b/drivers/gpu/drm/i915/intel_uncore.c
>>>> @@ -1929,7 +1929,8 @@ static inline bool __must_check
>>>>unclaimed_reg_debug_header(struct intel_uncore *uncore,
>>>>   const i915_reg_t reg, const bool read)
>>>>{
>>>> -  if (likely(!uncore->i915->params.mmio_debug) || !uncore->debug)
>>>> +  if (!IS_ENABLED(CONFIG_DRM_I915_DEBUG_MMIO) ||
>>>> +  likely(!uncore->i915->params.mmio_debug) || !uncore->debug)
>>>>return false;
>>>
>>> But now it would not be possible to enable mmio_debug, if Kconfig 
>>> _default_ is 'n'. What am I missing?
>> 
>> You're not missing anything, I am. *facepalm*
>> 
>> The question is, are the first two acceptable without the third?
>
>What are 1st, 2nd and 3rd in your counting?
>
>This area is confusing me a little bit.
>
>If I look at unclaimed_reg_debug it appears unclaimed register debug depends 
>on mmio_debug.
>
>But if I look at the message output by
>intel_uncore_arm_unclaimed_mmio_detection it appears that on detecting an 
>unclaimed register we suggest to enable mmio_debug.
>
>Isn't that a contradiction?
>
>Regards,
>
>Tvrtko

Hi Jani, Tvrtko,

We are still waiting for these patches to fix issue. May I get your help to 
re-visit this series? Thanks!

Best regards,
Shawn



[Intel-gfx] [PATCH] drm/i915: Refine mmio debug flow to avoid bad unlock balance detected.

2023-07-04 Thread Lee Shawn C
Perform reboot stresss test on a kernel build with lockdebug flag enabled.
Bad unlock balanace detected would happened sometimes. Below is the
problematic scenario. If params.mmio_debug value was changed at step #4.
And it would trigger this issue. Modify code flow that decide to
enable/disable mmio debug before unclaimed_reg_debug() can avoid
this symptom.

1. GEN6_READ_HEADER is called with params.mmio_debug = 0
2. unclaimed_reg_debug(before = true) is called
3. unclaimed_reg_debug return without taking a lock
   because params.mmio_debug == 0
4. other thread modifies params.mmio_debug to 1
5. GEN6_READ_FOOTER is called with params.mmio_debug != 0
6. unclaimed_reg_debug tries to assert non-taken lock (first WARN)
7. unclaimed_reg_debug tries to release non-taken lock (second WARN)

Closes:https://gitlab.freedesktop.org/drm/intel/-/issues/8749
Signed-off-by: Lee Shawn C 
Cc: Uma Shankar 
Cc: Matt Roper 
Cc: Andi Shyti 
---
 drivers/gpu/drm/i915/intel_uncore.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_uncore.c 
b/drivers/gpu/drm/i915/intel_uncore.c
index 796ebfe6c550..9d665978cc43 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -1931,9 +1931,6 @@ unclaimed_reg_debug(struct intel_uncore *uncore,
const bool read,
const bool before)
 {
-   if (likely(!uncore->i915->params.mmio_debug) || !uncore->debug)
-   return;
-
/* interrupts are disabled and re-enabled around uncore->lock usage */
lockdep_assert_held(>lock);
 
@@ -2001,13 +1998,16 @@ __gen2_read(64)
 #define GEN6_READ_HEADER(x) \
u32 offset = i915_mmio_reg_offset(reg); \
unsigned long irqflags; \
+   const bool mmio_debug = likely(uncore->i915->params.mmio_debug) || 
uncore->debug; \
u##x val = 0; \
assert_rpm_wakelock_held(uncore->rpm); \
spin_lock_irqsave(>lock, irqflags); \
-   unclaimed_reg_debug(uncore, reg, true, true)
+   if (mmio_debug) \
+   unclaimed_reg_debug(uncore, reg, true, true)
 
 #define GEN6_READ_FOOTER \
-   unclaimed_reg_debug(uncore, reg, true, false); \
+   if (mmio_debug) \
+   unclaimed_reg_debug(uncore, reg, true, false); \
spin_unlock_irqrestore(>lock, irqflags); \
trace_i915_reg_rw(false, reg, val, sizeof(val), trace); \
return val
-- 
2.17.1



[Intel-gfx] [v4] drm/i915/mtl: Add new vswing table for C20 phy to support DP 1.4

2023-06-08 Thread Lee Shawn C
Add vswing table to support DP 1.4 for C20 phy.

v2: rename mtl_c10_trans
v3: add default_entry for mtl_c20_trans_dp14
v4: rename mtl_cx0_trans_dp14

Bspec: 74104
Signed-off-by: Lee Shawn C 
Cc: Mika Kahola 
Cc: Clint Taylor 
Cc: Radhakrishna Sripada 
Cc: Uma Shankar 
Reviewed-by: Mika Kahola 
Reviewed-by: Radhakrishna Sripada 
---
 .../drm/i915/display/intel_ddi_buf_trans.c| 26 +--
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c 
b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c
index b7d20485bde5..8d2932d079cf 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c
@@ -1049,12 +1049,26 @@ static const union intel_ddi_buf_trans_entry 
_mtl_c10_trans_dp14[] = {
{ .snps = { 62, 0, 0  } },  /* preset 9 */
 };
 
-static const struct intel_ddi_buf_trans mtl_cx0_trans = {
+static const struct intel_ddi_buf_trans mtl_c10_trans_dp14 = {
.entries = _mtl_c10_trans_dp14,
.num_entries = ARRAY_SIZE(_mtl_c10_trans_dp14),
.hdmi_default_entry = ARRAY_SIZE(_mtl_c10_trans_dp14) - 1,
 };
 
+/* DP1.4 */
+static const union intel_ddi_buf_trans_entry _mtl_c20_trans_dp14[] = {
+   { .snps = { 20, 0, 0  } },  /* preset 0 */
+   { .snps = { 24, 0, 4  } },  /* preset 1 */
+   { .snps = { 30, 0, 9  } },  /* preset 2 */
+   { .snps = { 34, 0, 14 } },  /* preset 3 */
+   { .snps = { 29, 0, 0  } },  /* preset 4 */
+   { .snps = { 34, 0, 5  } },  /* preset 5 */
+   { .snps = { 38, 0, 10 } },  /* preset 6 */
+   { .snps = { 36, 0, 0  } },  /* preset 7 */
+   { .snps = { 40, 0, 6  } },  /* preset 8 */
+   { .snps = { 48, 0, 0  } },  /* preset 9 */
+};
+
 /* DP2.0 */
 static const union intel_ddi_buf_trans_entry _mtl_c20_trans_uhbr[] = {
{ .snps = { 48, 0, 0 } },   /* preset 0 */
@@ -1090,6 +1104,12 @@ static const struct intel_ddi_buf_trans 
mtl_c20_trans_hdmi = {
.hdmi_default_entry = 0,
 };
 
+static const struct intel_ddi_buf_trans mtl_c20_trans_dp14 = {
+   .entries = _mtl_c20_trans_dp14,
+   .num_entries = ARRAY_SIZE(_mtl_c20_trans_dp14),
+   .hdmi_default_entry = ARRAY_SIZE(_mtl_c20_trans_dp14) - 1,
+};
+
 static const struct intel_ddi_buf_trans mtl_c20_trans_uhbr = {
.entries = _mtl_c20_trans_uhbr,
.num_entries = ARRAY_SIZE(_mtl_c20_trans_uhbr),
@@ -1678,8 +1698,10 @@ mtl_get_cx0_buf_trans(struct intel_encoder *encoder,
return intel_get_buf_trans(_c20_trans_uhbr, n_entries);
else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) && 
!(intel_is_c10phy(i915, phy)))
return intel_get_buf_trans(_c20_trans_hdmi, n_entries);
+   else if (!intel_is_c10phy(i915, phy))
+   return intel_get_buf_trans(_c20_trans_dp14, n_entries);
else
-   return intel_get_buf_trans(_cx0_trans, n_entries);
+   return intel_get_buf_trans(_c10_trans_dp14, n_entries);
 }
 
 void intel_ddi_buf_trans_init(struct intel_encoder *encoder)
-- 
2.17.1



[Intel-gfx] [v3] drm/i915/mtl: Add new vswing table for C20 phy to support DP 1.4

2023-06-08 Thread Lee Shawn C
Add vswing table to support DP 1.4 for C20 phy.

v2: rename mtl_c10_trans
v3: add default_entry into mtl_c20_trans_dp14

Bspec: 74104
Signed-off-by: Lee Shawn C 
Cc: Mika Kahola 
Cc: Clint Taylor 
Cc: Radhakrishna Sripada 
Cc: Uma Shankar 
Reviewed-by: Mika Kahola 
Reviewed-by: Radhakrishna Sripada 
---
 .../drm/i915/display/intel_ddi_buf_trans.c| 26 +--
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c 
b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c
index b7d20485bde5..d7301f13c5cd 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c
@@ -1049,12 +1049,26 @@ static const union intel_ddi_buf_trans_entry 
_mtl_c10_trans_dp14[] = {
{ .snps = { 62, 0, 0  } },  /* preset 9 */
 };
 
-static const struct intel_ddi_buf_trans mtl_cx0_trans = {
+static const struct intel_ddi_buf_trans mtl_cx0_trans_dp14 = {
.entries = _mtl_c10_trans_dp14,
.num_entries = ARRAY_SIZE(_mtl_c10_trans_dp14),
.hdmi_default_entry = ARRAY_SIZE(_mtl_c10_trans_dp14) - 1,
 };
 
+/* DP1.4 */
+static const union intel_ddi_buf_trans_entry _mtl_c20_trans_dp14[] = {
+   { .snps = { 20, 0, 0  } },  /* preset 0 */
+   { .snps = { 24, 0, 4  } },  /* preset 1 */
+   { .snps = { 30, 0, 9  } },  /* preset 2 */
+   { .snps = { 34, 0, 14 } },  /* preset 3 */
+   { .snps = { 29, 0, 0  } },  /* preset 4 */
+   { .snps = { 34, 0, 5  } },  /* preset 5 */
+   { .snps = { 38, 0, 10 } },  /* preset 6 */
+   { .snps = { 36, 0, 0  } },  /* preset 7 */
+   { .snps = { 40, 0, 6  } },  /* preset 8 */
+   { .snps = { 48, 0, 0  } },  /* preset 9 */
+};
+
 /* DP2.0 */
 static const union intel_ddi_buf_trans_entry _mtl_c20_trans_uhbr[] = {
{ .snps = { 48, 0, 0 } },   /* preset 0 */
@@ -1090,6 +1104,12 @@ static const struct intel_ddi_buf_trans 
mtl_c20_trans_hdmi = {
.hdmi_default_entry = 0,
 };
 
+static const struct intel_ddi_buf_trans mtl_c20_trans_dp14 = {
+   .entries = _mtl_c20_trans_dp14,
+   .num_entries = ARRAY_SIZE(_mtl_c20_trans_dp14),
+   .hdmi_default_entry = ARRAY_SIZE(_mtl_c20_trans_dp14) - 1,
+};
+
 static const struct intel_ddi_buf_trans mtl_c20_trans_uhbr = {
.entries = _mtl_c20_trans_uhbr,
.num_entries = ARRAY_SIZE(_mtl_c20_trans_uhbr),
@@ -1678,8 +1698,10 @@ mtl_get_cx0_buf_trans(struct intel_encoder *encoder,
return intel_get_buf_trans(_c20_trans_uhbr, n_entries);
else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) && 
!(intel_is_c10phy(i915, phy)))
return intel_get_buf_trans(_c20_trans_hdmi, n_entries);
+   else if (!intel_is_c10phy(i915, phy))
+   return intel_get_buf_trans(_c20_trans_dp14, n_entries);
else
-   return intel_get_buf_trans(_cx0_trans, n_entries);
+   return intel_get_buf_trans(_cx0_trans_dp14, n_entries);
 }
 
 void intel_ddi_buf_trans_init(struct intel_encoder *encoder)
-- 
2.17.1



[Intel-gfx] [v2] drm/i915/mtl: Add new vswing table for C20 phy to support DP 1.4

2023-06-07 Thread Lee Shawn C
Add vswing table to support DP 1.4 for C20 phy.

v2: rename mtl_c10_trans

Bspec: 74104
Signed-off-by: Lee Shawn C 
Cc: Mika Kahola 
Cc: Clint Taylor 
Cc: Radhakrishna Sripada 
Cc: Uma Shankar 
Reviewed-by: Mika Kahola 
Reviewed-by: Radhakrishna Sripada 
---
 .../drm/i915/display/intel_ddi_buf_trans.c| 25 +--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c 
b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c
index b7d20485bde5..a6276a9ba61c 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c
@@ -1049,12 +1049,26 @@ static const union intel_ddi_buf_trans_entry 
_mtl_c10_trans_dp14[] = {
{ .snps = { 62, 0, 0  } },  /* preset 9 */
 };
 
-static const struct intel_ddi_buf_trans mtl_cx0_trans = {
+static const struct intel_ddi_buf_trans mtl_cx0_trans_dp14 = {
.entries = _mtl_c10_trans_dp14,
.num_entries = ARRAY_SIZE(_mtl_c10_trans_dp14),
.hdmi_default_entry = ARRAY_SIZE(_mtl_c10_trans_dp14) - 1,
 };
 
+/* DP1.4 */
+static const union intel_ddi_buf_trans_entry _mtl_c20_trans_dp14[] = {
+   { .snps = { 20, 0, 0  } },  /* preset 0 */
+   { .snps = { 24, 0, 4  } },  /* preset 1 */
+   { .snps = { 30, 0, 9  } },  /* preset 2 */
+   { .snps = { 34, 0, 14 } },  /* preset 3 */
+   { .snps = { 29, 0, 0  } },  /* preset 4 */
+   { .snps = { 34, 0, 5  } },  /* preset 5 */
+   { .snps = { 38, 0, 10 } },  /* preset 6 */
+   { .snps = { 36, 0, 0  } },  /* preset 7 */
+   { .snps = { 40, 0, 6  } },  /* preset 8 */
+   { .snps = { 48, 0, 0  } },  /* preset 9 */
+};
+
 /* DP2.0 */
 static const union intel_ddi_buf_trans_entry _mtl_c20_trans_uhbr[] = {
{ .snps = { 48, 0, 0 } },   /* preset 0 */
@@ -1090,6 +1104,11 @@ static const struct intel_ddi_buf_trans 
mtl_c20_trans_hdmi = {
.hdmi_default_entry = 0,
 };
 
+static const struct intel_ddi_buf_trans mtl_c20_trans_dp14 = {
+   .entries = _mtl_c20_trans_dp14,
+   .num_entries = ARRAY_SIZE(_mtl_c20_trans_dp14),
+};
+
 static const struct intel_ddi_buf_trans mtl_c20_trans_uhbr = {
.entries = _mtl_c20_trans_uhbr,
.num_entries = ARRAY_SIZE(_mtl_c20_trans_uhbr),
@@ -1678,8 +1697,10 @@ mtl_get_cx0_buf_trans(struct intel_encoder *encoder,
return intel_get_buf_trans(_c20_trans_uhbr, n_entries);
else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) && 
!(intel_is_c10phy(i915, phy)))
return intel_get_buf_trans(_c20_trans_hdmi, n_entries);
+   else if (!intel_is_c10phy(i915, phy))
+   return intel_get_buf_trans(_c20_trans_dp14, n_entries);
else
-   return intel_get_buf_trans(_cx0_trans, n_entries);
+   return intel_get_buf_trans(_cx0_trans_dp14, n_entries);
 }
 
 void intel_ddi_buf_trans_init(struct intel_encoder *encoder)
-- 
2.17.1



[Intel-gfx] [PATCH] drm/i915/mtl: Add new vswing table for C20 phy to support DP 1.4

2023-06-06 Thread Lee Shawn C
Add vswing table to support DP 1.4 for C20 phy.

Bspec: 74104
Signed-off-by: Lee Shawn C 
Cc: Mika Kahola 
Cc: Clint Taylor 
Cc: Radhakrishna Sripada 
Cc: Uma Shankar 
---
 .../drm/i915/display/intel_ddi_buf_trans.c| 21 +++
 1 file changed, 21 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c 
b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c
index b7d20485bde5..6a1507515119 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c
@@ -1055,6 +1055,20 @@ static const struct intel_ddi_buf_trans mtl_cx0_trans = {
.hdmi_default_entry = ARRAY_SIZE(_mtl_c10_trans_dp14) - 1,
 };
 
+/* DP1.4 */
+static const union intel_ddi_buf_trans_entry _mtl_c20_trans_dp14[] = {
+   { .snps = { 20, 0, 0  } },  /* preset 0 */
+   { .snps = { 24, 0, 4  } },  /* preset 1 */
+   { .snps = { 30, 0, 9  } },  /* preset 2 */
+   { .snps = { 34, 0, 14 } },  /* preset 3 */
+   { .snps = { 29, 0, 0  } },  /* preset 4 */
+   { .snps = { 34, 0, 5  } },  /* preset 5 */
+   { .snps = { 38, 0, 10 } },  /* preset 6 */
+   { .snps = { 36, 0, 0  } },  /* preset 7 */
+   { .snps = { 40, 0, 6  } },  /* preset 8 */
+   { .snps = { 48, 0, 0  } },  /* preset 9 */
+};
+
 /* DP2.0 */
 static const union intel_ddi_buf_trans_entry _mtl_c20_trans_uhbr[] = {
{ .snps = { 48, 0, 0 } },   /* preset 0 */
@@ -1090,6 +1104,11 @@ static const struct intel_ddi_buf_trans 
mtl_c20_trans_hdmi = {
.hdmi_default_entry = 0,
 };
 
+static const struct intel_ddi_buf_trans mtl_c20_trans_dp14 = {
+   .entries = _mtl_c20_trans_dp14,
+   .num_entries = ARRAY_SIZE(_mtl_c20_trans_dp14),
+};
+
 static const struct intel_ddi_buf_trans mtl_c20_trans_uhbr = {
.entries = _mtl_c20_trans_uhbr,
.num_entries = ARRAY_SIZE(_mtl_c20_trans_uhbr),
@@ -1678,6 +1697,8 @@ mtl_get_cx0_buf_trans(struct intel_encoder *encoder,
return intel_get_buf_trans(_c20_trans_uhbr, n_entries);
else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) && 
!(intel_is_c10phy(i915, phy)))
return intel_get_buf_trans(_c20_trans_hdmi, n_entries);
+   else if (!intel_is_c10phy(i915, phy))
+   return intel_get_buf_trans(_c20_trans_dp14, n_entries);
else
return intel_get_buf_trans(_cx0_trans, n_entries);
 }
-- 
2.31.1



[Intel-gfx] [PATCH] drm/i915/mtl: update DP 2.0 vswing table for C20 phy

2023-06-06 Thread Lee Shawn C
Update preset 15 setting to align the latest bspec value.

Bspec: 74104
Signed-off-by: Lee Shawn C 
Cc: Mika Kahola 
Cc: Clint Taylor 
Cc: Radhakrishna Sripada 
Cc: Uma Shankar 
---
 drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c 
b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c
index 6a1507515119..2af91a06f5fe 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c
@@ -1086,7 +1086,7 @@ static const union intel_ddi_buf_trans_entry 
_mtl_c20_trans_uhbr[] = {
{ .snps = { 37, 4, 7 } },   /* preset 12 */
{ .snps = { 33, 4, 11 } },  /* preset 13 */
{ .snps = { 40, 8, 0 } },   /* preset 14 */
-   { .snps = { 28, 2, 2 } },   /* preset 15 */
+   { .snps = { 30, 2, 2 } },   /* preset 15 */
 };
 
 /* HDMI2.0 */
-- 
2.31.1



Re: [Intel-gfx] [PATCH] drm/i915/psr: Add continuous full frame bit together with single

2022-11-29 Thread Lee, Shawn C
On Tuesday, November 29, 2022 3:51 PM, Hogander, Jouni 
 wrote:
>Currently we are observing occasionally display flickering or complete freeze. 
>This is narrowed down to be caused by single full frame update (SFF).
>
>SFF bit after it's written gets cleared by HW in subsequent vblank i.e. when 
>the update is sent to the panel. SFF bit is required to be written together 
>with partial frame update (PFU) bit. After the SFF bit gets cleared by the HW 
>psr2 man trk ctl register still contains PFU bit. If there is subsequent 
>update for any reason we will end up having selective update/fetch 
>configuration where start line is 0 and end line is 0. Also selective fetch 
>configuration for the planes is not properly performed. This seems to be 
>causing problems with some panels.
>
>Using CFF without SFF doesn't work either because it may happen that
>psr2 man track ctl register is overwritten by next update before vblank 
>triggers sending the update. This is causing problems to psr_invalidate/flush. 
>Using CFF and SFF together solves the problems as SFF is cleared only by HW in 
>subsequent vblank.
>
>Fix the flickering/freeze issue by adding continuous full frame with single 
>full frame update and switch to partial frame update only when selective 
>update area is properly calculated and configured.
>
>This is also workaround for HSD 14014971508
>
>Cc: Ville Syrjälä 
>Cc: José Roberto de Souza 
>Cc: Mika Kahola 
>
>Reported-by: Lee Shawn C 
>Signed-off-by: Jouni Högander 
>---
> drivers/gpu/drm/i915/display/intel_psr.c | 19 ++-
> 1 file changed, 10 insertions(+), 9 deletions(-)
>
>diff --git a/drivers/gpu/drm/i915/display/intel_psr.c 
>b/drivers/gpu/drm/i915/display/intel_psr.c
>index 5b678916e6db..88388201684e 100644
>--- a/drivers/gpu/drm/i915/display/intel_psr.c
>+++ b/drivers/gpu/drm/i915/display/intel_psr.c
>@@ -1510,7 +1510,8 @@ static void psr_force_hw_tracking_exit(struct intel_dp 
>*intel_dp)
>  PSR2_MAN_TRK_CTL(intel_dp->psr.transcoder),
>  man_trk_ctl_enable_bit_get(dev_priv) |
>  man_trk_ctl_partial_frame_bit_get(dev_priv) |
>- man_trk_ctl_single_full_frame_bit_get(dev_priv));
>+ man_trk_ctl_single_full_frame_bit_get(dev_priv) |
>+ man_trk_ctl_continuos_full_frame(dev_priv));
> 
>   /*
>* Display WA #0884: skl+
>@@ -1624,11 +1625,8 @@ static void psr2_man_trk_ctl_calc(struct 
>intel_crtc_state *crtc_state,
>   val |= man_trk_ctl_partial_frame_bit_get(dev_priv);
> 
>   if (full_update) {
>-  /*
>-   * Not applying Wa_14014971508:adlp as we do not support the
>-   * feature that requires this workaround.
>-   */
>   val |= man_trk_ctl_single_full_frame_bit_get(dev_priv);
>+  val |= man_trk_ctl_continuos_full_frame(dev_priv);
>   goto exit;
>   }
> 
>@@ -2307,12 +2305,15 @@ static void _psr_flush_handle(struct intel_dp 
>*intel_dp)
>   /* can we turn CFF off? */
>   if (intel_dp->psr.busy_frontbuffer_bits == 0) {
>   u32 val = man_trk_ctl_enable_bit_get(dev_priv) |
>-
>man_trk_ctl_partial_frame_bit_get(dev_priv) |
>-
>man_trk_ctl_single_full_frame_bit_get(dev_priv);
>+  
>man_trk_ctl_partial_frame_bit_get(dev_priv) |
>+  
>man_trk_ctl_single_full_frame_bit_get(dev_priv) |
>+  
>man_trk_ctl_continuos_full_frame(dev_priv);
> 
>   /*
>-   * turn continuous full frame off and do a 
>single
>-   * full frame
>+   * turn continuous full frame off and do a 
>single full frame. Still
>+   * keep cff bit enabled as we don't have proper 
>SU configuration in
>+   * case update is sent for any reason after sff 
>bit gets cleared by
>+   * the HW on next vblank.
>*/
>   intel_de_write(dev_priv, 
> PSR2_MAN_TRK_CTL(intel_dp->psr.transcoder),
>  val);
>--
>2.34.1

My DUT works well after applied this patch. Thanks!

Tested-by: Lee Shawn C 

Best regards,
Shawn


Re: [Intel-gfx] [v4] drm/i915/pps: improve eDP power on flow

2022-11-16 Thread Lee, Shawn C
On Wednesday, November 16, 2022 11:45 PM, Jani Nikula 
 wrote:
>On Mon, 14 Nov 2022, Lee Shawn C  wrote:
>> After i915 dirver initialized, a panel power off cycle delay always 
>> append before turn eDP on. If eDP display did not power on before. 
>> With this change, power off duration might longer than power cycle 
>> delay. So driver can save power cycle delay to speed up driver 
>> initialization time.
>>
>> v2: fix commit messages
>> v3: refine panel_power_off_time default value and modify
>> commit messages
>> v4: add eDP power off cycle delay at the path to unload i915 module
>>
>> Cc: Shankar Uma 
>> Cc: Jani Nikula 
>> Cc: Ville Syrjälä 
>> Signed-off-by: Lee Shawn C 
>> ---
>>  drivers/gpu/drm/i915/display/intel_pps.c | 2 +-
>>  drivers/gpu/drm/i915/i915_driver.c   | 4 
>>  2 files changed, 5 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_pps.c 
>> b/drivers/gpu/drm/i915/display/intel_pps.c
>> index 81ee7f3aadf6..ab4118b38120 100644
>> --- a/drivers/gpu/drm/i915/display/intel_pps.c
>> +++ b/drivers/gpu/drm/i915/display/intel_pps.c
>> @@ -1100,7 +1100,7 @@ bool intel_pps_have_panel_power_or_vdd(struct 
>> intel_dp *intel_dp)
>>  
>>  static void pps_init_timestamps(struct intel_dp *intel_dp)  {
>> -intel_dp->pps.panel_power_off_time = ktime_get_boottime();
>> +intel_dp->pps.panel_power_off_time = 0;
>>  intel_dp->pps.last_power_on = jiffies;
>>  intel_dp->pps.last_backlight_off = jiffies;  } diff --git 
>> a/drivers/gpu/drm/i915/i915_driver.c 
>> b/drivers/gpu/drm/i915/i915_driver.c
>> index c3d43f9b1e45..0e3cbd129055 100644
>> --- a/drivers/gpu/drm/i915/i915_driver.c
>> +++ b/drivers/gpu/drm/i915/i915_driver.c
>> @@ -107,6 +107,8 @@ static const char irst_name[] = "INT3392";
>>  
>>  static const struct drm_driver i915_drm_driver;
>>  
>> +static void intel_shutdown_encoders(struct drm_i915_private 
>> +*dev_priv);
>> +
>>  static void i915_release_bridge_dev(struct drm_device *dev,
>>  void *bridge)
>>  {
>> @@ -796,6 +798,8 @@ static void i915_driver_unregister(struct 
>> drm_i915_private *dev_priv)
>>  
>>  intel_display_driver_unregister(dev_priv);
>>  
>> +intel_shutdown_encoders(dev_priv);
>> +
>
>Per Ville's comments on IRC, this is still too early. See [1] for another 
>approach.
>
>BR,
>Jani.
>

Thank you! I've tested this patch and it works properly. Detail kernel log is 
attached on [2].
Please help to review and merge that patch ASAP. 

Best regards,
Shawn

>
>[1] 
>https://patchwork.freedesktop.org/patch/msgid/20221116150657.1347504-1-jani.nik...@intel.com

[2] https://gitlab.freedesktop.org/drm/intel/-/issues/7417#note_1643009

>
>
>>  for_each_gt(gt, dev_priv, i)
>>  intel_gt_driver_unregister(gt);
>
>--
>Jani Nikula, Intel Open Source Graphics Center


[Intel-gfx] [v4] drm/i915/pps: improve eDP power on flow

2022-11-13 Thread Lee Shawn C
After i915 dirver initialized, a panel power off cycle delay
always append before turn eDP on. If eDP display did not
power on before. With this change, power off duration might
longer than power cycle delay. So driver can save power cycle
delay to speed up driver initialization time.

v2: fix commit messages
v3: refine panel_power_off_time default value and modify
commit messages
v4: add eDP power off cycle delay at the path to unload i915 module

Cc: Shankar Uma 
Cc: Jani Nikula 
Cc: Ville Syrjälä 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/i915/display/intel_pps.c | 2 +-
 drivers/gpu/drm/i915/i915_driver.c   | 4 
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_pps.c 
b/drivers/gpu/drm/i915/display/intel_pps.c
index 81ee7f3aadf6..ab4118b38120 100644
--- a/drivers/gpu/drm/i915/display/intel_pps.c
+++ b/drivers/gpu/drm/i915/display/intel_pps.c
@@ -1100,7 +1100,7 @@ bool intel_pps_have_panel_power_or_vdd(struct intel_dp 
*intel_dp)
 
 static void pps_init_timestamps(struct intel_dp *intel_dp)
 {
-   intel_dp->pps.panel_power_off_time = ktime_get_boottime();
+   intel_dp->pps.panel_power_off_time = 0;
intel_dp->pps.last_power_on = jiffies;
intel_dp->pps.last_backlight_off = jiffies;
 }
diff --git a/drivers/gpu/drm/i915/i915_driver.c 
b/drivers/gpu/drm/i915/i915_driver.c
index c3d43f9b1e45..0e3cbd129055 100644
--- a/drivers/gpu/drm/i915/i915_driver.c
+++ b/drivers/gpu/drm/i915/i915_driver.c
@@ -107,6 +107,8 @@ static const char irst_name[] = "INT3392";
 
 static const struct drm_driver i915_drm_driver;
 
+static void intel_shutdown_encoders(struct drm_i915_private *dev_priv);
+
 static void i915_release_bridge_dev(struct drm_device *dev,
void *bridge)
 {
@@ -796,6 +798,8 @@ static void i915_driver_unregister(struct drm_i915_private 
*dev_priv)
 
intel_display_driver_unregister(dev_priv);
 
+   intel_shutdown_encoders(dev_priv);
+
for_each_gt(gt, dev_priv, i)
intel_gt_driver_unregister(gt);
 
-- 
2.17.1



Re: [Intel-gfx] [v3] drm/i915/pps: improve eDP power on flow

2022-11-03 Thread Lee, Shawn C
On Thursday, November 3, 2022 7:00 PM, Jani Nikula 
 wrote:
>On Thu, 03 Nov 2022, Lee Shawn C  wrote:
>> After i915 dirver initialized, a panel power off cycle delay always 
>> append before turn eDP on. If eDP display did not power on before. 
>> With this change, power off duration might longer than power cycle 
>> delay. So driver can save power cycle delay to speed up driver 
>> initialization time.
>>
>> v2: fix commit messages
>> v3: refine panel_power_off_time default value and modify
>> commit messages
>>
>> Cc: Shankar Uma 
>> Cc: Jani Nikula 
>> Cc: Ville Syrjälä 
>> Signed-off-by: Lee Shawn C 
>> ---
>>  drivers/gpu/drm/i915/display/intel_pps.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_pps.c 
>> b/drivers/gpu/drm/i915/display/intel_pps.c
>> index 21944f5bf3a8..a394bb1c92d0 100644
>> --- a/drivers/gpu/drm/i915/display/intel_pps.c
>> +++ b/drivers/gpu/drm/i915/display/intel_pps.c
>> @@ -1098,7 +1098,7 @@ bool intel_pps_have_panel_power_or_vdd(struct 
>> intel_dp *intel_dp)
>>  
>>  static void pps_init_timestamps(struct intel_dp *intel_dp)  {
>> -intel_dp->pps.panel_power_off_time = ktime_get_boottime();
>> +intel_dp->pps.panel_power_off_time = 0;
>
>So this is just copy-paste from [1] where we discuss the problems with this 
>approach, specifically module reload ignoring the power off time.
>Why would you post this without even mentioning the problem?
>

OK, we will stop commit any patch until we have proper solution. Could you 
please share your opinion about next step? Thanks!

Best regards,
Shawn

>
>BR,
>Jani.
>
>
>[1] https://gitlab.freedesktop.org/drm/intel/-/issues/7417#note_1619118
>
>>  intel_dp->pps.last_power_on = jiffies;
>>  intel_dp->pps.last_backlight_off = jiffies;  }
>
>--
>Jani Nikula, Intel Open Source Graphics Center


[Intel-gfx] [v3] drm/i915/pps: improve eDP power on flow

2022-11-02 Thread Lee Shawn C
After i915 dirver initialized, a panel power off cycle delay
always append before turn eDP on. If eDP display did not
power on before. With this change, power off duration might
longer than power cycle delay. So driver can save power cycle
delay to speed up driver initialization time.

v2: fix commit messages
v3: refine panel_power_off_time default value and modify
commit messages

Cc: Shankar Uma 
Cc: Jani Nikula 
Cc: Ville Syrjälä 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/i915/display/intel_pps.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_pps.c 
b/drivers/gpu/drm/i915/display/intel_pps.c
index 21944f5bf3a8..a394bb1c92d0 100644
--- a/drivers/gpu/drm/i915/display/intel_pps.c
+++ b/drivers/gpu/drm/i915/display/intel_pps.c
@@ -1098,7 +1098,7 @@ bool intel_pps_have_panel_power_or_vdd(struct intel_dp 
*intel_dp)
 
 static void pps_init_timestamps(struct intel_dp *intel_dp)
 {
-   intel_dp->pps.panel_power_off_time = ktime_get_boottime();
+   intel_dp->pps.panel_power_off_time = 0;
intel_dp->pps.last_power_on = jiffies;
intel_dp->pps.last_backlight_off = jiffies;
 }
-- 
2.17.1



Re: [Intel-gfx] [v2] drm/i915/pps: improve eDP power on flow

2022-11-02 Thread Lee, Shawn C
On Wednesday, November 2, 2022 6:19 PM, Jani Nikula 
 wrote:
>On Tue, 01 Nov 2022, "Lee, Shawn C"  wrote:
>> On Tue, Nov. 1, 2022, 1:43 p.m, Jani Nikula  
>> wrote:
>>>On Tue, 01 Nov 2022, "Lee, Shawn C"  wrote:
>>>> On Tuesday, November 1, 2022 5:53 PM, Jani Nikula 
>>>>  wrote:
>>>>>On Mon, 24 Oct 2022, Lee Shawn C  wrote:
>>>>>> A panel power off cycle delay always append before turn eDP on.
>>>>>> Driver should check last_power_on and last_backlight_off before 
>>>>>> insert this delay. If these values are the same, it means eDP was 
>>>>>> off until now and driver can bypass power off cycle delay to save 
>>>>>> some times to speed up eDP power on sequence.
>>>>>>
>>>>>> v2: fix commit messages
>>>>>
>>>>>There are more changes here than what the changelog says, but the previous 
>>>>>review comments were not answered [1].
>>>>>
>>>>
>>>> I'm sorry that lose the question in [1]. 
>>>>
>>>> "But someone else may have turned it off just before we were handed 
>>>> control, we have no idea."
>>>> This is the situation from Ville's comment. Agree that we don't know when 
>>>> panel will be powered off.
>>>> In my opinion, eDP panel should not be turned off before i915 take it 
>>>> over. If it was turned on or off by standard contorl (ex: modeset).
>>>> last_power_on and last_backlight_off would not be the same. So this change 
>>>> should be safe.
>>>
>>>I think it's pretty much a hard requirement we respect the panel 
>>>delays at i915 probe. If we don't know, we don't know, and we can't 
>>>make assumptions.
>>>
>>>If the goal is to speed up boot, you should ensure 1) the pre-os 
>>>enables the display, and 2) i915 can take over the display without a 
>>>modeset and a panel power cycle.
>>>
>>
>> After boot into kernel. It seems there are two cases we will see. 
>> 1) If eDP display did not enable at pre-os stage, this patch can save power 
>> cycle time. 
>> 2) If eDP display was enabled at pre-os, because of cdclk was setting to max 
>> freq always.
>>i915 driver will trigger modeset to reduce cdclk freq and run power 
>> off/on cycle.
>>At this case power cycle delay will not be ignored.
>
>In case 2, the effort should probably be spent on hardware take over using the 
>same cdclk as it was.
>I thought this was already the case, but maybe I'm wrong and/or there are 
>corner cases.
>

When cdclk was the same, it means driver will not trigger modeset and keep the 
setting from pre-os.
If so, this behavior sound like fastboot mode enabled.

>> So this patch can only benefit at case #1 (eDP did not enable at 
>> pre-os stage). And it is what we need. :)
>
>I understand a typical T12 min (i.e. from Vcc power down to up again) could 
>be, say, 500 ms and it's a long time to wait. Especially if the wait happens 
>in output init which is all serial and synchronous in probe.
>
>However, you're basically asking us to potentially violate panel timings. It 
>just doesn't strike me as an obviusly good idea.
>

>From my point of view, pre-os initialization already take 2~3 seconds (panel 
>power is off). Kernel log in below shows the first time driver try to enable 
>eDP pwoer in case 1.

[0.957991] i915 :00:02.0: [drm:intel_pps_vdd_on_unlocked] Turning 
[ENCODER:235:DDI A/PHY A] VDD on
[0.958021] i915 :00:02.0: [drm:wait_panel_power_cycle] Wait for panel 
power cycle

eDP panel power never turn on before time [0.958021]. So the panel power 
already off over 2 (pre-os) + 1 (kernel) seconds at least.
In my opinion, 3 seconds already over the power cycle delay setting. That's why 
i'm thinking maybe we don't need this additional 600ms delay in this case.

>It might be a good idea to file an issue at fdo gitlab [1] and attach a dmesg 
>with drm.debug=14 from boot to at least the first modeset so we can actually 
>see what the delays are and where the time is spent.

Here is the gitlab issue and you can find kernel log in it. Thanks!
https://gitlab.freedesktop.org/drm/intel/-/issues/7417

Best regards,
Shawn

>
>
>BR,
>Jani.
>
>
>[1] https://gitlab.freedesktop.org/drm/intel/issues/new
>
>
>
>
>>
>> Best regards,
>> Shawn
>>
>>>
>>>BR,
>>>Jani.
>>>
>>>
>>>>
>>>> Best regards,
>>>> Shawn
>>>>
>>>>>
>>>>>BR

Re: [Intel-gfx] [v2] drm/i915/pps: improve eDP power on flow

2022-11-01 Thread Lee, Shawn C
On Tue, Nov. 1, 2022, 1:43 p.m, Jani Nikula  wrote:
>On Tue, 01 Nov 2022, "Lee, Shawn C"  wrote:
>> On Tuesday, November 1, 2022 5:53 PM, Jani Nikula 
>>  wrote:
>>>On Mon, 24 Oct 2022, Lee Shawn C  wrote:
>>>> A panel power off cycle delay always append before turn eDP on.
>>>> Driver should check last_power_on and last_backlight_off before 
>>>> insert this delay. If these values are the same, it means eDP was 
>>>> off until now and driver can bypass power off cycle delay to save 
>>>> some times to speed up eDP power on sequence.
>>>>
>>>> v2: fix commit messages
>>>
>>>There are more changes here than what the changelog says, but the previous 
>>>review comments were not answered [1].
>>>
>>
>> I'm sorry that lose the question in [1]. 
>>
>> "But someone else may have turned it off just before we were handed control, 
>> we have no idea."
>> This is the situation from Ville's comment. Agree that we don't know when 
>> panel will be powered off.
>> In my opinion, eDP panel should not be turned off before i915 take it over. 
>> If it was turned on or off by standard contorl (ex: modeset).
>> last_power_on and last_backlight_off would not be the same. So this change 
>> should be safe.
>
>I think it's pretty much a hard requirement we respect the panel delays 
>at i915 probe. If we don't know, we don't know, and we can't make 
>assumptions.
>
>If the goal is to speed up boot, you should ensure 1) the pre-os 
>enables the display, and 2) i915 can take over the display without a 
>modeset and a panel power cycle.
>

After boot into kernel. It seems there are two cases we will see. 
1) If eDP display did not enable at pre-os stage, this patch can save power 
cycle time. 
2) If eDP display was enabled at pre-os, because of cdclk was setting to max 
freq always.
   i915 driver will trigger modeset to reduce cdclk freq and run power off/on 
cycle.
   At this case power cycle delay will not be ignored.

So this patch can only benefit at case #1 (eDP did not enable at pre-os stage). 
And it is what we need. :)

Best regards,
Shawn

>
>BR,
>Jani.
>
>
>>
>> Best regards,
>> Shawn
>>
>>>
>>>BR,
>>>Jani.
>>>
>>>
>>>[1] https://lore.kernel.org/r/y1afudawfvtac...@intel.com
>>>
>>>>
>>>> Cc: Shankar Uma 
>>>> Cc: Jani Nikula 
>>>> Cc: Ville Syrjälä 
>>>> Signed-off-by: Lee Shawn C 
>>>> ---
>>>>  drivers/gpu/drm/i915/display/intel_pps.c | 9 -
>>>>  1 file changed, 8 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/i915/display/intel_pps.c
>>>> b/drivers/gpu/drm/i915/display/intel_pps.c
>>>> index 21944f5bf3a8..290473ec70d5 100644
>>>> --- a/drivers/gpu/drm/i915/display/intel_pps.c
>>>> +++ b/drivers/gpu/drm/i915/display/intel_pps.c
>>>> @@ -509,6 +509,13 @@ static void wait_panel_power_cycle(struct intel_dp 
>>>> *intel_dp)
>>>>ktime_t panel_power_on_time;
>>>>s64 panel_power_off_duration;
>>>>  
>>>> +  /* When last_power_on equal to last_backlight_off, it means driver did 
>>>> not
>>>> +   * turn on or off eDP panel so far. So we can bypass power cycle delay 
>>>> to
>>>> +   * save some times here.
>>>> +   */
>>>> +  if (intel_dp->pps.last_power_on == intel_dp->pps.last_backlight_off)
>>>> +  return;
>>>> +
>>>>drm_dbg_kms(>drm, "Wait for panel power cycle\n");
>>>>  
>>>>/* take the difference of current time and panel power off time 
>>>> @@
>>>> -1100,7 +1107,7 @@ static void pps_init_timestamps(struct intel_dp
>>>> *intel_dp)  {
>>>>intel_dp->pps.panel_power_off_time = ktime_get_boottime();
>>>>intel_dp->pps.last_power_on = jiffies;
>>>> -  intel_dp->pps.last_backlight_off = jiffies;
>>>> +  intel_dp->pps.last_backlight_off = intel_dp->pps.last_power_on;
>>>>  }
>>>>  
>>>>  static void
>>>
>>>--
>>>Jani Nikula, Intel Open Source Graphics Center


Re: [Intel-gfx] [v2] drm/i915/pps: improve eDP power on flow

2022-11-01 Thread Lee, Shawn C
On Tue, Nov. 1, 2022, 1:43 p.m, Jani Nikula  wrote:
>On Tue, 01 Nov 2022, "Lee, Shawn C"  wrote:
>> On Tuesday, November 1, 2022 5:53 PM, Jani Nikula 
>>  wrote:
>>>On Mon, 24 Oct 2022, Lee Shawn C  wrote:
>>>> A panel power off cycle delay always append before turn eDP on.
>>>> Driver should check last_power_on and last_backlight_off before insert 
>>>> this delay. If these values are the same, it means eDP was off until 
>>>> now and driver can bypass power off cycle delay to save some times to 
>>>> speed up eDP power on sequence.
>>>>
>>>> v2: fix commit messages
>>>
>>>There are more changes here than what the changelog says, but the previous 
>>>review comments were not answered [1].
>>>
>>
>> I'm sorry that lose the question in [1]. 
>>
>> "But someone else may have turned it off just before we were handed control, 
>> we have no idea."
>> This is the situation from Ville's comment. Agree that we don't know when 
>> panel will be powered off.
>> In my opinion, eDP panel should not be turned off before i915 take it over. 
>> If it was turned on or off by standard contorl (ex: modeset).
>> last_power_on and last_backlight_off would not be the same. So this change 
>> should be safe.
>
>I think it's pretty much a hard requirement we respect the panel delays
>at i915 probe. If we don't know, we don't know, and we can't make
>assumptions.
>
>If the goal is to speed up boot, you should ensure 1) the pre-os enables
>the display, and 2) i915 can take over the display without a modeset and
>a panel power cycle.
>

After boot into kernel. It seems there are two cases we will see. 
1) If eDP display did not enable at pre-os stage, this patch can save power 
cycle time. 
2) If eDP display was enabled at pre-os, because of cdclk was setting to max 
freq always.
   i915 driver will trigger modeset to reduce cdclk freq and run power off/on 
cycle.
   At this case power cycle delay will not be ignored.

So this patch can only benefit at case #1 (eDP did not enable at pre-os stage). 
And it is what we need. :)

Best regards,
Shawn

>
>BR,
>Jani.
>
>
>>
>> Best regards,
>> Shawn
>>
>>>
>>>BR,
>>>Jani.
>>>
>>>
>>>[1] https://lore.kernel.org/r/y1afudawfvtac...@intel.com
>>>
>>>>
>>>> Cc: Shankar Uma 
>>>> Cc: Jani Nikula 
>>>> Cc: Ville Syrjälä 
>>>> Signed-off-by: Lee Shawn C 
>>>> ---
>>>>  drivers/gpu/drm/i915/display/intel_pps.c | 9 -
>>>>  1 file changed, 8 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/i915/display/intel_pps.c 
>>>> b/drivers/gpu/drm/i915/display/intel_pps.c
>>>> index 21944f5bf3a8..290473ec70d5 100644
>>>> --- a/drivers/gpu/drm/i915/display/intel_pps.c
>>>> +++ b/drivers/gpu/drm/i915/display/intel_pps.c
>>>> @@ -509,6 +509,13 @@ static void wait_panel_power_cycle(struct intel_dp 
>>>> *intel_dp)
>>>>ktime_t panel_power_on_time;
>>>>s64 panel_power_off_duration;
>>>>  
>>>> +  /* When last_power_on equal to last_backlight_off, it means driver did 
>>>> not
>>>> +   * turn on or off eDP panel so far. So we can bypass power cycle delay 
>>>> to
>>>> +   * save some times here.
>>>> +   */
>>>> +  if (intel_dp->pps.last_power_on == intel_dp->pps.last_backlight_off)
>>>> +  return;
>>>> +
>>>>drm_dbg_kms(>drm, "Wait for panel power cycle\n");
>>>>  
>>>>/* take the difference of current time and panel power off time @@ 
>>>> -1100,7 +1107,7 @@ static void pps_init_timestamps(struct intel_dp 
>>>> *intel_dp)  {
>>>>intel_dp->pps.panel_power_off_time = ktime_get_boottime();
>>>>intel_dp->pps.last_power_on = jiffies;
>>>> -  intel_dp->pps.last_backlight_off = jiffies;
>>>> +  intel_dp->pps.last_backlight_off = intel_dp->pps.last_power_on;
>>>>  }
>>>>  
>>>>  static void
>>>
>>>--
>>>Jani Nikula, Intel Open Source Graphics Center


Re: [Intel-gfx] [v2] drm/i915/pps: improve eDP power on flow

2022-11-01 Thread Lee, Shawn C


On Tuesday, November 1, 2022 5:53 PM, Jani Nikula  
wrote:
>On Mon, 24 Oct 2022, Lee Shawn C  wrote:
>> A panel power off cycle delay always append before turn eDP on.
>> Driver should check last_power_on and last_backlight_off before insert 
>> this delay. If these values are the same, it means eDP was off until 
>> now and driver can bypass power off cycle delay to save some times to 
>> speed up eDP power on sequence.
>>
>> v2: fix commit messages
>
>There are more changes here than what the changelog says, but the previous 
>review comments were not answered [1].
>

I'm sorry that lose the question in [1]. 

"But someone else may have turned it off just before we were handed control, we 
have no idea."
This is the situation from Ville's comment. Agree that we don't know when panel 
will be powered off.
In my opinion, eDP panel should not be turned off before i915 take it over. If 
it was turned on or off by standard contorl (ex: modeset).
last_power_on and last_backlight_off would not be the same. So this change 
should be safe.

Best regards,
Shawn

>
>BR,
>Jani.
>
>
>[1] https://lore.kernel.org/r/y1afudawfvtac...@intel.com
>
>>
>> Cc: Shankar Uma 
>> Cc: Jani Nikula 
>> Cc: Ville Syrjälä 
>> Signed-off-by: Lee Shawn C 
>> ---
>>  drivers/gpu/drm/i915/display/intel_pps.c | 9 -
>>  1 file changed, 8 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_pps.c 
>> b/drivers/gpu/drm/i915/display/intel_pps.c
>> index 21944f5bf3a8..290473ec70d5 100644
>> --- a/drivers/gpu/drm/i915/display/intel_pps.c
>> +++ b/drivers/gpu/drm/i915/display/intel_pps.c
>> @@ -509,6 +509,13 @@ static void wait_panel_power_cycle(struct intel_dp 
>> *intel_dp)
>>  ktime_t panel_power_on_time;
>>  s64 panel_power_off_duration;
>>  
>> +/* When last_power_on equal to last_backlight_off, it means driver did 
>> not
>> + * turn on or off eDP panel so far. So we can bypass power cycle delay 
>> to
>> + * save some times here.
>> + */
>> +if (intel_dp->pps.last_power_on == intel_dp->pps.last_backlight_off)
>> +return;
>> +
>>  drm_dbg_kms(>drm, "Wait for panel power cycle\n");
>>  
>>  /* take the difference of current time and panel power off time @@ 
>> -1100,7 +1107,7 @@ static void pps_init_timestamps(struct intel_dp 
>> *intel_dp)  {
>>  intel_dp->pps.panel_power_off_time = ktime_get_boottime();
>>  intel_dp->pps.last_power_on = jiffies;
>> -intel_dp->pps.last_backlight_off = jiffies;
>> +intel_dp->pps.last_backlight_off = intel_dp->pps.last_power_on;
>>  }
>>  
>>  static void
>
>--
>Jani Nikula, Intel Open Source Graphics Center


[Intel-gfx] [v2] drm/i915/pps: improve eDP power on flow

2022-10-24 Thread Lee Shawn C
A panel power off cycle delay always append before turn eDP on.
Driver should check last_power_on and last_backlight_off before
insert this delay. If these values are the same, it means eDP
was off until now and driver can bypass power off cycle delay
to save some times to speed up eDP power on sequence.

v2: fix commit messages

Cc: Shankar Uma 
Cc: Jani Nikula 
Cc: Ville Syrjälä 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/i915/display/intel_pps.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_pps.c 
b/drivers/gpu/drm/i915/display/intel_pps.c
index 21944f5bf3a8..290473ec70d5 100644
--- a/drivers/gpu/drm/i915/display/intel_pps.c
+++ b/drivers/gpu/drm/i915/display/intel_pps.c
@@ -509,6 +509,13 @@ static void wait_panel_power_cycle(struct intel_dp 
*intel_dp)
ktime_t panel_power_on_time;
s64 panel_power_off_duration;
 
+   /* When last_power_on equal to last_backlight_off, it means driver did 
not
+* turn on or off eDP panel so far. So we can bypass power cycle delay 
to
+* save some times here.
+*/
+   if (intel_dp->pps.last_power_on == intel_dp->pps.last_backlight_off)
+   return;
+
drm_dbg_kms(>drm, "Wait for panel power cycle\n");
 
/* take the difference of current time and panel power off time
@@ -1100,7 +1107,7 @@ static void pps_init_timestamps(struct intel_dp *intel_dp)
 {
intel_dp->pps.panel_power_off_time = ktime_get_boottime();
intel_dp->pps.last_power_on = jiffies;
-   intel_dp->pps.last_backlight_off = jiffies;
+   intel_dp->pps.last_backlight_off = intel_dp->pps.last_power_on;
 }
 
 static void
-- 
2.17.1



Re: [Intel-gfx] [PATCH] drm/i915/pps: improve eDP power on flow.

2022-10-24 Thread Lee, Shawn C


On Monday, October 24, 2022 9:17 PM, Ville Syrjälä 
 wrote:
>On Mon, Oct 24, 2022 at 02:40:04PM +0800, Lee Shawn C wrote:
>> Driver always apply panel power off cycle delay before eDP enable.
>> If eDP display was enabled at pre-os stage, driver would always 
>> trigger modeset to optimize cdclk setting after boot into kernel.
>> So last_power_on and last_backlight_off value will be updated.
>> 
>> We can check last_power_on and last_backlight_off before insert panel 
>> power cycle delay. If these values are the same, it means eDP was off 
>> until now and driver should bypass this delay to save some times to 
>> speed up eDP power on sequence.
>> 
>> Cc: Shankar Uma 
>> Cc: Jani Nikula 
>> Cc: Ville Syrjälä 
>> Signed-off-by: Lee Shawn C 
>> ---
>>  drivers/gpu/drm/i915/display/intel_pps.c | 13 +++--
>>  1 file changed, 11 insertions(+), 2 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/i915/display/intel_pps.c 
>> b/drivers/gpu/drm/i915/display/intel_pps.c
>> index 21944f5bf3a8..f3485a4fbfd0 100644
>> --- a/drivers/gpu/drm/i915/display/intel_pps.c
>> +++ b/drivers/gpu/drm/i915/display/intel_pps.c
>> @@ -509,6 +509,13 @@ static void wait_panel_power_cycle(struct intel_dp 
>> *intel_dp)
>>  ktime_t panel_power_on_time;
>>  s64 panel_power_off_duration;
>>  
>> +/* When last_power_on equal to last_backlight_off, it means driver did 
>> not
>> + * turn on or off eDP panel so far.
>
>But someone else may have turned it off just before we were handed control, we 
>have no idea. The pessimistic estimate is the safe one.

Thanks! It looks to me this situation should not be happpened. Right?

>
>Also I don't understand what this has to do with the story in the comit 
>message. In that story you say eDP was already on, so the power cycle delay is 
>not relevant at all. /me confused.
>

I will modify commit messages and send patch v2 later.

Best regards,
Shawn

>> So we can bypass power cycle delay to
>> + * save some times here.
>> + */
>> +if (intel_dp->pps.last_power_on == intel_dp->pps.last_backlight_off)
>> +return;
>> +
>>  drm_dbg_kms(>drm, "Wait for panel power cycle\n");
>>  
>>  /* take the difference of current time and panel power off time @@ 
>> -1098,9 +1105,11 @@ bool intel_pps_have_panel_power_or_vdd(struct 
>> intel_dp *intel_dp)
>>  
>>  static void pps_init_timestamps(struct intel_dp *intel_dp)  {
>> +unsigned long tmp_jiffies = jiffies;
>> +
>>  intel_dp->pps.panel_power_off_time = ktime_get_boottime();
>> -intel_dp->pps.last_power_on = jiffies;
>> -intel_dp->pps.last_backlight_off = jiffies;
>> +intel_dp->pps.last_power_on = tmp_jiffies;
>> +intel_dp->pps.last_backlight_off = tmp_jiffies;
>>  }
>>  
>>  static void
>> --
>> 2.17.1
>
>--
>Ville Syrjälä
>Intel
>


[Intel-gfx] [PATCH] drm/i915/pps: improve eDP power on flow.

2022-10-24 Thread Lee Shawn C
Driver always apply panel power off cycle delay before eDP enable.
If eDP display was enabled at pre-os stage, driver would always
trigger modeset to optimize cdclk setting after boot into kernel.
So last_power_on and last_backlight_off value will be updated.

We can check last_power_on and last_backlight_off before insert
panel power cycle delay. If these values are the same, it means eDP
was off until now and driver should bypass this delay to save
some times to speed up eDP power on sequence.

Cc: Shankar Uma 
Cc: Jani Nikula 
Cc: Ville Syrjälä 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/i915/display/intel_pps.c | 13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_pps.c 
b/drivers/gpu/drm/i915/display/intel_pps.c
index 21944f5bf3a8..f3485a4fbfd0 100644
--- a/drivers/gpu/drm/i915/display/intel_pps.c
+++ b/drivers/gpu/drm/i915/display/intel_pps.c
@@ -509,6 +509,13 @@ static void wait_panel_power_cycle(struct intel_dp 
*intel_dp)
ktime_t panel_power_on_time;
s64 panel_power_off_duration;
 
+   /* When last_power_on equal to last_backlight_off, it means driver did 
not
+* turn on or off eDP panel so far. So we can bypass power cycle delay 
to
+* save some times here.
+*/
+   if (intel_dp->pps.last_power_on == intel_dp->pps.last_backlight_off)
+   return;
+
drm_dbg_kms(>drm, "Wait for panel power cycle\n");
 
/* take the difference of current time and panel power off time
@@ -1098,9 +1105,11 @@ bool intel_pps_have_panel_power_or_vdd(struct intel_dp 
*intel_dp)
 
 static void pps_init_timestamps(struct intel_dp *intel_dp)
 {
+   unsigned long tmp_jiffies = jiffies;
+
intel_dp->pps.panel_power_off_time = ktime_get_boottime();
-   intel_dp->pps.last_power_on = jiffies;
-   intel_dp->pps.last_backlight_off = jiffies;
+   intel_dp->pps.last_power_on = tmp_jiffies;
+   intel_dp->pps.last_backlight_off = tmp_jiffies;
 }
 
 static void
-- 
2.17.1



[Intel-gfx] [PATCH] drm: Add 64:27 and 256:135 picture aspect ratio support

2022-10-01 Thread Lee Shawn C
Drm driver did not report connector can support 64:27 and 256:135 picture
aspect ratio. Even if drm_edid driver already have those modes in
CEA table. Add both of them then user space application would program
proper picture apsect ratio when HDMI 2.1 monitor connected.

Cc: Shankar Uma 
Cc: Ville Syrjälä 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/drm_connector.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index e3142c8142b3..45078d11c7d3 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -948,6 +948,8 @@ static const struct drm_prop_enum_list 
drm_aspect_ratio_enum_list[] = {
{ DRM_MODE_PICTURE_ASPECT_NONE, "Automatic" },
{ DRM_MODE_PICTURE_ASPECT_4_3, "4:3" },
{ DRM_MODE_PICTURE_ASPECT_16_9, "16:9" },
+   { DRM_MODE_PICTURE_ASPECT_64_27, "64:27" },
+   { DRM_MODE_PICTURE_ASPECT_256_135, "256:135" },
 };
 
 static const struct drm_prop_enum_list drm_content_type_enum_list[] = {
-- 
2.31.1



Re: [Intel-gfx] [PATCH] drm/i915/display: clear plane color control register when turn plane off

2022-08-31 Thread Lee, Shawn C
On Wed, August 31, 2022 8:33 PM, Ville Syrjälä wrote:
>On Mon, Aug 01, 2022 at 11:16:16PM +0800, Lee Shawn C wrote:
>> Customer report abnormal display output while switch eDP off sometimes.
>> In current display disable flow, plane will be off at first. Then turn 
>> eDP off and disable HW pipe line. We found the abnormal pixel comes 
>> after turn plane off. Clear plane color ctl register when driver 
>> disable plane can solve this symptom.
>> 
>> Signed-off-by: Lee Shawn C 
>> Reviewed-by: Uma Shankar 
>> ---
>>  drivers/gpu/drm/i915/display/skl_universal_plane.c | 3 +++
>>  1 file changed, 3 insertions(+)
>> 
>> diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c 
>> b/drivers/gpu/drm/i915/display/skl_universal_plane.c
>> index caa03324a733..90977cfb7ebb 100644
>> --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
>> +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
>> @@ -620,6 +620,8 @@ skl_plane_disable_arm(struct intel_plane *plane,
>>  
>>  intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), 0);
>>  intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), 0);
>> +if (DISPLAY_VER(dev_priv) >= 10)
>> +intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id), 0);
>>  }
>>  
>>  static void
>> @@ -638,6 +640,7 @@ icl_plane_disable_arm(struct intel_plane *plane,
>>  intel_psr2_disable_plane_sel_fetch(plane, crtc_state);
>>  intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), 0);
>>  intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), 0);
>> +intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id), 0);
>
>This makes no sense. The register value shouldn't even get latched since you 
>wrote the arming register (PLANE_SURF) before this one.
>
>What platform is the problematic machine?
>

ADL-P

Best regards,
Shawn

>>  }
>>  
>>  static bool
>> --
>> 2.17.1
>
>--
>Ville Syrjälä
>Intel


Re: [Intel-gfx] [PATCH] drm/i915/display: refine eDP power off sequence

2022-08-31 Thread Lee, Shawn C
On Wed, Aug 31, 2022 at 06:49, Ville Syrjälä wrote:
>On Wed, Aug 31, 2022 at 06:37:24PM +0800, Lee Shawn C wrote:
>> The current eDP disable sequence like this.
>> 
>> disable plane > disable backlight (include T9, the delay from 
>> backlight disable to end of valid video data) > disalbe 
>> transcoder/pipe > disable eDP power
>> 
>> Found abnormal pixel output after plane off sometimes.
>> It did not cause any issue but impact user experience.
>> So we modify the eDP disable flow to turn backlight off earlier to 
>> avoid abnormal display.
>
>NAK. Planes can be disable at any time by userspace.
>We need to find out what is causing the glitch.
>

Hi Ville, thanks for comment! I uploaded a patch earlier to fix the problem.
https://patchwork.freedesktop.org/patch/496067/

It pass the review by Uma. Unfortunately, the change is not able to pass CI.
With that change, FIFO underrun always be found during CI testing.

Best regards,
Shawn

>> 
>> disable backlight > disable plane > disalbe transcoder/pipe
>> > disable eDP power
>> 
>> Cc: Shankar Uma 
>> Cc: Jani Nikula 
>> Signed-off-by: Lee Shawn C 
>> ---
>>  drivers/gpu/drm/i915/display/intel_display.c | 8 +---
>>  1 file changed, 5 insertions(+), 3 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
>> b/drivers/gpu/drm/i915/display/intel_display.c
>> index 72e2091d9fcb..d08927036350 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display.c
>> +++ b/drivers/gpu/drm/i915/display/intel_display.c
>> @@ -2045,10 +2045,8 @@ static void hsw_crtc_disable(struct 
>> intel_atomic_state *state,
>>   * FIXME collapse everything to one hook.
>>   * Need care with mst->ddi interactions.
>>   */
>> -if (!intel_crtc_is_bigjoiner_slave(old_crtc_state)) {
>> -intel_encoders_disable(state, crtc);
>> +if (!intel_crtc_is_bigjoiner_slave(old_crtc_state))
>>  intel_encoders_post_disable(state, crtc);
>> -}
>>  }
>>  
>>  static void i9xx_pfit_enable(const struct intel_crtc_state 
>> *crtc_state) @@ -7224,6 +7222,10 @@ static void 
>> intel_commit_modeset_disables(struct intel_atomic_state *state)
>>  continue;
>>  
>>  intel_pre_plane_update(state, crtc);
>> +
>> +if (!intel_crtc_is_bigjoiner_slave(old_crtc_state))
>> +intel_encoders_disable(state, crtc);
>> +
>>  intel_crtc_disable_planes(state, crtc);
>>  }
>>  
>> --
>> 2.31.1
>
>--
>Ville Syrjälä
>Intel


[Intel-gfx] [PATCH] drm/i915/display: refine eDP power off sequence

2022-08-31 Thread Lee Shawn C
The current eDP disable sequence like this.

disable plane > disable backlight (include T9, the delay
from backlight disable to end of valid video data) >
disalbe transcoder/pipe > disable eDP power

Found abnormal pixel output after plane off sometimes.
It did not cause any issue but impact user experience.
So we modify the eDP disable flow to turn backlight off
earlier to avoid abnormal display.

disable backlight > disable plane > disalbe transcoder/pipe
> disable eDP power

Cc: Shankar Uma 
Cc: Jani Nikula 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/i915/display/intel_display.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 72e2091d9fcb..d08927036350 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -2045,10 +2045,8 @@ static void hsw_crtc_disable(struct intel_atomic_state 
*state,
 * FIXME collapse everything to one hook.
 * Need care with mst->ddi interactions.
 */
-   if (!intel_crtc_is_bigjoiner_slave(old_crtc_state)) {
-   intel_encoders_disable(state, crtc);
+   if (!intel_crtc_is_bigjoiner_slave(old_crtc_state))
intel_encoders_post_disable(state, crtc);
-   }
 }
 
 static void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state)
@@ -7224,6 +7222,10 @@ static void intel_commit_modeset_disables(struct 
intel_atomic_state *state)
continue;
 
intel_pre_plane_update(state, crtc);
+
+   if (!intel_crtc_is_bigjoiner_slave(old_crtc_state))
+   intel_encoders_disable(state, crtc);
+
intel_crtc_disable_planes(state, crtc);
}
 
-- 
2.31.1



[Intel-gfx] [PATCH] drm/i915/display: avoid abnormal pixel output when turn eDP display off

2022-08-02 Thread Lee Shawn C
Customer report abnormal display output while switch eDP off sometimes.
In current display disable flow, plane will be off at first. Then turn
eDP off and disable HW pipe line. Try to turn PLANE_SURF off before
disable PLANE_CTL. No more abnormal pixel appear on eDP with this changes.

Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/i915/display/skl_universal_plane.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c 
b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index 4d6a27757065..7e7d265131b2 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -618,8 +618,8 @@ skl_plane_disable_arm(struct intel_plane *plane,
 
skl_write_plane_wm(plane, crtc_state);
 
-   intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), 0);
intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), 0);
+   intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), 0);
 }
 
 static void
@@ -636,8 +636,8 @@ icl_plane_disable_arm(struct intel_plane *plane,
skl_write_plane_wm(plane, crtc_state);
 
intel_psr2_disable_plane_sel_fetch(plane, crtc_state);
-   intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), 0);
intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), 0);
+   intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), 0);
 }
 
 static bool
-- 
2.17.1



[Intel-gfx] [PATCH] drm/i915/display: clear plane color control register when turn plane off

2022-08-01 Thread Lee Shawn C
Customer report abnormal display output while switch eDP off sometimes.
In current display disable flow, plane will be off at first. Then turn
eDP off and disable HW pipe line. We found the abnormal pixel comes
after turn plane off. Clear plane color ctl register when driver disable
plane can solve this symptom.

Signed-off-by: Lee Shawn C 
Reviewed-by: Uma Shankar 
---
 drivers/gpu/drm/i915/display/skl_universal_plane.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c 
b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index caa03324a733..90977cfb7ebb 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -620,6 +620,8 @@ skl_plane_disable_arm(struct intel_plane *plane,
 
intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), 0);
intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), 0);
+   if (DISPLAY_VER(dev_priv) >= 10)
+   intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id), 0);
 }
 
 static void
@@ -638,6 +640,7 @@ icl_plane_disable_arm(struct intel_plane *plane,
intel_psr2_disable_plane_sel_fetch(plane, crtc_state);
intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), 0);
intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), 0);
+   intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id), 0);
 }
 
 static bool
-- 
2.17.1



Re: [Intel-gfx] ✗ Fi.CI.BAT: failure for drm/i915: clear plane color ctl setting when turn full plane off (rev3)

2022-07-28 Thread Lee, Shawn C

Hi Lakshmi,

Below issues are not related to the patch. Re-run these test cases with this 
patch and get pass result on my local machine.
Best regards,
Shawn

From: Patchwork 
Sent: Wednesday, July 27, 2022 4:54 PM
To: Lee, Shawn C 
Cc: intel-gfx@lists.freedesktop.org
Subject: ✗ Fi.CI.BAT: failure for drm/i915: clear plane color ctl setting when 
turn full plane off (rev3)

Patch Details
Series:
drm/i915: clear plane color ctl setting when turn full plane off (rev3)
URL:
https://patchwork.freedesktop.org/series/106292/
State:
failure
Details:
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_106292v3/index.html
CI Bug Log - changes from CI_DRM_11946 -> Patchwork_106292v3
Summary

FAILURE

Serious unknown changes coming with Patchwork_106292v3 absolutely need to be
verified manually.

If you think the reported changes have nothing to do with the changes
introduced in Patchwork_106292v3, please notify your bug team to allow them
to document this new failure mode, which will reduce false positives in CI.

External URL: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_106292v3/index.html

Participating hosts (38 -> 37)

Additional (2): fi-hsw-4770 bat-jsl-1
Missing (3): fi-rkl-11600 fi-bdw-samus bat-dg1-5

Possible new issues

Here are the unknown changes that may have been introduced in 
Patchwork_106292v3:

IGT changes
Possible regressions

  *   igt@kms_cursor_legacy@basic-flip-after-cursor@atomic-transitions:
 *   fi-adl-ddr5: 
PASS<https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11946/fi-adl-ddr5/igt@kms_cursor_legacy@basic-flip-after-cur...@atomic-transitions.html>
 -> 
DMESG-WARN<https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_106292v3/fi-adl-ddr5/igt@kms_cursor_legacy@basic-flip-after-cur...@atomic-transitions.html>
 +4 similar issues
  *   
igt@kms_cursor_legacy@basic-flip-before-cursor@atomic-transitions-varying-size:
 *   fi-rkl-guc: 
PASS<https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11946/fi-rkl-guc/igt@kms_cursor_legacy@basic-flip-before-cur...@atomic-transitions-varying-size.html>
 -> 
DMESG-WARN<https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_106292v3/fi-rkl-guc/igt@kms_cursor_legacy@basic-flip-before-cur...@atomic-transitions-varying-size.html>
 +3 similar issues

Suppressed

The following results come from untrusted machines, tests, or statuses.
They do not affect the overall result.

  *   igt@kms_cursor_legacy@basic-flip-before-cursor@atomic-transitions:
 *   {bat-rplp-1}: 
PASS<https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11946/bat-rplp-1/igt@kms_cursor_legacy@basic-flip-before-cur...@atomic-transitions.html>
 -> 
DMESG-WARN<https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_106292v3/bat-rplp-1/igt@kms_cursor_legacy@basic-flip-before-cur...@atomic-transitions.html>
 +3 similar issues
  *   
igt@kms_cursor_legacy@basic-flip-before-cursor@atomic-transitions-varying-size:
 *   {bat-rpls-2}: NOTRUN -> 
DMESG-WARN<https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_106292v3/bat-rpls-2/igt@kms_cursor_legacy@basic-flip-before-cur...@atomic-transitions-varying-size.html>
 +15 similar issues
 *   {fi-jsl-1}: 
PASS<https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11946/fi-jsl-1/igt@kms_cursor_legacy@basic-flip-before-cur...@atomic-transitions-varying-size.html>
 -> 
DMESG-WARN<https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_106292v3/fi-jsl-1/igt@kms_cursor_legacy@basic-flip-before-cur...@atomic-transitions-varying-size.html>
 +4 similar issues
 *   {bat-rpls-1}: 
PASS<https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11946/bat-rpls-1/igt@kms_cursor_legacy@basic-flip-before-cur...@atomic-transitions-varying-size.html>
 -> 
DMESG-WARN<https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_106292v3/bat-rpls-1/igt@kms_cursor_legacy@basic-flip-before-cur...@atomic-transitions-varying-size.html>
 +5 similar issues
 *   {fi-ehl-2}: 
PASS<https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11946/fi-ehl-2/igt@kms_cursor_legacy@basic-flip-before-cur...@atomic-transitions-varying-size.html>
 -> 
DMESG-WARN<https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_106292v3/fi-ehl-2/igt@kms_cursor_legacy@basic-flip-before-cur...@atomic-transitions-varying-size.html>
 +4 similar issues
  *   igt@kms_flip@basic-flip-vs-dpms@b-edp1:
 *   {bat-jsl-3}: 
PASS<https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11946/bat-jsl-3/igt@kms_flip@basic-flip-vs-d...@b-edp1.html>
 -> 
DMESG-WARN<https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_106292v3/bat-jsl-3/igt@kms_flip@basic-flip-vs-d...@b-edp1.html>
 +36 similar issues
  *   igt@kms_force_connector_basic@force-connector-state:
 *   {bat-jsl-1}: NOTRUN -> 
DMESG-WARN<https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_106292v3/bat-jsl-1/igt@kms_force_connector_ba...@force-connector-state.html>
 +36 similar issues
  *   igt@kms_frontbuffer_tracking@basic:
 *   {bat-dg2-9}: 
PASS<https://intel-gfx-ci.01.o

[Intel-gfx] [v2] drm/i915/display: clear plane color ctl setting when turn full plane off

2022-07-22 Thread Lee Shawn C
Customer report abnormal display output while switch eDP off sometimes.
In current display disable flow, plane will be off at first. Then turn
eDP off and disable HW pipe line. We found the abnormal pixel comes
after turn plane off. Clear plane color ctl register when driver disable
plane can solve this symptom.

Cc: Jani Nikula 
Cc: Ville Syrjälä 
Cc: Shankar Uma 
Cc: Stanislav Lisovskiy 
Cc: William Tseng 
Signed-off-by: Lee Shawn C 
Reviewed-by: Uma Shankar 
---
 drivers/gpu/drm/i915/display/skl_universal_plane.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c 
b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index caa03324a733..90977cfb7ebb 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -620,6 +620,8 @@ skl_plane_disable_arm(struct intel_plane *plane,
 
intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), 0);
intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), 0);
+   if (DISPLAY_VER(dev_priv) >= 10)
+   intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id), 0);
 }
 
 static void
@@ -638,6 +640,7 @@ icl_plane_disable_arm(struct intel_plane *plane,
intel_psr2_disable_plane_sel_fetch(plane, crtc_state);
intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), 0);
intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), 0);
+   intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id), 0);
 }
 
 static bool
-- 
2.17.1



Re: [Intel-gfx] [PATCH] drm/i915: clear plane color ctl setting when turn full plane off

2022-07-22 Thread Lee, Shawn C
On Fri, July 22, 2022, 4:26 a.m, Uma Shankar  wrote:
>> -Original Message-
>> From: Lee, Shawn C 
>> Sent: Wednesday, July 13, 2022 2:57 PM
>> To: intel-gfx@lists.freedesktop.org
>> Cc: Lee, Shawn C ; Jani Nikula 
>> ; Ville Syrjälä 
>> ; Shankar, Uma ; 
>> Lisovskiy, Stanislav ; Tseng, William 
>> 
>> Subject: [PATCH] drm/i915: clear plane color ctl setting when turn 
>> full plane off
>
>We can append "display" to drm/i915

Thanks for comment! I will modify the title and update patch later.

>
>> Customer report abnormal display output while switch eDP off sometimes.
>> In current display disable flow, plane will be off at first. Then turn 
>> eDP off and disable HW pipe line. We found the abnormal pixel comes 
>> after turn plane off. Clear plane color ctl register when driver disable 
>> plane can solve this symptom.
>
>Change Looks Good to me.
>Reviewed-by: Uma Shankar 
>
>> Cc: Jani Nikula 
>> Cc: Ville Syrjälä 
>> Cc: Shankar Uma 
>> Cc: Stanislav Lisovskiy 
>> Cc: William Tseng 
>> Signed-off-by: Lee Shawn C 
>> ---
>>  drivers/gpu/drm/i915/display/skl_universal_plane.c | 3 +++
>>  1 file changed, 3 insertions(+)
>> 
>> diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c
>> b/drivers/gpu/drm/i915/display/skl_universal_plane.c
>> index caa03324a733..90977cfb7ebb 100644
>> --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
>> +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
>> @@ -620,6 +620,8 @@ skl_plane_disable_arm(struct intel_plane *plane,
>> 
>>  intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), 0);
>>  intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), 0);
>> +if (DISPLAY_VER(dev_priv) >= 10)
>> +intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id), 0);
>>  }
>> 
>>  static void
>> @@ -638,6 +640,7 @@ icl_plane_disable_arm(struct intel_plane *plane,
>>  intel_psr2_disable_plane_sel_fetch(plane, crtc_state);
>>  intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), 0);
>>  intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), 0);
>> +intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id), 0);
>>  }
>> 
>>  static bool
>> --
>> 2.17.1



[Intel-gfx] [v4, 1/2] drm/i915/edid: convert DP, HDMI and LVDS to drm_edid

2022-07-19 Thread Lee, Shawn C
On Fri, Jul 01, 2022 at 12:57:38PM +0300, Ville Syrjälä wrote:
>On Fri, Jul 01, 2022 at 11:55:38AM +0300, Jani Nikula wrote:
>> Convert all the connectors that use cached connector edid and
>> detect_edid to drm_edid.
>> 
>> Since drm_get_edid() calls drm_connector_update_edid_property() while
>> drm_edid_read*() do not, we need to call drm_edid_connector_update()
>> separately, in part due to the EDID caching behaviour in HDMI and
>> DP. Especially DP depends on the details parsed from EDID. (The big
>> behavioural change conflating EDID reading with parsing and property
>> update was done in commit 5186421cbfe2 ("drm: Introduce epoch counter to
>> drm_connector"))
>> 
>> v4: Call drm_edid_connector_update() after reading HDMI/DP EDID
>> 
>> v3: Don't leak vga switcheroo EDID in LVDS init (Ville)
>> 
>> v2: Don't leak opregion fallback EDID (Ville)
>> 
>> Signed-off-by: Jani Nikula 
>> ---
>>  .../gpu/drm/i915/display/intel_connector.c|  4 +-
>>  .../drm/i915/display/intel_display_types.h|  4 +-
>>  drivers/gpu/drm/i915/display/intel_dp.c   | 80 +++
>>  drivers/gpu/drm/i915/display/intel_hdmi.c | 28 ---
>>  drivers/gpu/drm/i915/display/intel_lvds.c | 37 +
>>  5 files changed, 87 insertions(+), 66 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/i915/display/intel_connector.c 
>> b/drivers/gpu/drm/i915/display/intel_connector.c
>> index 1dcc268927a2..d83b2a64f618 100644
>> --- a/drivers/gpu/drm/i915/display/intel_connector.c
>> +++ b/drivers/gpu/drm/i915/display/intel_connector.c
>> @@ -95,12 +95,12 @@ void intel_connector_destroy(struct drm_connector 
>> *connector)
>>  {
>>  struct intel_connector *intel_connector = to_intel_connector(connector);
>>  
>> -kfree(intel_connector->detect_edid);
>> +drm_edid_free(intel_connector->detect_edid);
>>  
>>  intel_hdcp_cleanup(intel_connector);
>>  
>>  if (!IS_ERR_OR_NULL(intel_connector->edid))
>> -kfree(intel_connector->edid);
>> +drm_edid_free(intel_connector->edid);
>>  
>>  intel_panel_fini(intel_connector);
>>  
>> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
>> b/drivers/gpu/drm/i915/display/intel_display_types.h
>> index 0da9b208d56e..d476df0ac9df 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
>> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
>> @@ -592,8 +592,8 @@ struct intel_connector {
>>  struct intel_panel panel;
>>  
>>  /* Cached EDID for eDP and LVDS. May hold ERR_PTR for invalid EDID. */
>> -struct edid *edid;
>> -struct edid *detect_edid;
>> +const struct drm_edid *edid;
>> +const struct drm_edid *detect_edid;
>>  
>>  /* Number of times hotplug detection was tried after an HPD interrupt */
>>  int hotplug_retries;
>> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
>> b/drivers/gpu/drm/i915/display/intel_dp.c
>> index 32292c0be2bd..8a3b2dbebe04 100644
>> --- a/drivers/gpu/drm/i915/display/intel_dp.c
>> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
>> @@ -3577,12 +3577,11 @@ static u8 intel_dp_autotest_edid(struct intel_dp 
>> *intel_dp)
>>  intel_dp->aux.i2c_defer_count);
>>  intel_dp->compliance.test_data.edid = 
>> INTEL_DP_RESOLUTION_FAILSAFE;
>>  } else {
>> -struct edid *block = intel_connector->detect_edid;
>> +/* FIXME: Get rid of drm_edid_raw() */
>> +const struct edid *block = 
>> drm_edid_raw(intel_connector->detect_edid);
>>  
>> -/* We have to write the checksum
>> - * of the last block read
>> - */
>> -block += intel_connector->detect_edid->extensions;
>> +/* We have to write the checksum of the last block read */
>> +block += block->extensions;
>>  
>>  if (drm_dp_dpcd_writeb(_dp->aux, DP_TEST_EDID_CHECKSUM,
>> block->checksum) <= 0)
>> @@ -4461,7 +4460,7 @@ bool intel_digital_port_connected(struct intel_encoder 
>> *encoder)
>>  return is_connected;
>>  }
>>  
>> -static struct edid *
>> +static const struct drm_edid *
>>  intel_dp_get_edid(struct intel_dp *intel_dp)
>>  {
>>  struct intel_connector *intel_connector = intel_dp->attached_connector;
>> @@ -4472,18 +4471,22 @@ intel_dp_get_edid(struct intel_dp *intel_dp)
>>  if (IS_ERR(intel_connector->edid))
>>  return NULL;
>>  
>> -return drm_edid_duplicate(intel_connector->edid);
>> +return drm_edid_dup(intel_connector->edid);
>>  } else
>> -return drm_get_edid(_connector->base,
>> -_dp->aux.ddc);
>> +return drm_edid_read_ddc(_connector->base,
>> + _dp->aux.ddc);
>>  }
>>  
>>  static void
>>  intel_dp_update_dfp(struct intel_dp *intel_dp,
>> -const struct edid *edid)
>> +const struct drm_edid *drm_edid)
>>  

[Intel-gfx] [PATCH] drm/i915: clear plane color ctl setting when turn full plane off

2022-07-13 Thread Lee Shawn C
Customer report abnormal display output while switch eDP off sometimes.
In current display disable flow, plane will be off at first. Then turn
eDP off and disable HW pipe line. We found the abnormal pixel comes
after turn plane off. Clear plane color ctl register when driver disable
plane can solve this symptom.

Cc: Jani Nikula 
Cc: Ville Syrjälä 
Cc: Shankar Uma 
Cc: Stanislav Lisovskiy 
Cc: William Tseng 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/i915/display/skl_universal_plane.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c 
b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index caa03324a733..90977cfb7ebb 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -620,6 +620,8 @@ skl_plane_disable_arm(struct intel_plane *plane,
 
intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), 0);
intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), 0);
+   if (DISPLAY_VER(dev_priv) >= 10)
+   intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id), 0);
 }
 
 static void
@@ -638,6 +640,7 @@ icl_plane_disable_arm(struct intel_plane *plane,
intel_psr2_disable_plane_sel_fetch(plane, crtc_state);
intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), 0);
intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), 0);
+   intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id), 0);
 }
 
 static bool
-- 
2.17.1



[Intel-gfx] [v3] drm/edid: check basic audio support on CEA extension block

2022-03-24 Thread Lee Shawn C
From: Cooper Chiou 

Tag code stored in bit7:5 for CTA block byte[3] is not the same as
CEA extension block definition. Only check CEA block has
basic audio support.

v3: update commit message.

Cc: sta...@vger.kernel.org
Cc: Jani Nikula 
Cc: Shawn C Lee 
Cc: intel-gfx 
Signed-off-by: Cooper Chiou 
Signed-off-by: Lee Shawn C 
Fixes: e28ad544f462 ("drm/edid: parse CEA blocks embedded in DisplayID")
Reviewed-by: Jani Nikula 
---
 drivers/gpu/drm/drm_edid.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 561f53831e29..f07af6786cec 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4859,7 +4859,8 @@ bool drm_detect_monitor_audio(struct edid *edid)
if (!edid_ext)
goto end;
 
-   has_audio = ((edid_ext[3] & EDID_BASIC_AUDIO) != 0);
+   has_audio = (edid_ext[0] == CEA_EXT &&
+   (edid_ext[3] & EDID_BASIC_AUDIO) != 0);
 
if (has_audio) {
DRM_DEBUG_KMS("Monitor has basic audio support\n");
-- 
2.17.1



[Intel-gfx] [v3] drm/edid: check basic audio support on CEA extension block

2022-03-23 Thread Lee Shawn C
From: Cooper Chiou 

Tag code stored in bit7:5 for CTA block byte[3] is not the same as
CEA extension block definition. Only check CEA block has
basic audio support.

v3: update commit message.

Cc: sta...@vger.kernel.org
Cc: Jani Nikula 
Cc: Shawn C Lee 
Cc: intel-gfx 
Signed-off-by: Cooper Chiou 
Signed-off-by: Lee Shawn C 
Fixes: e28ad544f462 ("drm/edid: parse CEA blocks embedded in DisplayID")
Reviewed-by: Jani Nikula 
---
 drivers/gpu/drm/drm_edid.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 561f53831e29..f07af6786cec 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4859,7 +4859,8 @@ bool drm_detect_monitor_audio(struct edid *edid)
if (!edid_ext)
goto end;
 
-   has_audio = ((edid_ext[3] & EDID_BASIC_AUDIO) != 0);
+   has_audio = (edid_ext[0] == CEA_EXT &&
+   (edid_ext[3] & EDID_BASIC_AUDIO) != 0);
 
if (has_audio) {
DRM_DEBUG_KMS("Monitor has basic audio support\n");
-- 
2.17.1



Re: [Intel-gfx] [PATCH] drm/edid: filter DisplayID v2.0 CTA block in audio detection

2022-03-23 Thread Lee, Shawn C
On Wednesday, March 23, 2022 6:40 PM, Jani  wrote :
>On Wed, 23 Mar 2022, "Lee, Shawn C"  wrote:
>> On Wednesday, March 23, 2022 6:04 PM, Nikula, Jani  
>> wrote :
>>>On Mon, 21 Mar 2022, Cooper Chiou  wrote:
>>>> In DisplayID v2.0 CTS data block 0x81 case, there is no any audio 
>>>> information definition, but drm_detect_monitor_audio didn't filter 
>>>> it so that it caused eDP dummy audio card be detected improperly.
>>>>
>>>> We observed this issue on some AUO/BOE eDP panel with DID v2.0 CTA 
>>>> block, and fix issue by adding filter for edid_ext[0]=DATA_BLOCK_CTA 
>>>> case.
>>>
>>>Out of curiosity, what does the CTA DisplayID Data Block have for Data Block 
>>>revision?
>>>
>>>I haven't found any mention anywhere that it should have any correspondence 
>>>to the CEA *extension* revision number, which is supposed to be 1..3, and 
>>>really only 3 for about a decade now.
>>>
>>>Both the DisplayID v1.3 and v2.0 specs only mention revision 0.
>>>
>>>BR,
>>>Jani.
>>>
>>
>> We don't get many issues in EDID with DisplayID structure. In this case, the 
>> revision number is "0" as well.
>> As you mentioned, DisplayID v1.3 and v2.0 spec define the block revision 
>> value is always 0. Do you think it would cause any problem?
>
>A lot of places in the EDID parser expect CEA revision >= 3. This isn't true 
>for DisplayID data blocks, so we end up skipping a bunch of stuff if there's 
>no CEA extension and only a DisplayID block.
>
>I'm fixing this in my series.
>

Thanks for the information! Just like you said, block revision ID is always 
zero in DisplayID block.
Do you think we have to make sure revision ID is "0" instead of the other value?

Best regards,
Shawn

>
>BR,
>Jani.
>
>>
>> Best regards,
>> Shawn
>>
>>>>
>>>> Cc: Jani Nikula 
>>>> Cc: Shawn C Lee 
>>>>
>>>> Signed-off-by: Cooper Chiou 
>>>> ---
>>>>  drivers/gpu/drm/drm_edid.c | 2 +-
>>>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c 
>>>> index f5f5de362ff2..6c9ae4b130bd 100644
>>>> --- a/drivers/gpu/drm/drm_edid.c
>>>> +++ b/drivers/gpu/drm/drm_edid.c
>>>> @@ -4845,7 +4845,7 @@ bool drm_detect_monitor_audio(struct edid *edid)
>>>>  int start_offset, end_offset;
>>>>
>>>>  edid_ext = drm_find_cea_extension(edid);
>>>> -if (!edid_ext)
>>>> +if (!edid_ext || (edid_ext[0] == DATA_BLOCK_CTA))
>>>>  goto end;
>>>>
>>>>  has_audio = ((edid_ext[3] & EDID_BASIC_AUDIO) != 0);
>>>
>>>--
>>>Jani Nikula, Intel Open Source Graphics Center
>>>
>
>--
>Jani Nikula, Intel Open Source Graphics Center


Re: [Intel-gfx] [PATCH] drm/edid: filter DisplayID v2.0 CTA block in audio detection

2022-03-23 Thread Lee, Shawn C
On Wednesday, March 23, 2022 6:04 PM, Nikula, Jani  
wrote :
>On Mon, 21 Mar 2022, Cooper Chiou  wrote:
>> In DisplayID v2.0 CTS data block 0x81 case, there is no any audio 
>> information definition, but drm_detect_monitor_audio didn't filter it 
>> so that it caused eDP dummy audio card be detected improperly.
>>
>> We observed this issue on some AUO/BOE eDP panel with DID v2.0 CTA 
>> block, and fix issue by adding filter for edid_ext[0]=DATA_BLOCK_CTA 
>> case.
>
>Out of curiosity, what does the CTA DisplayID Data Block have for Data Block 
>revision?
>
>I haven't found any mention anywhere that it should have any correspondence to 
>the CEA *extension* revision number, which is supposed to be 1..3, and really 
>only 3 for about a decade now.
>
>Both the DisplayID v1.3 and v2.0 specs only mention revision 0.
>
>BR,
>Jani.
>

We don't get many issues in EDID with DisplayID structure. In this case, the 
revision number is "0" as well.
As you mentioned, DisplayID v1.3 and v2.0 spec define the block revision value 
is always 0. Do you think it would cause any problem?

Best regards,
Shawn

>>
>> Cc: Jani Nikula 
>> Cc: Shawn C Lee 
>>
>> Signed-off-by: Cooper Chiou 
>> ---
>>  drivers/gpu/drm/drm_edid.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c 
>> index f5f5de362ff2..6c9ae4b130bd 100644
>> --- a/drivers/gpu/drm/drm_edid.c
>> +++ b/drivers/gpu/drm/drm_edid.c
>> @@ -4845,7 +4845,7 @@ bool drm_detect_monitor_audio(struct edid *edid)
>>  int start_offset, end_offset;
>>  
>>  edid_ext = drm_find_cea_extension(edid);
>> -if (!edid_ext)
>> +if (!edid_ext || (edid_ext[0] == DATA_BLOCK_CTA))
>>  goto end;
>>  
>>  has_audio = ((edid_ext[3] & EDID_BASIC_AUDIO) != 0);
>
>--
>Jani Nikula, Intel Open Source Graphics Center
>


[Intel-gfx] [v2] drm/edid: check basic audio support on CEA extension block

2022-03-22 Thread Lee Shawn C
From: Cooper Chiou 

Tag code stored in bit7:5 for CTA block byte[3] is not the same as
CEA extension block definition. Only check CEA block has
basic audio support.

Cc: Jani Nikula 
Cc: Shawn C Lee 
Cc: intel-gfx 
Signed-off-by: Cooper Chiou 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/drm_edid.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 561f53831e29..f07af6786cec 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4859,7 +4859,8 @@ bool drm_detect_monitor_audio(struct edid *edid)
if (!edid_ext)
goto end;
 
-   has_audio = ((edid_ext[3] & EDID_BASIC_AUDIO) != 0);
+   has_audio = (edid_ext[0] == CEA_EXT &&
+   (edid_ext[3] & EDID_BASIC_AUDIO) != 0);
 
if (has_audio) {
DRM_DEBUG_KMS("Monitor has basic audio support\n");
-- 
2.17.1



[Intel-gfx] [v8 5/5] drm/edid: check for HF-SCDB block

2022-03-17 Thread Lee Shawn C
Find HF-SCDB information in CEA extensions block. And retrieve
Max_TMDS_Character_Rate that support by sink device.

v2: HF-SCDB and HF-VSDBS carry the same SCDS data. Reuse
drm_parse_hdmi_forum_vsdb() to parse this packet.

Cc: Jani Nikula 
Cc: Ville Syrjala 
Cc: Ankit Nautiyal 
Cc: intel-gfx 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/drm_edid.c | 18 +-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 40c192587f0a..64d13ba0f701 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3350,6 +3350,7 @@ add_detailed_modes(struct drm_connector *connector, 
struct edid *edid,
 #define EXT_VIDEO_DATA_BLOCK_420   0x0E
 #define EXT_VIDEO_CAP_BLOCK_Y420CMDB   0x0F
 #define EXT_VIDEO_HF_EEODB_DATA_BLOCK  0x78
+#define EXT_VIDEO_HF_SCDB_DATA_BLOCK   0x79
 #define EDID_BASIC_AUDIO   (1 << 6)
 #define EDID_CEA_YCRCB444  (1 << 5)
 #define EDID_CEA_YCRCB422  (1 << 4)
@@ -4277,6 +4278,20 @@ static bool cea_db_is_vcdb(const u8 *db)
return true;
 }
 
+static bool cea_db_is_hdmi_forum_scdb(const u8 *db)
+{
+   if (cea_db_tag(db) != USE_EXTENDED_TAG)
+   return false;
+
+   if (cea_db_payload_len(db) < 7)
+   return false;
+
+   if (cea_db_extended_tag(db) != EXT_VIDEO_HF_SCDB_DATA_BLOCK)
+   return false;
+
+   return true;
+}
+
 static bool cea_db_is_y420cmdb(const u8 *db)
 {
if (cea_db_tag(db) != USE_EXTENDED_TAG)
@@ -5274,7 +5289,8 @@ static void drm_parse_cea_ext(struct drm_connector 
*connector,
 
if (cea_db_is_hdmi_vsdb(db))
drm_parse_hdmi_vsdb_video(connector, db);
-   if (cea_db_is_hdmi_forum_vsdb(db))
+   if (cea_db_is_hdmi_forum_vsdb(db) ||
+   cea_db_is_hdmi_forum_scdb(db))
drm_parse_hdmi_forum_vsdb(connector, db);
if (cea_db_is_microsoft_vsdb(db))
drm_parse_microsoft_vsdb(connector, db);
-- 
2.17.1



[Intel-gfx] [v8 4/5] drm/edid: parse HF-EEODB CEA extension block

2022-03-17 Thread Lee Shawn C
While adding CEA modes, try to get available EEODB block
number. Then based on it to parse numbers of ext blocks,
retrieve CEA information and add more CEA modes.

Cc: Jani Nikula 
Cc: Ville Syrjala 
Cc: Ankit Nautiyal 
Cc: intel-gfx 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/drm_displayid.c |  5 -
 drivers/gpu/drm/drm_edid.c  | 35 +++--
 include/drm/drm_edid.h  |  2 +-
 3 files changed, 25 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/drm_displayid.c b/drivers/gpu/drm/drm_displayid.c
index 32da557b960f..dc649a9efaa2 100644
--- a/drivers/gpu/drm/drm_displayid.c
+++ b/drivers/gpu/drm/drm_displayid.c
@@ -37,7 +37,10 @@ static const u8 *drm_find_displayid_extension(const struct 
edid *edid,
  int *length, int *idx,
  int *ext_index)
 {
-   const u8 *displayid = drm_find_edid_extension(edid, DISPLAYID_EXT, 
ext_index);
+   const u8 *displayid = drm_find_edid_extension(edid,
+ DISPLAYID_EXT,
+ ext_index,
+ edid->extensions);
const struct displayid_header *base;
int ret;
 
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 890038758660..40c192587f0a 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3360,23 +3360,23 @@ add_detailed_modes(struct drm_connector *connector, 
struct edid *edid,
  * Search EDID for CEA extension block.
  */
 const u8 *drm_find_edid_extension(const struct edid *edid,
- int ext_id, int *ext_index)
+ int ext_id, int *ext_index, int ext_blk_num)
 {
const u8 *edid_ext = NULL;
int i;
 
/* No EDID or EDID extensions */
-   if (edid == NULL || edid->extensions == 0)
+   if (edid == NULL || edid->extensions == 0 || *ext_index >= ext_blk_num)
return NULL;
 
/* Find CEA extension */
-   for (i = *ext_index; i < edid->extensions; i++) {
+   for (i = *ext_index; i < ext_blk_num; i++) {
edid_ext = (const u8 *)edid + EDID_LENGTH * (i + 1);
if (edid_ext[0] == ext_id)
break;
}
 
-   if (i >= edid->extensions)
+   if (i >= ext_blk_num)
return NULL;
 
*ext_index = i + 1;
@@ -3384,14 +3384,15 @@ const u8 *drm_find_edid_extension(const struct edid 
*edid,
return edid_ext;
 }
 
-static const u8 *drm_find_cea_extension(const struct edid *edid, int 
*ext_index)
+static const u8 *drm_find_cea_extension(const struct edid *edid,
+   int *ext_index, int ext_blk_num)
 {
const struct displayid_block *block;
struct displayid_iter iter;
const u8 *cea;
 
/* Look for a CEA extension block from ext_index */
-   cea = drm_find_edid_extension(edid, CEA_EXT, ext_index);
+   cea = drm_find_edid_extension(edid, CEA_EXT, ext_index, ext_blk_num);
if (cea)
return cea;
 
@@ -3675,7 +3676,7 @@ add_alternate_cea_modes(struct drm_connector *connector, 
struct edid *edid)
int modes = 0, ext_index = 0;
 
/* Don't add CEA modes if the CEA extension block is missing */
-   if (!drm_find_cea_extension(edid, _index))
+   if (!drm_find_cea_extension(edid, _index, edid->extensions))
return 0;
 
/*
@@ -4327,7 +4328,7 @@ size_t drm_edid_read_hf_eeodb_blk_count(const struct edid 
*edid)
int i, start, end, ext_index = 0;
 
if (edid->extensions) {
-   cea = drm_find_cea_extension(edid, _index);
+   cea = drm_find_cea_extension(edid, _index, 
edid->extensions);
 
if (cea && !cea_db_offsets(cea, , ))
for_each_cea_db(cea, i, start, end)
@@ -4384,13 +4385,17 @@ add_cea_modes(struct drm_connector *connector, struct 
edid *edid)
 {
int modes = 0, ext_index = 0;
const u8 *cur_cea = NULL;
+   int ext_blk_num = drm_edid_read_hf_eeodb_blk_count(edid);
+
+   if (!ext_blk_num)
+   ext_blk_num = edid->extensions;
 
for (;;) {
const u8 *cea, *db, *hdmi = NULL, *video = NULL;
u8 dbl, hdmi_len = 0, video_len = 0;
int i, start, end;
 
-   cea = drm_find_cea_extension(edid, _index);
+   cea = drm_find_cea_extension(edid, _index, ext_blk_num);
if (!cea || cea == cur_cea)
break;
cur_cea = cea;
@@ -4640,7 +4645,7 @@ static void drm_edid_to_eld(struct drm_connector 
*connector, struct edid *edid)
if (!edid)
return;
 
-   cea = drm_find_cea_extension(edid, _index);
+   cea = drm

[Intel-gfx] [v8 3/5] drm/edid: read HF-EEODB ext block

2022-03-17 Thread Lee Shawn C
According to HDMI 2.1 spec.

"The HDMI Forum EDID Extension Override Data Block (HF-EEODB)
is utilized by Sink Devices to provide an alternate method to
indicate an EDID Extension Block count larger than 1, while
avoiding the need to present a VESA Block Map in the first
E-EDID Extension Block."

It is a mandatory for HDMI 2.1 protocol compliance as well.
This patch help to know how many HF_EEODB blocks report by sink
and read allo HF_EEODB blocks back.

v2: support to find CEA block, check EEODB block format, and return
available block number in drm_edid_read_hf_eeodb_blk_count().

Cc: Jani Nikula 
Cc: Ville Syrjala 
Cc: Ankit Nautiyal 
Cc: intel-gfx 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/drm_connector.c |  8 +++-
 drivers/gpu/drm/drm_edid.c  | 71 +++--
 include/drm/drm_edid.h  |  2 +-
 3 files changed, 74 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index a50c82bc2b2f..16011023c12e 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -2129,7 +2129,7 @@ int drm_connector_update_edid_property(struct 
drm_connector *connector,
   const struct edid *edid)
 {
struct drm_device *dev = connector->dev;
-   size_t size = 0;
+   size_t size = 0, hf_eeodb_blk_count;
int ret;
const struct edid *old_edid;
 
@@ -2137,8 +2137,12 @@ int drm_connector_update_edid_property(struct 
drm_connector *connector,
if (connector->override_edid)
return 0;
 
-   if (edid)
+   if (edid) {
size = EDID_LENGTH * (1 + edid->extensions);
+   hf_eeodb_blk_count = drm_edid_read_hf_eeodb_blk_count(edid);
+   if (hf_eeodb_blk_count)
+   size = EDID_LENGTH * (1 + hf_eeodb_blk_count);
+   }
 
/* Set the display info, using edid if available, otherwise
 * resetting the values to defaults. This duplicates the work
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index ef65dd97d700..890038758660 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1992,6 +1992,7 @@ struct edid *drm_do_get_edid(struct drm_connector 
*connector,
 {
int i, j = 0, valid_extensions = 0;
u8 *edid, *new;
+   size_t hf_eeodb_blk_count;
struct edid *override;
 
override = drm_get_override_edid(connector);
@@ -2051,7 +2052,35 @@ struct edid *drm_do_get_edid(struct drm_connector 
*connector,
}
 
kfree(edid);
+   return (struct edid *)new;
+   }
+
+   hf_eeodb_blk_count = drm_edid_read_hf_eeodb_blk_count((struct edid 
*)edid);
+   if (hf_eeodb_blk_count >= 2) {
+   new = krealloc(edid, (hf_eeodb_blk_count + 1) * EDID_LENGTH, 
GFP_KERNEL);
+   if (!new)
+   goto out;
edid = new;
+
+   valid_extensions = hf_eeodb_blk_count - 1;
+   for (j = 2; j <= hf_eeodb_blk_count; j++) {
+   u8 *block = edid + j * EDID_LENGTH;
+
+   for (i = 0; i < 4; i++) {
+   if (get_edid_block(data, block, j, EDID_LENGTH))
+   goto out;
+   if (drm_edid_block_valid(block, j, false, NULL))
+   break;
+   }
+
+   if (i == 4)
+   valid_extensions--;
+   }
+
+   if (valid_extensions != hf_eeodb_blk_count - 1) {
+   DRM_ERROR("Not able to retrieve proper EDID contain 
HF-EEODB data.\n");
+   goto out;
+   }
}
 
return (struct edid *)edid;
@@ -3315,15 +3344,17 @@ add_detailed_modes(struct drm_connector *connector, 
struct edid *edid,
 #define VIDEO_BLOCK 0x02
 #define VENDOR_BLOCK0x03
 #define SPEAKER_BLOCK  0x04
-#define HDR_STATIC_METADATA_BLOCK  0x6
-#define USE_EXTENDED_TAG 0x07
-#define EXT_VIDEO_CAPABILITY_BLOCK 0x00
+#define EXT_VIDEO_CAPABILITY_BLOCK 0x00
+#define HDR_STATIC_METADATA_BLOCK  0x06
+#define USE_EXTENDED_TAG   0x07
 #define EXT_VIDEO_DATA_BLOCK_420   0x0E
-#define EXT_VIDEO_CAP_BLOCK_Y420CMDB 0x0F
+#define EXT_VIDEO_CAP_BLOCK_Y420CMDB   0x0F
+#define EXT_VIDEO_HF_EEODB_DATA_BLOCK  0x78
 #define EDID_BASIC_AUDIO   (1 << 6)
 #define EDID_CEA_YCRCB444  (1 << 5)
 #define EDID_CEA_YCRCB422  (1 << 4)
 #define EDID_CEA_VCDB_QS   (1 << 6)
+#define HF_EEODB_LENGTH2
 
 /*
  * Search EDID for CEA extension block.
@@ -4273,9 +4304,41 @@ static bool cea_db_is_y420vdb(const u8 *db)
return true;
 }
 
+static bool cea_db_is_hdmi_forum_eeodb(const u8 *db)
+{
+   if (ce

[Intel-gfx] [v8 2/5] drm/edid: parse multiple CEA extension block

2022-03-17 Thread Lee Shawn C
Try to find and parse more CEA ext blocks if edid->extensions
is greater than one.

v2: split prvious patch to two. And do CEA block parsing
in this one.
v3: simplify this patch based on previous change.
v4: refine patch v3.
v5: revert previous change.
And check cea pointer return from drm_find_cea_extension().
If drvier got the same cea pointer then exit this routine.

Cc: Jani Nikula 
Cc: Ville Syrjala 
Cc: Ankit Nautiyal 
Cc: Drew Davenport 
Cc: intel-gfx 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/drm_edid.c | 34 +-
 1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 1251226d9284..ef65dd97d700 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4319,16 +4319,24 @@ static void drm_parse_y420cmdb_bitmap(struct 
drm_connector *connector,
 static int
 add_cea_modes(struct drm_connector *connector, struct edid *edid)
 {
-   const u8 *cea, *db, *hdmi = NULL, *video = NULL;
-   u8 dbl, hdmi_len, video_len = 0;
int modes = 0, ext_index = 0;
+   const u8 *cur_cea = NULL;
 
-   cea = drm_find_cea_extension(edid, _index);
-   if (cea && cea_revision(cea) >= 3) {
+   for (;;) {
+   const u8 *cea, *db, *hdmi = NULL, *video = NULL;
+   u8 dbl, hdmi_len = 0, video_len = 0;
int i, start, end;
 
+   cea = drm_find_cea_extension(edid, _index);
+   if (!cea || cea == cur_cea)
+   break;
+   cur_cea = cea;
+
+   if (cea_revision(cea) < 3)
+   continue;
+
if (cea_db_offsets(cea, , ))
-   return 0;
+   continue;
 
for_each_cea_db(cea, i, start, end) {
db = [i];
@@ -4350,15 +4358,15 @@ add_cea_modes(struct drm_connector *connector, struct 
edid *edid)
  dbl - 1);
}
}
-   }
 
-   /*
-* We parse the HDMI VSDB after having added the cea modes as we will
-* be patching their flags when the sink supports stereo 3D.
-*/
-   if (hdmi)
-   modes += do_hdmi_vsdb_modes(connector, hdmi, hdmi_len, video,
-   video_len);
+   /*
+* We parse the HDMI VSDB after having added the cea modes as 
we will
+* be patching their flags when the sink supports stereo 3D.
+*/
+   if (hdmi)
+   modes += do_hdmi_vsdb_modes(connector, hdmi, hdmi_len, 
video,
+   video_len);
+   }
 
return modes;
 }
-- 
2.17.1



[Intel-gfx] [v8 1/5] drm/edid: seek for available CEA block from specific EDID block index

2022-03-17 Thread Lee Shawn C
drm_find_cea_extension() always look for a top level CEA block. Pass
ext_index from caller then this function to search next available
CEA ext block from a specific EDID block pointer.

Cc: Jani Nikula 
Cc: Ville Syrjala 
Cc: Ankit Nautiyal 
Cc: intel-gfx 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/drm_edid.c | 42 ++
 1 file changed, 20 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 561f53831e29..1251226d9284 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3353,16 +3353,14 @@ const u8 *drm_find_edid_extension(const struct edid 
*edid,
return edid_ext;
 }
 
-static const u8 *drm_find_cea_extension(const struct edid *edid)
+static const u8 *drm_find_cea_extension(const struct edid *edid, int 
*ext_index)
 {
const struct displayid_block *block;
struct displayid_iter iter;
const u8 *cea;
-   int ext_index = 0;
 
-   /* Look for a top level CEA extension block */
-   /* FIXME: make callers iterate through multiple CEA ext blocks? */
-   cea = drm_find_edid_extension(edid, CEA_EXT, _index);
+   /* Look for a CEA extension block from ext_index */
+   cea = drm_find_edid_extension(edid, CEA_EXT, ext_index);
if (cea)
return cea;
 
@@ -3643,10 +3641,10 @@ add_alternate_cea_modes(struct drm_connector 
*connector, struct edid *edid)
struct drm_device *dev = connector->dev;
struct drm_display_mode *mode, *tmp;
LIST_HEAD(list);
-   int modes = 0;
+   int modes = 0, ext_index = 0;
 
/* Don't add CEA modes if the CEA extension block is missing */
-   if (!drm_find_cea_extension(edid))
+   if (!drm_find_cea_extension(edid, _index))
return 0;
 
/*
@@ -4321,11 +4319,11 @@ static void drm_parse_y420cmdb_bitmap(struct 
drm_connector *connector,
 static int
 add_cea_modes(struct drm_connector *connector, struct edid *edid)
 {
-   const u8 *cea = drm_find_cea_extension(edid);
-   const u8 *db, *hdmi = NULL, *video = NULL;
+   const u8 *cea, *db, *hdmi = NULL, *video = NULL;
u8 dbl, hdmi_len, video_len = 0;
-   int modes = 0;
+   int modes = 0, ext_index = 0;
 
+   cea = drm_find_cea_extension(edid, _index);
if (cea && cea_revision(cea) >= 3) {
int i, start, end;
 
@@ -4562,7 +4560,7 @@ static void drm_edid_to_eld(struct drm_connector 
*connector, struct edid *edid)
uint8_t *eld = connector->eld;
const u8 *cea;
const u8 *db;
-   int total_sad_count = 0;
+   int total_sad_count = 0, ext_index = 0;
int mnl;
int dbl;
 
@@ -4571,7 +4569,7 @@ static void drm_edid_to_eld(struct drm_connector 
*connector, struct edid *edid)
if (!edid)
return;
 
-   cea = drm_find_cea_extension(edid);
+   cea = drm_find_cea_extension(edid, _index);
if (!cea) {
DRM_DEBUG_KMS("ELD: no CEA Extension found\n");
return;
@@ -4655,11 +4653,11 @@ static void drm_edid_to_eld(struct drm_connector 
*connector, struct edid *edid)
  */
 int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads)
 {
-   int count = 0;
+   int count = 0, ext_index = 0;
int i, start, end, dbl;
const u8 *cea;
 
-   cea = drm_find_cea_extension(edid);
+   cea = drm_find_cea_extension(edid, _index);
if (!cea) {
DRM_DEBUG_KMS("SAD: no CEA Extension found\n");
return 0;
@@ -4717,11 +4715,11 @@ EXPORT_SYMBOL(drm_edid_to_sad);
  */
 int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb)
 {
-   int count = 0;
+   int count = 0, ext_index = 0;
int i, start, end, dbl;
const u8 *cea;
 
-   cea = drm_find_cea_extension(edid);
+   cea = drm_find_cea_extension(edid, _index);
if (!cea) {
DRM_DEBUG_KMS("SAD: no CEA Extension found\n");
return 0;
@@ -4814,9 +4812,9 @@ bool drm_detect_hdmi_monitor(struct edid *edid)
 {
const u8 *edid_ext;
int i;
-   int start_offset, end_offset;
+   int start_offset, end_offset, ext_index = 0;
 
-   edid_ext = drm_find_cea_extension(edid);
+   edid_ext = drm_find_cea_extension(edid, _index);
if (!edid_ext)
return false;
 
@@ -4853,9 +4851,9 @@ bool drm_detect_monitor_audio(struct edid *edid)
const u8 *edid_ext;
int i, j;
bool has_audio = false;
-   int start_offset, end_offset;
+   int start_offset, end_offset, ext_index = 0;
 
-   edid_ext = drm_find_cea_extension(edid);
+   edid_ext = drm_find_cea_extension(edid, _index);
if (!edid_ext)
goto end;
 
@@ -5177,9 +5175,9 @@ static void drm_parse_cea_ext(struct drm_connector 
*connector,
 {
struct drm_display_info *info = >display_info;
   

[Intel-gfx] [v8 0/5] enhanced edid driver compatibility

2022-03-17 Thread Lee Shawn C
Support to parse multiple CEA extension blocks and HF-EEODB to
extend drm edid driver's capability.

v4: add one more patch to support HF-SCDB
v5: HF-SCDB and HF-VSDBS carry the same SCDS data. Reuse
drm_parse_hdmi_forum_vsdb() to parse this packet.
v6: save proper extension block index if CTA data information
was found in DispalyID block.
v7: using different parameters to store CEA and DisplayID block index.
configure DisplayID extansion block index before search available
DisplayID block.
v8: revert patch [v7 2/5] change.
And check cea pointer return from drm_find_cea_extension().
If drvier got the same cea pointer then exit this routine.

Lee Shawn C (5):
  drm/edid: seek for available CEA block from specific EDID block index
  drm/edid: parse multiple CEA extension block
  drm/edid: read HF-EEODB ext block
  drm/edid: parse HF-EEODB CEA extension block
  drm/edid: check for HF-SCDB block

 drivers/gpu/drm/drm_connector.c |   8 +-
 drivers/gpu/drm/drm_displayid.c |   5 +-
 drivers/gpu/drm/drm_edid.c  | 174 
 include/drm/drm_edid.h  |   4 +-
 4 files changed, 144 insertions(+), 47 deletions(-)

-- 
2.17.1



Re: [Intel-gfx] [v7 1/5] drm/edid: seek for available CEA and DisplayID block from specific EDID block index

2022-03-15 Thread Lee, Shawn C
On Tuesday, March 15, 2022 8:33 PM, Nikula, Jani  wrote:
>On Mon, 14 Mar 2022, Drew Davenport  wrote:
>> On Mon, Mar 14, 2022 at 10:40:47AM +0200, Jani Nikula wrote:
>>> On Sun, 13 Mar 2022, Lee Shawn C  wrote:
>>> > drm_find_cea_extension() always look for a top level CEA block. 
>>> > Pass ext_index from caller then this function to search next 
>>> > available CEA ext block from a specific EDID block pointer.
>>> >
>>> > v2: save proper extension block index if CTA data information
>>> > was found in DispalyID block.
>>> > v3: using different parameters to store CEA and DisplayID block index.
>>> > configure DisplayID extansion block index before search available
>>> > DisplayID block.
>>> >
>>> > Cc: Jani Nikula 
>>> > Cc: Ville Syrjala 
>>> > Cc: Ankit Nautiyal 
>>> > Cc: Drew Davenport 
>>> > Cc: intel-gfx 
>>> > Signed-off-by: Lee Shawn C 
>>> > ---
>>> >  drivers/gpu/drm/drm_displayid.c | 10 +--
>>> >  drivers/gpu/drm/drm_edid.c  | 53 ++---
>>> >  include/drm/drm_displayid.h |  4 +--
>>> >  3 files changed, 39 insertions(+), 28 deletions(-)
>>> >
>>> > diff --git a/drivers/gpu/drm/drm_displayid.c 
>>> > b/drivers/gpu/drm/drm_displayid.c index 32da557b960f..31c3e6d7d549 
>>> > 100644
>>> > --- a/drivers/gpu/drm/drm_displayid.c
>>> > +++ b/drivers/gpu/drm/drm_displayid.c
>>> > @@ -59,11 +59,14 @@ static const u8 
>>> > *drm_find_displayid_extension(const struct edid *edid,  }
>>> >  
>>> >  void displayid_iter_edid_begin(const struct edid *edid,
>>> > -struct displayid_iter *iter)
>>> > +struct displayid_iter *iter, int *ext_index)
>>> 
>>> Please don't do this. This just ruins the clean approach displayid 
>>> iterator added.
>>> 
>>> Instead of making the displayid iterator ugly, and leaking its 
>>> abstractions, I'll repeat what I said should be done in reply to the 
>>> very first version of this patch series [1]:
>>> 
>>> "I think we're going to need abstracted EDID iteration similar to 
>>> what I've done for DisplayID iteration. We can't have all places 
>>> reimplementing the iteration like we have now."
>>> 
>>> This isn't a problem that should be solved by having all the callers 
>>> hold a bunch of local variables and pass them around to all the 
>>> functions. Nobody's going to be able to keep track of this anymore. 
>>> And this series, as it is, makes it harder to fix this properly later on.
>>
>> I missed your original review comment, so apologies for repeating what 
>> you said there already.
>>
>> I'd agree that passing a starting index to the displayid_iter_* 
>> functions is probably not the right direction here. More thoughts below.
>>
>>> 
>>> 
>>> BR,
>>> Jani.
>>> 
>>> 
>>> [1] https://lore.kernel.org/r/87czjf8dik@intel.com
>>> 
>>> 
>>> 
>>> >  {
>>> >   memset(iter, 0, sizeof(*iter));
>>> >  
>>> >   iter->edid = edid;
>>> > +
>>> > + if (ext_index)
>>> > + iter->ext_index = *ext_index;
>>> >  }
>>> >  
>>> >  static const struct displayid_block * @@ -126,7 +129,10 @@ 
>>> > __displayid_iter_next(struct displayid_iter *iter)
>>> >   }
>>> >  }
>>> >  
>>> > -void displayid_iter_end(struct displayid_iter *iter)
>>> > +void displayid_iter_end(struct displayid_iter *iter, int 
>>> > +*ext_index)
>>> >  {
>>> > + if (ext_index)
>>> > + *ext_index = iter->ext_index;
>>> > +
>>> >   memset(iter, 0, sizeof(*iter));
>>> >  }
>>> > diff --git a/drivers/gpu/drm/drm_edid.c 
>>> > b/drivers/gpu/drm/drm_edid.c index 561f53831e29..78c415aa6889 
>>> > 100644
>>> > --- a/drivers/gpu/drm/drm_edid.c
>>> > +++ b/drivers/gpu/drm/drm_edid.c
>>> > @@ -3353,28 +3353,27 @@ const u8 *drm_find_edid_extension(const struct 
>>> > edid *edid,
>>> >   return edid_ext;
>>> >  }
>>> >  
>>> > -static const u8 *drm_find_cea_extension(const struct edid *edid)
>>> > +static const 

Re: [Intel-gfx] [v7 3/5] drm/edid: read HF-EEODB ext block

2022-03-15 Thread Lee, Shawn C
On Tuesday, March 15, 2022 7:03 PM, Nikula, Jani  wrote:
>On Sun, 13 Mar 2022, Lee Shawn C  wrote:
>> According to HDMI 2.1 spec.
>>
>> "The HDMI Forum EDID Extension Override Data Block (HF-EEODB) is 
>> utilized by Sink Devices to provide an alternate method to indicate an 
>> EDID Extension Block count larger than 1, while avoiding the need to 
>> present a VESA Block Map in the first E-EDID Extension Block."
>>
>> It is a mandatory for HDMI 2.1 protocol compliance as well.
>> This patch help to know how many HF_EEODB blocks report by sink and 
>> read allo HF_EEODB blocks back.
>>
>> v2: support to find CEA block, check EEODB block format, and return
>> available block number in drm_edid_read_hf_eeodb_blk_count().
>>
>> Cc: Jani Nikula 
>> Cc: Ville Syrjala 
>> Cc: Ankit Nautiyal 
>> Cc: Drew Davenport 
>> Cc: intel-gfx 
>> Signed-off-by: Lee Shawn C 
>> ---
>>  drivers/gpu/drm/drm_connector.c |  8 +++-
>>  drivers/gpu/drm/drm_edid.c  | 71 +++--
>>  include/drm/drm_edid.h  |  1 +
>>  3 files changed, 74 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_connector.c 
>> b/drivers/gpu/drm/drm_connector.c index a50c82bc2b2f..16011023c12e 
>> 100644
>> --- a/drivers/gpu/drm/drm_connector.c
>> +++ b/drivers/gpu/drm/drm_connector.c
>> @@ -2129,7 +2129,7 @@ int drm_connector_update_edid_property(struct 
>> drm_connector *connector,
>> const struct edid *edid)
>>  {
>>  struct drm_device *dev = connector->dev;
>> -size_t size = 0;
>> +size_t size = 0, hf_eeodb_blk_count;
>>  int ret;
>>  const struct edid *old_edid;
>>  
>> @@ -2137,8 +2137,12 @@ int drm_connector_update_edid_property(struct 
>> drm_connector *connector,
>>  if (connector->override_edid)
>>  return 0;
>>  
>> -if (edid)
>> +if (edid) {
>>  size = EDID_LENGTH * (1 + edid->extensions);
>> +hf_eeodb_blk_count = drm_edid_read_hf_eeodb_blk_count(edid);
>> +if (hf_eeodb_blk_count)
>> +size = EDID_LENGTH * (1 + hf_eeodb_blk_count);
>
>This approach does not scale. If the number of extensions and thus the total 
>EDID size depend on HF-EEODB, this *must* be abstracted.
>
>Consider, for example, drm_edid_duplicate(), which only looks at
>edid->extensions. A subsequent HF-EEODB aware access on an EDID
>duplicated using drm_edid_duplicate() will access beyond the allocated buffer.
>
>Yes, it's a lot of work to introduce drm_edid_size() and
>drm_edid_extension_count() or similar, and use them everywhere, but this is 
>what we must do. It's a lot more work to try to take HF-EEODB into account 
>everywhere. The latter is going to be riddled with bugs with everyone doing it 
>a little different.
>

As you mentioned, we should have new functions to provide proper EDID byte size 
or extension counter.
And reuse them to handle/retrieve EDID more accurately in drm driver. Thanks 
for your comment!

>> +}
>>  
>>  /* Set the display info, using edid if available, otherwise
>>   * resetting the values to defaults. This duplicates the work diff 
>> --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 
>> 9fa84881fbba..5ae4e83fa5e3 100644
>> --- a/drivers/gpu/drm/drm_edid.c
>> +++ b/drivers/gpu/drm/drm_edid.c
>> @@ -1992,6 +1992,7 @@ struct edid *drm_do_get_edid(struct 
>> drm_connector *connector,  {
>>  int i, j = 0, valid_extensions = 0;
>>  u8 *edid, *new;
>> +size_t hf_eeodb_blk_count;
>>  struct edid *override;
>>  
>>  override = drm_get_override_edid(connector); @@ -2051,7 +2052,35 @@ 
>> struct edid *drm_do_get_edid(struct drm_connector *connector,
>>  }
>>  
>>  kfree(edid);
>> +return (struct edid *)new;
>> +}
>> +
>> +hf_eeodb_blk_count = drm_edid_read_hf_eeodb_blk_count((struct edid 
>> *)edid);
>> +if (hf_eeodb_blk_count >= 2) {
>> +new = krealloc(edid, (hf_eeodb_blk_count + 1) * EDID_LENGTH, 
>> GFP_KERNEL);
>> +if (!new)
>> +goto out;
>>  edid = new;
>> +
>> +valid_extensions = hf_eeodb_blk_count - 1;
>> +for (j = 2; j <= hf_eeodb_blk_count; j++) {
>> +u8 *block = edid + j * EDID_LENGTH;
>> +
>> +for (i = 0; i <

[Intel-gfx] [v7 5/5] drm/edid: check for HF-SCDB block

2022-03-13 Thread Lee Shawn C
Find HF-SCDB information in CEA extensions block. And retrieve
Max_TMDS_Character_Rate that support by sink device.

v2: HF-SCDB and HF-VSDBS carry the same SCDS data. Reuse
drm_parse_hdmi_forum_vsdb() to parse this packet.

Cc: Jani Nikula 
Cc: Ville Syrjala 
Cc: Ankit Nautiyal 
Cc: Drew Davenport 
Cc: intel-gfx 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/drm_edid.c | 18 +-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 5de85ba20bdf..351a729bddb6 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3350,6 +3350,7 @@ add_detailed_modes(struct drm_connector *connector, 
struct edid *edid,
 #define EXT_VIDEO_DATA_BLOCK_420   0x0E
 #define EXT_VIDEO_CAP_BLOCK_Y420CMDB   0x0F
 #define EXT_VIDEO_HF_EEODB_DATA_BLOCK  0x78
+#define EXT_VIDEO_HF_SCDB_DATA_BLOCK   0x79
 #define EDID_BASIC_AUDIO   (1 << 6)
 #define EDID_CEA_YCRCB444  (1 << 5)
 #define EDID_CEA_YCRCB422  (1 << 4)
@@ -4287,6 +4288,20 @@ static bool cea_db_is_vcdb(const u8 *db)
return true;
 }
 
+static bool cea_db_is_hdmi_forum_scdb(const u8 *db)
+{
+   if (cea_db_tag(db) != USE_EXTENDED_TAG)
+   return false;
+
+   if (cea_db_payload_len(db) < 7)
+   return false;
+
+   if (cea_db_extended_tag(db) != EXT_VIDEO_HF_SCDB_DATA_BLOCK)
+   return false;
+
+   return true;
+}
+
 static bool cea_db_is_y420cmdb(const u8 *db)
 {
if (cea_db_tag(db) != USE_EXTENDED_TAG)
@@ -5312,7 +5327,8 @@ static void drm_parse_cea_ext(struct drm_connector 
*connector,
 
if (cea_db_is_hdmi_vsdb(db))
drm_parse_hdmi_vsdb_video(connector, db);
-   if (cea_db_is_hdmi_forum_vsdb(db))
+   if (cea_db_is_hdmi_forum_vsdb(db) ||
+   cea_db_is_hdmi_forum_scdb(db))
drm_parse_hdmi_forum_vsdb(connector, db);
if (cea_db_is_microsoft_vsdb(db))
drm_parse_microsoft_vsdb(connector, db);
-- 
2.17.1



[Intel-gfx] [v7 2/5] drm/edid: parse multiple CEA extension block

2022-03-13 Thread Lee Shawn C
Try to find and parse more CEA ext blocks if edid->extensions
is greater than one.

v2: split prvious patch to two. And do CEA block parsing
in this one.
v3: simplify this patch based on previous change.
v4: refine patch v3.

Cc: Jani Nikula 
Cc: Ville Syrjala 
Cc: Ankit Nautiyal 
Cc: Drew Davenport 
Cc: intel-gfx 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/drm_edid.c | 32 +++-
 1 file changed, 19 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 78c415aa6889..9fa84881fbba 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4320,16 +4320,22 @@ static void drm_parse_y420cmdb_bitmap(struct 
drm_connector *connector,
 static int
 add_cea_modes(struct drm_connector *connector, struct edid *edid)
 {
-   const u8 *cea, *db, *hdmi = NULL, *video = NULL;
-   u8 dbl, hdmi_len, video_len = 0;
int modes = 0, cea_ext_index = 0, displayid_ext_index = 0;
 
-   cea = drm_find_cea_extension(edid, _ext_index, 
_ext_index);
-   if (cea && cea_revision(cea) >= 3) {
+   for (;;) {
+   const u8 *cea, *db, *hdmi = NULL, *video = NULL;
+   u8 dbl, hdmi_len = 0, video_len = 0;
int i, start, end;
 
+   cea = drm_find_cea_extension(edid, _ext_index, 
_ext_index);
+   if (!cea)
+   break;
+
+   if (cea_revision(cea) < 3)
+   continue;
+
if (cea_db_offsets(cea, , ))
-   return 0;
+   continue;
 
for_each_cea_db(cea, i, start, end) {
db = [i];
@@ -4351,15 +4357,15 @@ add_cea_modes(struct drm_connector *connector, struct 
edid *edid)
  dbl - 1);
}
}
-   }
 
-   /*
-* We parse the HDMI VSDB after having added the cea modes as we will
-* be patching their flags when the sink supports stereo 3D.
-*/
-   if (hdmi)
-   modes += do_hdmi_vsdb_modes(connector, hdmi, hdmi_len, video,
-   video_len);
+   /*
+* We parse the HDMI VSDB after having added the cea modes as 
we will
+* be patching their flags when the sink supports stereo 3D.
+*/
+   if (hdmi)
+   modes += do_hdmi_vsdb_modes(connector, hdmi, hdmi_len, 
video,
+   video_len);
+   }
 
return modes;
 }
-- 
2.17.1



[Intel-gfx] [v7 4/5] drm/edid: parse HF-EEODB CEA extension block

2022-03-13 Thread Lee Shawn C
While adding CEA modes, try to get available EEODB block
number. Then based on it to parse numbers of ext blocks,
retrieve CEA information and add more CEA modes.

Cc: Jani Nikula 
Cc: Ville Syrjala 
Cc: Ankit Nautiyal 
Cc: Drew Davenport 
Cc: intel-gfx 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/drm_displayid.c |  5 ++-
 drivers/gpu/drm/drm_edid.c  | 68 +
 include/drm/drm_edid.h  |  2 +-
 3 files changed, 58 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/drm_displayid.c b/drivers/gpu/drm/drm_displayid.c
index 31c3e6d7d549..a769c55146f4 100644
--- a/drivers/gpu/drm/drm_displayid.c
+++ b/drivers/gpu/drm/drm_displayid.c
@@ -37,7 +37,10 @@ static const u8 *drm_find_displayid_extension(const struct 
edid *edid,
  int *length, int *idx,
  int *ext_index)
 {
-   const u8 *displayid = drm_find_edid_extension(edid, DISPLAYID_EXT, 
ext_index);
+   const u8 *displayid = drm_find_edid_extension(edid,
+ DISPLAYID_EXT,
+ ext_index,
+ edid->extensions);
const struct displayid_header *base;
int ret;
 
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 5ae4e83fa5e3..5de85ba20bdf 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3360,23 +3360,25 @@ add_detailed_modes(struct drm_connector *connector, 
struct edid *edid,
  * Search EDID for CEA extension block.
  */
 const u8 *drm_find_edid_extension(const struct edid *edid,
- int ext_id, int *ext_index)
+ int ext_id,
+ int *ext_index,
+ int ext_blk_num)
 {
const u8 *edid_ext = NULL;
int i;
 
/* No EDID or EDID extensions */
-   if (edid == NULL || edid->extensions == 0)
+   if (edid == NULL || edid->extensions == 0 || *ext_index >= ext_blk_num)
return NULL;
 
/* Find CEA extension */
-   for (i = *ext_index; i < edid->extensions; i++) {
+   for (i = *ext_index; i < ext_blk_num; i++) {
edid_ext = (const u8 *)edid + EDID_LENGTH * (i + 1);
if (edid_ext[0] == ext_id)
break;
}
 
-   if (i >= edid->extensions)
+   if (i >= ext_blk_num)
return NULL;
 
*ext_index = i + 1;
@@ -3385,14 +3387,19 @@ const u8 *drm_find_edid_extension(const struct edid 
*edid,
 }
 
 static const u8 *drm_find_cea_extension(const struct edid *edid,
-   int *cea_ext_index, int 
*displayid_ext_index)
+   int *cea_ext_index,
+   int *displayid_ext_index,
+   int ext_blk_num)
 {
const struct displayid_block *block;
struct displayid_iter iter;
const u8 *cea;
 
/* Look for a CEA extension block from ext_index */
-   cea = drm_find_edid_extension(edid, CEA_EXT, cea_ext_index);
+   cea = drm_find_edid_extension(edid,
+ CEA_EXT,
+ cea_ext_index,
+ ext_blk_num);
if (cea)
return cea;
 
@@ -3676,7 +3683,10 @@ add_alternate_cea_modes(struct drm_connector *connector, 
struct edid *edid)
int modes = 0, cea_ext_index = 0, displayid_ext_index = 0;
 
/* Don't add CEA modes if the CEA extension block is missing */
-   if (!drm_find_cea_extension(edid, _ext_index, _ext_index))
+   if (!drm_find_cea_extension(edid,
+   _ext_index,
+   _ext_index,
+   edid->extensions))
return 0;
 
/*
@@ -4328,7 +4338,10 @@ size_t drm_edid_read_hf_eeodb_blk_count(const struct 
edid *edid)
int i, start, end, cea_ext_index = 0, displayid_ext_index = 0;
 
if (edid->extensions) {
-   cea = drm_find_cea_extension(edid, _ext_index, 
_ext_index);
+   cea = drm_find_cea_extension(edid,
+_ext_index,
+_ext_index,
+edid->extensions);
 
if (cea && !cea_db_offsets(cea, , ))
for_each_cea_db(cea, i, start, end)
@@ -4384,13 +4397,20 @@ static int
 add_cea_modes(struct drm_connector *connector, struct edid *edid)
 {
int modes = 0, cea_ext_index = 0, displayid_ext_index = 0;
+   int ext_blk_num = drm_edid_read_hf_eeodb_blk_count(edid);
+
+   if (!ext_blk_num)

[Intel-gfx] [v7 3/5] drm/edid: read HF-EEODB ext block

2022-03-13 Thread Lee Shawn C
According to HDMI 2.1 spec.

"The HDMI Forum EDID Extension Override Data Block (HF-EEODB)
is utilized by Sink Devices to provide an alternate method to
indicate an EDID Extension Block count larger than 1, while
avoiding the need to present a VESA Block Map in the first
E-EDID Extension Block."

It is a mandatory for HDMI 2.1 protocol compliance as well.
This patch help to know how many HF_EEODB blocks report by sink
and read allo HF_EEODB blocks back.

v2: support to find CEA block, check EEODB block format, and return
available block number in drm_edid_read_hf_eeodb_blk_count().

Cc: Jani Nikula 
Cc: Ville Syrjala 
Cc: Ankit Nautiyal 
Cc: Drew Davenport 
Cc: intel-gfx 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/drm_connector.c |  8 +++-
 drivers/gpu/drm/drm_edid.c  | 71 +++--
 include/drm/drm_edid.h  |  1 +
 3 files changed, 74 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index a50c82bc2b2f..16011023c12e 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -2129,7 +2129,7 @@ int drm_connector_update_edid_property(struct 
drm_connector *connector,
   const struct edid *edid)
 {
struct drm_device *dev = connector->dev;
-   size_t size = 0;
+   size_t size = 0, hf_eeodb_blk_count;
int ret;
const struct edid *old_edid;
 
@@ -2137,8 +2137,12 @@ int drm_connector_update_edid_property(struct 
drm_connector *connector,
if (connector->override_edid)
return 0;
 
-   if (edid)
+   if (edid) {
size = EDID_LENGTH * (1 + edid->extensions);
+   hf_eeodb_blk_count = drm_edid_read_hf_eeodb_blk_count(edid);
+   if (hf_eeodb_blk_count)
+   size = EDID_LENGTH * (1 + hf_eeodb_blk_count);
+   }
 
/* Set the display info, using edid if available, otherwise
 * resetting the values to defaults. This duplicates the work
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 9fa84881fbba..5ae4e83fa5e3 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1992,6 +1992,7 @@ struct edid *drm_do_get_edid(struct drm_connector 
*connector,
 {
int i, j = 0, valid_extensions = 0;
u8 *edid, *new;
+   size_t hf_eeodb_blk_count;
struct edid *override;
 
override = drm_get_override_edid(connector);
@@ -2051,7 +2052,35 @@ struct edid *drm_do_get_edid(struct drm_connector 
*connector,
}
 
kfree(edid);
+   return (struct edid *)new;
+   }
+
+   hf_eeodb_blk_count = drm_edid_read_hf_eeodb_blk_count((struct edid 
*)edid);
+   if (hf_eeodb_blk_count >= 2) {
+   new = krealloc(edid, (hf_eeodb_blk_count + 1) * EDID_LENGTH, 
GFP_KERNEL);
+   if (!new)
+   goto out;
edid = new;
+
+   valid_extensions = hf_eeodb_blk_count - 1;
+   for (j = 2; j <= hf_eeodb_blk_count; j++) {
+   u8 *block = edid + j * EDID_LENGTH;
+
+   for (i = 0; i < 4; i++) {
+   if (get_edid_block(data, block, j, EDID_LENGTH))
+   goto out;
+   if (drm_edid_block_valid(block, j, false, NULL))
+   break;
+   }
+
+   if (i == 4)
+   valid_extensions--;
+   }
+
+   if (valid_extensions != hf_eeodb_blk_count - 1) {
+   DRM_ERROR("Not able to retrieve proper EDID contain 
HF-EEODB data.\n");
+   goto out;
+   }
}
 
return (struct edid *)edid;
@@ -3315,15 +3344,17 @@ add_detailed_modes(struct drm_connector *connector, 
struct edid *edid,
 #define VIDEO_BLOCK 0x02
 #define VENDOR_BLOCK0x03
 #define SPEAKER_BLOCK  0x04
-#define HDR_STATIC_METADATA_BLOCK  0x6
-#define USE_EXTENDED_TAG 0x07
-#define EXT_VIDEO_CAPABILITY_BLOCK 0x00
+#define EXT_VIDEO_CAPABILITY_BLOCK 0x00
+#define HDR_STATIC_METADATA_BLOCK  0x06
+#define USE_EXTENDED_TAG   0x07
 #define EXT_VIDEO_DATA_BLOCK_420   0x0E
-#define EXT_VIDEO_CAP_BLOCK_Y420CMDB 0x0F
+#define EXT_VIDEO_CAP_BLOCK_Y420CMDB   0x0F
+#define EXT_VIDEO_HF_EEODB_DATA_BLOCK  0x78
 #define EDID_BASIC_AUDIO   (1 << 6)
 #define EDID_CEA_YCRCB444  (1 << 5)
 #define EDID_CEA_YCRCB422  (1 << 4)
 #define EDID_CEA_VCDB_QS   (1 << 6)
+#define HF_EEODB_LENGTH2
 
 /*
  * Search EDID for CEA extension block.
@@ -4274,9 +4305,41 @@ static bool cea_db_is_y420vdb(const u8 *db)
return true;
 }
 
+static bool cea_db_is_hdmi_forum_eeodb(const u8 *db)
+{
+   if (ce

[Intel-gfx] [v7 1/5] drm/edid: seek for available CEA and DisplayID block from specific EDID block index

2022-03-13 Thread Lee Shawn C
drm_find_cea_extension() always look for a top level CEA block. Pass
ext_index from caller then this function to search next available
CEA ext block from a specific EDID block pointer.

v2: save proper extension block index if CTA data information
was found in DispalyID block.
v3: using different parameters to store CEA and DisplayID block index.
configure DisplayID extansion block index before search available
DisplayID block.

Cc: Jani Nikula 
Cc: Ville Syrjala 
Cc: Ankit Nautiyal 
Cc: Drew Davenport 
Cc: intel-gfx 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/drm_displayid.c | 10 +--
 drivers/gpu/drm/drm_edid.c  | 53 ++---
 include/drm/drm_displayid.h |  4 +--
 3 files changed, 39 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/drm_displayid.c b/drivers/gpu/drm/drm_displayid.c
index 32da557b960f..31c3e6d7d549 100644
--- a/drivers/gpu/drm/drm_displayid.c
+++ b/drivers/gpu/drm/drm_displayid.c
@@ -59,11 +59,14 @@ static const u8 *drm_find_displayid_extension(const struct 
edid *edid,
 }
 
 void displayid_iter_edid_begin(const struct edid *edid,
-  struct displayid_iter *iter)
+  struct displayid_iter *iter, int *ext_index)
 {
memset(iter, 0, sizeof(*iter));
 
iter->edid = edid;
+
+   if (ext_index)
+   iter->ext_index = *ext_index;
 }
 
 static const struct displayid_block *
@@ -126,7 +129,10 @@ __displayid_iter_next(struct displayid_iter *iter)
}
 }
 
-void displayid_iter_end(struct displayid_iter *iter)
+void displayid_iter_end(struct displayid_iter *iter, int *ext_index)
 {
+   if (ext_index)
+   *ext_index = iter->ext_index;
+
memset(iter, 0, sizeof(*iter));
 }
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 561f53831e29..78c415aa6889 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3353,28 +3353,27 @@ const u8 *drm_find_edid_extension(const struct edid 
*edid,
return edid_ext;
 }
 
-static const u8 *drm_find_cea_extension(const struct edid *edid)
+static const u8 *drm_find_cea_extension(const struct edid *edid,
+   int *cea_ext_index, int 
*displayid_ext_index)
 {
const struct displayid_block *block;
struct displayid_iter iter;
const u8 *cea;
-   int ext_index = 0;
 
-   /* Look for a top level CEA extension block */
-   /* FIXME: make callers iterate through multiple CEA ext blocks? */
-   cea = drm_find_edid_extension(edid, CEA_EXT, _index);
+   /* Look for a CEA extension block from ext_index */
+   cea = drm_find_edid_extension(edid, CEA_EXT, cea_ext_index);
if (cea)
return cea;
 
/* CEA blocks can also be found embedded in a DisplayID block */
-   displayid_iter_edid_begin(edid, );
+   displayid_iter_edid_begin(edid, , displayid_ext_index);
displayid_iter_for_each(block, ) {
if (block->tag == DATA_BLOCK_CTA) {
cea = (const u8 *)block;
break;
}
}
-   displayid_iter_end();
+   displayid_iter_end(, displayid_ext_index);
 
return cea;
 }
@@ -3643,10 +3642,10 @@ add_alternate_cea_modes(struct drm_connector 
*connector, struct edid *edid)
struct drm_device *dev = connector->dev;
struct drm_display_mode *mode, *tmp;
LIST_HEAD(list);
-   int modes = 0;
+   int modes = 0, cea_ext_index = 0, displayid_ext_index = 0;
 
/* Don't add CEA modes if the CEA extension block is missing */
-   if (!drm_find_cea_extension(edid))
+   if (!drm_find_cea_extension(edid, _ext_index, _ext_index))
return 0;
 
/*
@@ -4321,11 +4320,11 @@ static void drm_parse_y420cmdb_bitmap(struct 
drm_connector *connector,
 static int
 add_cea_modes(struct drm_connector *connector, struct edid *edid)
 {
-   const u8 *cea = drm_find_cea_extension(edid);
-   const u8 *db, *hdmi = NULL, *video = NULL;
+   const u8 *cea, *db, *hdmi = NULL, *video = NULL;
u8 dbl, hdmi_len, video_len = 0;
-   int modes = 0;
+   int modes = 0, cea_ext_index = 0, displayid_ext_index = 0;
 
+   cea = drm_find_cea_extension(edid, _ext_index, 
_ext_index);
if (cea && cea_revision(cea) >= 3) {
int i, start, end;
 
@@ -4563,6 +4562,7 @@ static void drm_edid_to_eld(struct drm_connector 
*connector, struct edid *edid)
const u8 *cea;
const u8 *db;
int total_sad_count = 0;
+   int cea_ext_index = 0, displayid_ext_index = 0;
int mnl;
int dbl;
 
@@ -4571,7 +4571,7 @@ static void drm_edid_to_eld(struct drm_connector 
*connector, struct edid *edid)
if (!edid)
return;
 
-   cea = drm_find_cea_extension(edid);
+   cea = drm_find_cea_extension(edid, _ext_index, 
_ex

[Intel-gfx] [v7 0/5] enhanced edid driver compatibility

2022-03-13 Thread Lee Shawn C
Support to parse multiple CEA extension blocks and HF-EEODB to
extend drm edid driver's capability.

v4: add one more patch to support HF-SCDB
v5: HF-SCDB and HF-VSDBS carry the same SCDS data. Reuse
drm_parse_hdmi_forum_vsdb() to parse this packet.
v6: save proper extension block index if CTA data information
was found in DispalyID block.
v7: using different parameters to store CEA and DisplayID block index.
configure DisplayID extansion block index before search available
DisplayID block.

Lee Shawn C (5):
  drm/edid: seek for available CEA and DisplayID block from specific
EDID block index
  drm/edid: parse multiple CEA extension block
  drm/edid: read HF-EEODB ext block
  drm/edid: parse HF-EEODB CEA extension block
  drm/edid: check for HF-SCDB block

 drivers/gpu/drm/drm_connector.c |   8 +-
 drivers/gpu/drm/drm_displayid.c |  15 ++-
 drivers/gpu/drm/drm_edid.c  | 216 +---
 include/drm/drm_displayid.h |   4 +-
 include/drm/drm_edid.h  |   3 +-
 5 files changed, 194 insertions(+), 52 deletions(-)

-- 
2.17.1



Re: [Intel-gfx] [v6 1/5] drm/edid: seek for available CEA block from specific EDID block index

2022-03-12 Thread Lee, Shawn C
On Saturday, March 12, 2022 7:41 AM, Drew Davenport  
wrote:
>On Fri, Mar 11, 2022 at 09:22:14AM +0800, Lee Shawn C wrote:
>> drm_find_cea_extension() always look for a top level CEA block. Pass 
>> ext_index from caller then this function to search next available CEA 
>> ext block from a specific EDID block pointer.
>> 
>> v2: save proper extension block index if CTA data information
>> was found in DispalyID block.
>> 
>> Cc: Jani Nikula 
>> Cc: Ville Syrjala 
>> Cc: Ankit Nautiyal 
>> Cc: intel-gfx 
>> Signed-off-by: Lee Shawn C 
>> ---
>>  drivers/gpu/drm/drm_edid.c | 43 
>> +++---
>>  1 file changed, 21 insertions(+), 22 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c 
>> index 561f53831e29..e267d31d5c87 100644
>> --- a/drivers/gpu/drm/drm_edid.c
>> +++ b/drivers/gpu/drm/drm_edid.c
>> @@ -3353,16 +3353,14 @@ const u8 *drm_find_edid_extension(const struct edid 
>> *edid,
>>  return edid_ext;
>>  }
>>  
>> -static const u8 *drm_find_cea_extension(const struct edid *edid)
>> +static const u8 *drm_find_cea_extension(const struct edid *edid, int 
>> +*ext_index)
>>  {
>>  const struct displayid_block *block;
>>  struct displayid_iter iter;
>>  const u8 *cea;
>> -int ext_index = 0;
>>  
>> -/* Look for a top level CEA extension block */
>> -/* FIXME: make callers iterate through multiple CEA ext blocks? */
>> -cea = drm_find_edid_extension(edid, CEA_EXT, _index);
>> +/* Look for a CEA extension block from ext_index */
>> +cea = drm_find_edid_extension(edid, CEA_EXT, ext_index);
>>  if (cea)
>>  return cea;
>>  
>> @@ -3370,6 +3368,7 @@ static const u8 *drm_find_cea_extension(const struct 
>> edid *edid)
>>  displayid_iter_edid_begin(edid, );
>>  displayid_iter_for_each(block, ) {
>>  if (block->tag == DATA_BLOCK_CTA) {
>> +*ext_index = iter.ext_index;
>This could still end up in an infinite loop in patch 2 in the case that there 
>is no CEA_EXT block in the edid, but there is a CEA block in the DisplayId 
>block.
>
>Repeating my review comment from elsewhere, consider the case:
>- If there are no cea extension blocks in the EDID,
>  drm_find_edid_extension returns NULL
>- drm_find_cea_extension will then return the first DisplayId block
>  with tag DATA_BLOCK_CTA
>
>If the version of the cea data from DisplayId block is less than 3, the loop 
>will restart and call drm_find_cea_extension the same way, returning the same 
>DisplayID block every time.
>
>Setting *ext_index inside the display_iter_for_each block doesn't change this, 
>since we're not checking it.
>
>But I don't think we want to use the same *ext_index both to pass into 
>drm_find_edid_extension and for tracking the next DisplayId block to check.
>This might end up in similar infinite loops or skipping DisplayId blocks.
>
>Maybe you'll need to pass in two indexes to drm_find_cea_extension, one which 
>is passed to drm_find_edid_extension, and the other to keep track of the next 
>DisplayId block to check.

As you mentioned, this situation would cause infinite loop. We may need two 
different parameters to store CEA and DisplayID block index.

Best regards,
Shawn

>>  cea = (const u8 *)block;
>>  break;
>>  }
>> @@ -3643,10 +3642,10 @@ add_alternate_cea_modes(struct drm_connector 
>> *connector, struct edid *edid)
>>  struct drm_device *dev = connector->dev;
>>  struct drm_display_mode *mode, *tmp;
>>  LIST_HEAD(list);
>> -int modes = 0;
>> +int modes = 0, ext_index = 0;
>>  
>>  /* Don't add CEA modes if the CEA extension block is missing */
>> -if (!drm_find_cea_extension(edid))
>> +if (!drm_find_cea_extension(edid, _index))
>>  return 0;
>>  
>>  /*
>> @@ -4321,11 +4320,11 @@ static void drm_parse_y420cmdb_bitmap(struct 
>> drm_connector *connector,  static int  add_cea_modes(struct 
>> drm_connector *connector, struct edid *edid)  {
>> -const u8 *cea = drm_find_cea_extension(edid);
>> -const u8 *db, *hdmi = NULL, *video = NULL;
>> +const u8 *cea, *db, *hdmi = NULL, *video = NULL;
>>  u8 dbl, hdmi_len, video_len = 0;
>> -int modes = 0;
>> +int modes = 0, ext_index = 0;
>>  
>> +cea = drm_find_cea_extension(edid, _index);
>>  if (cea && cea_revision(cea) >= 3) {
>>  int i, s

[Intel-gfx] [v6 2/5] drm/edid: parse multiple CEA extension block

2022-03-10 Thread Lee Shawn C
Try to find and parse more CEA ext blocks if edid->extensions
is greater than one.

v2: split prvious patch to two. And do CEA block parsing
in this one.
v3: simplify this patch based on previous change.
v4: refine patch v3.

Cc: Jani Nikula 
Cc: Ville Syrjala 
Cc: Ankit Nautiyal 
Cc: intel-gfx 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/drm_edid.c | 32 +++-
 1 file changed, 19 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index e267d31d5c87..7717bf86c07d 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4320,16 +4320,22 @@ static void drm_parse_y420cmdb_bitmap(struct 
drm_connector *connector,
 static int
 add_cea_modes(struct drm_connector *connector, struct edid *edid)
 {
-   const u8 *cea, *db, *hdmi = NULL, *video = NULL;
-   u8 dbl, hdmi_len, video_len = 0;
int modes = 0, ext_index = 0;
 
-   cea = drm_find_cea_extension(edid, _index);
-   if (cea && cea_revision(cea) >= 3) {
+   for (;;) {
+   const u8 *cea, *db, *hdmi = NULL, *video = NULL;
+   u8 dbl, hdmi_len = 0, video_len = 0;
int i, start, end;
 
+   cea = drm_find_cea_extension(edid, _index);
+   if (!cea)
+   break;
+
+   if (cea_revision(cea) < 3)
+   continue;
+
if (cea_db_offsets(cea, , ))
-   return 0;
+   continue;
 
for_each_cea_db(cea, i, start, end) {
db = [i];
@@ -4351,15 +4357,15 @@ add_cea_modes(struct drm_connector *connector, struct 
edid *edid)
  dbl - 1);
}
}
-   }
 
-   /*
-* We parse the HDMI VSDB after having added the cea modes as we will
-* be patching their flags when the sink supports stereo 3D.
-*/
-   if (hdmi)
-   modes += do_hdmi_vsdb_modes(connector, hdmi, hdmi_len, video,
-   video_len);
+   /*
+* We parse the HDMI VSDB after having added the cea modes as 
we will
+* be patching their flags when the sink supports stereo 3D.
+*/
+   if (hdmi)
+   modes += do_hdmi_vsdb_modes(connector, hdmi, hdmi_len, 
video,
+   video_len);
+   }
 
return modes;
 }
-- 
2.17.1



[Intel-gfx] [v6 5/5] drm/edid: check for HF-SCDB block

2022-03-10 Thread Lee Shawn C
Find HF-SCDB information in CEA extensions block. And retrieve
Max_TMDS_Character_Rate that support by sink device.

v2: HF-SCDB and HF-VSDBS carry the same SCDS data. Reuse
drm_parse_hdmi_forum_vsdb() to parse this packet.

Cc: Jani Nikula 
Cc: Ville Syrjala 
Cc: Ankit Nautiyal 
Cc: intel-gfx 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/drm_edid.c | 18 +-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index eac6ce336507..159e01be6f68 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3350,6 +3350,7 @@ add_detailed_modes(struct drm_connector *connector, 
struct edid *edid,
 #define EXT_VIDEO_DATA_BLOCK_420   0x0E
 #define EXT_VIDEO_CAP_BLOCK_Y420CMDB   0x0F
 #define EXT_VIDEO_HF_EEODB_DATA_BLOCK  0x78
+#define EXT_VIDEO_HF_SCDB_DATA_BLOCK   0x79
 #define EDID_BASIC_AUDIO   (1 << 6)
 #define EDID_CEA_YCRCB444  (1 << 5)
 #define EDID_CEA_YCRCB422  (1 << 4)
@@ -4278,6 +4279,20 @@ static bool cea_db_is_vcdb(const u8 *db)
return true;
 }
 
+static bool cea_db_is_hdmi_forum_scdb(const u8 *db)
+{
+   if (cea_db_tag(db) != USE_EXTENDED_TAG)
+   return false;
+
+   if (cea_db_payload_len(db) < 7)
+   return false;
+
+   if (cea_db_extended_tag(db) != EXT_VIDEO_HF_SCDB_DATA_BLOCK)
+   return false;
+
+   return true;
+}
+
 static bool cea_db_is_y420cmdb(const u8 *db)
 {
if (cea_db_tag(db) != USE_EXTENDED_TAG)
@@ -5273,7 +5288,8 @@ static void drm_parse_cea_ext(struct drm_connector 
*connector,
 
if (cea_db_is_hdmi_vsdb(db))
drm_parse_hdmi_vsdb_video(connector, db);
-   if (cea_db_is_hdmi_forum_vsdb(db))
+   if (cea_db_is_hdmi_forum_vsdb(db) ||
+   cea_db_is_hdmi_forum_scdb(db))
drm_parse_hdmi_forum_vsdb(connector, db);
if (cea_db_is_microsoft_vsdb(db))
drm_parse_microsoft_vsdb(connector, db);
-- 
2.17.1



[Intel-gfx] [v6 4/5] drm/edid: parse HF-EEODB CEA extension block

2022-03-10 Thread Lee Shawn C
While adding CEA modes, try to get available EEODB block
number. Then based on it to parse numbers of ext blocks,
retrieve CEA information and add more CEA modes.

Cc: Jani Nikula 
Cc: Ville Syrjala 
Cc: Ankit Nautiyal 
Cc: intel-gfx 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/drm_displayid.c |  5 -
 drivers/gpu/drm/drm_edid.c  | 35 +++--
 include/drm/drm_edid.h  |  2 +-
 3 files changed, 25 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/drm_displayid.c b/drivers/gpu/drm/drm_displayid.c
index 32da557b960f..dc649a9efaa2 100644
--- a/drivers/gpu/drm/drm_displayid.c
+++ b/drivers/gpu/drm/drm_displayid.c
@@ -37,7 +37,10 @@ static const u8 *drm_find_displayid_extension(const struct 
edid *edid,
  int *length, int *idx,
  int *ext_index)
 {
-   const u8 *displayid = drm_find_edid_extension(edid, DISPLAYID_EXT, 
ext_index);
+   const u8 *displayid = drm_find_edid_extension(edid,
+ DISPLAYID_EXT,
+ ext_index,
+ edid->extensions);
const struct displayid_header *base;
int ret;
 
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 9f7fcecae3a2..eac6ce336507 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3360,23 +3360,23 @@ add_detailed_modes(struct drm_connector *connector, 
struct edid *edid,
  * Search EDID for CEA extension block.
  */
 const u8 *drm_find_edid_extension(const struct edid *edid,
- int ext_id, int *ext_index)
+ int ext_id, int *ext_index, int ext_blk_num)
 {
const u8 *edid_ext = NULL;
int i;
 
/* No EDID or EDID extensions */
-   if (edid == NULL || edid->extensions == 0)
+   if (edid == NULL || edid->extensions == 0 || *ext_index >= ext_blk_num)
return NULL;
 
/* Find CEA extension */
-   for (i = *ext_index; i < edid->extensions; i++) {
+   for (i = *ext_index; i < ext_blk_num; i++) {
edid_ext = (const u8 *)edid + EDID_LENGTH * (i + 1);
if (edid_ext[0] == ext_id)
break;
}
 
-   if (i >= edid->extensions)
+   if (i >= ext_blk_num)
return NULL;
 
*ext_index = i + 1;
@@ -3384,14 +3384,15 @@ const u8 *drm_find_edid_extension(const struct edid 
*edid,
return edid_ext;
 }
 
-static const u8 *drm_find_cea_extension(const struct edid *edid, int 
*ext_index)
+static const u8 *drm_find_cea_extension(const struct edid *edid,
+   int *ext_index, int ext_blk_num)
 {
const struct displayid_block *block;
struct displayid_iter iter;
const u8 *cea;
 
/* Look for a CEA extension block from ext_index */
-   cea = drm_find_edid_extension(edid, CEA_EXT, ext_index);
+   cea = drm_find_edid_extension(edid, CEA_EXT, ext_index, ext_blk_num);
if (cea)
return cea;
 
@@ -3676,7 +3677,7 @@ add_alternate_cea_modes(struct drm_connector *connector, 
struct edid *edid)
int modes = 0, ext_index = 0;
 
/* Don't add CEA modes if the CEA extension block is missing */
-   if (!drm_find_cea_extension(edid, _index))
+   if (!drm_find_cea_extension(edid, _index, edid->extensions))
return 0;
 
/*
@@ -4328,7 +4329,7 @@ size_t drm_edid_read_hf_eeodb_blk_count(const struct edid 
*edid)
int i, start, end, ext_index = 0;
 
if (edid->extensions) {
-   cea = drm_find_cea_extension(edid, _index);
+   cea = drm_find_cea_extension(edid, _index, 
edid->extensions);
 
if (cea && !cea_db_offsets(cea, , ))
for_each_cea_db(cea, i, start, end)
@@ -4384,13 +4385,17 @@ static int
 add_cea_modes(struct drm_connector *connector, struct edid *edid)
 {
int modes = 0, ext_index = 0;
+   int ext_blk_num = drm_edid_read_hf_eeodb_blk_count(edid);
+
+   if (!ext_blk_num)
+   ext_blk_num = edid->extensions;
 
for (;;) {
const u8 *cea, *db, *hdmi = NULL, *video = NULL;
u8 dbl, hdmi_len = 0, video_len = 0;
int i, start, end;
 
-   cea = drm_find_cea_extension(edid, _index);
+   cea = drm_find_cea_extension(edid, _index, ext_blk_num);
if (!cea)
break;
 
@@ -4639,7 +4644,7 @@ static void drm_edid_to_eld(struct drm_connector 
*connector, struct edid *edid)
if (!edid)
return;
 
-   cea = drm_find_cea_extension(edid, _index);
+   cea = drm_find_cea_extension(edid, _index, edid->extensions);
if (!cea) {

[Intel-gfx] [v6 3/5] drm/edid: read HF-EEODB ext block

2022-03-10 Thread Lee Shawn C
According to HDMI 2.1 spec.

"The HDMI Forum EDID Extension Override Data Block (HF-EEODB)
is utilized by Sink Devices to provide an alternate method to
indicate an EDID Extension Block count larger than 1, while
avoiding the need to present a VESA Block Map in the first
E-EDID Extension Block."

It is a mandatory for HDMI 2.1 protocol compliance as well.
This patch help to know how many HF_EEODB blocks report by sink
and read allo HF_EEODB blocks back.

v2: support to find CEA block, check EEODB block format, and return
available block number in drm_edid_read_hf_eeodb_blk_count().

Cc: Jani Nikula 
Cc: Ville Syrjala 
Cc: Ankit Nautiyal 
Cc: intel-gfx 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/drm_connector.c |  8 +++-
 drivers/gpu/drm/drm_edid.c  | 71 +++--
 include/drm/drm_edid.h  |  2 +-
 3 files changed, 74 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index a50c82bc2b2f..16011023c12e 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -2129,7 +2129,7 @@ int drm_connector_update_edid_property(struct 
drm_connector *connector,
   const struct edid *edid)
 {
struct drm_device *dev = connector->dev;
-   size_t size = 0;
+   size_t size = 0, hf_eeodb_blk_count;
int ret;
const struct edid *old_edid;
 
@@ -2137,8 +2137,12 @@ int drm_connector_update_edid_property(struct 
drm_connector *connector,
if (connector->override_edid)
return 0;
 
-   if (edid)
+   if (edid) {
size = EDID_LENGTH * (1 + edid->extensions);
+   hf_eeodb_blk_count = drm_edid_read_hf_eeodb_blk_count(edid);
+   if (hf_eeodb_blk_count)
+   size = EDID_LENGTH * (1 + hf_eeodb_blk_count);
+   }
 
/* Set the display info, using edid if available, otherwise
 * resetting the values to defaults. This duplicates the work
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 7717bf86c07d..9f7fcecae3a2 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1992,6 +1992,7 @@ struct edid *drm_do_get_edid(struct drm_connector 
*connector,
 {
int i, j = 0, valid_extensions = 0;
u8 *edid, *new;
+   size_t hf_eeodb_blk_count;
struct edid *override;
 
override = drm_get_override_edid(connector);
@@ -2051,7 +2052,35 @@ struct edid *drm_do_get_edid(struct drm_connector 
*connector,
}
 
kfree(edid);
+   return (struct edid *)new;
+   }
+
+   hf_eeodb_blk_count = drm_edid_read_hf_eeodb_blk_count((struct edid 
*)edid);
+   if (hf_eeodb_blk_count >= 2) {
+   new = krealloc(edid, (hf_eeodb_blk_count + 1) * EDID_LENGTH, 
GFP_KERNEL);
+   if (!new)
+   goto out;
edid = new;
+
+   valid_extensions = hf_eeodb_blk_count - 1;
+   for (j = 2; j <= hf_eeodb_blk_count; j++) {
+   u8 *block = edid + j * EDID_LENGTH;
+
+   for (i = 0; i < 4; i++) {
+   if (get_edid_block(data, block, j, EDID_LENGTH))
+   goto out;
+   if (drm_edid_block_valid(block, j, false, NULL))
+   break;
+   }
+
+   if (i == 4)
+   valid_extensions--;
+   }
+
+   if (valid_extensions != hf_eeodb_blk_count - 1) {
+   DRM_ERROR("Not able to retrieve proper EDID contain 
HF-EEODB data.\n");
+   goto out;
+   }
}
 
return (struct edid *)edid;
@@ -3315,15 +3344,17 @@ add_detailed_modes(struct drm_connector *connector, 
struct edid *edid,
 #define VIDEO_BLOCK 0x02
 #define VENDOR_BLOCK0x03
 #define SPEAKER_BLOCK  0x04
-#define HDR_STATIC_METADATA_BLOCK  0x6
-#define USE_EXTENDED_TAG 0x07
-#define EXT_VIDEO_CAPABILITY_BLOCK 0x00
+#define EXT_VIDEO_CAPABILITY_BLOCK 0x00
+#define HDR_STATIC_METADATA_BLOCK  0x06
+#define USE_EXTENDED_TAG   0x07
 #define EXT_VIDEO_DATA_BLOCK_420   0x0E
-#define EXT_VIDEO_CAP_BLOCK_Y420CMDB 0x0F
+#define EXT_VIDEO_CAP_BLOCK_Y420CMDB   0x0F
+#define EXT_VIDEO_HF_EEODB_DATA_BLOCK  0x78
 #define EDID_BASIC_AUDIO   (1 << 6)
 #define EDID_CEA_YCRCB444  (1 << 5)
 #define EDID_CEA_YCRCB422  (1 << 4)
 #define EDID_CEA_VCDB_QS   (1 << 6)
+#define HF_EEODB_LENGTH2
 
 /*
  * Search EDID for CEA extension block.
@@ -4274,9 +4305,41 @@ static bool cea_db_is_y420vdb(const u8 *db)
return true;
 }
 
+static bool cea_db_is_hdmi_forum_eeodb(const u8 *db)
+{
+   if (ce

[Intel-gfx] [v6 1/5] drm/edid: seek for available CEA block from specific EDID block index

2022-03-10 Thread Lee Shawn C
drm_find_cea_extension() always look for a top level CEA block. Pass
ext_index from caller then this function to search next available
CEA ext block from a specific EDID block pointer.

v2: save proper extension block index if CTA data information
was found in DispalyID block.

Cc: Jani Nikula 
Cc: Ville Syrjala 
Cc: Ankit Nautiyal 
Cc: intel-gfx 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/drm_edid.c | 43 +++---
 1 file changed, 21 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 561f53831e29..e267d31d5c87 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3353,16 +3353,14 @@ const u8 *drm_find_edid_extension(const struct edid 
*edid,
return edid_ext;
 }
 
-static const u8 *drm_find_cea_extension(const struct edid *edid)
+static const u8 *drm_find_cea_extension(const struct edid *edid, int 
*ext_index)
 {
const struct displayid_block *block;
struct displayid_iter iter;
const u8 *cea;
-   int ext_index = 0;
 
-   /* Look for a top level CEA extension block */
-   /* FIXME: make callers iterate through multiple CEA ext blocks? */
-   cea = drm_find_edid_extension(edid, CEA_EXT, _index);
+   /* Look for a CEA extension block from ext_index */
+   cea = drm_find_edid_extension(edid, CEA_EXT, ext_index);
if (cea)
return cea;
 
@@ -3370,6 +3368,7 @@ static const u8 *drm_find_cea_extension(const struct edid 
*edid)
displayid_iter_edid_begin(edid, );
displayid_iter_for_each(block, ) {
if (block->tag == DATA_BLOCK_CTA) {
+   *ext_index = iter.ext_index;
cea = (const u8 *)block;
break;
}
@@ -3643,10 +3642,10 @@ add_alternate_cea_modes(struct drm_connector 
*connector, struct edid *edid)
struct drm_device *dev = connector->dev;
struct drm_display_mode *mode, *tmp;
LIST_HEAD(list);
-   int modes = 0;
+   int modes = 0, ext_index = 0;
 
/* Don't add CEA modes if the CEA extension block is missing */
-   if (!drm_find_cea_extension(edid))
+   if (!drm_find_cea_extension(edid, _index))
return 0;
 
/*
@@ -4321,11 +4320,11 @@ static void drm_parse_y420cmdb_bitmap(struct 
drm_connector *connector,
 static int
 add_cea_modes(struct drm_connector *connector, struct edid *edid)
 {
-   const u8 *cea = drm_find_cea_extension(edid);
-   const u8 *db, *hdmi = NULL, *video = NULL;
+   const u8 *cea, *db, *hdmi = NULL, *video = NULL;
u8 dbl, hdmi_len, video_len = 0;
-   int modes = 0;
+   int modes = 0, ext_index = 0;
 
+   cea = drm_find_cea_extension(edid, _index);
if (cea && cea_revision(cea) >= 3) {
int i, start, end;
 
@@ -4562,7 +4561,7 @@ static void drm_edid_to_eld(struct drm_connector 
*connector, struct edid *edid)
uint8_t *eld = connector->eld;
const u8 *cea;
const u8 *db;
-   int total_sad_count = 0;
+   int total_sad_count = 0, ext_index = 0;
int mnl;
int dbl;
 
@@ -4571,7 +4570,7 @@ static void drm_edid_to_eld(struct drm_connector 
*connector, struct edid *edid)
if (!edid)
return;
 
-   cea = drm_find_cea_extension(edid);
+   cea = drm_find_cea_extension(edid, _index);
if (!cea) {
DRM_DEBUG_KMS("ELD: no CEA Extension found\n");
return;
@@ -4655,11 +4654,11 @@ static void drm_edid_to_eld(struct drm_connector 
*connector, struct edid *edid)
  */
 int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads)
 {
-   int count = 0;
+   int count = 0, ext_index = 0;
int i, start, end, dbl;
const u8 *cea;
 
-   cea = drm_find_cea_extension(edid);
+   cea = drm_find_cea_extension(edid, _index);
if (!cea) {
DRM_DEBUG_KMS("SAD: no CEA Extension found\n");
return 0;
@@ -4717,11 +4716,11 @@ EXPORT_SYMBOL(drm_edid_to_sad);
  */
 int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb)
 {
-   int count = 0;
+   int count = 0, ext_index = 0;
int i, start, end, dbl;
const u8 *cea;
 
-   cea = drm_find_cea_extension(edid);
+   cea = drm_find_cea_extension(edid, _index);
if (!cea) {
DRM_DEBUG_KMS("SAD: no CEA Extension found\n");
return 0;
@@ -4814,9 +4813,9 @@ bool drm_detect_hdmi_monitor(struct edid *edid)
 {
const u8 *edid_ext;
int i;
-   int start_offset, end_offset;
+   int start_offset, end_offset, ext_index = 0;
 
-   edid_ext = drm_find_cea_extension(edid);
+   edid_ext = drm_find_cea_extension(edid, _index);
if (!edid_ext)
return false;
 
@@ -4853,9 +4852,9 @@ bool drm_detect_monitor_audio(struct edid *

[Intel-gfx] [v6 0/5] enhanced edid driver compatibility

2022-03-10 Thread Lee Shawn C
Support to parse multiple CEA extension blocks and HF-EEODB to
extend drm edid driver's capability.

v4: add one more patch to support HF-SCDB
v5: HF-SCDB and HF-VSDBS carry the same SCDS data. Reuse
drm_parse_hdmi_forum_vsdb() to parse this packet.
v6: save proper extension block index if CTA data information
was found in DispalyID block.

Lee Shawn C (5):
  drm/edid: seek for available CEA block from specific EDID block index
  drm/edid: parse multiple CEA extension block
  drm/edid: read HF-EEODB ext block
  drm/edid: parse HF-EEODB CEA extension block
  drm/edid: check for HF-SCDB block

 drivers/gpu/drm/drm_connector.c |   8 +-
 drivers/gpu/drm/drm_displayid.c |   5 +-
 drivers/gpu/drm/drm_edid.c  | 173 
 include/drm/drm_edid.h  |   4 +-
 4 files changed, 143 insertions(+), 47 deletions(-)

-- 
2.17.1



[Intel-gfx] [v5 5/5] drm/edid: check for HF-SCDB block

2022-03-10 Thread Lee Shawn C
Find HF-SCDB information in CEA extensions block. And retrieve
Max_TMDS_Character_Rate that support by sink device.

v2: HF-SCDB and HF-VSDBS carry the same SCDS data. Reuse
drm_parse_hdmi_forum_vsdb() to parse this packet.

Cc: Jani Nikula 
Cc: Ville Syrjala 
Cc: Ankit Nautiyal 
Cc: intel-gfx 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/drm_edid.c | 18 +-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 1da1239c21cb..f1d5180ee5a9 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3350,6 +3350,7 @@ add_detailed_modes(struct drm_connector *connector, 
struct edid *edid,
 #define EXT_VIDEO_DATA_BLOCK_420   0x0E
 #define EXT_VIDEO_CAP_BLOCK_Y420CMDB   0x0F
 #define EXT_VIDEO_HF_EEODB_DATA_BLOCK  0x78
+#define EXT_VIDEO_HF_SCDB_DATA_BLOCK   0x79
 #define EDID_BASIC_AUDIO   (1 << 6)
 #define EDID_CEA_YCRCB444  (1 << 5)
 #define EDID_CEA_YCRCB422  (1 << 4)
@@ -4277,6 +4278,20 @@ static bool cea_db_is_vcdb(const u8 *db)
return true;
 }
 
+static bool cea_db_is_hdmi_forum_scdb(const u8 *db)
+{
+   if (cea_db_tag(db) != USE_EXTENDED_TAG)
+   return false;
+
+   if (cea_db_payload_len(db) < 7)
+   return false;
+
+   if (cea_db_extended_tag(db) != EXT_VIDEO_HF_SCDB_DATA_BLOCK)
+   return false;
+
+   return true;
+}
+
 static bool cea_db_is_y420cmdb(const u8 *db)
 {
if (cea_db_tag(db) != USE_EXTENDED_TAG)
@@ -5272,7 +5287,8 @@ static void drm_parse_cea_ext(struct drm_connector 
*connector,
 
if (cea_db_is_hdmi_vsdb(db))
drm_parse_hdmi_vsdb_video(connector, db);
-   if (cea_db_is_hdmi_forum_vsdb(db))
+   if (cea_db_is_hdmi_forum_vsdb(db) ||
+   cea_db_is_hdmi_forum_scdb(db))
drm_parse_hdmi_forum_vsdb(connector, db);
if (cea_db_is_microsoft_vsdb(db))
drm_parse_microsoft_vsdb(connector, db);
-- 
2.31.1



[Intel-gfx] [v5 4/5] drm/edid: parse HF-EEODB CEA extension block

2022-03-10 Thread Lee Shawn C
While adding CEA modes, try to get available EEODB block
number. Then based on it to parse numbers of ext blocks,
retrieve CEA information and add more CEA modes.

Cc: Jani Nikula 
Cc: Ville Syrjala 
Cc: Ankit Nautiyal 
Cc: intel-gfx 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/drm_displayid.c |  5 -
 drivers/gpu/drm/drm_edid.c  | 35 +++--
 include/drm/drm_edid.h  |  2 +-
 3 files changed, 25 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/drm_displayid.c b/drivers/gpu/drm/drm_displayid.c
index 32da557b960f..dc649a9efaa2 100644
--- a/drivers/gpu/drm/drm_displayid.c
+++ b/drivers/gpu/drm/drm_displayid.c
@@ -37,7 +37,10 @@ static const u8 *drm_find_displayid_extension(const struct 
edid *edid,
  int *length, int *idx,
  int *ext_index)
 {
-   const u8 *displayid = drm_find_edid_extension(edid, DISPLAYID_EXT, 
ext_index);
+   const u8 *displayid = drm_find_edid_extension(edid,
+ DISPLAYID_EXT,
+ ext_index,
+ edid->extensions);
const struct displayid_header *base;
int ret;
 
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 38b041c8b4ad..1da1239c21cb 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3360,23 +3360,23 @@ add_detailed_modes(struct drm_connector *connector, 
struct edid *edid,
  * Search EDID for CEA extension block.
  */
 const u8 *drm_find_edid_extension(const struct edid *edid,
- int ext_id, int *ext_index)
+ int ext_id, int *ext_index, int ext_blk_num)
 {
const u8 *edid_ext = NULL;
int i;
 
/* No EDID or EDID extensions */
-   if (edid == NULL || edid->extensions == 0)
+   if (edid == NULL || edid->extensions == 0 || *ext_index >= ext_blk_num)
return NULL;
 
/* Find CEA extension */
-   for (i = *ext_index; i < edid->extensions; i++) {
+   for (i = *ext_index; i < ext_blk_num; i++) {
edid_ext = (const u8 *)edid + EDID_LENGTH * (i + 1);
if (edid_ext[0] == ext_id)
break;
}
 
-   if (i >= edid->extensions)
+   if (i >= ext_blk_num)
return NULL;
 
*ext_index = i + 1;
@@ -3384,14 +3384,15 @@ const u8 *drm_find_edid_extension(const struct edid 
*edid,
return edid_ext;
 }
 
-static const u8 *drm_find_cea_extension(const struct edid *edid, int 
*ext_index)
+static const u8 *drm_find_cea_extension(const struct edid *edid,
+   int *ext_index, int ext_blk_num)
 {
const struct displayid_block *block;
struct displayid_iter iter;
const u8 *cea;
 
/* Look for a CEA extension block from ext_index */
-   cea = drm_find_edid_extension(edid, CEA_EXT, ext_index);
+   cea = drm_find_edid_extension(edid, CEA_EXT, ext_index, ext_blk_num);
if (cea)
return cea;
 
@@ -3675,7 +3676,7 @@ add_alternate_cea_modes(struct drm_connector *connector, 
struct edid *edid)
int modes = 0, ext_index = 0;
 
/* Don't add CEA modes if the CEA extension block is missing */
-   if (!drm_find_cea_extension(edid, _index))
+   if (!drm_find_cea_extension(edid, _index, edid->extensions))
return 0;
 
/*
@@ -4327,7 +4328,7 @@ size_t drm_edid_read_hf_eeodb_blk_count(const struct edid 
*edid)
int i, start, end, ext_index = 0;
 
if (edid->extensions) {
-   cea = drm_find_cea_extension(edid, _index);
+   cea = drm_find_cea_extension(edid, _index, 
edid->extensions);
 
if (cea && !cea_db_offsets(cea, , ))
for_each_cea_db(cea, i, start, end)
@@ -4383,13 +4384,17 @@ static int
 add_cea_modes(struct drm_connector *connector, struct edid *edid)
 {
int modes = 0, ext_index = 0;
+   int ext_blk_num = drm_edid_read_hf_eeodb_blk_count(edid);
+
+   if (!ext_blk_num)
+   ext_blk_num = edid->extensions;
 
for (;;) {
const u8 *cea, *db, *hdmi = NULL, *video = NULL;
u8 dbl, hdmi_len = 0, video_len = 0;
int i, start, end;
 
-   cea = drm_find_cea_extension(edid, _index);
+   cea = drm_find_cea_extension(edid, _index, ext_blk_num);
if (!cea)
break;
 
@@ -4638,7 +4643,7 @@ static void drm_edid_to_eld(struct drm_connector 
*connector, struct edid *edid)
if (!edid)
return;
 
-   cea = drm_find_cea_extension(edid, _index);
+   cea = drm_find_cea_extension(edid, _index, edid->extensions);
if (!cea) {

[Intel-gfx] [v5 3/5] drm/edid: read HF-EEODB ext block

2022-03-10 Thread Lee Shawn C
According to HDMI 2.1 spec.

"The HDMI Forum EDID Extension Override Data Block (HF-EEODB)
is utilized by Sink Devices to provide an alternate method to
indicate an EDID Extension Block count larger than 1, while
avoiding the need to present a VESA Block Map in the first
E-EDID Extension Block."

It is a mandatory for HDMI 2.1 protocol compliance as well.
This patch help to know how many HF_EEODB blocks report by sink
and read allo HF_EEODB blocks back.

v2: support to find CEA block, check EEODB block format, and return
available block number in drm_edid_read_hf_eeodb_blk_count().

Cc: Jani Nikula 
Cc: Ville Syrjala 
Cc: Ankit Nautiyal 
Cc: intel-gfx 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/drm_connector.c |  8 +++-
 drivers/gpu/drm/drm_edid.c  | 71 +++--
 include/drm/drm_edid.h  |  2 +-
 3 files changed, 74 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index a50c82bc2b2f..16011023c12e 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -2129,7 +2129,7 @@ int drm_connector_update_edid_property(struct 
drm_connector *connector,
   const struct edid *edid)
 {
struct drm_device *dev = connector->dev;
-   size_t size = 0;
+   size_t size = 0, hf_eeodb_blk_count;
int ret;
const struct edid *old_edid;
 
@@ -2137,8 +2137,12 @@ int drm_connector_update_edid_property(struct 
drm_connector *connector,
if (connector->override_edid)
return 0;
 
-   if (edid)
+   if (edid) {
size = EDID_LENGTH * (1 + edid->extensions);
+   hf_eeodb_blk_count = drm_edid_read_hf_eeodb_blk_count(edid);
+   if (hf_eeodb_blk_count)
+   size = EDID_LENGTH * (1 + hf_eeodb_blk_count);
+   }
 
/* Set the display info, using edid if available, otherwise
 * resetting the values to defaults. This duplicates the work
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 7b672166fab4..38b041c8b4ad 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1992,6 +1992,7 @@ struct edid *drm_do_get_edid(struct drm_connector 
*connector,
 {
int i, j = 0, valid_extensions = 0;
u8 *edid, *new;
+   size_t hf_eeodb_blk_count;
struct edid *override;
 
override = drm_get_override_edid(connector);
@@ -2051,7 +2052,35 @@ struct edid *drm_do_get_edid(struct drm_connector 
*connector,
}
 
kfree(edid);
+   return (struct edid *)new;
+   }
+
+   hf_eeodb_blk_count = drm_edid_read_hf_eeodb_blk_count((struct edid 
*)edid);
+   if (hf_eeodb_blk_count >= 2) {
+   new = krealloc(edid, (hf_eeodb_blk_count + 1) * EDID_LENGTH, 
GFP_KERNEL);
+   if (!new)
+   goto out;
edid = new;
+
+   valid_extensions = hf_eeodb_blk_count - 1;
+   for (j = 2; j <= hf_eeodb_blk_count; j++) {
+   u8 *block = edid + j * EDID_LENGTH;
+
+   for (i = 0; i < 4; i++) {
+   if (get_edid_block(data, block, j, EDID_LENGTH))
+   goto out;
+   if (drm_edid_block_valid(block, j, false, NULL))
+   break;
+   }
+
+   if (i == 4)
+   valid_extensions--;
+   }
+
+   if (valid_extensions != hf_eeodb_blk_count - 1) {
+   DRM_ERROR("Not able to retrieve proper EDID contain 
HF-EEODB data.\n");
+   goto out;
+   }
}
 
return (struct edid *)edid;
@@ -3315,15 +3344,17 @@ add_detailed_modes(struct drm_connector *connector, 
struct edid *edid,
 #define VIDEO_BLOCK 0x02
 #define VENDOR_BLOCK0x03
 #define SPEAKER_BLOCK  0x04
-#define HDR_STATIC_METADATA_BLOCK  0x6
-#define USE_EXTENDED_TAG 0x07
-#define EXT_VIDEO_CAPABILITY_BLOCK 0x00
+#define EXT_VIDEO_CAPABILITY_BLOCK 0x00
+#define HDR_STATIC_METADATA_BLOCK  0x06
+#define USE_EXTENDED_TAG   0x07
 #define EXT_VIDEO_DATA_BLOCK_420   0x0E
-#define EXT_VIDEO_CAP_BLOCK_Y420CMDB 0x0F
+#define EXT_VIDEO_CAP_BLOCK_Y420CMDB   0x0F
+#define EXT_VIDEO_HF_EEODB_DATA_BLOCK  0x78
 #define EDID_BASIC_AUDIO   (1 << 6)
 #define EDID_CEA_YCRCB444  (1 << 5)
 #define EDID_CEA_YCRCB422  (1 << 4)
 #define EDID_CEA_VCDB_QS   (1 << 6)
+#define HF_EEODB_LENGTH2
 
 /*
  * Search EDID for CEA extension block.
@@ -4273,9 +4304,41 @@ static bool cea_db_is_y420vdb(const u8 *db)
return true;
 }
 
+static bool cea_db_is_hdmi_forum_eeodb(const u8 *db)
+{
+   if (ce

[Intel-gfx] [v5 2/5] drm/edid: parse multiple CEA extension block

2022-03-10 Thread Lee Shawn C
Try to find and parse more CEA ext blocks if edid->extensions
is greater than one.

v2: split prvious patch to two. And do CEA block parsing
in this one.
v3: simplify this patch based on previous change.
v4: refine patch v3.

Cc: Jani Nikula 
Cc: Ville Syrjala 
Cc: Ankit Nautiyal 
Cc: intel-gfx 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/drm_edid.c | 32 +++-
 1 file changed, 19 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 1251226d9284..7b672166fab4 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4319,16 +4319,22 @@ static void drm_parse_y420cmdb_bitmap(struct 
drm_connector *connector,
 static int
 add_cea_modes(struct drm_connector *connector, struct edid *edid)
 {
-   const u8 *cea, *db, *hdmi = NULL, *video = NULL;
-   u8 dbl, hdmi_len, video_len = 0;
int modes = 0, ext_index = 0;
 
-   cea = drm_find_cea_extension(edid, _index);
-   if (cea && cea_revision(cea) >= 3) {
+   for (;;) {
+   const u8 *cea, *db, *hdmi = NULL, *video = NULL;
+   u8 dbl, hdmi_len = 0, video_len = 0;
int i, start, end;
 
+   cea = drm_find_cea_extension(edid, _index);
+   if (!cea)
+   break;
+
+   if (cea_revision(cea) < 3)
+   continue;
+
if (cea_db_offsets(cea, , ))
-   return 0;
+   continue;
 
for_each_cea_db(cea, i, start, end) {
db = [i];
@@ -4350,15 +4356,15 @@ add_cea_modes(struct drm_connector *connector, struct 
edid *edid)
  dbl - 1);
}
}
-   }
 
-   /*
-* We parse the HDMI VSDB after having added the cea modes as we will
-* be patching their flags when the sink supports stereo 3D.
-*/
-   if (hdmi)
-   modes += do_hdmi_vsdb_modes(connector, hdmi, hdmi_len, video,
-   video_len);
+   /*
+* We parse the HDMI VSDB after having added the cea modes as 
we will
+* be patching their flags when the sink supports stereo 3D.
+*/
+   if (hdmi)
+   modes += do_hdmi_vsdb_modes(connector, hdmi, hdmi_len, 
video,
+   video_len);
+   }
 
return modes;
 }
-- 
2.31.1



[Intel-gfx] [v5 1/5] drm/edid: seek for available CEA block from specific EDID block index

2022-03-10 Thread Lee Shawn C
drm_find_cea_extension() always look for a top level CEA block. Pass
ext_index from caller then this function to search next available
CEA ext block from a specific EDID block pointer.

Cc: Jani Nikula 
Cc: Ville Syrjala 
Cc: Ankit Nautiyal 
Cc: intel-gfx 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/drm_edid.c | 42 ++
 1 file changed, 20 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 561f53831e29..1251226d9284 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3353,16 +3353,14 @@ const u8 *drm_find_edid_extension(const struct edid 
*edid,
return edid_ext;
 }
 
-static const u8 *drm_find_cea_extension(const struct edid *edid)
+static const u8 *drm_find_cea_extension(const struct edid *edid, int 
*ext_index)
 {
const struct displayid_block *block;
struct displayid_iter iter;
const u8 *cea;
-   int ext_index = 0;
 
-   /* Look for a top level CEA extension block */
-   /* FIXME: make callers iterate through multiple CEA ext blocks? */
-   cea = drm_find_edid_extension(edid, CEA_EXT, _index);
+   /* Look for a CEA extension block from ext_index */
+   cea = drm_find_edid_extension(edid, CEA_EXT, ext_index);
if (cea)
return cea;
 
@@ -3643,10 +3641,10 @@ add_alternate_cea_modes(struct drm_connector 
*connector, struct edid *edid)
struct drm_device *dev = connector->dev;
struct drm_display_mode *mode, *tmp;
LIST_HEAD(list);
-   int modes = 0;
+   int modes = 0, ext_index = 0;
 
/* Don't add CEA modes if the CEA extension block is missing */
-   if (!drm_find_cea_extension(edid))
+   if (!drm_find_cea_extension(edid, _index))
return 0;
 
/*
@@ -4321,11 +4319,11 @@ static void drm_parse_y420cmdb_bitmap(struct 
drm_connector *connector,
 static int
 add_cea_modes(struct drm_connector *connector, struct edid *edid)
 {
-   const u8 *cea = drm_find_cea_extension(edid);
-   const u8 *db, *hdmi = NULL, *video = NULL;
+   const u8 *cea, *db, *hdmi = NULL, *video = NULL;
u8 dbl, hdmi_len, video_len = 0;
-   int modes = 0;
+   int modes = 0, ext_index = 0;
 
+   cea = drm_find_cea_extension(edid, _index);
if (cea && cea_revision(cea) >= 3) {
int i, start, end;
 
@@ -4562,7 +4560,7 @@ static void drm_edid_to_eld(struct drm_connector 
*connector, struct edid *edid)
uint8_t *eld = connector->eld;
const u8 *cea;
const u8 *db;
-   int total_sad_count = 0;
+   int total_sad_count = 0, ext_index = 0;
int mnl;
int dbl;
 
@@ -4571,7 +4569,7 @@ static void drm_edid_to_eld(struct drm_connector 
*connector, struct edid *edid)
if (!edid)
return;
 
-   cea = drm_find_cea_extension(edid);
+   cea = drm_find_cea_extension(edid, _index);
if (!cea) {
DRM_DEBUG_KMS("ELD: no CEA Extension found\n");
return;
@@ -4655,11 +4653,11 @@ static void drm_edid_to_eld(struct drm_connector 
*connector, struct edid *edid)
  */
 int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads)
 {
-   int count = 0;
+   int count = 0, ext_index = 0;
int i, start, end, dbl;
const u8 *cea;
 
-   cea = drm_find_cea_extension(edid);
+   cea = drm_find_cea_extension(edid, _index);
if (!cea) {
DRM_DEBUG_KMS("SAD: no CEA Extension found\n");
return 0;
@@ -4717,11 +4715,11 @@ EXPORT_SYMBOL(drm_edid_to_sad);
  */
 int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb)
 {
-   int count = 0;
+   int count = 0, ext_index = 0;
int i, start, end, dbl;
const u8 *cea;
 
-   cea = drm_find_cea_extension(edid);
+   cea = drm_find_cea_extension(edid, _index);
if (!cea) {
DRM_DEBUG_KMS("SAD: no CEA Extension found\n");
return 0;
@@ -4814,9 +4812,9 @@ bool drm_detect_hdmi_monitor(struct edid *edid)
 {
const u8 *edid_ext;
int i;
-   int start_offset, end_offset;
+   int start_offset, end_offset, ext_index = 0;
 
-   edid_ext = drm_find_cea_extension(edid);
+   edid_ext = drm_find_cea_extension(edid, _index);
if (!edid_ext)
return false;
 
@@ -4853,9 +4851,9 @@ bool drm_detect_monitor_audio(struct edid *edid)
const u8 *edid_ext;
int i, j;
bool has_audio = false;
-   int start_offset, end_offset;
+   int start_offset, end_offset, ext_index = 0;
 
-   edid_ext = drm_find_cea_extension(edid);
+   edid_ext = drm_find_cea_extension(edid, _index);
if (!edid_ext)
goto end;
 
@@ -5177,9 +5175,9 @@ static void drm_parse_cea_ext(struct drm_connector 
*connector,
 {
struct drm_display_info *info = >display_info;
   

[Intel-gfx] [v5 0/5] enhanced edid driver compatibility

2022-03-10 Thread Lee Shawn C
Support to parse multiple CEA extension blocks and HF-EEODB to
extend drm edid driver's capability.

v4: add one more patch to support HF-SCDB
v5: HF-SCDB and HF-VSDBS carry the same SCDS data. Reuse
drm_parse_hdmi_forum_vsdb() to parse this packet.

Lee Shawn C (5):
  drm/edid: seek for available CEA block from specific EDID block index
  drm/edid: parse multiple CEA extension block
  drm/edid: read HF-EEODB ext block
  drm/edid: parse HF-EEODB CEA extension block
  drm/edid: check for HF-SCDB block

 drivers/gpu/drm/drm_connector.c |   8 +-
 drivers/gpu/drm/drm_displayid.c |   5 +-
 drivers/gpu/drm/drm_edid.c  | 172 
 include/drm/drm_edid.h  |   4 +-
 4 files changed, 142 insertions(+), 47 deletions(-)

-- 
2.31.1



[Intel-gfx] [v2] drm/i915: update new TMDS clock setting defined by VBT

2022-03-03 Thread Lee Shawn C
VBT 249 update to support more TMDS clock rate 3.00G, 3.40G
and 5.94G. Refer to this new definition to configure max
TMDS clock rate for HDMI driver.

BSpec: 20124

v2: new subject

Cc: Jani Nikula 
Cc: Ville Syrjala 
Cc: Ankit Nautiyal 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/i915/display/intel_bios.c | 6 ++
 drivers/gpu/drm/i915/display/intel_vbt_defs.h | 3 +++
 2 files changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_bios.c 
b/drivers/gpu/drm/i915/display/intel_bios.c
index 40b5e7ed12c2..a559a1914588 100644
--- a/drivers/gpu/drm/i915/display/intel_bios.c
+++ b/drivers/gpu/drm/i915/display/intel_bios.c
@@ -1955,6 +1955,12 @@ static int _intel_bios_max_tmds_clock(const struct 
intel_bios_encoder_data *devd
fallthrough;
case HDMI_MAX_DATA_RATE_PLATFORM:
return 0;
+   case HDMI_MAX_DATA_RATE_594:
+   return 594000;
+   case HDMI_MAX_DATA_RATE_340:
+   return 34;
+   case HDMI_MAX_DATA_RATE_300:
+   return 30;
case HDMI_MAX_DATA_RATE_297:
return 297000;
case HDMI_MAX_DATA_RATE_165:
diff --git a/drivers/gpu/drm/i915/display/intel_vbt_defs.h 
b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
index b9397d9363c5..e0508990df48 100644
--- a/drivers/gpu/drm/i915/display/intel_vbt_defs.h
+++ b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
@@ -289,6 +289,9 @@ struct bdb_general_features {
 #define HDMI_MAX_DATA_RATE_PLATFORM0   /* 204 */
 #define HDMI_MAX_DATA_RATE_297 1   /* 204 */
 #define HDMI_MAX_DATA_RATE_165 2   /* 204 */
+#define HDMI_MAX_DATA_RATE_594 3   /* 249 */
+#define HDMI_MAX_DATA_RATE_340 4   /* 249 */
+#define HDMI_MAX_DATA_RATE_300 5   /* 249 */
 
 #define LEGACY_CHILD_DEVICE_CONFIG_SIZE33
 
-- 
2.17.1



[Intel-gfx] [PATCH] drm/i915: add more TMDS clock rate supported by HDMI driver

2022-02-28 Thread Lee Shawn C
VBT 249 update to support more TMDS clock rate 3.00G, 3.40G
and 5.94G. Refer to this new definition to configure max
TMDS clock rate for HDMI driver.

BSpec: 20124

Cc: Jani Nikula 
Cc: Ville Syrjala 
Cc: Ankit Nautiyal 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/i915/display/intel_bios.c | 6 ++
 drivers/gpu/drm/i915/display/intel_vbt_defs.h | 3 +++
 2 files changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_bios.c 
b/drivers/gpu/drm/i915/display/intel_bios.c
index 40b5e7ed12c2..a559a1914588 100644
--- a/drivers/gpu/drm/i915/display/intel_bios.c
+++ b/drivers/gpu/drm/i915/display/intel_bios.c
@@ -1955,6 +1955,12 @@ static int _intel_bios_max_tmds_clock(const struct 
intel_bios_encoder_data *devd
fallthrough;
case HDMI_MAX_DATA_RATE_PLATFORM:
return 0;
+   case HDMI_MAX_DATA_RATE_594:
+   return 594000;
+   case HDMI_MAX_DATA_RATE_340:
+   return 34;
+   case HDMI_MAX_DATA_RATE_300:
+   return 30;
case HDMI_MAX_DATA_RATE_297:
return 297000;
case HDMI_MAX_DATA_RATE_165:
diff --git a/drivers/gpu/drm/i915/display/intel_vbt_defs.h 
b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
index b9397d9363c5..e0508990df48 100644
--- a/drivers/gpu/drm/i915/display/intel_vbt_defs.h
+++ b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
@@ -289,6 +289,9 @@ struct bdb_general_features {
 #define HDMI_MAX_DATA_RATE_PLATFORM0   /* 204 */
 #define HDMI_MAX_DATA_RATE_297 1   /* 204 */
 #define HDMI_MAX_DATA_RATE_165 2   /* 204 */
+#define HDMI_MAX_DATA_RATE_594 3   /* 249 */
+#define HDMI_MAX_DATA_RATE_340 4   /* 249 */
+#define HDMI_MAX_DATA_RATE_300 5   /* 249 */
 
 #define LEGACY_CHILD_DEVICE_CONFIG_SIZE33
 
-- 
2.17.1



[Intel-gfx] [v2] drm/i915: Fix cursor coordinates on bigjoiner slave

2022-02-23 Thread Lee Shawn C
From: Ville Syrjälä 

Adjust the cursor dst coordinates appripriately when it's on
the bigjoiner slave pipe. intel_atomic_plane_check_clipping()
already did this but with the cursor we discard those results
(apart from uapi.visible and error checks) since the hardware
will be doing the clipping for us.

v2: fix compile error

Signed-off-by: Ville Syrjälä 
Signed-off-by: Lee Shawn C 
Tested-by: Lee Shawn C 
---
 drivers/gpu/drm/i915/display/intel_cursor.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c 
b/drivers/gpu/drm/i915/display/intel_cursor.c
index 2ade8fdd9bdd..3e80763aa828 100644
--- a/drivers/gpu/drm/i915/display/intel_cursor.c
+++ b/drivers/gpu/drm/i915/display/intel_cursor.c
@@ -152,6 +152,9 @@ static int intel_check_cursor(struct intel_crtc_state 
*crtc_state,
/* Use the unclipped src/dst rectangles, which we program to hw */
plane_state->uapi.src = src;
plane_state->uapi.dst = dst;
+   if (intel_crtc_is_bigjoiner_slave(crtc_state))
+   drm_rect_translate(_state->uapi.dst,
+  -crtc_state->pipe_src_w, 0);
 
ret = intel_cursor_check_surface(plane_state);
if (ret)
-- 
2.31.1



[Intel-gfx] [PATCH] drm/i915: Fix cursor coordinates on bigjoiner slave

2022-02-17 Thread Lee Shawn C
From: Ville Syrjälä 

Adjust the cursor dst coordinates appripriately when it's on
the bigjoiner slave pipe. intel_atomic_plane_check_clipping()
already did this but with the cursor we discard those results
(apart from uapi.visible and error checks) since the hardware
will be doing the clipping for us.

Signed-off-by: Ville Syrjälä 
Tested-by: Lee Shawn C 
---
 drivers/gpu/drm/i915/display/intel_cursor.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c 
b/drivers/gpu/drm/i915/display/intel_cursor.c
index 67633f9f0e4a..de5c8617f585 100644
--- a/drivers/gpu/drm/i915/display/intel_cursor.c
+++ b/drivers/gpu/drm/i915/display/intel_cursor.c
@@ -157,6 +157,9 @@ static int intel_check_cursor(struct intel_crtc_state 
*crtc_state,
/* Use the unclipped src/dst rectangles, which we program to hw */
plane_state->uapi.src = src;
plane_state->uapi.dst = dst;
+   if (crtc_state->bigjoiner_slave)
+   drm_rect_translate(_state->uapi.dst,
+  -crtc_state->pipe_src_w, 0);
 
ret = intel_cursor_check_surface(plane_state);
if (ret)
-- 
2.17.1



Re: [Intel-gfx] [PATCH] drm/i915/adl_p: Add adl-p ddc pin mapping

2021-11-22 Thread Lee, Shawn C


Hi all,

May I have your comment for this patch? Thank you!

Best regards,
Shawn

>From VBT, ddc pin info suggests the following mapping:
>VBTDRIVER
>DDI A->ddc_pin=1 should translate to PORT_A->0x1 
>DDI B->ddc_pin=2 should translate to PORT_B->0x2
>TCP 0->ddc_pin=3 should translate to PORT_TC1->0x9
>TCP 1->ddc_pin=4 should translate to PORT_TC2->0xa
>TCP 2->ddc_pin=5 should translate to PORT_TC3->0xb
>TCP 3->ddc_pin=6 should translate to PORT_TC4->0xc
>
>Adding adl_p pin map to facilitate this translation
>as we cannot use existing icl ddc pin map due to
>DDI C is not available on adl-p platform.
>
>Bspec:20124
>
>Cc: Jani Nikula 
>Cc: Ville Syrjälä 
>Cc: Imre Deak 
>Cc: Matt Roper 
>Cc: Lucas De Marchi 
>Cc: Cooper Chiou 
>Cc: William Tseng 
>Signed-off-by: Lee Shawn C 
>---
> drivers/gpu/drm/i915/display/intel_bios.c | 12 
> drivers/gpu/drm/i915/display/intel_vbt_defs.h |  6 +-
> 2 files changed, 17 insertions(+), 1 deletion(-)
>
>diff --git a/drivers/gpu/drm/i915/display/intel_bios.c 
>b/drivers/gpu/drm/i915/display/intel_bios.c
>index 2b1423a43437..c1479e61f032 100644
>--- a/drivers/gpu/drm/i915/display/intel_bios.c
>+++ b/drivers/gpu/drm/i915/display/intel_bios.c
>@@ -1549,6 +1549,15 @@ static const u8 adls_ddc_pin_map[] = {
>   [ADLS_DDC_BUS_PORT_TC4] = GMBUS_PIN_12_TC4_ICP,  };
> 
>+static const u8 adlp_ddc_pin_map[] = {
>+  [ICL_DDC_BUS_DDI_A] = GMBUS_PIN_1_BXT,
>+  [ICL_DDC_BUS_DDI_B] = GMBUS_PIN_2_BXT,
>+  [ADLP_DDC_BUS_PORT_TC1] = GMBUS_PIN_9_TC1_ICP,
>+  [ADLP_DDC_BUS_PORT_TC2] = GMBUS_PIN_10_TC2_ICP,
>+  [ADLP_DDC_BUS_PORT_TC3] = GMBUS_PIN_11_TC3_ICP,
>+  [ADLP_DDC_BUS_PORT_TC4] = GMBUS_PIN_12_TC4_ICP, };
>+
> static const u8 gen9bc_tgp_ddc_pin_map[] = {
>   [DDC_BUS_DDI_B] = GMBUS_PIN_2_BXT,
>   [DDC_BUS_DDI_C] = GMBUS_PIN_9_TC1_ICP, @@ -1563,6 +1572,9 @@ static u8 
> map_ddc_pin(struct drm_i915_private *i915, u8 vbt_pin)
>   if (IS_ALDERLAKE_S(i915)) {
>   ddc_pin_map = adls_ddc_pin_map;
>   n_entries = ARRAY_SIZE(adls_ddc_pin_map);
>+  } else if (IS_ALDERLAKE_P(i915)) {
>+  ddc_pin_map = adlp_ddc_pin_map;
>+  n_entries = ARRAY_SIZE(adlp_ddc_pin_map);
>   } else if (INTEL_PCH_TYPE(i915) >= PCH_DG1) {
>   return vbt_pin;
>   } else if (IS_ROCKETLAKE(i915) && INTEL_PCH_TYPE(i915) == PCH_TGP) { 
> diff --git a/drivers/gpu/drm/i915/display/intel_vbt_defs.h 
> b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
>index a2108a8f544d..d5be01b983f4 100644
>--- a/drivers/gpu/drm/i915/display/intel_vbt_defs.h
>+++ b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
>@@ -330,7 +330,11 @@ enum vbt_gmbus_ddi {
>   ADLS_DDC_BUS_PORT_TC1 = 0x2,
>   ADLS_DDC_BUS_PORT_TC2,
>   ADLS_DDC_BUS_PORT_TC3,
>-  ADLS_DDC_BUS_PORT_TC4
>+  ADLS_DDC_BUS_PORT_TC4,
>+  ADLP_DDC_BUS_PORT_TC1 = 0x3,
>+  ADLP_DDC_BUS_PORT_TC2,
>+  ADLP_DDC_BUS_PORT_TC3,
>+  ADLP_DDC_BUS_PORT_TC4,
> };
> 
> #define DP_AUX_A 0x40
>--
>2.17.1
>


[Intel-gfx] [PATCH] drm/i915/adl_p: Add adl-p ddc pin mapping

2021-11-16 Thread Lee Shawn C
>From VBT, ddc pin info suggests the following mapping:
VBTDRIVER
DDI A->ddc_pin=1 should translate to PORT_A->0x1
DDI B->ddc_pin=2 should translate to PORT_B->0x2
TCP 0->ddc_pin=3 should translate to PORT_TC1->0x9
TCP 1->ddc_pin=4 should translate to PORT_TC2->0xa
TCP 2->ddc_pin=5 should translate to PORT_TC3->0xb
TCP 3->ddc_pin=6 should translate to PORT_TC4->0xc

Adding adl_p pin map to facilitate this translation
as we cannot use existing icl ddc pin map due to
DDI C is not available on adl-p platform.

Bspec:20124

Cc: Jani Nikula 
Cc: Ville Syrjälä 
Cc: Imre Deak 
Cc: Matt Roper 
Cc: Lucas De Marchi 
Cc: Cooper Chiou 
Cc: William Tseng 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/i915/display/intel_bios.c | 12 
 drivers/gpu/drm/i915/display/intel_vbt_defs.h |  6 +-
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_bios.c 
b/drivers/gpu/drm/i915/display/intel_bios.c
index 2b1423a43437..c1479e61f032 100644
--- a/drivers/gpu/drm/i915/display/intel_bios.c
+++ b/drivers/gpu/drm/i915/display/intel_bios.c
@@ -1549,6 +1549,15 @@ static const u8 adls_ddc_pin_map[] = {
[ADLS_DDC_BUS_PORT_TC4] = GMBUS_PIN_12_TC4_ICP,
 };
 
+static const u8 adlp_ddc_pin_map[] = {
+   [ICL_DDC_BUS_DDI_A] = GMBUS_PIN_1_BXT,
+   [ICL_DDC_BUS_DDI_B] = GMBUS_PIN_2_BXT,
+   [ADLP_DDC_BUS_PORT_TC1] = GMBUS_PIN_9_TC1_ICP,
+   [ADLP_DDC_BUS_PORT_TC2] = GMBUS_PIN_10_TC2_ICP,
+   [ADLP_DDC_BUS_PORT_TC3] = GMBUS_PIN_11_TC3_ICP,
+   [ADLP_DDC_BUS_PORT_TC4] = GMBUS_PIN_12_TC4_ICP,
+};
+
 static const u8 gen9bc_tgp_ddc_pin_map[] = {
[DDC_BUS_DDI_B] = GMBUS_PIN_2_BXT,
[DDC_BUS_DDI_C] = GMBUS_PIN_9_TC1_ICP,
@@ -1563,6 +1572,9 @@ static u8 map_ddc_pin(struct drm_i915_private *i915, u8 
vbt_pin)
if (IS_ALDERLAKE_S(i915)) {
ddc_pin_map = adls_ddc_pin_map;
n_entries = ARRAY_SIZE(adls_ddc_pin_map);
+   } else if (IS_ALDERLAKE_P(i915)) {
+   ddc_pin_map = adlp_ddc_pin_map;
+   n_entries = ARRAY_SIZE(adlp_ddc_pin_map);
} else if (INTEL_PCH_TYPE(i915) >= PCH_DG1) {
return vbt_pin;
} else if (IS_ROCKETLAKE(i915) && INTEL_PCH_TYPE(i915) == PCH_TGP) {
diff --git a/drivers/gpu/drm/i915/display/intel_vbt_defs.h 
b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
index a2108a8f544d..d5be01b983f4 100644
--- a/drivers/gpu/drm/i915/display/intel_vbt_defs.h
+++ b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
@@ -330,7 +330,11 @@ enum vbt_gmbus_ddi {
ADLS_DDC_BUS_PORT_TC1 = 0x2,
ADLS_DDC_BUS_PORT_TC2,
ADLS_DDC_BUS_PORT_TC3,
-   ADLS_DDC_BUS_PORT_TC4
+   ADLS_DDC_BUS_PORT_TC4,
+   ADLP_DDC_BUS_PORT_TC1 = 0x3,
+   ADLP_DDC_BUS_PORT_TC2,
+   ADLP_DDC_BUS_PORT_TC3,
+   ADLP_DDC_BUS_PORT_TC4,
 };
 
 #define DP_AUX_A 0x40
-- 
2.17.1



Re: [Intel-gfx] [v4] drm/i915/dsi: do not register gmbus if it was reserved for MIPI display

2021-10-04 Thread Lee, Shawn C


Hi all, could you please share your comments for the latest patch? Thanks!

Best regards,
Shawn

>
>Gmbus driver would setup all Intel i2c GMBuses. But DDC bus may configured as 
>gpio and reserved for MIPI driver to control panel power on/off sequence.
>
>Using i2c tool to communicate to peripherals via i2c interface reversed for 
>gmbus(DDC). There will be some high/low pulse appear on DDC SCL and SDA (might 
>be host sent out i2c slave address). MIPI panel would be impacted due to 
>unexpected signal then caused abnormal display or shut down issue.
>
>v2: gmbus driver should not add i2c adapter for DDC interface
>if LFP display was configured to support MIPI panel.
>v3: fix sparse warning
>v4: before gmbus driver add/delete/access i2c adapter would
>call intel_gmbus_is_valid_pin() to know target adapter
>is available or not. Avoid to access unexisting adapter.
>Driver should check DSI status and pin's availability in
>intel_gmbus_is_valid_pin().
>
>Cc: Jani Nikula 
>Cc: Vandita Kulkarni 
>Cc: Cooper Chiou 
>Cc: William Tseng 
>Signed-off-by: Lee Shawn C 
>---
> drivers/gpu/drm/i915/display/intel_gmbus.c | 18 ++
> 1 file changed, 18 insertions(+)
>
>diff --git a/drivers/gpu/drm/i915/display/intel_gmbus.c 
>b/drivers/gpu/drm/i915/display/intel_gmbus.c
>index ceb1bf8a8c3c..852e499e2e8c 100644
>--- a/drivers/gpu/drm/i915/display/intel_gmbus.c
>+++ b/drivers/gpu/drm/i915/display/intel_gmbus.c
>@@ -118,11 +118,29 @@ static const struct gmbus_pin *get_gmbus_pin(struct 
>drm_i915_private *dev_priv,
>   return _pins[pin];
> }
> 
>+static bool intel_gmbus_ddc_reserve_for_mipi_dsi(struct drm_i915_private 
>*dev_priv,
>+   unsigned int pin)
>+{
>+  if (intel_bios_is_dsi_present(dev_priv, NULL)) {
>+  if (DISPLAY_VER(dev_priv) >= 11) {
>+  if ((pin == GMBUS_PIN_2_BXT && 
>dev_priv->vbt.dsi.config->dual_link) ||
>+   pin == GMBUS_PIN_1_BXT) {
>+  return true;
>+  }
>+  }
>+  }
>+
>+  return false;
>+}
>+
> bool intel_gmbus_is_valid_pin(struct drm_i915_private *dev_priv,
> unsigned int pin)
> {
>   unsigned int size;
> 
>+  if (intel_gmbus_ddc_reserve_for_mipi_dsi(dev_priv, pin))
>+  return false;
>+
>   if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1)
>   size = ARRAY_SIZE(gmbus_pins_dg1);
>   else if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP)
>--
>2.17.1
>


[Intel-gfx] [v4] drm/i915/dsi: do not register gmbus if it was reserved for MIPI display

2021-09-22 Thread Lee Shawn C
Gmbus driver would setup all Intel i2c GMBuses. But DDC bus
may configured as gpio and reserved for MIPI driver to control
panel power on/off sequence.

Using i2c tool to communicate to peripherals via i2c interface
reversed for gmbus(DDC). There will be some high/low pulse
appear on DDC SCL and SDA (might be host sent out i2c slave
address). MIPI panel would be impacted due to unexpected signal
then caused abnormal display or shut down issue.

v2: gmbus driver should not add i2c adapter for DDC interface
if LFP display was configured to support MIPI panel.
v3: fix sparse warning
v4: before gmbus driver add/delete/access i2c adapter would
call intel_gmbus_is_valid_pin() to know target adapter
is available or not. Avoid to access unexisting adapter.
Driver should check DSI status and pin's availability in
intel_gmbus_is_valid_pin().

Cc: Jani Nikula 
Cc: Vandita Kulkarni 
Cc: Cooper Chiou 
Cc: William Tseng 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/i915/display/intel_gmbus.c | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_gmbus.c 
b/drivers/gpu/drm/i915/display/intel_gmbus.c
index ceb1bf8a8c3c..852e499e2e8c 100644
--- a/drivers/gpu/drm/i915/display/intel_gmbus.c
+++ b/drivers/gpu/drm/i915/display/intel_gmbus.c
@@ -118,11 +118,29 @@ static const struct gmbus_pin *get_gmbus_pin(struct 
drm_i915_private *dev_priv,
return _pins[pin];
 }
 
+static bool intel_gmbus_ddc_reserve_for_mipi_dsi(struct drm_i915_private 
*dev_priv,
+unsigned int pin)
+{
+   if (intel_bios_is_dsi_present(dev_priv, NULL)) {
+   if (DISPLAY_VER(dev_priv) >= 11) {
+   if ((pin == GMBUS_PIN_2_BXT && 
dev_priv->vbt.dsi.config->dual_link) ||
+pin == GMBUS_PIN_1_BXT) {
+   return true;
+   }
+   }
+   }
+
+   return false;
+}
+
 bool intel_gmbus_is_valid_pin(struct drm_i915_private *dev_priv,
  unsigned int pin)
 {
unsigned int size;
 
+   if (intel_gmbus_ddc_reserve_for_mipi_dsi(dev_priv, pin))
+   return false;
+
if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1)
size = ARRAY_SIZE(gmbus_pins_dg1);
else if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP)
-- 
2.17.1



Re: [Intel-gfx] [PATCH] drm/i915/dsi: do not register gmbus if it was reserved for MIPI display

2021-09-17 Thread Lee, Shawn C
On Fri, 17 Sep 2021, Jani Nikula  wrote:
>On Fri, 17 Sep 2021, Lee Shawn C  wrote:
>> Gmbus driver would setup all Intel i2c GMBuses. But DDC bus may 
>> configured as gpio and reserved for MIPI driver to control panel power 
>> on/off sequence.
>>
>> Using i2c tool to communicate to peripherals via i2c interface 
>> reversed for gmbus(DDC). There will be some high/low pulse appear on 
>> DDC SCL and SDA (might be host sent out i2c slave address). MIPI panel 
>> would be impacted due to unexpected signal then caused abnormal 
>> display or shut down issue.
>>
>> v2: gmbus driver should not add i2c adapter for DDC interface
>> if LFP display was configured to support MIPI panel.
>> v3: fix sparse warning
>>
>> Cc: Jani Nikula 
>> Cc: Vandita Kulkarni 
>> Cc: Cooper Chiou 
>> Cc: William Tseng 
>> Signed-off-by: Lee Shawn C 
>> ---
>>  drivers/gpu/drm/i915/display/intel_gmbus.c | 18 +-
>>  1 file changed, 17 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_gmbus.c 
>> b/drivers/gpu/drm/i915/display/intel_gmbus.c
>> index ceb1bf8a8c3c..51d2b6bf2ed2 100644
>> --- a/drivers/gpu/drm/i915/display/intel_gmbus.c
>> +++ b/drivers/gpu/drm/i915/display/intel_gmbus.c
>> @@ -141,6 +141,21 @@ bool intel_gmbus_is_valid_pin(struct drm_i915_private 
>> *dev_priv,
>>  return pin < size && get_gmbus_pin(dev_priv, pin)->name;  }
>>  
>> +static bool intel_gmbus_ddc_reserve_for_mipi(struct drm_i915_private 
>> *dev_priv,
>> + unsigned int pin)
>> +{
>> +if (intel_bios_is_dsi_present(dev_priv, NULL)) {
>> +if (DISPLAY_VER(dev_priv) >= 11) {
>> +if ((pin == GMBUS_PIN_2_BXT && 
>> dev_priv->vbt.dsi.config->dual_link) ||
>> + pin == GMBUS_PIN_1_BXT) {
>> +return true;
>> +}
>> +}
>> +}
>> +
>> +return false;
>> +}
>> +
>>  /* Intel GPIO access functions */
>>  
>>  #define I2C_RISEFALL_TIME 10
>> @@ -859,7 +874,8 @@ int intel_gmbus_setup(struct drm_i915_private *dev_priv)
>>  init_waitqueue_head(_priv->gmbus_wait_queue);
>>  
>>  for (pin = 0; pin < ARRAY_SIZE(dev_priv->gmbus); pin++) {
>> -if (!intel_gmbus_is_valid_pin(dev_priv, pin))
>> +if (!intel_gmbus_is_valid_pin(dev_priv, pin) ||
>> + intel_gmbus_ddc_reserve_for_mipi(dev_priv, pin))
>>  continue;
>>  
>>  bus = _priv->gmbus[pin];
>
>This does not prevent the pin from being used for e.g. HDMI, 

Agree that customer may connect DDC pin to HDMI port. In my opinion, we should 
take care that while doing HW design review on customer board.
HW member should aware these pins were reserved for MIPI display design. And 
i915 driver would reserve them as well if LFP display was MIPI DSI panel.

>and things are probably going to go awfully wrong with 
>intel_gmbus_get_adapter() when the adapter hasn't been registered. In that 
>sense, this is no different from v1.
>

Before gmbus driver do i2c_add_adapter() or i2c_del_adapter(), it always check 
the pin is valid or not.
It seems we can move intel_gmbus_ddc_reserve_for_mipi() into 
intel_gmbus_is_valid_pin() to check pin was reserved or not.
Then gmbus driver would not went wrong in intel_gmbus_get_adapter() when the 
adapter hasn't been registered.

Best regards,
Shawn

>Sure, the VBT probably shouldn't do that, but that's not an excuse for us to 
>not take it into account.
>
>Cc: Ville in case he has some clever ideas off the top of his head. I know I'd 
>have to spend time I don't have to figure this out.
>
>
>BR,
>Jani.
>
>
>--
>Jani Nikula, Intel Open Source Graphics Center


[Intel-gfx] [PATCH] drm/i915/dsi: do not register gmbus if it was reserved for MIPI display

2021-09-16 Thread Lee Shawn C
Gmbus driver would setup all Intel i2c GMBuses. But DDC bus
may configured as gpio and reserved for MIPI driver to control
panel power on/off sequence.

Using i2c tool to communicate to peripherals via i2c interface
reversed for gmbus(DDC). There will be some high/low pulse
appear on DDC SCL and SDA (might be host sent out i2c slave
address). MIPI panel would be impacted due to unexpected signal
then caused abnormal display or shut down issue.

v2: gmbus driver should not add i2c adapter for DDC interface
if LFP display was configured to support MIPI panel.
v3: fix sparse warning

Cc: Jani Nikula 
Cc: Vandita Kulkarni 
Cc: Cooper Chiou 
Cc: William Tseng 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/i915/display/intel_gmbus.c | 18 +-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_gmbus.c 
b/drivers/gpu/drm/i915/display/intel_gmbus.c
index ceb1bf8a8c3c..51d2b6bf2ed2 100644
--- a/drivers/gpu/drm/i915/display/intel_gmbus.c
+++ b/drivers/gpu/drm/i915/display/intel_gmbus.c
@@ -141,6 +141,21 @@ bool intel_gmbus_is_valid_pin(struct drm_i915_private 
*dev_priv,
return pin < size && get_gmbus_pin(dev_priv, pin)->name;
 }
 
+static bool intel_gmbus_ddc_reserve_for_mipi(struct drm_i915_private *dev_priv,
+unsigned int pin)
+{
+   if (intel_bios_is_dsi_present(dev_priv, NULL)) {
+   if (DISPLAY_VER(dev_priv) >= 11) {
+   if ((pin == GMBUS_PIN_2_BXT && 
dev_priv->vbt.dsi.config->dual_link) ||
+pin == GMBUS_PIN_1_BXT) {
+   return true;
+   }
+   }
+   }
+
+   return false;
+}
+
 /* Intel GPIO access functions */
 
 #define I2C_RISEFALL_TIME 10
@@ -859,7 +874,8 @@ int intel_gmbus_setup(struct drm_i915_private *dev_priv)
init_waitqueue_head(_priv->gmbus_wait_queue);
 
for (pin = 0; pin < ARRAY_SIZE(dev_priv->gmbus); pin++) {
-   if (!intel_gmbus_is_valid_pin(dev_priv, pin))
+   if (!intel_gmbus_is_valid_pin(dev_priv, pin) ||
+intel_gmbus_ddc_reserve_for_mipi(dev_priv, pin))
continue;
 
bus = _priv->gmbus[pin];
-- 
2.17.1



[Intel-gfx] [PATCH] drm/i915/dsi: do not register gmbus if it was reserved for MIPI display

2021-09-16 Thread Lee Shawn C
Gmbus driver would setup all Intel i2c GMBuses. But DDC bus
may configured as gpio and reserved for MIPI driver to control
panel power on/off sequence.

Using i2c tool to communicate to peripherals via i2c interface
reversed for gmbus(DDC). There will be some high/low pulse
appear on DDC SCL and SDA (might be host sent out i2c slave
address). MIPI panel would be impacted due to unexpected signal
then caused abnormal display or shut down issue.

v2: gmbus driver should not add i2c adapter for DDC interface
if LFP display was configured to support MIPI panel.

Cc: Jani Nikula 
Cc: Vandita Kulkarni 
Cc: Cooper Chiou 
Cc: William Tseng 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/i915/display/intel_gmbus.c | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_gmbus.c 
b/drivers/gpu/drm/i915/display/intel_gmbus.c
index ceb1bf8a8c3c..8d2dcc4a6a53 100644
--- a/drivers/gpu/drm/i915/display/intel_gmbus.c
+++ b/drivers/gpu/drm/i915/display/intel_gmbus.c
@@ -141,6 +141,22 @@ bool intel_gmbus_is_valid_pin(struct drm_i915_private 
*dev_priv,
return pin < size && get_gmbus_pin(dev_priv, pin)->name;
 }
 
+bool intel_gmbus_ddc_reserve_for_mipi(struct drm_i915_private *dev_priv,
+ unsigned int pin)
+{
+   enum port port;
+
+   if (intel_bios_is_dsi_present(dev_priv, )) {
+   if (DISPLAY_VER(dev_priv) >= 11) {
+   if ((pin == GMBUS_PIN_2_BXT && 
dev_priv->vbt.dsi.config->dual_link) ||
+pin == GMBUS_PIN_1_BXT)
+   return true;
+   }
+   }
+
+   return false;
+}
+
 /* Intel GPIO access functions */
 
 #define I2C_RISEFALL_TIME 10
@@ -862,6 +878,9 @@ int intel_gmbus_setup(struct drm_i915_private *dev_priv)
if (!intel_gmbus_is_valid_pin(dev_priv, pin))
continue;
 
+   if (intel_gmbus_ddc_reserve_for_mipi(dev_priv, pin))
+   continue;
+
bus = _priv->gmbus[pin];
 
bus->adapter.owner = THIS_MODULE;
-- 
2.17.1



Re: [Intel-gfx] [PATCH] drm/i915/dsi: unregister gmbus if LFP display was MIPI panel

2021-09-16 Thread Lee, Shawn C
On Thu, 16 Sep 2021, Jani Nikula  wrote:
>On Thu, 16 Sep 2021, Lee Shawn C  wrote:
>> Gmbus driver would setup all Intel i2c GMBuses. But DDC bus may 
>> configured as gpio and reserved for MIPI driver to control panel power 
>> on/off sequence.
>>
>> Using i2c tool to communicate to peripherals via i2c interface 
>> reversed for gmbus(DDC). There will be some high/low pulse appear on 
>> DDC SCL and SDA (might be host sent out i2c slave address). MIPI panel 
>> would be impacted due to unexpected signal then caused abnormal 
>> display or shut down issue.
>
>Just a quick reply:
>
>So I don't know off the bat what the right solution is, but it's very obvious 
>to me that we absolute can't go deleting gmbus adapters from DSI code.
>
>
>BR,
>Jani.
>

Create a new function in gmbus driver that allow to remove a given gmbus 
adapter. And DSI driver used it to unregister particular gmbus.
It looks to me more reasonable for DSI and gmbus driver. What do you think?

Best regards,
Shawn

>>
>> Cc: Jani Nikula 
>> Cc: Vandita Kulkarni 
>> Cc: Cooper Chiou 
>> Cc: William Tseng 
>> Signed-off-by: Lee Shawn C 
>> ---
>>  drivers/gpu/drm/i915/display/icl_dsi.c | 14 ++
>>  1 file changed, 14 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c 
>> b/drivers/gpu/drm/i915/display/icl_dsi.c
>> index 060bc8fb0d30..d2504e291fcb 100644
>> --- a/drivers/gpu/drm/i915/display/icl_dsi.c
>> +++ b/drivers/gpu/drm/i915/display/icl_dsi.c
>> @@ -1999,6 +1999,7 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
>>  struct intel_connector *intel_connector;
>>  struct drm_connector *connector;
>>  struct drm_display_mode *fixed_mode;
>> +struct intel_gmbus *bus;
>>  enum port port;
>>  
>>  if (!intel_bios_is_dsi_present(dev_priv, )) @@ -2092,6 +2093,19 
>> @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
>>  icl_dphy_param_init(intel_dsi);
>>  
>>  icl_dsi_add_properties(intel_connector);
>> +
>> +/*
>> + * DDC bus may configured as gpio and reserved for MIPI driver
>> + * to control panel power on/off sequence. so, unregister gmbus
>> + * if MIPI was LFP display.
>> + */
>> +bus = _priv->gmbus[GMBUS_PIN_1_BXT];
>> +i2c_del_adapter(>adapter);
>> +
>> +if (dev_priv->vbt.dsi.config->dual_link) {
>> +bus = _priv->gmbus[GMBUS_PIN_2_BXT];
>> +i2c_del_adapter(>adapter);
>> +}
>>  return;
>>  
>>  err:
>
>--
>Jani Nikula, Intel Open Source Graphics Center


[Intel-gfx] [PATCH] drm/i915/dsi: unregister gmbus if LFP display was MIPI panel

2021-09-16 Thread Lee Shawn C
Gmbus driver would setup all Intel i2c GMBuses. But DDC bus
may configured as gpio and reserved for MIPI driver to control
panel power on/off sequence.

Using i2c tool to communicate to peripherals via i2c interface
reversed for gmbus(DDC). There will be some high/low pulse
appear on DDC SCL and SDA (might be host sent out i2c slave
address). MIPI panel would be impacted due to unexpected signal
then caused abnormal display or shut down issue.

Cc: Jani Nikula 
Cc: Vandita Kulkarni 
Cc: Cooper Chiou 
Cc: William Tseng 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/i915/display/icl_dsi.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c 
b/drivers/gpu/drm/i915/display/icl_dsi.c
index 060bc8fb0d30..d2504e291fcb 100644
--- a/drivers/gpu/drm/i915/display/icl_dsi.c
+++ b/drivers/gpu/drm/i915/display/icl_dsi.c
@@ -1999,6 +1999,7 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
struct intel_connector *intel_connector;
struct drm_connector *connector;
struct drm_display_mode *fixed_mode;
+   struct intel_gmbus *bus;
enum port port;
 
if (!intel_bios_is_dsi_present(dev_priv, ))
@@ -2092,6 +2093,19 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
icl_dphy_param_init(intel_dsi);
 
icl_dsi_add_properties(intel_connector);
+
+   /*
+* DDC bus may configured as gpio and reserved for MIPI driver
+* to control panel power on/off sequence. so, unregister gmbus
+* if MIPI was LFP display.
+*/
+   bus = _priv->gmbus[GMBUS_PIN_1_BXT];
+   i2c_del_adapter(>adapter);
+
+   if (dev_priv->vbt.dsi.config->dual_link) {
+   bus = _priv->gmbus[GMBUS_PIN_2_BXT];
+   i2c_del_adapter(>adapter);
+   }
return;
 
 err:
-- 
2.31.1



Re: [Intel-gfx] ✗ Fi.CI.IGT: failure for DSI driver improvement (rev3)

2021-09-08 Thread Lee, Shawn C

These errors did not relate to this patch series. Thanks!

Best regards,
Shawn

From: Patchwork 
Sent: Friday, September 3, 2021 3:21 AM
To: Lee, Shawn C 
Cc: intel-gfx@lists.freedesktop.org
Subject: ✗ Fi.CI.IGT: failure for DSI driver improvement (rev3)

Patch Details
Series:
DSI driver improvement (rev3)
URL:
https://patchwork.freedesktop.org/series/94237/
State:
failure
Details:
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20943/index.html
CI Bug Log - changes from CI_DRM_10548_full -> Patchwork_20943_full
Summary

FAILURE

Serious unknown changes coming with Patchwork_20943_full absolutely need to be
verified manually.

If you think the reported changes have nothing to do with the changes
introduced in Patchwork_20943_full, please notify your bug team to allow them
to document this new failure mode, which will reduce false positives in CI.

Possible new issues

Here are the unknown changes that may have been introduced in 
Patchwork_20943_full:

IGT changes
Possible regressions

  *   igt@kms_pipe_crc_basic@suspend-read-crc-pipe-b:
 *   shard-iclb: 
PASS<https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10548/shard-iclb4/igt@kms_pipe_crc_ba...@suspend-read-crc-pipe-b.html>
 -> 
INCOMPLETE<https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20943/shard-iclb3/igt@kms_pipe_crc_ba...@suspend-read-crc-pipe-b.html>
 +1 similar issue

Suppressed

The following results come from untrusted machines, tests, or statuses.
They do not affect the overall result.

  *   igt@gem_eio@hibernate:
 *   {shard-rkl}: NOTRUN -> 
FAIL<https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20943/shard-rkl-5/igt@gem_...@hibernate.html>

Known issues

Here are the changes found in Patchwork_20943_full that come from known issues:

IGT changes
Issues hit

  *   igt@gem_create@create-massive:
 *   shard-apl: NOTRUN -> 
DMESG-WARN<https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20943/shard-apl1/igt@gem_cre...@create-massive.html>
 ([i915#3002])
  *   igt@gem_ctx_persistence@engines-hostile-preempt:
 *   shard-snb: NOTRUN -> 
SKIP<https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20943/shard-snb5/igt@gem_ctx_persiste...@engines-hostile-preempt.html>
 ([fdo#109271] / [i915#1099]) +4 similar issues
  *   igt@gem_ctx_persistence@many-contexts:
 *   shard-tglb: 
PASS<https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10548/shard-tglb6/igt@gem_ctx_persiste...@many-contexts.html>
 -> 
FAIL<https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20943/shard-tglb5/igt@gem_ctx_persiste...@many-contexts.html>
 ([i915#2410])
  *   igt@gem_exec_fair@basic-deadline:
 *   shard-apl: NOTRUN -> 
FAIL<https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20943/shard-apl8/igt@gem_exec_f...@basic-deadline.html>
 ([i915#2846])
  *   igt@gem_exec_fair@basic-flow@rcs0:
 *   shard-tglb: 
PASS<https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10548/shard-tglb8/igt@gem_exec_fair@basic-f...@rcs0.html>
 -> 
FAIL<https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20943/shard-tglb3/igt@gem_exec_fair@basic-f...@rcs0.html>
 ([i915#2842]) +1 similar issue
  *   igt@gem_exec_fair@basic-none@vecs0:
 *   shard-kbl: 
PASS<https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10548/shard-kbl4/igt@gem_exec_fair@basic-n...@vecs0.html>
 -> 
FAIL<https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20943/shard-kbl3/igt@gem_exec_fair@basic-n...@vecs0.html>
 ([i915#2842])
  *   igt@gem_exec_fair@basic-pace-share@rcs0:
 *   shard-glk: 
PASS<https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10548/shard-glk7/igt@gem_exec_fair@basic-pace-sh...@rcs0.html>
 -> 
FAIL<https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20943/shard-glk3/igt@gem_exec_fair@basic-pace-sh...@rcs0.html>
 ([i915#2842])
  *   igt@gem_exec_fair@basic-throttle@rcs0:
 *   shard-iclb: 
PASS<https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10548/shard-iclb3/igt@gem_exec_fair@basic-throt...@rcs0.html>
 -> 
FAIL<https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20943/shard-iclb8/igt@gem_exec_fair@basic-throt...@rcs0.html>
 ([i915#2849])
  *   igt@gem_mmap_gtt@cpuset-basic-small-copy-odd:
 *   shard-iclb: 
PASS<https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10548/shard-iclb5/igt@gem_mmap_...@cpuset-basic-small-copy-odd.html>
 -> 
FAIL<https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20943/shard-iclb5/igt@gem_mmap_...@cpuset-basic-small-copy-odd.html>
 ([i915#307])
  *   igt@gem_pread@exhaustion:
 *   shard-skl: NOTRUN -> 
WARN<https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20943/shard-skl10/igt@gem_pr...@exhaustion.html>
 ([i915#2658])
  *   igt@gem_pwrite@basic-exhaustion:
 *   shard-snb: NOTRUN -> 
WARN<https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20943/shard-snb5/igt@gem_pwr...@basic-exhaustion.html>
 ([i915#2658]) +1 similar issue
  *   igt@gem_render_copy@yf-tiled-mc-ccs-to-vebox-y-tiled:
 *   shard

Re: [Intel-gfx] [v4 0/5] DSI driver improvement

2021-09-08 Thread Lee, Shawn C
On Wed, 08 Sep 2021, Jani Nikula  wrote:
>On Wed, 08 Sep 2021, Lee Shawn C  wrote:
>> v2: Get data length of brightness value more easily while driver try to
>> read/write MIPI_DCS_DISPLAY_BRIGHTNESS command.
>> v3: fix checkpatch warning.
>
>The series is v4, what's new here?
>
>BR,
>Jani.
>

We don't change anything, just rebase.

Best regards,
Shawn

>
>>
>> Signed-off-by: Lee Shawn C 
>>
>> Lee Shawn C (5):
>>   drm/i915/dsi: wait for header and payload credit available
>>   drm/i915/dsi: refine send MIPI DCS command sequence
>>   drm/i915: Get proper min cdclk if vDSC enabled
>>   drm/i915/dsi: Retrieve max brightness level from VBT
>>   drm/i915/dsi: Read/write proper brightness value via MIPI DCS command
>>
>>  drivers/gpu/drm/i915/display/icl_dsi.c| 50 +--
>>  drivers/gpu/drm/i915/display/intel_bios.c |  3 ++
>>  drivers/gpu/drm/i915/display/intel_cdclk.c| 10 
>>  .../i915/display/intel_dsi_dcs_backlight.c| 33 
>>  drivers/gpu/drm/i915/i915_drv.h   |  1 +
>>  5 files changed, 62 insertions(+), 35 deletions(-)
>
>-- 
>Jani Nikula, Intel Open Source Graphics Center
>


[Intel-gfx] [v4 5/5] drm/i915/dsi: Read/write proper brightness value via MIPI DCS command

2021-09-08 Thread Lee Shawn C
Driver has to swap the endian before send brightness level value
to tcon.

v2: Use __be16 instead of u16 to fix sparse warning.
v3: Send one or two bytes brightness value depend on the precision.
v4: get data length of brightness value more easily.

Reported-by: kernel test robot 
Cc: Ville Syrjala 
Cc: Jani Nikula 
Cc: Vandita Kulkarni 
Cc: Cooper Chiou 
Cc: William Tseng 
Signed-off-by: Lee Shawn C 
Reviewed-by: Jani Nikula 
---
 .../i915/display/intel_dsi_dcs_backlight.c| 23 +--
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c 
b/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c
index 567c086602d5..f61ed82e8867 100644
--- a/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c
+++ b/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c
@@ -47,33 +47,42 @@ static u32 dcs_get_backlight(struct intel_connector 
*connector, enum pipe unused
 {
struct intel_encoder *encoder = intel_attached_encoder(connector);
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+   struct intel_panel *panel = >panel;
struct mipi_dsi_device *dsi_device;
-   u8 data = 0;
+   u8 data[2] = {};
enum port port;
+   size_t len = panel->backlight.max > U8_MAX ? 2 : 1;
 
-   /* FIXME: Need to take care of 16 bit brightness level */
for_each_dsi_port(port, intel_dsi->dcs_backlight_ports) {
dsi_device = intel_dsi->dsi_hosts[port]->device;
mipi_dsi_dcs_read(dsi_device, MIPI_DCS_GET_DISPLAY_BRIGHTNESS,
- , sizeof(data));
+ , len);
break;
}
 
-   return data;
+   return (data[1] << 8) | data[0];
 }
 
 static void dcs_set_backlight(const struct drm_connector_state *conn_state, 
u32 level)
 {
struct intel_dsi *intel_dsi = 
enc_to_intel_dsi(to_intel_encoder(conn_state->best_encoder));
+   struct intel_panel *panel = 
_intel_connector(conn_state->connector)->panel;
struct mipi_dsi_device *dsi_device;
-   u8 data = level;
+   u8 data[2] = {};
enum port port;
+   size_t len = panel->backlight.max > U8_MAX ? 2 : 1;
+
+   if (len == 1) {
+   data[0] = level;
+   } else {
+   data[0] = level >> 8;
+   data[1] = level;
+   }
 
-   /* FIXME: Need to take care of 16 bit brightness level */
for_each_dsi_port(port, intel_dsi->dcs_backlight_ports) {
dsi_device = intel_dsi->dsi_hosts[port]->device;
mipi_dsi_dcs_write(dsi_device, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
-  , sizeof(data));
+  , len);
}
 }
 
-- 
2.17.1



[Intel-gfx] [v4 4/5] drm/i915/dsi: Retrieve max brightness level from VBT

2021-09-08 Thread Lee Shawn C
So far, DCS backlight driver hardcode (0xFF) for max brightness level.
MIPI DCS spec allow max 0x for set_display_brightness (51h) command.
And VBT brightness precision bits can support 8 ~ 16 bits.

We should set correct precision bits in VBT that meet panel's request.
Driver can refer to this setting then configure max brightness level
in DCS backlight driver properly.

v2: modify variable name brightness_precision_bits instead of
max_brightness_level.
v3: fix checkpatch warning.

Cc: Ville Syrjala 
Cc: Jani Nikula 
Cc: Vandita Kulkarni 
Cc: Cooper Chiou 
Cc: William Tseng 
Signed-off-by: Lee Shawn C 
Reviewed-by: Jani Nikula 
---
 drivers/gpu/drm/i915/display/intel_bios.c  |  3 +++
 drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c | 10 --
 drivers/gpu/drm/i915/i915_drv.h|  1 +
 3 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_bios.c 
b/drivers/gpu/drm/i915/display/intel_bios.c
index e86e6ed2d3bf..ccaf0a3100f7 100644
--- a/drivers/gpu/drm/i915/display/intel_bios.c
+++ b/drivers/gpu/drm/i915/display/intel_bios.c
@@ -483,6 +483,9 @@ parse_lfp_backlight(struct drm_i915_private *i915,
level = 255;
}
i915->vbt.backlight.min_brightness = min_level;
+
+   i915->vbt.backlight.brightness_precision_bits =
+   backlight_data->brightness_precision_bits[panel_type];
} else {
level = backlight_data->level[panel_type];
i915->vbt.backlight.min_brightness = entry->min_brightness;
diff --git a/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c 
b/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c
index 584c14c4cbd0..567c086602d5 100644
--- a/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c
+++ b/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c
@@ -147,10 +147,16 @@ static void dcs_enable_backlight(const struct 
intel_crtc_state *crtc_state,
 static int dcs_setup_backlight(struct intel_connector *connector,
   enum pipe unused)
 {
+   struct drm_device *dev = connector->base.dev;
+   struct drm_i915_private *dev_priv = to_i915(dev);
struct intel_panel *panel = >panel;
 
-   panel->backlight.max = PANEL_PWM_MAX_VALUE;
-   panel->backlight.level = PANEL_PWM_MAX_VALUE;
+   if (dev_priv->vbt.backlight.brightness_precision_bits > 8)
+   panel->backlight.max = (1 << 
dev_priv->vbt.backlight.brightness_precision_bits) - 1;
+   else
+   panel->backlight.max = PANEL_PWM_MAX_VALUE;
+
+   panel->backlight.level = panel->backlight.max;
 
return 0;
 }
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index be2392bbcecc..99a2d308b24d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -705,6 +705,7 @@ struct intel_vbt_data {
 
struct {
u16 pwm_freq_hz;
+   u16 brightness_precision_bits;
bool present;
bool active_low_pwm;
u8 min_brightness;  /* min_brightness/255 of max */
-- 
2.17.1



[Intel-gfx] [v4 3/5] drm/i915: Get proper min cdclk if vDSC enabled

2021-09-08 Thread Lee Shawn C
VDSC engine can process only 1 pixel per Cd clock. In case
VDSC is used and max slice count == 1, max supported pixel
clock should be 100% of CD clock. Then do min_cdclk and
pixel clock comparison to get proper min cdclk.

v2:
- Check for dsc enable and slice count ==1 then allow to
  double confirm min cdclk value.

Cc: Ville Syrjala 
Cc: Jani Nikula 
Cc: Vandita Kulkarni 
Cc: Cooper Chiou 
Cc: William Tseng 
Signed-off-by: Lee Shawn C 
Reviewed-by: Vandita Kulkarni 
Acked-by: Jani Nikula 
---
 drivers/gpu/drm/i915/display/intel_cdclk.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c 
b/drivers/gpu/drm/i915/display/intel_cdclk.c
index 34fa4130d5c4..9aec17b33819 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -2139,6 +2139,16 @@ int intel_crtc_compute_min_cdclk(const struct 
intel_crtc_state *crtc_state)
/* Account for additional needs from the planes */
min_cdclk = max(intel_planes_min_cdclk(crtc_state), min_cdclk);
 
+   /*
+* VDSC engine can process only 1 pixel per Cd clock.
+* In case VDSC is used and max slice count == 1,
+* max supported pixel clock should be 100% of CD clock.
+* Then do min_cdclk and pixel clock comparison to get cdclk.
+*/
+   if (crtc_state->dsc.compression_enable &&
+   crtc_state->dsc.slice_count == 1)
+   min_cdclk = max(min_cdclk, (int)crtc_state->pixel_rate);
+
/*
 * HACK. Currently for TGL platforms we calculate
 * min_cdclk initially based on pixel_rate divided
-- 
2.17.1



[Intel-gfx] [v4 2/5] drm/i915/dsi: refine send MIPI DCS command sequence

2021-09-08 Thread Lee Shawn C
According to chapter "Sending Commands to the Panel" in bspec #29738
and #49188. If driver try to send DCS long pakcet, we have to program
TX payload register at first. And configure TX header HW register later.
DSC long packet would not be sent properly if we don't follow this
sequence.

Cc: Ville Syrjala 
Cc: Jani Nikula 
Cc: Vandita Kulkarni 
Cc: Cooper Chiou 
Cc: William Tseng 
Signed-off-by: Lee Shawn C 
Reviewed-by: Vandita Kulkarni 
---
 drivers/gpu/drm/i915/display/icl_dsi.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c 
b/drivers/gpu/drm/i915/display/icl_dsi.c
index 44289003b709..060bc8fb0d30 100644
--- a/drivers/gpu/drm/i915/display/icl_dsi.c
+++ b/drivers/gpu/drm/i915/display/icl_dsi.c
@@ -1831,11 +1831,6 @@ static ssize_t gen11_dsi_host_transfer(struct 
mipi_dsi_host *host,
if (msg->flags & MIPI_DSI_MSG_USE_LPM)
enable_lpdt = true;
 
-   /* send packet header */
-   ret  = dsi_send_pkt_hdr(intel_dsi_host, dsi_pkt, enable_lpdt);
-   if (ret < 0)
-   return ret;
-
/* only long packet contains payload */
if (mipi_dsi_packet_format_is_long(msg->type)) {
ret = dsi_send_pkt_payld(intel_dsi_host, dsi_pkt);
@@ -1843,6 +1838,11 @@ static ssize_t gen11_dsi_host_transfer(struct 
mipi_dsi_host *host,
return ret;
}
 
+   /* send packet header */
+   ret  = dsi_send_pkt_hdr(intel_dsi_host, dsi_pkt, enable_lpdt);
+   if (ret < 0)
+   return ret;
+
//TODO: add payload receive code if needed
 
ret = sizeof(dsi_pkt.header) + dsi_pkt.payload_length;
-- 
2.17.1



[Intel-gfx] [v4 1/5] drm/i915/dsi: wait for header and payload credit available

2021-09-08 Thread Lee Shawn C
Driver should wait for free header or payload buffer in FIFO.
It would be good to wait a while for HW to release credit before
give it up to write to HW. Without sending initailize command
sets completely. It would caused MIPI display can't light up properly.

Cc: Ville Syrjala 
Cc: Jani Nikula 
Cc: Vandita Kulkarni 
Cc: Cooper Chiou 
Cc: William Tseng 
Signed-off-by: Lee Shawn C 
Reviewed-by: Vandita Kulkarni 
---
 drivers/gpu/drm/i915/display/icl_dsi.c | 40 --
 1 file changed, 19 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c 
b/drivers/gpu/drm/i915/display/icl_dsi.c
index a1e35180d5dd..44289003b709 100644
--- a/drivers/gpu/drm/i915/display/icl_dsi.c
+++ b/drivers/gpu/drm/i915/display/icl_dsi.c
@@ -55,20 +55,28 @@ static int payload_credits_available(struct 
drm_i915_private *dev_priv,
>> FREE_PLOAD_CREDIT_SHIFT;
 }
 
-static void wait_for_header_credits(struct drm_i915_private *dev_priv,
-   enum transcoder dsi_trans)
+static bool wait_for_header_credits(struct drm_i915_private *dev_priv,
+   enum transcoder dsi_trans, int hdr_credit)
 {
if (wait_for_us(header_credits_available(dev_priv, dsi_trans) >=
-   MAX_HEADER_CREDIT, 100))
+   hdr_credit, 100)) {
drm_err(_priv->drm, "DSI header credits not released\n");
+   return false;
+   }
+
+   return true;
 }
 
-static void wait_for_payload_credits(struct drm_i915_private *dev_priv,
-enum transcoder dsi_trans)
+static bool wait_for_payload_credits(struct drm_i915_private *dev_priv,
+enum transcoder dsi_trans, int 
payld_credit)
 {
if (wait_for_us(payload_credits_available(dev_priv, dsi_trans) >=
-   MAX_PLOAD_CREDIT, 100))
+   payld_credit, 100)) {
drm_err(_priv->drm, "DSI payload credits not released\n");
+   return false;
+   }
+
+   return true;
 }
 
 static enum transcoder dsi_port_to_transcoder(enum port port)
@@ -91,8 +99,8 @@ static void wait_for_cmds_dispatched_to_panel(struct 
intel_encoder *encoder)
/* wait for header/payload credits to be released */
for_each_dsi_port(port, intel_dsi->ports) {
dsi_trans = dsi_port_to_transcoder(port);
-   wait_for_header_credits(dev_priv, dsi_trans);
-   wait_for_payload_credits(dev_priv, dsi_trans);
+   wait_for_header_credits(dev_priv, dsi_trans, MAX_HEADER_CREDIT);
+   wait_for_payload_credits(dev_priv, dsi_trans, MAX_PLOAD_CREDIT);
}
 
/* send nop DCS command */
@@ -109,7 +117,7 @@ static void wait_for_cmds_dispatched_to_panel(struct 
intel_encoder *encoder)
/* wait for header credits to be released */
for_each_dsi_port(port, intel_dsi->ports) {
dsi_trans = dsi_port_to_transcoder(port);
-   wait_for_header_credits(dev_priv, dsi_trans);
+   wait_for_header_credits(dev_priv, dsi_trans, MAX_HEADER_CREDIT);
}
 
/* wait for LP TX in progress bit to be cleared */
@@ -127,18 +135,13 @@ static bool add_payld_to_queue(struct intel_dsi_host 
*host, const u8 *data,
struct intel_dsi *intel_dsi = host->intel_dsi;
struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev);
enum transcoder dsi_trans = dsi_port_to_transcoder(host->port);
-   int free_credits;
int i, j;
 
for (i = 0; i < len; i += 4) {
u32 tmp = 0;
 
-   free_credits = payload_credits_available(dev_priv, dsi_trans);
-   if (free_credits < 1) {
-   drm_err(_priv->drm,
-   "Payload credit not available\n");
+   if (!wait_for_payload_credits(dev_priv, dsi_trans, 1))
return false;
-   }
 
for (j = 0; j < min_t(u32, len - i, 4); j++)
tmp |= *data++ << 8 * j;
@@ -156,15 +159,10 @@ static int dsi_send_pkt_hdr(struct intel_dsi_host *host,
struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev);
enum transcoder dsi_trans = dsi_port_to_transcoder(host->port);
u32 tmp;
-   int free_credits;
 
/* check if header credit available */
-   free_credits = header_credits_available(dev_priv, dsi_trans);
-   if (free_credits < 1) {
-   drm_err(_priv->drm,
-   "send pkt header failed, not enough hdr credits\n");
+   if (!wait_for_header_credits(dev_priv, dsi_trans, 1))
return -1;
-   }
 
tmp = intel_de_read(dev_priv, DSI_CMD_TXHDR(dsi_trans));
 
-- 
2.17.1



[Intel-gfx] [v4 0/5] DSI driver improvement

2021-09-08 Thread Lee Shawn C
v2: Get data length of brightness value more easily while driver try to
read/write MIPI_DCS_DISPLAY_BRIGHTNESS command.
v3: fix checkpatch warning.

Signed-off-by: Lee Shawn C 

Lee Shawn C (5):
  drm/i915/dsi: wait for header and payload credit available
  drm/i915/dsi: refine send MIPI DCS command sequence
  drm/i915: Get proper min cdclk if vDSC enabled
  drm/i915/dsi: Retrieve max brightness level from VBT
  drm/i915/dsi: Read/write proper brightness value via MIPI DCS command

 drivers/gpu/drm/i915/display/icl_dsi.c| 50 +--
 drivers/gpu/drm/i915/display/intel_bios.c |  3 ++
 drivers/gpu/drm/i915/display/intel_cdclk.c| 10 
 .../i915/display/intel_dsi_dcs_backlight.c| 33 
 drivers/gpu/drm/i915/i915_drv.h   |  1 +
 5 files changed, 62 insertions(+), 35 deletions(-)

-- 
2.17.1



[Intel-gfx] [v3 5/5] drm/i915/dsi: Read/write proper brightness value via MIPI DCS command

2021-09-02 Thread Lee Shawn C
Driver has to swap the endian before send brightness level value
to tcon.

v2: Use __be16 instead of u16 to fix sparse warning.
v3: Send one or two bytes brightness value depend on the precision.
v4: get data length of brightness value more easily.

Reported-by: kernel test robot 
Cc: Ville Syrjala 
Cc: Jani Nikula 
Cc: Vandita Kulkarni 
Cc: Cooper Chiou 
Cc: William Tseng 
Signed-off-by: Lee Shawn C 
Reviewed-by: Jani Nikula 
---
 .../i915/display/intel_dsi_dcs_backlight.c| 23 +--
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c 
b/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c
index 567c086602d5..f61ed82e8867 100644
--- a/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c
+++ b/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c
@@ -47,33 +47,42 @@ static u32 dcs_get_backlight(struct intel_connector 
*connector, enum pipe unused
 {
struct intel_encoder *encoder = intel_attached_encoder(connector);
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+   struct intel_panel *panel = >panel;
struct mipi_dsi_device *dsi_device;
-   u8 data = 0;
+   u8 data[2] = {};
enum port port;
+   size_t len = panel->backlight.max > U8_MAX ? 2 : 1;
 
-   /* FIXME: Need to take care of 16 bit brightness level */
for_each_dsi_port(port, intel_dsi->dcs_backlight_ports) {
dsi_device = intel_dsi->dsi_hosts[port]->device;
mipi_dsi_dcs_read(dsi_device, MIPI_DCS_GET_DISPLAY_BRIGHTNESS,
- , sizeof(data));
+ , len);
break;
}
 
-   return data;
+   return (data[1] << 8) | data[0];
 }
 
 static void dcs_set_backlight(const struct drm_connector_state *conn_state, 
u32 level)
 {
struct intel_dsi *intel_dsi = 
enc_to_intel_dsi(to_intel_encoder(conn_state->best_encoder));
+   struct intel_panel *panel = 
_intel_connector(conn_state->connector)->panel;
struct mipi_dsi_device *dsi_device;
-   u8 data = level;
+   u8 data[2] = {};
enum port port;
+   size_t len = panel->backlight.max > U8_MAX ? 2 : 1;
+
+   if (len == 1) {
+   data[0] = level;
+   } else {
+   data[0] = level >> 8;
+   data[1] = level;
+   }
 
-   /* FIXME: Need to take care of 16 bit brightness level */
for_each_dsi_port(port, intel_dsi->dcs_backlight_ports) {
dsi_device = intel_dsi->dsi_hosts[port]->device;
mipi_dsi_dcs_write(dsi_device, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
-  , sizeof(data));
+  , len);
}
 }
 
-- 
2.17.1



[Intel-gfx] [v3 4/5] drm/i915/dsi: Retrieve max brightness level from VBT

2021-09-02 Thread Lee Shawn C
So far, DCS backlight driver hardcode (0xFF) for max brightness level.
MIPI DCS spec allow max 0x for set_display_brightness (51h) command.
And VBT brightness precision bits can support 8 ~ 16 bits.

We should set correct precision bits in VBT that meet panel's request.
Driver can refer to this setting then configure max brightness level
in DCS backlight driver properly.

v2: modify variable name brightness_precision_bits instead of
max_brightness_level.
v3: fix checkpatch warning.

Cc: Ville Syrjala 
Cc: Jani Nikula 
Cc: Vandita Kulkarni 
Cc: Cooper Chiou 
Cc: William Tseng 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/i915/display/intel_bios.c  |  3 +++
 drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c | 10 --
 drivers/gpu/drm/i915/i915_drv.h|  1 +
 3 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_bios.c 
b/drivers/gpu/drm/i915/display/intel_bios.c
index e86e6ed2d3bf..ccaf0a3100f7 100644
--- a/drivers/gpu/drm/i915/display/intel_bios.c
+++ b/drivers/gpu/drm/i915/display/intel_bios.c
@@ -483,6 +483,9 @@ parse_lfp_backlight(struct drm_i915_private *i915,
level = 255;
}
i915->vbt.backlight.min_brightness = min_level;
+
+   i915->vbt.backlight.brightness_precision_bits =
+   backlight_data->brightness_precision_bits[panel_type];
} else {
level = backlight_data->level[panel_type];
i915->vbt.backlight.min_brightness = entry->min_brightness;
diff --git a/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c 
b/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c
index 584c14c4cbd0..567c086602d5 100644
--- a/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c
+++ b/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c
@@ -147,10 +147,16 @@ static void dcs_enable_backlight(const struct 
intel_crtc_state *crtc_state,
 static int dcs_setup_backlight(struct intel_connector *connector,
   enum pipe unused)
 {
+   struct drm_device *dev = connector->base.dev;
+   struct drm_i915_private *dev_priv = to_i915(dev);
struct intel_panel *panel = >panel;
 
-   panel->backlight.max = PANEL_PWM_MAX_VALUE;
-   panel->backlight.level = PANEL_PWM_MAX_VALUE;
+   if (dev_priv->vbt.backlight.brightness_precision_bits > 8)
+   panel->backlight.max = (1 << 
dev_priv->vbt.backlight.brightness_precision_bits) - 1;
+   else
+   panel->backlight.max = PANEL_PWM_MAX_VALUE;
+
+   panel->backlight.level = panel->backlight.max;
 
return 0;
 }
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index be2392bbcecc..99a2d308b24d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -705,6 +705,7 @@ struct intel_vbt_data {
 
struct {
u16 pwm_freq_hz;
+   u16 brightness_precision_bits;
bool present;
bool active_low_pwm;
u8 min_brightness;  /* min_brightness/255 of max */
-- 
2.17.1



[Intel-gfx] [v3 3/5] drm/i915: Get proper min cdclk if vDSC enabled

2021-09-02 Thread Lee Shawn C
VDSC engine can process only 1 pixel per Cd clock. In case
VDSC is used and max slice count == 1, max supported pixel
clock should be 100% of CD clock. Then do min_cdclk and
pixel clock comparison to get proper min cdclk.

v2:
- Check for dsc enable and slice count ==1 then allow to
  double confirm min cdclk value.

Cc: Ville Syrjala 
Cc: Jani Nikula 
Cc: Vandita Kulkarni 
Cc: Cooper Chiou 
Cc: William Tseng 
Signed-off-by: Lee Shawn C 
Reviewed-by: Vandita Kulkarni 
---
 drivers/gpu/drm/i915/display/intel_cdclk.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c 
b/drivers/gpu/drm/i915/display/intel_cdclk.c
index 34fa4130d5c4..9aec17b33819 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -2139,6 +2139,16 @@ int intel_crtc_compute_min_cdclk(const struct 
intel_crtc_state *crtc_state)
/* Account for additional needs from the planes */
min_cdclk = max(intel_planes_min_cdclk(crtc_state), min_cdclk);
 
+   /*
+* VDSC engine can process only 1 pixel per Cd clock.
+* In case VDSC is used and max slice count == 1,
+* max supported pixel clock should be 100% of CD clock.
+* Then do min_cdclk and pixel clock comparison to get cdclk.
+*/
+   if (crtc_state->dsc.compression_enable &&
+   crtc_state->dsc.slice_count == 1)
+   min_cdclk = max(min_cdclk, (int)crtc_state->pixel_rate);
+
/*
 * HACK. Currently for TGL platforms we calculate
 * min_cdclk initially based on pixel_rate divided
-- 
2.17.1



[Intel-gfx] [v3 2/5] drm/i915/dsi: refine send MIPI DCS command sequence

2021-09-02 Thread Lee Shawn C
According to chapter "Sending Commands to the Panel" in bspec #29738
and #49188. If driver try to send DCS long pakcet, we have to program
TX payload register at first. And configure TX header HW register later.
DSC long packet would not be sent properly if we don't follow this
sequence.

Cc: Ville Syrjala 
Cc: Jani Nikula 
Cc: Vandita Kulkarni 
Cc: Cooper Chiou 
Cc: William Tseng 
Signed-off-by: Lee Shawn C 
Reviewed-by: Vandita Kulkarni 
---
 drivers/gpu/drm/i915/display/icl_dsi.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c 
b/drivers/gpu/drm/i915/display/icl_dsi.c
index 44289003b709..060bc8fb0d30 100644
--- a/drivers/gpu/drm/i915/display/icl_dsi.c
+++ b/drivers/gpu/drm/i915/display/icl_dsi.c
@@ -1831,11 +1831,6 @@ static ssize_t gen11_dsi_host_transfer(struct 
mipi_dsi_host *host,
if (msg->flags & MIPI_DSI_MSG_USE_LPM)
enable_lpdt = true;
 
-   /* send packet header */
-   ret  = dsi_send_pkt_hdr(intel_dsi_host, dsi_pkt, enable_lpdt);
-   if (ret < 0)
-   return ret;
-
/* only long packet contains payload */
if (mipi_dsi_packet_format_is_long(msg->type)) {
ret = dsi_send_pkt_payld(intel_dsi_host, dsi_pkt);
@@ -1843,6 +1838,11 @@ static ssize_t gen11_dsi_host_transfer(struct 
mipi_dsi_host *host,
return ret;
}
 
+   /* send packet header */
+   ret  = dsi_send_pkt_hdr(intel_dsi_host, dsi_pkt, enable_lpdt);
+   if (ret < 0)
+   return ret;
+
//TODO: add payload receive code if needed
 
ret = sizeof(dsi_pkt.header) + dsi_pkt.payload_length;
-- 
2.17.1



[Intel-gfx] [v3 1/5] drm/i915/dsi: wait for header and payload credit available

2021-09-02 Thread Lee Shawn C
Driver should wait for free header or payload buffer in FIFO.
It would be good to wait a while for HW to release credit before
give it up to write to HW. Without sending initailize command
sets completely. It would caused MIPI display can't light up properly.

Cc: Ville Syrjala 
Cc: Jani Nikula 
Cc: Vandita Kulkarni 
Cc: Cooper Chiou 
Cc: William Tseng 
Signed-off-by: Lee Shawn C 
Reviewed-by: Vandita Kulkarni 
---
 drivers/gpu/drm/i915/display/icl_dsi.c | 40 --
 1 file changed, 19 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c 
b/drivers/gpu/drm/i915/display/icl_dsi.c
index a1e35180d5dd..44289003b709 100644
--- a/drivers/gpu/drm/i915/display/icl_dsi.c
+++ b/drivers/gpu/drm/i915/display/icl_dsi.c
@@ -55,20 +55,28 @@ static int payload_credits_available(struct 
drm_i915_private *dev_priv,
>> FREE_PLOAD_CREDIT_SHIFT;
 }
 
-static void wait_for_header_credits(struct drm_i915_private *dev_priv,
-   enum transcoder dsi_trans)
+static bool wait_for_header_credits(struct drm_i915_private *dev_priv,
+   enum transcoder dsi_trans, int hdr_credit)
 {
if (wait_for_us(header_credits_available(dev_priv, dsi_trans) >=
-   MAX_HEADER_CREDIT, 100))
+   hdr_credit, 100)) {
drm_err(_priv->drm, "DSI header credits not released\n");
+   return false;
+   }
+
+   return true;
 }
 
-static void wait_for_payload_credits(struct drm_i915_private *dev_priv,
-enum transcoder dsi_trans)
+static bool wait_for_payload_credits(struct drm_i915_private *dev_priv,
+enum transcoder dsi_trans, int 
payld_credit)
 {
if (wait_for_us(payload_credits_available(dev_priv, dsi_trans) >=
-   MAX_PLOAD_CREDIT, 100))
+   payld_credit, 100)) {
drm_err(_priv->drm, "DSI payload credits not released\n");
+   return false;
+   }
+
+   return true;
 }
 
 static enum transcoder dsi_port_to_transcoder(enum port port)
@@ -91,8 +99,8 @@ static void wait_for_cmds_dispatched_to_panel(struct 
intel_encoder *encoder)
/* wait for header/payload credits to be released */
for_each_dsi_port(port, intel_dsi->ports) {
dsi_trans = dsi_port_to_transcoder(port);
-   wait_for_header_credits(dev_priv, dsi_trans);
-   wait_for_payload_credits(dev_priv, dsi_trans);
+   wait_for_header_credits(dev_priv, dsi_trans, MAX_HEADER_CREDIT);
+   wait_for_payload_credits(dev_priv, dsi_trans, MAX_PLOAD_CREDIT);
}
 
/* send nop DCS command */
@@ -109,7 +117,7 @@ static void wait_for_cmds_dispatched_to_panel(struct 
intel_encoder *encoder)
/* wait for header credits to be released */
for_each_dsi_port(port, intel_dsi->ports) {
dsi_trans = dsi_port_to_transcoder(port);
-   wait_for_header_credits(dev_priv, dsi_trans);
+   wait_for_header_credits(dev_priv, dsi_trans, MAX_HEADER_CREDIT);
}
 
/* wait for LP TX in progress bit to be cleared */
@@ -127,18 +135,13 @@ static bool add_payld_to_queue(struct intel_dsi_host 
*host, const u8 *data,
struct intel_dsi *intel_dsi = host->intel_dsi;
struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev);
enum transcoder dsi_trans = dsi_port_to_transcoder(host->port);
-   int free_credits;
int i, j;
 
for (i = 0; i < len; i += 4) {
u32 tmp = 0;
 
-   free_credits = payload_credits_available(dev_priv, dsi_trans);
-   if (free_credits < 1) {
-   drm_err(_priv->drm,
-   "Payload credit not available\n");
+   if (!wait_for_payload_credits(dev_priv, dsi_trans, 1))
return false;
-   }
 
for (j = 0; j < min_t(u32, len - i, 4); j++)
tmp |= *data++ << 8 * j;
@@ -156,15 +159,10 @@ static int dsi_send_pkt_hdr(struct intel_dsi_host *host,
struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev);
enum transcoder dsi_trans = dsi_port_to_transcoder(host->port);
u32 tmp;
-   int free_credits;
 
/* check if header credit available */
-   free_credits = header_credits_available(dev_priv, dsi_trans);
-   if (free_credits < 1) {
-   drm_err(_priv->drm,
-   "send pkt header failed, not enough hdr credits\n");
+   if (!wait_for_header_credits(dev_priv, dsi_trans, 1))
return -1;
-   }
 
tmp = intel_de_read(dev_priv, DSI_CMD_TXHDR(dsi_trans));
 
-- 
2.17.1



[Intel-gfx] [v3 0/5] DSI driver improvement

2021-09-02 Thread Lee Shawn C
v2: Get data length of brightness value more easily while driver try to
read/write MIPI_DCS_DISPLAY_BRIGHTNESS command.
v3: fix checkpatch warning.

Signed-off-by: Lee Shawn C 

Lee Shawn C (5):
  drm/i915/dsi: wait for header and payload credit available
  drm/i915/dsi: refine send MIPI DCS command sequence
  drm/i915: Get proper min cdclk if vDSC enabled
  drm/i915/dsi: Retrieve max brightness level from VBT
  drm/i915/dsi: Read/write proper brightness value via MIPI DCS command

 drivers/gpu/drm/i915/display/icl_dsi.c| 50 +--
 drivers/gpu/drm/i915/display/intel_bios.c |  3 ++
 drivers/gpu/drm/i915/display/intel_cdclk.c| 10 
 .../i915/display/intel_dsi_dcs_backlight.c| 33 
 drivers/gpu/drm/i915/i915_drv.h   |  1 +
 5 files changed, 62 insertions(+), 35 deletions(-)

-- 
2.17.1



[Intel-gfx] [v2 5/5] drm/i915/dsi: Read/write proper brightness value via MIPI DCS command

2021-09-02 Thread Lee Shawn C
Driver has to swap the endian before send brightness level value
to tcon.

v2: Use __be16 instead of u16 to fix sparse warning.
v3: Send one or two bytes brightness value depend on the precision.
v4: get data length of brightness value more easily.

Reported-by: kernel test robot 
Cc: Ville Syrjala 
Cc: Jani Nikula 
Cc: Vandita Kulkarni 
Cc: Cooper Chiou 
Cc: William Tseng 
Signed-off-by: Lee Shawn C 
---
 .../i915/display/intel_dsi_dcs_backlight.c| 23 +--
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c 
b/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c
index 21ab9e1acb57..d2bf2bc9ae46 100644
--- a/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c
+++ b/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c
@@ -47,33 +47,42 @@ static u32 dcs_get_backlight(struct intel_connector 
*connector, enum pipe unused
 {
struct intel_encoder *encoder = intel_attached_encoder(connector);
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+   struct intel_panel *panel = >panel;
struct mipi_dsi_device *dsi_device;
-   u8 data = 0;
+   u8 data[2] = {};
enum port port;
+   size_t len = panel->backlight.max > U8_MAX ? 2 : 1;
 
-   /* FIXME: Need to take care of 16 bit brightness level */
for_each_dsi_port(port, intel_dsi->dcs_backlight_ports) {
dsi_device = intel_dsi->dsi_hosts[port]->device;
mipi_dsi_dcs_read(dsi_device, MIPI_DCS_GET_DISPLAY_BRIGHTNESS,
- , sizeof(data));
+ , len);
break;
}
 
-   return data;
+   return (data[1] << 8) | data[0];
 }
 
 static void dcs_set_backlight(const struct drm_connector_state *conn_state, 
u32 level)
 {
struct intel_dsi *intel_dsi = 
enc_to_intel_dsi(to_intel_encoder(conn_state->best_encoder));
+   struct intel_panel *panel = 
_intel_connector(conn_state->connector)->panel;
struct mipi_dsi_device *dsi_device;
-   u8 data = level;
+   u8 data[2] = {};
enum port port;
+   size_t len = panel->backlight.max > U8_MAX ? 2 : 1;
+
+   if (len == 1) {
+   data[0] = level;
+   } else {
+   data[0] = level >> 8;
+   data[1] = level;
+   }
 
-   /* FIXME: Need to take care of 16 bit brightness level */
for_each_dsi_port(port, intel_dsi->dcs_backlight_ports) {
dsi_device = intel_dsi->dsi_hosts[port]->device;
mipi_dsi_dcs_write(dsi_device, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
-  , sizeof(data));
+  , len);
}
 }
 
-- 
2.17.1



[Intel-gfx] [v2 4/5] drm/i915/dsi: Retrieve max brightness level from VBT

2021-09-02 Thread Lee Shawn C
So far, DCS backlight driver hardcode (0xFF) for max brightness level.
MIPI DCS spec allow max 0x for set_display_brightness (51h) command.
And VBT brightness precision bits can support 8 ~ 16 bits.

We should set correct precision bits in VBT that meet panel's request.
Driver can refer to this setting then configure max brightness level
in DCS backlight driver properly.

v2: modify variable name brightness_precision_bits instead of
max_brightness_level.

Cc: Ville Syrjala 
Cc: Jani Nikula 
Cc: Vandita Kulkarni 
Cc: Cooper Chiou 
Cc: William Tseng 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/i915/display/intel_bios.c  | 3 +++
 drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c | 8 ++--
 drivers/gpu/drm/i915/i915_drv.h| 1 +
 3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_bios.c 
b/drivers/gpu/drm/i915/display/intel_bios.c
index e86e6ed2d3bf..ccaf0a3100f7 100644
--- a/drivers/gpu/drm/i915/display/intel_bios.c
+++ b/drivers/gpu/drm/i915/display/intel_bios.c
@@ -483,6 +483,9 @@ parse_lfp_backlight(struct drm_i915_private *i915,
level = 255;
}
i915->vbt.backlight.min_brightness = min_level;
+
+   i915->vbt.backlight.brightness_precision_bits =
+   backlight_data->brightness_precision_bits[panel_type];
} else {
level = backlight_data->level[panel_type];
i915->vbt.backlight.min_brightness = entry->min_brightness;
diff --git a/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c 
b/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c
index 584c14c4cbd0..21ab9e1acb57 100644
--- a/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c
+++ b/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c
@@ -147,10 +147,14 @@ static void dcs_enable_backlight(const struct 
intel_crtc_state *crtc_state,
 static int dcs_setup_backlight(struct intel_connector *connector,
   enum pipe unused)
 {
+   struct drm_device *dev = connector->base.dev;
+   struct drm_i915_private *dev_priv = to_i915(dev);
struct intel_panel *panel = >panel;
 
-   panel->backlight.max = PANEL_PWM_MAX_VALUE;
-   panel->backlight.level = PANEL_PWM_MAX_VALUE;
+   panel->backlight.max = 
(dev_priv->vbt.backlight.brightness_precision_bits > 8) \
+  ? (1 << 
dev_priv->vbt.backlight.brightness_precision_bits) - 1 \
+  : PANEL_PWM_MAX_VALUE;
+   panel->backlight.level = panel->backlight.max;
 
return 0;
 }
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index be2392bbcecc..99a2d308b24d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -705,6 +705,7 @@ struct intel_vbt_data {
 
struct {
u16 pwm_freq_hz;
+   u16 brightness_precision_bits;
bool present;
bool active_low_pwm;
u8 min_brightness;  /* min_brightness/255 of max */
-- 
2.17.1



[Intel-gfx] [v2 2/5] drm/i915/dsi: refine send MIPI DCS command sequence

2021-09-02 Thread Lee Shawn C
According to chapter "Sending Commands to the Panel" in bspec #29738
and #49188. If driver try to send DCS long pakcet, we have to program
TX payload register at first. And configure TX header HW register later.
DSC long packet would not be sent properly if we don't follow this
sequence.

Cc: Ville Syrjala 
Cc: Jani Nikula 
Cc: Vandita Kulkarni 
Cc: Cooper Chiou 
Cc: William Tseng 
Signed-off-by: Lee Shawn C 
Reviewed-by: Vandita Kulkarni 
---
 drivers/gpu/drm/i915/display/icl_dsi.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c 
b/drivers/gpu/drm/i915/display/icl_dsi.c
index 44289003b709..060bc8fb0d30 100644
--- a/drivers/gpu/drm/i915/display/icl_dsi.c
+++ b/drivers/gpu/drm/i915/display/icl_dsi.c
@@ -1831,11 +1831,6 @@ static ssize_t gen11_dsi_host_transfer(struct 
mipi_dsi_host *host,
if (msg->flags & MIPI_DSI_MSG_USE_LPM)
enable_lpdt = true;
 
-   /* send packet header */
-   ret  = dsi_send_pkt_hdr(intel_dsi_host, dsi_pkt, enable_lpdt);
-   if (ret < 0)
-   return ret;
-
/* only long packet contains payload */
if (mipi_dsi_packet_format_is_long(msg->type)) {
ret = dsi_send_pkt_payld(intel_dsi_host, dsi_pkt);
@@ -1843,6 +1838,11 @@ static ssize_t gen11_dsi_host_transfer(struct 
mipi_dsi_host *host,
return ret;
}
 
+   /* send packet header */
+   ret  = dsi_send_pkt_hdr(intel_dsi_host, dsi_pkt, enable_lpdt);
+   if (ret < 0)
+   return ret;
+
//TODO: add payload receive code if needed
 
ret = sizeof(dsi_pkt.header) + dsi_pkt.payload_length;
-- 
2.17.1



[Intel-gfx] [v2 3/5] drm/i915: Get proper min cdclk if vDSC enabled

2021-09-02 Thread Lee Shawn C
VDSC engine can process only 1 pixel per Cd clock. In case
VDSC is used and max slice count == 1, max supported pixel
clock should be 100% of CD clock. Then do min_cdclk and
pixel clock comparison to get proper min cdclk.

v2:
- Check for dsc enable and slice count ==1 then allow to
  double confirm min cdclk value.

Cc: Ville Syrjala 
Cc: Jani Nikula 
Cc: Vandita Kulkarni 
Cc: Cooper Chiou 
Cc: William Tseng 
Signed-off-by: Lee Shawn C 
Reviewed-by: Vandita Kulkarni 
---
 drivers/gpu/drm/i915/display/intel_cdclk.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c 
b/drivers/gpu/drm/i915/display/intel_cdclk.c
index 34fa4130d5c4..9aec17b33819 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -2139,6 +2139,16 @@ int intel_crtc_compute_min_cdclk(const struct 
intel_crtc_state *crtc_state)
/* Account for additional needs from the planes */
min_cdclk = max(intel_planes_min_cdclk(crtc_state), min_cdclk);
 
+   /*
+* VDSC engine can process only 1 pixel per Cd clock.
+* In case VDSC is used and max slice count == 1,
+* max supported pixel clock should be 100% of CD clock.
+* Then do min_cdclk and pixel clock comparison to get cdclk.
+*/
+   if (crtc_state->dsc.compression_enable &&
+   crtc_state->dsc.slice_count == 1)
+   min_cdclk = max(min_cdclk, (int)crtc_state->pixel_rate);
+
/*
 * HACK. Currently for TGL platforms we calculate
 * min_cdclk initially based on pixel_rate divided
-- 
2.17.1



[Intel-gfx] [v2 0/5] DSI driver improvement

2021-09-02 Thread Lee Shawn C
v2: Get data length of brightness value more easily while driver try to
read/write MIPI_DCS_DISPLAY_BRIGHTNESS command.

Signed-off-by: Lee Shawn C 

Lee Shawn C (5):
  drm/i915/dsi: wait for header and payload credit available
  drm/i915/dsi: refine send MIPI DCS command sequence
  drm/i915: Get proper min cdclk if vDSC enabled
  drm/i915/dsi: Retrieve max brightness level from VBT
  drm/i915/dsi: Read/write proper brightness value via MIPI DCS command

 drivers/gpu/drm/i915/display/icl_dsi.c| 50 +--
 drivers/gpu/drm/i915/display/intel_bios.c |  3 ++
 drivers/gpu/drm/i915/display/intel_cdclk.c| 10 
 .../i915/display/intel_dsi_dcs_backlight.c| 31 
 drivers/gpu/drm/i915/i915_drv.h   |  1 +
 5 files changed, 60 insertions(+), 35 deletions(-)

-- 
2.17.1



[Intel-gfx] [v2 1/5] drm/i915/dsi: wait for header and payload credit available

2021-09-02 Thread Lee Shawn C
Driver should wait for free header or payload buffer in FIFO.
It would be good to wait a while for HW to release credit before
give it up to write to HW. Without sending initailize command
sets completely. It would caused MIPI display can't light up properly.

Cc: Ville Syrjala 
Cc: Jani Nikula 
Cc: Vandita Kulkarni 
Cc: Cooper Chiou 
Cc: William Tseng 
Signed-off-by: Lee Shawn C 
Reviewed-by: Vandita Kulkarni 
---
 drivers/gpu/drm/i915/display/icl_dsi.c | 40 --
 1 file changed, 19 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c 
b/drivers/gpu/drm/i915/display/icl_dsi.c
index a1e35180d5dd..44289003b709 100644
--- a/drivers/gpu/drm/i915/display/icl_dsi.c
+++ b/drivers/gpu/drm/i915/display/icl_dsi.c
@@ -55,20 +55,28 @@ static int payload_credits_available(struct 
drm_i915_private *dev_priv,
>> FREE_PLOAD_CREDIT_SHIFT;
 }
 
-static void wait_for_header_credits(struct drm_i915_private *dev_priv,
-   enum transcoder dsi_trans)
+static bool wait_for_header_credits(struct drm_i915_private *dev_priv,
+   enum transcoder dsi_trans, int hdr_credit)
 {
if (wait_for_us(header_credits_available(dev_priv, dsi_trans) >=
-   MAX_HEADER_CREDIT, 100))
+   hdr_credit, 100)) {
drm_err(_priv->drm, "DSI header credits not released\n");
+   return false;
+   }
+
+   return true;
 }
 
-static void wait_for_payload_credits(struct drm_i915_private *dev_priv,
-enum transcoder dsi_trans)
+static bool wait_for_payload_credits(struct drm_i915_private *dev_priv,
+enum transcoder dsi_trans, int 
payld_credit)
 {
if (wait_for_us(payload_credits_available(dev_priv, dsi_trans) >=
-   MAX_PLOAD_CREDIT, 100))
+   payld_credit, 100)) {
drm_err(_priv->drm, "DSI payload credits not released\n");
+   return false;
+   }
+
+   return true;
 }
 
 static enum transcoder dsi_port_to_transcoder(enum port port)
@@ -91,8 +99,8 @@ static void wait_for_cmds_dispatched_to_panel(struct 
intel_encoder *encoder)
/* wait for header/payload credits to be released */
for_each_dsi_port(port, intel_dsi->ports) {
dsi_trans = dsi_port_to_transcoder(port);
-   wait_for_header_credits(dev_priv, dsi_trans);
-   wait_for_payload_credits(dev_priv, dsi_trans);
+   wait_for_header_credits(dev_priv, dsi_trans, MAX_HEADER_CREDIT);
+   wait_for_payload_credits(dev_priv, dsi_trans, MAX_PLOAD_CREDIT);
}
 
/* send nop DCS command */
@@ -109,7 +117,7 @@ static void wait_for_cmds_dispatched_to_panel(struct 
intel_encoder *encoder)
/* wait for header credits to be released */
for_each_dsi_port(port, intel_dsi->ports) {
dsi_trans = dsi_port_to_transcoder(port);
-   wait_for_header_credits(dev_priv, dsi_trans);
+   wait_for_header_credits(dev_priv, dsi_trans, MAX_HEADER_CREDIT);
}
 
/* wait for LP TX in progress bit to be cleared */
@@ -127,18 +135,13 @@ static bool add_payld_to_queue(struct intel_dsi_host 
*host, const u8 *data,
struct intel_dsi *intel_dsi = host->intel_dsi;
struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev);
enum transcoder dsi_trans = dsi_port_to_transcoder(host->port);
-   int free_credits;
int i, j;
 
for (i = 0; i < len; i += 4) {
u32 tmp = 0;
 
-   free_credits = payload_credits_available(dev_priv, dsi_trans);
-   if (free_credits < 1) {
-   drm_err(_priv->drm,
-   "Payload credit not available\n");
+   if (!wait_for_payload_credits(dev_priv, dsi_trans, 1))
return false;
-   }
 
for (j = 0; j < min_t(u32, len - i, 4); j++)
tmp |= *data++ << 8 * j;
@@ -156,15 +159,10 @@ static int dsi_send_pkt_hdr(struct intel_dsi_host *host,
struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev);
enum transcoder dsi_trans = dsi_port_to_transcoder(host->port);
u32 tmp;
-   int free_credits;
 
/* check if header credit available */
-   free_credits = header_credits_available(dev_priv, dsi_trans);
-   if (free_credits < 1) {
-   drm_err(_priv->drm,
-   "send pkt header failed, not enough hdr credits\n");
+   if (!wait_for_header_credits(dev_priv, dsi_trans, 1))
return -1;
-   }
 
tmp = intel_de_read(dev_priv, DSI_CMD_TXHDR(dsi_trans));
 
-- 
2.17.1



[Intel-gfx] [PATCH 5/5] drm/i915/dsi: Read/write proper brightness value via MIPI DCS command

2021-09-01 Thread Lee Shawn C
Driver has to swap the endian before send brightness level value
to tcon.

v2: Use __be16 instead of u16 to fix sparse warning.
v3: Send one or two bytes brightness value depend on the precision.

Reported-by: kernel test robot 
Cc: Ville Syrjala 
Cc: Jani Nikula 
Cc: Vandita Kulkarni 
Cc: Cooper Chiou 
Cc: William Tseng 
Signed-off-by: Lee Shawn C 
---
 .../drm/i915/display/intel_dsi_dcs_backlight.c| 15 +--
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c 
b/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c
index 21ab9e1acb57..722411b5cb21 100644
--- a/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c
+++ b/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c
@@ -47,33 +47,36 @@ static u32 dcs_get_backlight(struct intel_connector 
*connector, enum pipe unused
 {
struct intel_encoder *encoder = intel_attached_encoder(connector);
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+   struct intel_panel *panel = >panel;
struct mipi_dsi_device *dsi_device;
-   u8 data = 0;
+   u8 data[2] = {0, 0};
enum port port;
 
/* FIXME: Need to take care of 16 bit brightness level */
for_each_dsi_port(port, intel_dsi->dcs_backlight_ports) {
dsi_device = intel_dsi->dsi_hosts[port]->device;
mipi_dsi_dcs_read(dsi_device, MIPI_DCS_GET_DISPLAY_BRIGHTNESS,
- , sizeof(data));
+ ,
+ (panel->backlight.max >> 8) ? sizeof(data) : 
1);
break;
}
 
-   return data;
+   return ((data[1] << 8) | data[0]);
 }
 
 static void dcs_set_backlight(const struct drm_connector_state *conn_state, 
u32 level)
 {
struct intel_dsi *intel_dsi = 
enc_to_intel_dsi(to_intel_encoder(conn_state->best_encoder));
+   struct intel_panel *panel = 
_intel_connector(conn_state->connector)->panel;
struct mipi_dsi_device *dsi_device;
-   u8 data = level;
+   __be16 data = cpu_to_be16(level);
enum port port;
 
-   /* FIXME: Need to take care of 16 bit brightness level */
for_each_dsi_port(port, intel_dsi->dcs_backlight_ports) {
dsi_device = intel_dsi->dsi_hosts[port]->device;
mipi_dsi_dcs_write(dsi_device, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
-  , sizeof(data));
+  ,
+  (panel->backlight.max >> 8) ? sizeof(data) : 
1);
}
 }
 
-- 
2.17.1



[Intel-gfx] [PATCH 4/5] drm/i915/dsi: Retrieve max brightness level from VBT

2021-09-01 Thread Lee Shawn C
So far, DCS backlight driver hardcode (0xFF) for max brightness level.
MIPI DCS spec allow max 0x for set_display_brightness (51h) command.
And VBT brightness precision bits can support 8 ~ 16 bits.

We should set correct precision bits in VBT that meet panel's request.
Driver can refer to this setting then configure max brightness level
in DCS backlight driver properly.

v2: modify variable name brightness_precision_bits instead of
max_brightness_level.

Cc: Ville Syrjala 
Cc: Jani Nikula 
Cc: Vandita Kulkarni 
Cc: Cooper Chiou 
Cc: William Tseng 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/i915/display/intel_bios.c  | 3 +++
 drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c | 8 ++--
 drivers/gpu/drm/i915/i915_drv.h| 1 +
 3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_bios.c 
b/drivers/gpu/drm/i915/display/intel_bios.c
index e86e6ed2d3bf..ccaf0a3100f7 100644
--- a/drivers/gpu/drm/i915/display/intel_bios.c
+++ b/drivers/gpu/drm/i915/display/intel_bios.c
@@ -483,6 +483,9 @@ parse_lfp_backlight(struct drm_i915_private *i915,
level = 255;
}
i915->vbt.backlight.min_brightness = min_level;
+
+   i915->vbt.backlight.brightness_precision_bits =
+   backlight_data->brightness_precision_bits[panel_type];
} else {
level = backlight_data->level[panel_type];
i915->vbt.backlight.min_brightness = entry->min_brightness;
diff --git a/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c 
b/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c
index 584c14c4cbd0..21ab9e1acb57 100644
--- a/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c
+++ b/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c
@@ -147,10 +147,14 @@ static void dcs_enable_backlight(const struct 
intel_crtc_state *crtc_state,
 static int dcs_setup_backlight(struct intel_connector *connector,
   enum pipe unused)
 {
+   struct drm_device *dev = connector->base.dev;
+   struct drm_i915_private *dev_priv = to_i915(dev);
struct intel_panel *panel = >panel;
 
-   panel->backlight.max = PANEL_PWM_MAX_VALUE;
-   panel->backlight.level = PANEL_PWM_MAX_VALUE;
+   panel->backlight.max = 
(dev_priv->vbt.backlight.brightness_precision_bits > 8) \
+  ? (1 << 
dev_priv->vbt.backlight.brightness_precision_bits) - 1 \
+  : PANEL_PWM_MAX_VALUE;
+   panel->backlight.level = panel->backlight.max;
 
return 0;
 }
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 005b1cec7007..1b42e39a7cd4 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -706,6 +706,7 @@ struct intel_vbt_data {
 
struct {
u16 pwm_freq_hz;
+   u16 brightness_precision_bits;
bool present;
bool active_low_pwm;
u8 min_brightness;  /* min_brightness/255 of max */
-- 
2.17.1



[Intel-gfx] [PATCH 3/5] drm/i915: Get proper min cdclk if vDSC enabled

2021-09-01 Thread Lee Shawn C
VDSC engine can process only 1 pixel per Cd clock. In case
VDSC is used and max slice count == 1, max supported pixel
clock should be 100% of CD clock. Then do min_cdclk and
pixel clock comparison to get proper min cdclk.

v2:
- Check for dsc enable and slice count ==1 then allow to
  double confirm min cdclk value.

Cc: Ville Syrjala 
Cc: Jani Nikula 
Cc: Vandita Kulkarni 
Cc: Cooper Chiou 
Cc: William Tseng 
Signed-off-by: Lee Shawn C 
Reviewed-by: Vandita Kulkarni 
---
 drivers/gpu/drm/i915/display/intel_cdclk.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c 
b/drivers/gpu/drm/i915/display/intel_cdclk.c
index 34fa4130d5c4..9aec17b33819 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -2139,6 +2139,16 @@ int intel_crtc_compute_min_cdclk(const struct 
intel_crtc_state *crtc_state)
/* Account for additional needs from the planes */
min_cdclk = max(intel_planes_min_cdclk(crtc_state), min_cdclk);
 
+   /*
+* VDSC engine can process only 1 pixel per Cd clock.
+* In case VDSC is used and max slice count == 1,
+* max supported pixel clock should be 100% of CD clock.
+* Then do min_cdclk and pixel clock comparison to get cdclk.
+*/
+   if (crtc_state->dsc.compression_enable &&
+   crtc_state->dsc.slice_count == 1)
+   min_cdclk = max(min_cdclk, (int)crtc_state->pixel_rate);
+
/*
 * HACK. Currently for TGL platforms we calculate
 * min_cdclk initially based on pixel_rate divided
-- 
2.17.1



  1   2   3   4   >