Re: [PATCH] drm/stm: dsi: relax mode_valid clock tolerance

2024-05-15 Thread Yannick FERTRE

Hi Sean,

thanks for your patch.

Tested-by: Yannick Fertre 

I think that a helper could be useful in simplifying this part.
This might be reworked when a new helper will be implemented.

Best regards


On 4/22/24 16:05, Sean Nyekjaer wrote:

On Fri, Mar 22, 2024 at 11:47:31AM +0100, Sean Nyekjaer wrote:

When using the DSI interface via DSI2LVDS bridge, it seems a bit harsh
to reguire the requested and the actual px clock to be within
50Hz. A typical LVDS display requires the px clock to be within +-10%.

In case for HDMI .5% tolerance is required.

Fixes: e01356d18273 ("drm/stm: dsi: provide the implementation of mode_valid()")
Signed-off-by: Sean Nyekjaer 
---

Any feedback on this?


  drivers/gpu/drm/stm/dw_mipi_dsi-stm.c | 7 +++
  1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c 
b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
index d5f8c923d7bc..97936b0ef702 100644
--- a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
+++ b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
@@ -322,8 +322,6 @@ dw_mipi_dsi_phy_get_timing(void *priv_data, unsigned int 
lane_mbps,
return 0;
  }
  
-#define CLK_TOLERANCE_HZ 50

-
  static enum drm_mode_status
  dw_mipi_dsi_stm_mode_valid(void *priv_data,
   const struct drm_display_mode *mode,
@@ -375,9 +373,10 @@ dw_mipi_dsi_stm_mode_valid(void *priv_data,
/*
 * Filter modes according to the clock value, particularly 
useful for
 * hdmi modes that require precise pixel clocks.
+* Check that px_clock is within .5% tolerance.
 */
-   if (px_clock_hz < target_px_clock_hz - CLK_TOLERANCE_HZ ||
-   px_clock_hz > target_px_clock_hz + CLK_TOLERANCE_HZ)
+   if (px_clock_hz < mult_frac(target_px_clock_hz, 995, 1000) ||
+   px_clock_hz > mult_frac(target_px_clock_hz, 1005, 1000))
return MODE_CLOCK_RANGE;
  
  		/* sync packets are codes as DSI short packets (4 bytes) */

--
2.44.0



Re: [PATCH v6 1/3] dt-bindings: display: add STM32 LVDS device

2024-03-18 Thread Yannick FERTRE

Hi Raphael,

thanks for the patch.
Acked-by: Yannick Fertre 

Best regards

On 2/26/24 11:48, Raphael Gallais-Pou wrote:

Add "st,stm32mp25-lvds" compatible.

Signed-off-by: Raphael Gallais-Pou 
Reviewed-by: Conor Dooley 
---
Depends on: "dt-bindings: stm32: add clocks and reset binding for
stm32mp25 platform" by Gabriel Fernandez

Changes in v6:
- Added Conor's Reviewed-by

Changes in v5:
- Fixed path in MAINTAINERS

Changes in v4:
- Align filename to compatible
- Fix compatible in the example
- Remove redundant word in the subject

Changes in v3:
- Clarify commit dependency
- Fix includes in the example
- Fix YAML
- Add "clock-cells" description
- s/regroups/is composed of/
- Changed compatible to show SoC specificity

Changes in v2:
- Switch compatible and clock-cells related areas
- Remove faulty #include in the example.
- Add entry in MAINTAINERS
---
  .../bindings/display/st,stm32mp25-lvds.yaml| 119 +
  MAINTAINERS|   1 +
  2 files changed, 120 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/st,stm32mp25-lvds.yaml 
b/Documentation/devicetree/bindings/display/st,stm32mp25-lvds.yaml
new file mode 100644
index ..6736f93256b5
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/st,stm32mp25-lvds.yaml
@@ -0,0 +1,119 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/st,stm32mp25-lvds.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: STMicroelectronics STM32 LVDS Display Interface Transmitter
+
+maintainers:
+  - Raphael Gallais-Pou 
+  - Yannick Fertre 
+
+description: |
+  The STMicroelectronics STM32 LVDS Display Interface Transmitter handles the
+  LVDS protocol: it maps the pixels received from the upstream Pixel-DMA (LTDC)
+  onto the LVDS PHY.
+
+  It is composed of three sub blocks:
+- LVDS host: handles the LVDS protocol (FPD / OpenLDI) and maps its input
+  pixels onto the data lanes of the PHY
+- LVDS PHY: parallelize the data and drives the LVDS data lanes
+- LVDS wrapper: handles top-level settings
+
+  The LVDS controller driver supports the following high-level features:
+- FDP-Link-I and OpenLDI (v0.95) protocols
+- Single-Link or Dual-Link operation
+- Single-Display or Double-Display (with the same content duplicated on 
both)
+- Flexible Bit-Mapping, including JEIDA and VESA
+- RGB888 or RGB666 output
+- Synchronous design, with one input pixel per clock cycle
+
+properties:
+  compatible:
+const: st,stm32mp25-lvds
+
+  "#clock-cells":
+const: 0
+description:
+  Provides the internal LVDS PHY clock to the framework.
+
+  reg:
+maxItems: 1
+
+  clocks:
+items:
+  - description: APB peripheral clock
+  - description: Reference clock for the internal PLL
+
+  clock-names:
+items:
+  - const: pclk
+  - const: ref
+
+  resets:
+maxItems: 1
+
+  ports:
+$ref: /schemas/graph.yaml#/properties/ports
+
+properties:
+  port@0:
+$ref: /schemas/graph.yaml#/properties/port
+description:
+  LVDS input port node, connected to the LTDC RGB output port.
+
+  port@1:
+$ref: /schemas/graph.yaml#/properties/port
+description:
+  LVDS output port node, connected to a panel or bridge input port.
+
+required:
+  - port@0
+  - port@1
+
+required:
+  - compatible
+  - "#clock-cells"
+  - reg
+  - clocks
+  - clock-names
+  - resets
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+#include 
+
+lvds: lvds@4806 {
+compatible = "st,stm32mp25-lvds";
+reg = <0x4806 0x2000>;
+#clock-cells = <0>;
+clocks = < CK_BUS_LVDS>, < CK_KER_LVDSPHY>;
+clock-names = "pclk", "ref";
+resets = < LVDS_R>;
+
+ports {
+#address-cells = <1>;
+#size-cells = <0>;
+
+port@0 {
+reg = <0>;
+lvds_in: endpoint {
+   remote-endpoint = <_ep1_out>;
+};
+};
+
+port@1 {
+reg = <1>;
+lvds_out0: endpoint {
+   remote-endpoint = <_panel_in>;
+};
+};
+};
+};
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 3527a2ece6cd..ff5c945f206e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7240,6 +7240,7 @@ L:dri-devel@lists.freedesktop.org
  S:Maintained
  T:git git://anongit.freedesktop.org/drm/drm-misc
  F:Documentation/devicetree/bindings/display/st,stm32-ltdc.yaml
+F: Documentation/devicetree/bindings/display/st,stm32mp25-lvds.yaml
  F:drivers/gpu/drm/stm
  
  DRM DRIVERS FOR TI KEYSTONE




Re: [PATCH v6 2/3] drm/stm: lvds: add new STM32 LVDS Display Interface Transmitter driver

2024-03-18 Thread Yannick FERTRE

Hi Raphael,

thanks for the patch.
Acked-by: Yannick Fertre 

Best regards

On 2/26/24 11:48, Raphael Gallais-Pou wrote:

The Low-Voltage Differential Signaling (LVDS) Display Interface
Transmitter handles the LVDS protocol: it maps the pixels received from
the upstream Pixel-DMA LCD-TFT Display Controller (LTDC) onto the LVDS
PHY.

It is composed of three sub blocks:
* LVDS host: handles the LVDS protocol (FPD / OpenLDI) and maps
  its input pixels onto the data lanes of the PHY
* LVDS PHY: parallelize the data and drives the LVDS data lanes
* LVDS wrapper: handles top-level settings

The LVDS controller driver supports the following high-level features:
* FDP-Link-I and OpenLDI (v0.95) protocols
* Single-Link or Dual-Link operation
* Single-Display or Double-Display (with the same content
  duplicated on both)
* Flexible Bit-Mapping, including JEIDA and VESA
* RGB888 or RGB666 output
* Synchronous design, with one input pixel per clock cycle

Signed-off-by: Raphael Gallais-Pou 
---
Changes in v6:
- Fixes sparse symbols detected by kernel test robot

Changes in v5:
- Align compatible

Changes in v4:
- Explicitly include linux/platform_device.h, dependency introduced by
ef175b29a242 of: Stop circularly including of_device.h and of_platform.h

Changes in v3:
- s/regroups/is composed of/ in commit log
- Change the compatible to show SoC specificity

Changes in v2:
- Fixed Camel Case macros
- Removed debug log
---
  drivers/gpu/drm/stm/Kconfig  |   11 +
  drivers/gpu/drm/stm/Makefile |2 +
  drivers/gpu/drm/stm/lvds.c   | 1226 ++
  3 files changed, 1239 insertions(+)

diff --git a/drivers/gpu/drm/stm/Kconfig b/drivers/gpu/drm/stm/Kconfig
index fa49cde43bb2..9627814d027c 100644
--- a/drivers/gpu/drm/stm/Kconfig
+++ b/drivers/gpu/drm/stm/Kconfig
@@ -20,3 +20,14 @@ config DRM_STM_DSI
select DRM_DW_MIPI_DSI
help
  Choose this option for MIPI DSI support on STMicroelectronics SoC.
+
+config DRM_STM_LVDS
+   tristate "STMicroelectronics LVDS Display Interface Transmitter DRM 
driver"
+   depends on DRM_STM
+   help
+ Enable support for LVDS encoders on STMicroelectronics SoC.
+ The STM LVDS is a bridge which serialize pixel stream onto
+ a LVDS protocol.
+
+ To compile this driver as a module, choose M here: the module will be
+ called lvds.
diff --git a/drivers/gpu/drm/stm/Makefile b/drivers/gpu/drm/stm/Makefile
index 4df5caf01f35..ad740d6175a6 100644
--- a/drivers/gpu/drm/stm/Makefile
+++ b/drivers/gpu/drm/stm/Makefile
@@ -5,4 +5,6 @@ stm-drm-y := \
  
  obj-$(CONFIG_DRM_STM_DSI) += dw_mipi_dsi-stm.o
  
+obj-$(CONFIG_DRM_STM_LVDS) += lvds.o

+
  obj-$(CONFIG_DRM_STM) += stm-drm.o
diff --git a/drivers/gpu/drm/stm/lvds.c b/drivers/gpu/drm/stm/lvds.c
new file mode 100644
index ..bfc8cb13fbc5
--- /dev/null
+++ b/drivers/gpu/drm/stm/lvds.c
@@ -0,0 +1,1226 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
+ * Author(s): Raphaël GALLAIS-POU  for 
STMicroelectronics.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* LVDS Host registers */
+#define LVDS_CR0x  /* configuration register */
+#define LVDS_DMLCR00x0004  /* data mapping lsb configuration register 0 */
+#define LVDS_DMMCR00x0008  /* data mapping msb configuration register 0 */
+#define LVDS_DMLCR10x000C  /* data mapping lsb configuration register 1 */
+#define LVDS_DMMCR10x0010  /* data mapping msb configuration register 1 */
+#define LVDS_DMLCR20x0014  /* data mapping lsb configuration register 2 */
+#define LVDS_DMMCR20x0018  /* data mapping msb configuration register 2 */
+#define LVDS_DMLCR30x001C  /* data mapping lsb configuration register 3 */
+#define LVDS_DMMCR30x0020  /* data mapping msb configuration register 3 */
+#define LVDS_DMLCR40x0024  /* data mapping lsb configuration register 4 */
+#define LVDS_DMMCR40x0028  /* data mapping msb configuration register 4 */
+#define LVDS_CDL1CR0x002C  /* channel distrib link 1 configuration 
register */
+#define LVDS_CDL2CR0x0030  /* channel distrib link 2 configuration 
register */
+
+#define CDL1CR_DEFAULT 0x04321 /* Default value for CDL1CR */
+#define CDL2CR_DEFAULT 0x59876 /* Default value for CDL2CR */
+
+#define LVDS_DMLCR(bit)(LVDS_DMLCR0 + 0x8 * (bit))
+#define LVDS_DMMCR(bit)(LVDS_DMMCR0 + 0x8 * (bit))
+
+/* LVDS Wrapper registers */
+#define LVDS_WCLKCR0x11B0  /* Wrapper clock control register */
+
+#define LVDS_HWCFGR0x1FF0  /* HW configuration register*/
+#define LVDS_VERR  0x1FF4  /* Version register *

Re: [PATCH] drm/stm: ltdc: fix late dereference check

2023-04-13 Thread Yannick FERTRE

Hi Raphael,

thanks for the patch.

Reviewed-by: Yannick Fertre 


On 4/12/23 11:25, Raphael GALLAIS-POU wrote:

Attention: Sender not authenticated
--

In ltdc_crtc_set_crc_source(), struct drm_crtc was dereferenced in a
container_of() before the pointer check. This could cause a kernel panic.

Fix this smatch warning:
drivers/gpu/drm/stm/ltdc.c:1124 ltdc_crtc_set_crc_source() warn: variable 
dereferenced before check 'crtc' (see line 1119)

Reported-by: kernel test robot 
Reported-by: Dan Carpenter 
Link: https://lore.kernel.org/lkml/202212241802.zelfzcxb-...@intel.com/
Signed-off-by: Raphael Gallais-Pou 
---
  drivers/gpu/drm/stm/ltdc.c | 4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index 03c6becda795..b8be4c1db423 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -1145,7 +1145,7 @@ static void ltdc_crtc_disable_vblank(struct drm_crtc 
*crtc)

  static int ltdc_crtc_set_crc_source(struct drm_crtc *crtc, const char *source)
  {
-   struct ltdc_device *ldev = crtc_to_ltdc(crtc);
+   struct ltdc_device *ldev;
 int ret;

 DRM_DEBUG_DRIVER("\n");
@@ -1153,6 +1153,8 @@ static int ltdc_crtc_set_crc_source(struct drm_crtc 
*crtc, const char *source)
 if (!crtc)
 return -ENODEV;

+   ldev = crtc_to_ltdc(crtc);
+
 if (source && strcmp(source, "auto") == 0) {
 ldev->crc_active = true;
 ret = regmap_set_bits(ldev->regmap, LTDC_GCR, GCR_CRCEN);
--
2.25.1



Re: [PATCH] drm/stm: Fix resolution bitmasks

2022-10-14 Thread Yannick FERTRE

Hi Marek,

The genmask of regsiter SSCR, BPCR & others were setted accordly to the 
chipset stm32f4.


You can see more details on page 493 of reference manual RM0090:

https://www.st.com/resource/en/reference_manual/DM00031020-.pdf

With future hardware, all of these registers will aligned on 16bits.

I would like to know if you use a display which resolution exceed 2048.

Best regards

Yannick Fertré


On 10/14/22 14:17, Yannick FERTRE wrote:

Hi Marek,

thanks for the patch.

Reviewed-by: Yannick Fertre 

On 10/12/22 01:10, Marek Vasut wrote:

STM32MP15xx RM0436 Rev 6 "35.7.3 LTDC synchronization size configuration
register (LTDC_SSCR)" on page 1784 and onward indicates VSH and similar
bits are all [11:0] instead of [10:0] wide. Fix this.

[1] https://www.st.com/resource/en/reference_manual/DM00327659-.pdf

Fixes: b759012c5fa7 ("drm/stm: Add STM32 LTDC driver")
Signed-off-by: Marek Vasut 
---
Cc: Alexandre Torgue 
Cc: Antonio Borneo 
Cc: Benjamin Gaignard 
Cc: Maxime Coquelin 
Cc: Philippe Cornu 
Cc: Sam Ravnborg 
Cc: Vincent Abriou 
Cc: Yannick Fertre 
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-st...@st-md-mailman.stormreply.com
To: dri-devel@lists.freedesktop.org
---
  drivers/gpu/drm/stm/ltdc.c | 8 
  1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index 03c6becda795c..639ed00b44a57 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -111,16 +111,16 @@
  #define LTDC_L1FPF1R    (ldev->caps.layer_regs[24])    /* L1 
Flexible Pixel Format 1 */

    /* Bit definitions */
-#define SSCR_VSH    GENMASK(10, 0)    /* Vertical Synchronization 
Height */
+#define SSCR_VSH    GENMASK(11, 0)    /* Vertical Synchronization 
Height */
  #define SSCR_HSW    GENMASK(27, 16)    /* Horizontal 
Synchronization Width */
  -#define BPCR_AVBP    GENMASK(10, 0)    /* Accumulated Vertical 
Back Porch */
+#define BPCR_AVBP    GENMASK(11, 0)    /* Accumulated Vertical Back 
Porch */
  #define BPCR_AHBP    GENMASK(27, 16)    /* Accumulated Horizontal 
Back Porch */

  -#define AWCR_AAH    GENMASK(10, 0)    /* Accumulated Active Height */
+#define AWCR_AAH    GENMASK(11, 0)    /* Accumulated Active Height */
  #define AWCR_AAW    GENMASK(27, 16)    /* Accumulated Active Width */
  -#define TWCR_TOTALH    GENMASK(10, 0)    /* TOTAL Height */
+#define TWCR_TOTALH    GENMASK(11, 0)    /* TOTAL Height */
  #define TWCR_TOTALW    GENMASK(27, 16)    /* TOTAL Width */
    #define GCR_LTDCEN    BIT(0)    /* LTDC ENable */

Re: [PATCH] drm/stm: Fix resolution bitmasks

2022-10-14 Thread Yannick FERTRE

Hi Marek,

thanks for the patch.

Reviewed-by: Yannick Fertre 

On 10/12/22 01:10, Marek Vasut wrote:

STM32MP15xx RM0436 Rev 6 "35.7.3 LTDC synchronization size configuration
register (LTDC_SSCR)" on page 1784 and onward indicates VSH and similar
bits are all [11:0] instead of [10:0] wide. Fix this.

[1] https://www.st.com/resource/en/reference_manual/DM00327659-.pdf

Fixes: b759012c5fa7 ("drm/stm: Add STM32 LTDC driver")
Signed-off-by: Marek Vasut 
---
Cc: Alexandre Torgue 
Cc: Antonio Borneo 
Cc: Benjamin Gaignard 
Cc: Maxime Coquelin 
Cc: Philippe Cornu 
Cc: Sam Ravnborg 
Cc: Vincent Abriou 
Cc: Yannick Fertre 
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-st...@st-md-mailman.stormreply.com
To: dri-devel@lists.freedesktop.org
---
  drivers/gpu/drm/stm/ltdc.c | 8 
  1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index 03c6becda795c..639ed00b44a57 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -111,16 +111,16 @@
  #define LTDC_L1FPF1R  (ldev->caps.layer_regs[24])  /* L1 Flexible Pixel 
Format 1 */
  
  /* Bit definitions */

-#define SSCR_VSH   GENMASK(10, 0)  /* Vertical Synchronization Height */
+#define SSCR_VSH   GENMASK(11, 0)  /* Vertical Synchronization Height */
  #define SSCR_HSW  GENMASK(27, 16) /* Horizontal Synchronization Width */
  
-#define BPCR_AVBP	GENMASK(10, 0)	/* Accumulated Vertical Back Porch */

+#define BPCR_AVBP  GENMASK(11, 0)  /* Accumulated Vertical Back Porch */
  #define BPCR_AHBP GENMASK(27, 16) /* Accumulated Horizontal Back Porch */
  
-#define AWCR_AAH	GENMASK(10, 0)	/* Accumulated Active Height */

+#define AWCR_AAH   GENMASK(11, 0)  /* Accumulated Active Height */
  #define AWCR_AAW  GENMASK(27, 16) /* Accumulated Active Width */
  
-#define TWCR_TOTALH	GENMASK(10, 0)	/* TOTAL Height */

+#define TWCR_TOTALHGENMASK(11, 0)  /* TOTAL Height */
  #define TWCR_TOTALW   GENMASK(27, 16) /* TOTAL Width */
  
  #define GCR_LTDCEN	BIT(0)		/* LTDC ENable */


[PATCH] drm/stm: ltdc: remove error message about scaling

2022-06-03 Thread Yannick Fertre
Remove error message about scaling & replace it by a debug
message to avoid too much error.

Signed-off-by: Yannick Fertre 
---
 drivers/gpu/drm/stm/ltdc.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index eeefc3260c07..a4098aaff243 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -1215,7 +1215,8 @@ static int ltdc_plane_atomic_check(struct drm_plane 
*plane,
 
/* Reject scaling */
if (src_w != new_plane_state->crtc_w || src_h != 
new_plane_state->crtc_h) {
-   DRM_ERROR("Scaling is not supported");
+   DRM_DEBUG_DRIVER("Scaling is not supported");
+
return -EINVAL;
}
 
-- 
2.25.1



[PATCH] drm/stm: ltdc: add support of the dynamic z-order

2022-06-03 Thread Yannick Fertre
Zpos property is immutable for all hardware versions except the last
version (0x40100) which support the blending order feature
(dynamic z-order).

Signed-off-by: Yannick Fertre 
---
 drivers/gpu/drm/stm/drv.c  |  1 +
 drivers/gpu/drm/stm/ltdc.c | 23 ---
 drivers/gpu/drm/stm/ltdc.h |  1 +
 3 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c
index 0da7cce2a1a2..c63945dc2260 100644
--- a/drivers/gpu/drm/stm/drv.c
+++ b/drivers/gpu/drm/stm/drv.c
@@ -95,6 +95,7 @@ static int drv_load(struct drm_device *ddev)
ddev->mode_config.max_width = STM_MAX_FB_WIDTH;
ddev->mode_config.max_height = STM_MAX_FB_HEIGHT;
ddev->mode_config.funcs = _mode_config_funcs;
+   ddev->mode_config.normalize_zpos = true;
 
ret = ltdc_load(ddev);
if (ret)
diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index 6a9f613839b5..00a6bc1b1d7c 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -194,6 +194,7 @@
 
 #define LXBFCR_BF2 GENMASK(2, 0)   /* Blending Factor 2 */
 #define LXBFCR_BF1 GENMASK(10, 8)  /* Blending Factor 1 */
+#define LXBFCR_BOR GENMASK(18, 16) /* Blending ORder */
 
 #define LXCFBLR_CFBLL  GENMASK(12, 0)  /* Color Frame Buffer Line Length */
 #define LXCFBLR_CFBP   GENMASK(28, 16) /* Color Frame Buffer Pitch in bytes */
@@ -1309,7 +1310,14 @@ static void ltdc_plane_atomic_update(struct drm_plane 
*plane,
plane->type != DRM_PLANE_TYPE_PRIMARY)
val = BF1_PAXCA | BF2_1PAXCA;
 
-   regmap_write_bits(ldev->regmap, LTDC_L1BFCR + lofs, LXBFCR_BF2 | 
LXBFCR_BF1, val);
+   if (ldev->caps.dynamic_zorder) {
+   val |= (newstate->normalized_zpos << 16);
+   regmap_write_bits(ldev->regmap, LTDC_L1BFCR + lofs,
+ LXBFCR_BF2 | LXBFCR_BF1 | LXBFCR_BOR, val);
+   } else {
+   regmap_write_bits(ldev->regmap, LTDC_L1BFCR + lofs,
+ LXBFCR_BF2 | LXBFCR_BF1, val);
+   }
 
/* Configures the frame buffer line number */
line_number = y1 - y0 + 1;
@@ -1578,7 +1586,10 @@ static int ltdc_crtc_init(struct drm_device *ddev, 
struct drm_crtc *crtc)
return -EINVAL;
}
 
-   drm_plane_create_zpos_immutable_property(primary, 0);
+   if (ldev->caps.dynamic_zorder)
+   drm_plane_create_zpos_property(primary, 0, 0, 
ldev->caps.nb_layers - 1);
+   else
+   drm_plane_create_zpos_immutable_property(primary, 0);
 
/* Init CRTC according to its hardware features */
if (ldev->caps.crc)
@@ -1607,7 +1618,10 @@ static int ltdc_crtc_init(struct drm_device *ddev, 
struct drm_crtc *crtc)
DRM_ERROR("Can not create overlay plane %d\n", i);
goto cleanup;
}
-   drm_plane_create_zpos_immutable_property(overlay, i);
+   if (ldev->caps.dynamic_zorder)
+   drm_plane_create_zpos_property(overlay, i, 0, 
ldev->caps.nb_layers - 1);
+   else
+   drm_plane_create_zpos_immutable_property(overlay, i);
}
 
return 0;
@@ -1737,6 +1751,7 @@ static int ltdc_get_caps(struct drm_device *ddev)
ldev->caps.ycbcr_output = false;
ldev->caps.plane_reg_shadow = false;
ldev->caps.crc = false;
+   ldev->caps.dynamic_zorder = false;
break;
case HWVER_20101:
ldev->caps.layer_ofs = LAY_OFS_0;
@@ -1752,6 +1767,7 @@ static int ltdc_get_caps(struct drm_device *ddev)
ldev->caps.ycbcr_output = false;
ldev->caps.plane_reg_shadow = false;
ldev->caps.crc = false;
+   ldev->caps.dynamic_zorder = false;
break;
case HWVER_40100:
ldev->caps.layer_ofs = LAY_OFS_1;
@@ -1767,6 +1783,7 @@ static int ltdc_get_caps(struct drm_device *ddev)
ldev->caps.ycbcr_output = true;
ldev->caps.plane_reg_shadow = true;
ldev->caps.crc = true;
+   ldev->caps.dynamic_zorder = true;
break;
default:
return -ENODEV;
diff --git a/drivers/gpu/drm/stm/ltdc.h b/drivers/gpu/drm/stm/ltdc.h
index 59fc5d1bbbab..4855898bd4c0 100644
--- a/drivers/gpu/drm/stm/ltdc.h
+++ b/drivers/gpu/drm/stm/ltdc.h
@@ -28,6 +28,7 @@ struct ltdc_caps {
bool ycbcr_output;  /* ycbcr output converter supported */
bool plane_reg_shadow;  /* plane shadow registers ability */
bool crc;   /* cyclic redundancy check supported */
+   bool dynamic_zorder;/* dynamic z-order */
 };
 
 #define LTDC_MAX_LAYER 4
-- 
2.25.1



[PATCH] drm/stm: ltdc: disable all layers before crtc shutdown

2022-06-03 Thread Yannick Fertre
All plans must be disabled before the CRTC shutdown helping
the crtc to restart from a clean situation (without unwanted
planes already enable).

Signed-off-by: Yannick Fertre 
---
 drivers/gpu/drm/stm/ltdc.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index 6bd45df8f5a7..eeefc3260c07 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -787,11 +787,17 @@ static void ltdc_crtc_atomic_disable(struct drm_crtc 
*crtc,
 {
struct ltdc_device *ldev = crtc_to_ltdc(crtc);
struct drm_device *ddev = crtc->dev;
+   int layer_index = 0;
 
DRM_DEBUG_DRIVER("\n");
 
drm_crtc_vblank_off(crtc);
 
+   /* Disable all layers */
+   for (layer_index = 0; layer_index < ldev->caps.nb_layers; layer_index++)
+   regmap_write_bits(ldev->regmap, LTDC_L1CR + layer_index * 
LAY_OFS,
+ LXCR_CLUTEN | LXCR_LEN, 0);
+
/* disable IRQ */
regmap_clear_bits(ldev->regmap, LTDC_IER, IER_RRIE | IER_FUIE | 
IER_TERRIE);
 
-- 
2.25.1



[PATCH] drm/stm: ltdc: fix various coding-style warnings

2022-06-03 Thread Yannick Fertre
Fix issues reported by checkpatch.pl:
- Braces {} should be used on all arms
- Blank lines

Signed-off-by: Yannick Fertre 
---
 drivers/gpu/drm/stm/ltdc.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index a4098aaff243..6a9f613839b5 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -908,9 +908,9 @@ static void ltdc_crtc_mode_set_nofb(struct drm_crtc *crtc)
drm_connector_list_iter_end();
}
 
-   if (bridge && bridge->timings)
+   if (bridge && bridge->timings) {
bus_flags = bridge->timings->input_bus_flags;
-   else if (connector) {
+   } else if (connector) {
bus_flags = connector->display_info.bus_flags;
if (connector->display_info.num_bus_formats)
bus_formats = connector->display_info.bus_formats[0];
@@ -1917,7 +1917,6 @@ int ltdc_load(struct drm_device *ddev)
DRM_ERROR("Failed to register LTDC interrupt\n");
goto err;
}
-
}
 
crtc = devm_kzalloc(dev, sizeof(*crtc), GFP_KERNEL);
-- 
2.25.1



[PATCH] drm/stm: ltdc: add support of horizontal & vertical mirroring

2022-06-03 Thread Yannick Fertre
Support of vertical & horizontal mirroring features thanks to
the plane rotation property.

Signed-off-by: Yannick Fertre 
---
 drivers/gpu/drm/stm/ltdc.c | 163 -
 drivers/gpu/drm/stm/ltdc.h |   1 +
 2 files changed, 108 insertions(+), 56 deletions(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index 00a6bc1b1d7c..ff2075dd9474 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -180,6 +180,7 @@
 #define LXCR_LEN   BIT(0)  /* Layer ENable */
 #define LXCR_COLKENBIT(1)  /* Color Keying Enable */
 #define LXCR_CLUTENBIT(4)  /* Color Look-Up Table ENable */
+#define LXCR_HMEN  BIT(8)  /* Horizontal Mirroring ENable */
 
 #define LXWHPCR_WHSTPOSGENMASK(11, 0)  /* Window Horizontal StarT 
POSition */
 #define LXWHPCR_WHSPPOSGENMASK(27, 16) /* Window Horizontal StoP 
POSition */
@@ -197,7 +198,7 @@
 #define LXBFCR_BOR GENMASK(18, 16) /* Blending ORder */
 
 #define LXCFBLR_CFBLL  GENMASK(12, 0)  /* Color Frame Buffer Line Length */
-#define LXCFBLR_CFBP   GENMASK(28, 16) /* Color Frame Buffer Pitch in bytes */
+#define LXCFBLR_CFBP   GENMASK(31, 16) /* Color Frame Buffer Pitch in bytes */
 
 #define LXCFBLNR_CFBLN GENMASK(10, 0)  /* Color Frame Buffer Line Number */
 
@@ -1237,7 +1238,8 @@ static void ltdc_plane_atomic_update(struct drm_plane 
*plane,
u32 y0 = newstate->crtc_y;
u32 y1 = newstate->crtc_y + newstate->crtc_h - 1;
u32 src_x, src_y, src_w, src_h;
-   u32 val, pitch_in_bytes, line_length, line_number, paddr, ahbp, avbp, 
bpcr;
+   u32 val, pitch_in_bytes, line_length, line_number, ahbp, avbp, bpcr;
+   u32 paddr, paddr1, paddr2;
enum ltdc_pix_fmt pf;
 
if (!newstate->crtc || !fb) {
@@ -1289,13 +1291,6 @@ static void ltdc_plane_atomic_update(struct drm_plane 
*plane,
}
regmap_write_bits(ldev->regmap, LTDC_L1PFCR + lofs, LXPFCR_PF, val);
 
-   /* Configures the color frame buffer pitch in bytes & line length */
-   pitch_in_bytes = fb->pitches[0];
-   line_length = fb->format->cpp[0] *
- (x1 - x0 + 1) + (ldev->caps.bus_width >> 3) - 1;
-   val = ((pitch_in_bytes << 16) | line_length);
-   regmap_write_bits(ldev->regmap, LTDC_L1CFBLR + lofs, LXCFBLR_CFBLL | 
LXCFBLR_CFBP, val);
-
/* Specifies the constant alpha value */
val = newstate->alpha >> 8;
regmap_write_bits(ldev->regmap, LTDC_L1CACR + lofs, LXCACR_CONSTA, val);
@@ -1319,76 +1314,115 @@ static void ltdc_plane_atomic_update(struct drm_plane 
*plane,
  LXBFCR_BF2 | LXBFCR_BF1, val);
}
 
-   /* Configures the frame buffer line number */
-   line_number = y1 - y0 + 1;
-   regmap_write_bits(ldev->regmap, LTDC_L1CFBLNR + lofs, LXCFBLNR_CFBLN, 
line_number);
-
/* Sets the FB address */
paddr = (u32)drm_fb_cma_get_gem_addr(fb, newstate, 0);
 
+   if (newstate->rotation & DRM_MODE_REFLECT_X)
+   paddr += (fb->format->cpp[0] * (x1 - x0 + 1)) - 1;
+
+   if (newstate->rotation & DRM_MODE_REFLECT_Y)
+   paddr += (fb->pitches[0] * (y1 - y0));
+
DRM_DEBUG_DRIVER("fb: phys 0x%08x", paddr);
regmap_write(ldev->regmap, LTDC_L1CFBAR + lofs, paddr);
 
+   /* Configures the color frame buffer pitch in bytes & line length */
+   line_length = fb->format->cpp[0] *
+ (x1 - x0 + 1) + (ldev->caps.bus_width >> 3) - 1;
+
+   if (newstate->rotation & DRM_MODE_REFLECT_Y)
+   /* Compute negative value (signed on 16 bits) for the picth */
+   pitch_in_bytes = 0x1 - fb->pitches[0];
+   else
+   pitch_in_bytes = fb->pitches[0];
+
+   val = (pitch_in_bytes << 16) | line_length;
+   regmap_write_bits(ldev->regmap, LTDC_L1CFBLR + lofs, LXCFBLR_CFBLL | 
LXCFBLR_CFBP, val);
+
+   /* Configures the frame buffer line number */
+   line_number = y1 - y0 + 1;
+   regmap_write_bits(ldev->regmap, LTDC_L1CFBLNR + lofs, LXCFBLNR_CFBLN, 
line_number);
+
if (ldev->caps.ycbcr_input) {
if (fb->format->is_yuv) {
switch (fb->format->format) {
case DRM_FORMAT_NV12:
case DRM_FORMAT_NV21:
-   /* Configure the auxiliary frame buffer address 0 & 1 */
-   paddr = (u32)drm_fb_cma_get_gem_addr(fb, newstate, 1);
-   regmap_write(ldev->regmap, LTDC_L1AFBA0R + lofs, paddr);
-   regmap_write(ldev->regmap, LTDC_L1AFBA1R + lofs, paddr 
+ 1);
+   /* Configure the auxiliary frame buffer address 0 */
+   paddr1 = (u32)drm_fb_cma_get_gem_addr(fb, 

[PATCH] drm/stm: ltdc: update hardware error management

2022-06-03 Thread Yannick Fertre
The latest hardware version (0x40100) supports a hardware threshold
register (aka FUTR) to trigger a fifo underrun interrupt.
A software threshold has been implemented for other hardware versions.
The threshold is set to 128 by default.

Signed-off-by: Yannick Fertre 
---
 drivers/gpu/drm/stm/ltdc.c | 90 ++
 drivers/gpu/drm/stm/ltdc.h |  6 ++-
 2 files changed, 77 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index ff2075dd9474..42a3bd515477 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -162,16 +162,20 @@
 #define BCCR_BCWHITE   GENMASK(23, 0)  /* Background Color WHITE */
 
 #define IER_LIEBIT(0)  /* Line Interrupt Enable */
-#define IER_FUIE   BIT(1)  /* Fifo Underrun Interrupt Enable */
+#define IER_FUWIE  BIT(1)  /* Fifo Underrun Warning Interrupt 
Enable */
 #define IER_TERRIE BIT(2)  /* Transfer ERRor Interrupt Enable */
-#define IER_RRIE   BIT(3)  /* Register Reload Interrupt enable */
+#define IER_RRIE   BIT(3)  /* Register Reload Interrupt Enable */
+#define IER_FUEIE  BIT(6)  /* Fifo Underrun Error Interrupt Enable 
*/
+#define IER_CRCIE  BIT(7)  /* CRC Error Interrupt Enable */
 
 #define CPSR_CYPOS GENMASK(15, 0)  /* Current Y position */
 
 #define ISR_LIFBIT(0)  /* Line Interrupt Flag */
-#define ISR_FUIF   BIT(1)  /* Fifo Underrun Interrupt Flag */
+#define ISR_FUWIF  BIT(1)  /* Fifo Underrun Warning Interrupt Flag 
*/
 #define ISR_TERRIF BIT(2)  /* Transfer ERRor Interrupt Flag */
 #define ISR_RRIF   BIT(3)  /* Register Reload Interrupt Flag */
+#define ISR_FUEIF  BIT(6)  /* Fifo Underrun Error Interrupt Flag */
+#define ISR_CRCIF  BIT(7)  /* CRC Error Interrupt Flag */
 
 #define EDCR_OCYEN BIT(25) /* Output Conversion to YCbCr 422: 
ENable */
 #define EDCR_OCYSELBIT(26) /* Output Conversion to YCbCr 422: 
SELection of the CCIR */
@@ -231,6 +235,8 @@
 
 #define NB_PF  8   /* Max nb of HW pixel format */
 
+#define FUT_DFT128 /* Default value of fifo 
underrun threshold */
+
 /*
  * Skip the first value and the second in case CRC was enabled during
  * the thread irq. This is to be sure CRC value is relevant for the
@@ -711,12 +717,13 @@ static irqreturn_t ltdc_irq_thread(int irq, void *arg)
ltdc_irq_crc_handle(ldev, crtc);
}
 
-   /* Save FIFO Underrun & Transfer Error status */
mutex_lock(>err_lock);
-   if (ldev->irq_status & ISR_FUIF)
-   ldev->error_status |= ISR_FUIF;
if (ldev->irq_status & ISR_TERRIF)
-   ldev->error_status |= ISR_TERRIF;
+   ldev->transfer_err++;
+   if (ldev->irq_status & ISR_FUEIF)
+   ldev->fifo_err++;
+   if (ldev->irq_status & ISR_FUWIF)
+   ldev->fifo_warn++;
mutex_unlock(>err_lock);
 
return IRQ_HANDLED;
@@ -775,7 +782,7 @@ static void ltdc_crtc_atomic_enable(struct drm_crtc *crtc,
regmap_write(ldev->regmap, LTDC_BCCR, BCCR_BCBLACK);
 
/* Enable IRQ */
-   regmap_set_bits(ldev->regmap, LTDC_IER, IER_RRIE | IER_FUIE | 
IER_TERRIE);
+   regmap_set_bits(ldev->regmap, LTDC_IER, IER_FUWIE | IER_FUEIE | 
IER_RRIE | IER_TERRIE);
 
/* Commit shadow registers = update planes at next vblank */
if (!ldev->caps.plane_reg_shadow)
@@ -801,13 +808,20 @@ static void ltdc_crtc_atomic_disable(struct drm_crtc 
*crtc,
  LXCR_CLUTEN | LXCR_LEN, 0);
 
/* disable IRQ */
-   regmap_clear_bits(ldev->regmap, LTDC_IER, IER_RRIE | IER_FUIE | 
IER_TERRIE);
+   regmap_clear_bits(ldev->regmap, LTDC_IER, IER_FUWIE | IER_FUEIE | 
IER_RRIE | IER_TERRIE);
 
/* immediately commit disable of layers before switching off LTDC */
if (!ldev->caps.plane_reg_shadow)
regmap_set_bits(ldev->regmap, LTDC_SRCR, SRCR_IMR);
 
pm_runtime_put_sync(ddev->dev);
+
+   /*  clear interrupt error counters */
+   mutex_lock(>err_lock);
+   ldev->transfer_err = 0;
+   ldev->fifo_err = 0;
+   ldev->fifo_warn = 0;
+   mutex_unlock(>err_lock);
 }
 
 #define CLK_TOLERANCE_HZ 50
@@ -1168,6 +1182,18 @@ static int ltdc_crtc_verify_crc_source(struct drm_crtc 
*crtc,
return 0;
 }
 
+static void ltdc_crtc_atomic_print_state(struct drm_printer *p,
+const struct drm_crtc_state *state)
+{
+   struct drm_crtc *crtc = state->crtc;
+   struct ltdc_device *ldev = crtc_to_ltdc(crtc);
+
+   drm_printf(p, "\ttransfer_error=%d\n", ldev->transfer_err);
+   drm_printf(p, "

Re: [PATCH] drm/stm: ltdc: add support for CRC hashing feature

2022-02-22 Thread yannick Fertre

Hi Raphael,
thanks for the patch.

Acked-by: Yannick Fertre 

Best regards


On 2/11/22 11:46, Raphaël Gallais-Pou wrote:

From: Raphael Gallais-Pou 

This patch adds the CRC hashing feature supported by some recent hardware
versions of the LTDC. This is useful for test suite such as IGT-GPU-tools
[1] where a CRTC output frame can be compared to a test reference frame
thanks to their respective CRC hash.

[1] https://cgit.freedesktop.org/drm/igt-gpu-tools

Signed-off-by: Raphael Gallais-Pou 
---
  drivers/gpu/drm/stm/ltdc.c | 104 +++--
  drivers/gpu/drm/stm/ltdc.h |   3 ++
  2 files changed, 104 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index 5eeb32c9c9ce..b29476aec3a1 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -77,6 +77,7 @@
  #define LTDC_CPSR 0x0044  /* Current Position Status */
  #define LTDC_CDSR 0x0048  /* Current Display Status */
  #define LTDC_EDCR 0x0060  /* External Display Control */
+#define LTDC_CCRCR 0x007C  /* Computed CRC value */
  #define LTDC_FUT  0x0090  /* Fifo underrun Threshold */
  
  /* Layer register offsets */

@@ -121,6 +122,7 @@
  
  #define GCR_LTDCEN	BIT(0)		/* LTDC ENable */

  #define GCR_DEN   BIT(16) /* Dither ENable */
+#define GCR_CRCEN  BIT(19) /* CRC ENable */
  #define GCR_PCPOL BIT(28) /* Pixel Clock POLarity-Inverted */
  #define GCR_DEPOL BIT(29) /* Data Enable POLarity-High */
  #define GCR_VSPOL BIT(30) /* Vertical Synchro POLarity-High */
@@ -227,6 +229,13 @@
  
  #define NB_PF		8		/* Max nb of HW pixel format */
  
+/*

+ * Skip the first value and the second in case CRC was enabled during
+ * the thread irq. This is to be sure CRC value is relevant for the
+ * frame.
+ */
+#define CRC_SKIP_FRAMES 2
+
  enum ltdc_pix_fmt {
PF_NONE,
/* RGB formats */
@@ -664,6 +673,26 @@ static inline void ltdc_set_ycbcr_coeffs(struct drm_plane 
*plane)
 ltdc_ycbcr2rgb_coeffs[enc][ran][1]);
  }
  
+static inline void ltdc_irq_crc_handle(struct ltdc_device *ldev,

+  struct drm_crtc *crtc)
+{
+   u32 crc;
+   int ret;
+
+   if (ldev->crc_skip_count < CRC_SKIP_FRAMES) {
+   ldev->crc_skip_count++;
+   return;
+   }
+
+   /* Get the CRC of the frame */
+   ret = regmap_read(ldev->regmap, LTDC_CCRCR, );
+   if (ret)
+   return;
+
+   /* Report to DRM the CRC (hw dependent feature) */
+   drm_crtc_add_crc_entry(crtc, true, drm_crtc_accurate_vblank_count(crtc), 
);
+}
+
  static irqreturn_t ltdc_irq_thread(int irq, void *arg)
  {
struct drm_device *ddev = arg;
@@ -671,9 +700,14 @@ static irqreturn_t ltdc_irq_thread(int irq, void *arg)
struct drm_crtc *crtc = drm_crtc_from_index(ddev, 0);
  
  	/* Line IRQ : trigger the vblank event */

-   if (ldev->irq_status & ISR_LIF)
+   if (ldev->irq_status & ISR_LIF) {
drm_crtc_handle_vblank(crtc);
  
+		/* Early return if CRC is not active */

+   if (ldev->crc_active)
+   ltdc_irq_crc_handle(ldev, crtc);
+   }
+
/* Save FIFO Underrun & Transfer Error status */
mutex_lock(>err_lock);
if (ldev->irq_status & ISR_FUIF)
@@ -1079,6 +1113,48 @@ static void ltdc_crtc_disable_vblank(struct drm_crtc 
*crtc)
regmap_clear_bits(ldev->regmap, LTDC_IER, IER_LIE);
  }
  
+static int ltdc_crtc_set_crc_source(struct drm_crtc *crtc, const char *source)

+{
+   struct ltdc_device *ldev = crtc_to_ltdc(crtc);
+   int ret;
+
+   DRM_DEBUG_DRIVER("\n");
+
+   if (!crtc)
+   return -ENODEV;
+
+   if (source && strcmp(source, "auto") == 0) {
+   ldev->crc_active = true;
+   ret = regmap_set_bits(ldev->regmap, LTDC_GCR, GCR_CRCEN);
+   } else if (!source) {
+   ldev->crc_active = false;
+   ret = regmap_clear_bits(ldev->regmap, LTDC_GCR, GCR_CRCEN);
+   } else {
+   ret = -EINVAL;
+   }
+
+   ldev->crc_skip_count = 0;
+   return ret;
+}
+
+static int ltdc_crtc_verify_crc_source(struct drm_crtc *crtc,
+  const char *source, size_t *values_cnt)
+{
+   DRM_DEBUG_DRIVER("\n");
+
+   if (!crtc)
+   return -ENODEV;
+
+   if (source && strcmp(source, "auto") != 0) {
+   DRM_DEBUG_DRIVER("Unknown CRC source %s for %s\n",
+source, crtc->name);
+   return -EINVAL;
+   }
+
+   *values_cnt = 1;
+   return 0;
+}
+
  static const struct drm_crtc_funcs ltdc_crtc_funcs = {
.destroy = drm_crtc_clea

Re: [PATCH] drm/stm: Avoid using val uninitialized in ltdc_set_ycbcr_config()

2022-02-08 Thread yannick Fertre

Hi Nathan,
Thenks for the patch.

Acked-by: Yannick Fertre 

Best regards

On 2/7/22 17:53, Nathan Chancellor wrote:

Clang warns:

   drivers/gpu/drm/stm/ltdc.c:625:2: warning: variable 'val' is used 
uninitialized whenever switch default is taken [-Wsometimes-uninitialized]
   default:
   ^~~
   drivers/gpu/drm/stm/ltdc.c:635:2: note: uninitialized use occurs here
   val |= LxPCR_YCEN;
   ^~~
   drivers/gpu/drm/stm/ltdc.c:600:9: note: initialize the variable 'val' to 
silence this warning
   u32 val;
  ^
   = 0
   1 warning generated.

Use a return instead of break in the default case to fix the warning.
Add an error message so that this return is not silent, which could hide
issues in the future.

Fixes: 484e72d3146b ("drm/stm: ltdc: add support of ycbcr pixel formats")
Link: https://github.com/ClangBuiltLinux/linux/issues/1575
Signed-off-by: Nathan Chancellor 
---
  drivers/gpu/drm/stm/ltdc.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index 5eeb32c9c9ce..447ddde1786c 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -624,7 +624,8 @@ static inline void ltdc_set_ycbcr_config(struct drm_plane 
*plane, u32 drm_pix_fm
break;
default:
/* RGB or not a YCbCr supported format */
-   break;
+   drm_err(plane->dev, "Unsupported pixel format: %u\n", 
drm_pix_fmt);
+   return;
}
  
  	/* Enable limited range */


base-commit: 542898c5aa5c6a3179dffb1d1606884a63f75fed


Re: [PATCH 5/5] drm/stm: ltdc: add support of ycbcr pixel formats

2022-02-07 Thread yannick Fertre

Hi Nathan,

On 2/2/22 17:54, Nathan Chancellor wrote:

Hi Yannick,

On Wed, Dec 15, 2021 at 10:48:43PM +0100, Yannick Fertre wrote:

This patch adds the following YCbCr input pixel formats on the latest
LTDC hardware version:

1 plane  (co-planar)  : YUYV, YVYU, UYVY, VYUY
2 planes (semi-planar): NV12, NV21
3 planes (full-planar): YU12=I420=DRM YUV420, YV12=DRM YVU420

Signed-off-by: Yannick Fertre 





+static inline void ltdc_set_ycbcr_config(struct drm_plane *plane, u32 
drm_pix_fmt)
+{
+   struct ltdc_device *ldev = plane_to_ltdc(plane);
+   struct drm_plane_state *state = plane->state;
+   u32 lofs = plane->index * LAY_OFS;
+   u32 val;
+
+   switch (drm_pix_fmt) {
+   case DRM_FORMAT_YUYV:
+   val = (YCM_I << 4) | LxPCR_YF | LxPCR_CBF;
+   break;
+   case DRM_FORMAT_YVYU:
+   val = (YCM_I << 4) | LxPCR_YF;
+   break;
+   case DRM_FORMAT_UYVY:
+   val = (YCM_I << 4) | LxPCR_CBF;
+   break;
+   case DRM_FORMAT_VYUY:
+   val = (YCM_I << 4);
+   break;
+   case DRM_FORMAT_NV12:
+   val = (YCM_SP << 4) | LxPCR_CBF;
+   break;
+   case DRM_FORMAT_NV21:
+   val = (YCM_SP << 4);
+   break;
+   case DRM_FORMAT_YUV420:
+   case DRM_FORMAT_YVU420:
+   val = (YCM_FP << 4);
+   break;
+   default:
+   /* RGB or not a YCbCr supported format */
+   break;
+   }
+
+   /* Enable limited range */
+   if (state->color_range == DRM_COLOR_YCBCR_LIMITED_RANGE)
+   val |= LxPCR_YREN;
+
+   /* enable ycbcr conversion */
+   val |= LxPCR_YCEN;
+
+   regmap_write(ldev->regmap, LTDC_L1PCR + lofs, val);
+}


This patch as commit 484e72d3146b ("drm/stm: ltdc: add support of ycbcr
pixel formats") in -next introduced the following clang warning:

drivers/gpu/drm/stm/ltdc.c:625:2: warning: variable 'val' is used uninitialized 
whenever switch default is taken [-Wsometimes-uninitialized]
 default:
 ^~~
drivers/gpu/drm/stm/ltdc.c:635:2: note: uninitialized use occurs here
 val |= LxPCR_YCEN;
 ^~~
drivers/gpu/drm/stm/ltdc.c:600:9: note: initialize the variable 'val' to 
silence this warning
 u32 val;
^
 = 0
1 warning generated.

Would it be okay to just return in the default case (maybe with a
message about an unsupported format?) or should there be another fix?

Cheers,



Thanks for your help.
It'okay for a message for unsupported format with a return in the 
default case.

Do you want create & push the patch?

Best regards


Re: [PATCH v2 6/6] drm/stm: ltdc: Drop format_mod_supported function

2022-01-12 Thread yannick Fertre

Hello José,
thanks for your patch.

Reviewed-by: Yannick Fertre 
Tested-by: Yannick Fertre 


On 12/22/21 10:05 AM, José Expósito wrote:

The "drm_plane_funcs.format_mod_supported" can be removed in favor of
the default implementation.

Signed-off-by: José Expósito 
---
  drivers/gpu/drm/stm/ltdc.c | 11 ---
  1 file changed, 11 deletions(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index dbdee954692a..ef909e50f0e4 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -925,16 +925,6 @@ static void ltdc_plane_atomic_print_state(struct 
drm_printer *p,
fpsi->counter = 0;
  }
  
-static bool ltdc_plane_format_mod_supported(struct drm_plane *plane,

-   u32 format,
-   u64 modifier)
-{
-   if (modifier == DRM_FORMAT_MOD_LINEAR)
-   return true;
-
-   return false;
-}
-
  static const struct drm_plane_funcs ltdc_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
@@ -943,7 +933,6 @@ static const struct drm_plane_funcs ltdc_plane_funcs = {
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
.atomic_print_state = ltdc_plane_atomic_print_state,
-   .format_mod_supported = ltdc_plane_format_mod_supported,
  };
  
  static const struct drm_plane_helper_funcs ltdc_plane_helper_funcs = {




[PATCH 5/5] drm/stm: ltdc: add support of ycbcr pixel formats

2021-12-15 Thread Yannick Fertre
This patch adds the following YCbCr input pixel formats on the latest
LTDC hardware version:

1 plane  (co-planar)  : YUYV, YVYU, UYVY, VYUY
2 planes (semi-planar): NV12, NV21
3 planes (full-planar): YU12=I420=DRM YUV420, YV12=DRM YVU420

Signed-off-by: Yannick Fertre 
---
 drivers/gpu/drm/stm/ltdc.c | 251 +++--
 drivers/gpu/drm/stm/ltdc.h |   1 +
 2 files changed, 245 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index 4d249bc99894..7fd173390b9f 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -198,6 +198,21 @@
 
 #define LXCFBLNR_CFBLN GENMASK(10, 0)  /* Color Frame Buffer Line Number */
 
+#define LXCR_C1R_YIA   BIT(0)  /* Ycbcr 422 Interleaved Ability */
+#define LXCR_C1R_YSPA  BIT(1)  /* Ycbcr 420 Semi-Planar Ability */
+#define LXCR_C1R_YFPA  BIT(2)  /* Ycbcr 420 Full-Planar Ability */
+#define LXCR_C1R_SCA   BIT(31) /* SCaling Ability*/
+
+#define LxPCR_YREN BIT(9)  /* Y Rescale Enable for the color 
dynamic range */
+#define LxPCR_OF   BIT(8)  /* Odd pixel First */
+#define LxPCR_CBF  BIT(7)  /* CB component First */
+#define LxPCR_YF   BIT(6)  /* Y component First */
+#define LxPCR_YCM  GENMASK(5, 4)   /* Ycbcr Conversion Mode */
+#define YCM_I  0x0 /* Interleaved 422 */
+#define YCM_SP 0x1 /* Semi-Planar 420 */
+#define YCM_FP 0x2 /* Full-Planar 420 */
+#define LxPCR_YCEN BIT(3)  /* YCbCr-to-RGB Conversion Enable */
+
 #define LXRCR_IMR  BIT(0)  /* IMmediate Reload */
 #define LXRCR_VBR  BIT(1)  /* Vertical Blanking Reload */
 #define LXRCR_GRMSKBIT(2)  /* Global (centralized) Reload MaSKed */
@@ -311,6 +326,23 @@ static const u32 ltdc_drm_fmt_a2[] = {
DRM_FORMAT_C8
 };
 
+static const u32 ltdc_drm_fmt_ycbcr_cp[] = {
+   DRM_FORMAT_YUYV,
+   DRM_FORMAT_YVYU,
+   DRM_FORMAT_UYVY,
+   DRM_FORMAT_VYUY
+};
+
+static const u32 ltdc_drm_fmt_ycbcr_sp[] = {
+   DRM_FORMAT_NV12,
+   DRM_FORMAT_NV21
+};
+
+static const u32 ltdc_drm_fmt_ycbcr_fp[] = {
+   DRM_FORMAT_YUV420,
+   DRM_FORMAT_YVU420
+};
+
 /* Layer register offsets */
 static const u32 ltdc_layer_regs_a0[] = {
0x80,   /* L1 configuration 0 */
@@ -410,6 +442,26 @@ static const struct regmap_config stm32_ltdc_regmap_cfg = {
.cache_type = REGCACHE_NONE,
 };
 
+static const u32 
ltdc_ycbcr2rgb_coeffs[DRM_COLOR_ENCODING_MAX][DRM_COLOR_RANGE_MAX][2] = {
+   [DRM_COLOR_YCBCR_BT601][DRM_COLOR_YCBCR_LIMITED_RANGE] = {
+   0x02040199, /* (b_cb = 516 / r_cr = 409) */
+   0x006400D0  /* (g_cb = 100 / g_cr = 208) */
+   },
+   [DRM_COLOR_YCBCR_BT601][DRM_COLOR_YCBCR_FULL_RANGE] = {
+   0x01C60167, /* (b_cb = 454 / r_cr = 359) */
+   0x005800B7  /* (g_cb = 88 / g_cr = 183) */
+   },
+   [DRM_COLOR_YCBCR_BT709][DRM_COLOR_YCBCR_LIMITED_RANGE] = {
+   0x021D01CB, /* (b_cb = 541 / r_cr = 459) */
+   0x00370089  /* (g_cb = 55 / g_cr = 137) */
+   },
+   [DRM_COLOR_YCBCR_BT709][DRM_COLOR_YCBCR_FULL_RANGE] = {
+   0x01DB0193, /* (b_cb = 475 / r_cr = 403) */
+   0x00300078  /* (g_cb = 48 / g_cr = 120) */
+   }
+   /* BT2020 not supported */
+};
+
 static inline struct ltdc_device *crtc_to_ltdc(struct drm_crtc *crtc)
 {
return (struct ltdc_device *)crtc->dev->dev_private;
@@ -540,6 +592,78 @@ static inline u32 is_xrgb(u32 drm)
return ((drm & 0xFF) == 'X' || ((drm >> 8) & 0xFF) == 'X');
 }
 
+static inline void ltdc_set_ycbcr_config(struct drm_plane *plane, u32 
drm_pix_fmt)
+{
+   struct ltdc_device *ldev = plane_to_ltdc(plane);
+   struct drm_plane_state *state = plane->state;
+   u32 lofs = plane->index * LAY_OFS;
+   u32 val;
+
+   switch (drm_pix_fmt) {
+   case DRM_FORMAT_YUYV:
+   val = (YCM_I << 4) | LxPCR_YF | LxPCR_CBF;
+   break;
+   case DRM_FORMAT_YVYU:
+   val = (YCM_I << 4) | LxPCR_YF;
+   break;
+   case DRM_FORMAT_UYVY:
+   val = (YCM_I << 4) | LxPCR_CBF;
+   break;
+   case DRM_FORMAT_VYUY:
+   val = (YCM_I << 4);
+   break;
+   case DRM_FORMAT_NV12:
+   val = (YCM_SP << 4) | LxPCR_CBF;
+   break;
+   case DRM_FORMAT_NV21:
+   val = (YCM_SP << 4);
+   break;
+   case DRM_FORMAT_YUV420:
+   case DRM_FORMAT_YVU420:
+   val = (YCM_FP << 4);
+   break;
+   default:
+   /* RGB or not a YCbCr supported format */
+   break;
+   }
+
+   /* Enable limited range */
+   if (state->color_ra

[PATCH 4/5] drm/stm: ltdc: add support of flexible pixel formats

2021-12-15 Thread Yannick Fertre
This feature allows the generation of any RGB pixel format.
The list of supported formats is no longer linked to the
register LXPFCR_PF, that the reason why a list of drm formats is
defined for each display controller version.

Signed-off-by: Yannick Fertre 
---
 drivers/gpu/drm/stm/ltdc.c | 196 ++---
 drivers/gpu/drm/stm/ltdc.h |   5 +-
 2 files changed, 145 insertions(+), 56 deletions(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index 862d43fe3087..4d249bc99894 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -186,6 +186,7 @@
 #define LXWVPCR_WVSPPOSGENMASK(26, 16) /* Window Vertical StoP 
POSition */
 
 #define LXPFCR_PF  GENMASK(2, 0)   /* Pixel Format */
+#define PF_FLEXIBLE0x7 /* Flexible Pixel Format selected */
 
 #define LXCACR_CONSTA  GENMASK(7, 0)   /* CONSTant Alpha */
 
@@ -216,17 +217,18 @@ enum ltdc_pix_fmt {
/* RGB formats */
PF_ARGB,/* ARGB [32 bits] */
PF_RGBA,/* RGBA [32 bits] */
+   PF_ABGR,/* ABGR [32 bits] */
+   PF_BGRA,/* BGRA [32 bits] */
PF_RGB888,  /* RGB [24 bits] */
+   PF_BGR888,  /* BGR [24 bits] */
PF_RGB565,  /* RGB [16 bits] */
+   PF_BGR565,  /* BGR [16 bits] */
PF_ARGB1555,/* ARGB A:1 bit RGB:15 bits [16 bits] */
PF_ARGB,/* ARGB A:4 bits R/G/B: 4 bits each [16 bits] */
/* Indexed formats */
PF_L8,  /* Indexed 8 bits [8 bits] */
PF_AL44,/* Alpha:4 bits + indexed 4 bits [8 bits] */
-   PF_AL88,/* Alpha:8 bits + indexed 8 bits [16 bits] */
-   PF_ABGR,/* ABGR [32 bits] */
-   PF_BGRA,/* BGRA [32 bits] */
-   PF_BGR565   /* RGB [16 bits] */
+   PF_AL88 /* Alpha:8 bits + indexed 8 bits [16 bits] */
 };
 
 /* The index gives the encoding of the pixel format for an HW version */
@@ -260,7 +262,53 @@ static const enum ltdc_pix_fmt ltdc_pix_fmt_a2[NB_PF] = {
PF_RGB565,  /* 0x04 */
PF_BGR565,  /* 0x05 */
PF_RGB888,  /* 0x06 */
-   PF_ARGB1555 /* 0x07 */
+   PF_NONE /* 0x07 */
+};
+
+static const u32 ltdc_drm_fmt_a0[] = {
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_ARGB1555,
+   DRM_FORMAT_XRGB1555,
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_C8
+};
+
+static const u32 ltdc_drm_fmt_a1[] = {
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_RGBA,
+   DRM_FORMAT_RGBX,
+   DRM_FORMAT_ARGB1555,
+   DRM_FORMAT_XRGB1555,
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_C8
+};
+
+static const u32 ltdc_drm_fmt_a2[] = {
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_ABGR,
+   DRM_FORMAT_XBGR,
+   DRM_FORMAT_RGBA,
+   DRM_FORMAT_RGBX,
+   DRM_FORMAT_BGRA,
+   DRM_FORMAT_BGRX,
+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_BGR565,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_BGR888,
+   DRM_FORMAT_ARGB1555,
+   DRM_FORMAT_XRGB1555,
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_C8
 };
 
 /* Layer register offsets */
@@ -386,16 +434,30 @@ static inline enum ltdc_pix_fmt to_ltdc_pixelformat(u32 
drm_fmt)
case DRM_FORMAT_XRGB:
pf = PF_ARGB;
break;
+   case DRM_FORMAT_ABGR:
+   case DRM_FORMAT_XBGR:
+   pf = PF_ABGR;
+   break;
case DRM_FORMAT_RGBA:
case DRM_FORMAT_RGBX:
pf = PF_RGBA;
break;
+   case DRM_FORMAT_BGRA:
+   case DRM_FORMAT_BGRX:
+   pf = PF_BGRA;
+   break;
case DRM_FORMAT_RGB888:
pf = PF_RGB888;
break;
+   case DRM_FORMAT_BGR888:
+   pf = PF_BGR888;
+   break;
case DRM_FORMAT_RGB565:
pf = PF_RGB565;
break;
+   case DRM_FORMAT_BGR565:
+   pf = PF_BGR565;
+   break;
case DRM_FORMAT_ARGB1555:
case DRM_FORMAT_XRGB1555:
pf = PF_ARGB1555;
@@ -416,49 +478,66 @@ static inline enum ltdc_pix_fmt to_ltdc_pixelformat(u32 
drm_fmt)
return pf;
 }
 
-static inline u32 to_drm_pixelformat(enum ltdc_pix_fmt pf)
+static inline u32 ltdc_set_flexible_pixel_format(struct drm_plane *plane, enum 
ltdc_pix_fmt pix_fmt)
 {
-   switch (pf) {
-   case PF_ARGB:
-   return DRM_FORMAT_ARGB

[PATCH 3/5] drm/stm: ltdc: add per plane update support

2021-12-15 Thread Yannick Fertre
Recent ltdc hardware versions offer the ability
to update a plane independently of others planes.
This is could be useful especially if a plane is
assigned to another OS.

Signed-off-by: Yannick Fertre 
---
 drivers/gpu/drm/stm/ltdc.c | 26 +++---
 drivers/gpu/drm/stm/ltdc.h |  1 +
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index b819f4cbcc3d..862d43fe3087 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -197,6 +197,10 @@
 
 #define LXCFBLNR_CFBLN GENMASK(10, 0)  /* Color Frame Buffer Line Number */
 
+#define LXRCR_IMR  BIT(0)  /* IMmediate Reload */
+#define LXRCR_VBR  BIT(1)  /* Vertical Blanking Reload */
+#define LXRCR_GRMSKBIT(2)  /* Global (centralized) Reload MaSKed */
+
 #define CLUT_SIZE  256
 
 #define CONSTA_MAX 0xFF/* CONSTant Alpha MAX= 1.0 */
@@ -534,7 +538,8 @@ static void ltdc_crtc_atomic_enable(struct drm_crtc *crtc,
regmap_set_bits(ldev->regmap, LTDC_IER, IER_RRIE | IER_FUIE | 
IER_TERRIE);
 
/* Commit shadow registers = update planes at next vblank */
-   regmap_set_bits(ldev->regmap, LTDC_SRCR, SRCR_VBR);
+   if (!ldev->caps.plane_reg_shadow)
+   regmap_set_bits(ldev->regmap, LTDC_SRCR, SRCR_VBR);
 
drm_crtc_vblank_on(crtc);
 }
@@ -553,7 +558,8 @@ static void ltdc_crtc_atomic_disable(struct drm_crtc *crtc,
regmap_clear_bits(ldev->regmap, LTDC_IER, IER_RRIE | IER_FUIE | 
IER_TERRIE);
 
/* immediately commit disable of layers before switching off LTDC */
-   regmap_set_bits(ldev->regmap, LTDC_SRCR, SRCR_IMR);
+   if (!ldev->caps.plane_reg_shadow)
+   regmap_set_bits(ldev->regmap, LTDC_SRCR, SRCR_IMR);
 
pm_runtime_put_sync(ddev->dev);
 }
@@ -769,7 +775,8 @@ static void ltdc_crtc_atomic_flush(struct drm_crtc *crtc,
ltdc_crtc_update_clut(crtc);
 
/* Commit shadow registers = update planes at next vblank */
-   regmap_set_bits(ldev->regmap, LTDC_SRCR, SRCR_VBR);
+   if (!ldev->caps.plane_reg_shadow)
+   regmap_set_bits(ldev->regmap, LTDC_SRCR, SRCR_VBR);
 
if (event) {
crtc->state->event = NULL;
@@ -1010,6 +1017,11 @@ static void ltdc_plane_atomic_update(struct drm_plane 
*plane,
val |= LXCR_LEN;
regmap_write_bits(ldev->regmap, LTDC_L1CR + lofs, LXCR_LEN | 
LXCR_CLUTEN, val);
 
+   /* Commit shadow registers = update plane at next vblank */
+   if (ldev->caps.plane_reg_shadow)
+   regmap_write_bits(ldev->regmap, LTDC_L1RCR + lofs,
+ LXRCR_IMR | LXRCR_VBR | LXRCR_GRMSK, 
LXRCR_VBR);
+
ldev->plane_fpsi[plane->index].counter++;
 
mutex_lock(>err_lock);
@@ -1035,6 +1047,11 @@ static void ltdc_plane_atomic_disable(struct drm_plane 
*plane,
/* disable layer */
regmap_write_bits(ldev->regmap, LTDC_L1CR + lofs, LXCR_LEN, 0);
 
+   /* Commit shadow registers = update plane at next vblank */
+   if (ldev->caps.plane_reg_shadow)
+   regmap_write_bits(ldev->regmap, LTDC_L1RCR + lofs,
+ LXRCR_IMR | LXRCR_VBR | LXRCR_GRMSK, 
LXRCR_VBR);
+
DRM_DEBUG_DRIVER("CRTC:%d plane:%d\n",
 oldstate->crtc->base.id, plane->base.id);
 }
@@ -1307,6 +1324,7 @@ static int ltdc_get_caps(struct drm_device *ddev)
ldev->caps.pad_max_freq_hz = 6500;
ldev->caps.nb_irq = 2;
ldev->caps.ycbcr_output = false;
+   ldev->caps.plane_reg_shadow = false;
break;
case HWVER_20101:
ldev->caps.layer_ofs = LAY_OFS_0;
@@ -1316,6 +1334,7 @@ static int ltdc_get_caps(struct drm_device *ddev)
ldev->caps.pad_max_freq_hz = 15000;
ldev->caps.nb_irq = 4;
ldev->caps.ycbcr_output = false;
+   ldev->caps.plane_reg_shadow = false;
break;
case HWVER_40100:
ldev->caps.layer_ofs = LAY_OFS_1;
@@ -1325,6 +1344,7 @@ static int ltdc_get_caps(struct drm_device *ddev)
ldev->caps.pad_max_freq_hz = 9000;
ldev->caps.nb_irq = 2;
ldev->caps.ycbcr_output = true;
+   ldev->caps.plane_reg_shadow = true;
break;
default:
return -ENODEV;
diff --git a/drivers/gpu/drm/stm/ltdc.h b/drivers/gpu/drm/stm/ltdc.h
index f04fcebb5223..68a5a199e320 100644
--- a/drivers/gpu/drm/stm/ltdc.h
+++ b/drivers/gpu/drm/stm/ltdc.h
@@ -22,6 +22,7 @@ struct ltdc_caps {
int pad_max_freq_hz;/* max frequency supported by pad */
int nb_irq; /* number of hardware interrupts */
bool ycbcr_output;  /* ycbcr 

[PATCH 2/5] drm/stm: ltdc: add YCbCr 422 output support

2021-12-15 Thread Yannick Fertre
LTDC 40100 hw version supports the YCbCr 422 output,
reducing the output pins from 24 to 16. This feature
is useful for some external devices like HDMI bridges.

Both ITU-R BT.601 & ITU-R BT.709 are supported.

It is also possible to choose the chrominance order between
* Cb is output first (Y0Cb, then Y1Cr, Y2Cb and so on).
* Cr is output first (Y0Cr, then Y1Cb, Y2Cr and so on).

Signed-off-by: Yannick Fertre 
---
 drivers/gpu/drm/stm/ltdc.c | 44 +-
 drivers/gpu/drm/stm/ltdc.h |  1 +
 2 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index 8dad3d00aa5c..b819f4cbcc3d 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -76,6 +76,7 @@
 #define LTDC_LIPCR 0x0040  /* Line Interrupt Position Conf. */
 #define LTDC_CPSR  0x0044  /* Current Position Status */
 #define LTDC_CDSR  0x0048  /* Current Display Status */
+#define LTDC_EDCR  0x0060  /* External Display Control */
 #define LTDC_FUT   0x0090  /* Fifo underrun Threshold */
 
 /* Layer register offsets */
@@ -170,6 +171,10 @@
 #define ISR_TERRIF BIT(2)  /* Transfer ERRor Interrupt Flag */
 #define ISR_RRIF   BIT(3)  /* Register Reload Interrupt Flag */
 
+#define EDCR_OCYEN BIT(25) /* Output Conversion to YCbCr 422: 
ENable */
+#define EDCR_OCYSELBIT(26) /* Output Conversion to YCbCr 422: 
SELection of the CCIR */
+#define EDCR_OCYCO BIT(27) /* Output Conversion to YCbCr 422: 
Chrominance Order */
+
 #define LXCR_LEN   BIT(0)  /* Layer ENable */
 #define LXCR_COLKENBIT(1)  /* Color Keying Enable */
 #define LXCR_CLUTENBIT(4)  /* Color Look-Up Table ENable */
@@ -625,6 +630,7 @@ static void ltdc_crtc_mode_set_nofb(struct drm_crtc *crtc)
struct drm_display_mode *mode = >state->adjusted_mode;
u32 hsync, vsync, accum_hbp, accum_vbp, accum_act_w, accum_act_h;
u32 total_width, total_height;
+   u32 bus_formats = MEDIA_BUS_FMT_RGB888_1X24;
u32 bus_flags = 0;
u32 val;
int ret;
@@ -650,8 +656,11 @@ static void ltdc_crtc_mode_set_nofb(struct drm_crtc *crtc)
 
if (bridge && bridge->timings)
bus_flags = bridge->timings->input_bus_flags;
-   else if (connector)
+   else if (connector) {
bus_flags = connector->display_info.bus_flags;
+   if (connector->display_info.num_bus_formats)
+   bus_formats = connector->display_info.bus_formats[0];
+   }
 
if (!pm_runtime_active(ddev->dev)) {
ret = pm_runtime_get_sync(ddev->dev);
@@ -716,6 +725,36 @@ static void ltdc_crtc_mode_set_nofb(struct drm_crtc *crtc)
regmap_update_bits(ldev->regmap, LTDC_TWCR, TWCR_TOTALH | TWCR_TOTALW, 
val);
 
regmap_write(ldev->regmap, LTDC_LIPCR, (accum_act_h + 1));
+
+   /* Configure the output format (hw version dependent) */
+   if (ldev->caps.ycbcr_output) {
+   /* Input video dynamic_range & colorimetry */
+   int vic = drm_match_cea_mode(mode);
+   u32 val;
+
+   if (vic == 6 || vic == 7 || vic == 21 || vic == 22 ||
+   vic == 2 || vic == 3 || vic == 17 || vic == 18)
+   /* ITU-R BT.601 */
+   val = 0;
+   else
+   /* ITU-R BT.709 */
+   val = EDCR_OCYSEL;
+
+   switch (bus_formats) {
+   case MEDIA_BUS_FMT_YUYV8_1X16:
+   /* enable ycbcr output converter */
+   regmap_write(ldev->regmap, LTDC_EDCR, EDCR_OCYEN | val);
+   break;
+   case MEDIA_BUS_FMT_YVYU8_1X16:
+   /* enable ycbcr output converter & invert chrominance 
order */
+   regmap_write(ldev->regmap, LTDC_EDCR, EDCR_OCYEN | 
EDCR_OCYCO | val);
+   break;
+   default:
+   /* disable ycbcr output converter */
+   regmap_write(ldev->regmap, LTDC_EDCR, 0);
+   break;
+   }
+   }
 }
 
 static void ltdc_crtc_atomic_flush(struct drm_crtc *crtc,
@@ -1267,6 +1306,7 @@ static int ltdc_get_caps(struct drm_device *ddev)
if (ldev->caps.hw_version == HWVER_10200)
ldev->caps.pad_max_freq_hz = 6500;
ldev->caps.nb_irq = 2;
+   ldev->caps.ycbcr_output = false;
break;
case HWVER_20101:
ldev->caps.layer_ofs = LAY_OFS_0;
@@ -1275,6 +1315,7 @@ static int ltdc_get_caps(struct drm_device *ddev)
ldev->caps.non_alpha_only_l1 = false;
ldev->caps.pad_max_freq_hz = 1500

[PATCH 1/5] drm/stm: ltdc: switch to regmap

2021-12-15 Thread Yannick Fertre
Replace the legacy register access by regmap API.

Signed-off-by: Yannick Fertre 
---
 drivers/gpu/drm/stm/ltdc.c | 138 ++---
 drivers/gpu/drm/stm/ltdc.h |   1 +
 2 files changed, 68 insertions(+), 71 deletions(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index c0619f372630..8dad3d00aa5c 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -343,31 +344,14 @@ static const u64 ltdc_format_modifiers[] = {
DRM_FORMAT_MOD_INVALID
 };
 
-static inline u32 reg_read(void __iomem *base, u32 reg)
-{
-   return readl_relaxed(base + reg);
-}
-
-static inline void reg_write(void __iomem *base, u32 reg, u32 val)
-{
-   writel_relaxed(val, base + reg);
-}
-
-static inline void reg_set(void __iomem *base, u32 reg, u32 mask)
-{
-   reg_write(base, reg, reg_read(base, reg) | mask);
-}
-
-static inline void reg_clear(void __iomem *base, u32 reg, u32 mask)
-{
-   reg_write(base, reg, reg_read(base, reg) & ~mask);
-}
-
-static inline void reg_update_bits(void __iomem *base, u32 reg, u32 mask,
-  u32 val)
-{
-   reg_write(base, reg, (reg_read(base, reg) & ~mask) | val);
-}
+static const struct regmap_config stm32_ltdc_regmap_cfg = {
+   .reg_bits = 32,
+   .val_bits = 32,
+   .reg_stride = sizeof(u32),
+   .max_register = 0x400,
+   .use_relaxed_mmio = true,
+   .cache_type = REGCACHE_NONE,
+};
 
 static inline struct ltdc_device *crtc_to_ltdc(struct drm_crtc *crtc)
 {
@@ -494,9 +478,13 @@ static irqreturn_t ltdc_irq(int irq, void *arg)
struct drm_device *ddev = arg;
struct ltdc_device *ldev = ddev->dev_private;
 
-   /* Read & Clear the interrupt status */
-   ldev->irq_status = reg_read(ldev->regs, LTDC_ISR);
-   reg_write(ldev->regs, LTDC_ICR, ldev->irq_status);
+   /*
+*  Read & Clear the interrupt status
+*  In order to write / read registers in this critical section
+*  very quickly, the regmap functions are not used.
+*/
+   ldev->irq_status = readl_relaxed(ldev->regs + LTDC_ISR);
+   writel_relaxed(ldev->irq_status, ldev->regs + LTDC_ICR);
 
return IRQ_WAKE_THREAD;
 }
@@ -520,7 +508,7 @@ static void ltdc_crtc_update_clut(struct drm_crtc *crtc)
for (i = 0; i < CLUT_SIZE; i++, lut++) {
val = ((lut->red << 8) & 0xff) | (lut->green & 0xff00) |
(lut->blue >> 8) | (i << 24);
-   reg_write(ldev->regs, LTDC_L1CLUTWR, val);
+   regmap_write(ldev->regmap, LTDC_L1CLUTWR, val);
}
 }
 
@@ -535,13 +523,13 @@ static void ltdc_crtc_atomic_enable(struct drm_crtc *crtc,
pm_runtime_get_sync(ddev->dev);
 
/* Sets the background color value */
-   reg_write(ldev->regs, LTDC_BCCR, BCCR_BCBLACK);
+   regmap_write(ldev->regmap, LTDC_BCCR, BCCR_BCBLACK);
 
/* Enable IRQ */
-   reg_set(ldev->regs, LTDC_IER, IER_RRIE | IER_FUIE | IER_TERRIE);
+   regmap_set_bits(ldev->regmap, LTDC_IER, IER_RRIE | IER_FUIE | 
IER_TERRIE);
 
/* Commit shadow registers = update planes at next vblank */
-   reg_set(ldev->regs, LTDC_SRCR, SRCR_VBR);
+   regmap_set_bits(ldev->regmap, LTDC_SRCR, SRCR_VBR);
 
drm_crtc_vblank_on(crtc);
 }
@@ -557,10 +545,10 @@ static void ltdc_crtc_atomic_disable(struct drm_crtc 
*crtc,
drm_crtc_vblank_off(crtc);
 
/* disable IRQ */
-   reg_clear(ldev->regs, LTDC_IER, IER_RRIE | IER_FUIE | IER_TERRIE);
+   regmap_clear_bits(ldev->regmap, LTDC_IER, IER_RRIE | IER_FUIE | 
IER_TERRIE);
 
/* immediately commit disable of layers before switching off LTDC */
-   reg_set(ldev->regs, LTDC_SRCR, SRCR_IMR);
+   regmap_set_bits(ldev->regmap, LTDC_SRCR, SRCR_IMR);
 
pm_runtime_put_sync(ddev->dev);
 }
@@ -708,26 +696,26 @@ static void ltdc_crtc_mode_set_nofb(struct drm_crtc *crtc)
if (bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)
val |= GCR_PCPOL;
 
-   reg_update_bits(ldev->regs, LTDC_GCR,
-   GCR_HSPOL | GCR_VSPOL | GCR_DEPOL | GCR_PCPOL, val);
+   regmap_update_bits(ldev->regmap, LTDC_GCR,
+  GCR_HSPOL | GCR_VSPOL | GCR_DEPOL | GCR_PCPOL, val);
 
/* Set Synchronization size */
val = (hsync << 16) | vsync;
-   reg_update_bits(ldev->regs, LTDC_SSCR, SSCR_VSH | SSCR_HSW, val);
+   regmap_update_bits(ldev->regmap, LTDC_SSCR, SSCR_VSH | SSCR_HSW, val);
 
/* Set Accumulated Back porch */
val = (accum_hbp << 16) | accum_vbp;
-   reg_update_bits(ldev->regs, LTDC_BPCR, BPCR_AVBP | BPCR_AHBP, val);
+   regmap_update_bits(ldev->regmap, LTDC_BPCR, BPCR_AVBP |

[PATCH 0/5] drm/stm: new features to display controller

2021-12-15 Thread Yannick Fertre
Hello,
List of new feature:
* Replace the legacy register access by regmap API.
* Support of YCbCr 422 output
* Update layer shadow registers per plane.
* Support of YCbCr output (planar, semiplanar & coplanar)

These featues are available only with last hardware version of ltdc
(0x401000) link to patch"drm/stm: ltdc: support of new hardware version"
(https://patchwork.freedesktop.org/patch/465207).

Yannick Fertre (5):
  drm/stm: ltdc: switch to regmap
  drm/stm: ltdc: add YCbCr 422 output support
  drm/stm: ltdc: add per plane update support
  drm/stm: ltdc: add support of flexible pixel formats
  drm/stm: ltdc: add support of ycbcr pixel formats

 drivers/gpu/drm/stm/ltdc.c | 639 +
 drivers/gpu/drm/stm/ltdc.h |   9 +-
 2 files changed, 518 insertions(+), 130 deletions(-)

-- 
2.17.1



[PATCH] drm/stm: remove conflicting framebuffers

2021-12-06 Thread Yannick Fertre
In case of using simplefb or another conflicting framebuffer,
call drm_aperture_remove_framebuffers() to remove memory allocated.

Signed-off-by: Yannick Fertre 
---
 drivers/gpu/drm/stm/drv.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c
index 222869b232ae..9f441aadf2d5 100644
--- a/drivers/gpu/drm/stm/drv.c
+++ b/drivers/gpu/drm/stm/drv.c
@@ -14,6 +14,7 @@
 #include 
 #include 
 
+#include 
 #include 
 #include 
 #include 
@@ -183,6 +184,10 @@ static int stm_drm_platform_probe(struct platform_device 
*pdev)
 
DRM_DEBUG("%s\n", __func__);
 
+   ret = drm_aperture_remove_framebuffers(false, _driver);
+   if (ret)
+   return ret;
+
dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
 
ddev = drm_dev_alloc(_driver, dev);
-- 
2.17.1



Re: [PATCH] drm/stm: remove conflicting framebuffers

2021-12-06 Thread yannick Fertre

Hi Thomas,


On 12/3/21 10:35 AM, Thomas Zimmermann wrote:

Hi

Am 03.12.21 um 09:55 schrieb Yannick Fertre:

In case of using simplefb or another conflicting framebuffer,
call drm_aperture_remove_framebuffers() to remove memory allocated.

Signed-off-by: Yannick Fertre 
---
  drivers/gpu/drm/stm/drv.c | 5 +
  1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c
index 222869b232ae..5ba46f70f081 100644
--- a/drivers/gpu/drm/stm/drv.c
+++ b/drivers/gpu/drm/stm/drv.c
@@ -14,6 +14,7 @@
  #include 
  #include 
+#include 
  #include 
  #include 
  #include 
@@ -193,6 +194,10 @@ static int stm_drm_platform_probe(struct 
platform_device *pdev)

  if (ret)
  goto err_put;
+    ret = drm_aperture_remove_framebuffers(false, _driver);
+    if (ret)
+    goto err_put;
+


This has to be done at the very top of the probe function, before 
anything that touches the device. Otherwise both drivers interfere with 
each other while probing and setup's going on.


Best regards
Thomas


  ret = drm_dev_register(ddev, 0);
  if (ret)
  goto err_put;




Thanks for reviewing the patch.
I will follow your advice and push a new patch.

Yannick


[PATCH] drm/stm: ltdc: support of new hardware version

2021-12-03 Thread Yannick Fertre
Add support of new hardware version 0x40100.

Signed-off-by: Yannick Fertre 
---
 drivers/gpu/drm/stm/ltdc.c | 172 ++---
 drivers/gpu/drm/stm/ltdc.h |   3 +-
 2 files changed, 145 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index dbdee954692a..c0619f372630 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -46,15 +46,15 @@
 #define HWVER_10200 0x010200
 #define HWVER_10300 0x010300
 #define HWVER_20101 0x020101
+#define HWVER_40100 0x040100
 
 /*
  * The address of some registers depends on the HW version: such registers have
- * an extra offset specified with reg_ofs.
+ * an extra offset specified with layer_ofs.
  */
-#define REG_OFS_NONE   0
-#define REG_OFS_4  4   /* Insertion of "Layer Conf. 2" reg */
-#define REG_OFS(ldev->caps.reg_ofs)
-#define LAY_OFS0x80/* Register Offset between 2 
layers */
+#define LAY_OFS_0  0x80
+#define LAY_OFS_1  0x100
+#define LAY_OFS(ldev->caps.layer_ofs)
 
 /* Global register offsets */
 #define LTDC_IDR   0x  /* IDentification */
@@ -75,29 +75,34 @@
 #define LTDC_LIPCR 0x0040  /* Line Interrupt Position Conf. */
 #define LTDC_CPSR  0x0044  /* Current Position Status */
 #define LTDC_CDSR  0x0048  /* Current Display Status */
+#define LTDC_FUT   0x0090  /* Fifo underrun Threshold */
 
 /* Layer register offsets */
-#define LTDC_L1LC1R(0x80)  /* L1 Layer Configuration 1 */
-#define LTDC_L1LC2R(0x84)  /* L1 Layer Configuration 2 */
-#define LTDC_L1CR  (0x84 + REG_OFS)/* L1 Control */
-#define LTDC_L1WHPCR   (0x88 + REG_OFS)/* L1 Window Hor Position Config */
-#define LTDC_L1WVPCR   (0x8C + REG_OFS)/* L1 Window Vert Position Config */
-#define LTDC_L1CKCR(0x90 + REG_OFS)/* L1 Color Keying Configuration */
-#define LTDC_L1PFCR(0x94 + REG_OFS)/* L1 Pixel Format Configuration */
-#define LTDC_L1CACR(0x98 + REG_OFS)/* L1 Constant Alpha Config */
-#define LTDC_L1DCCR(0x9C + REG_OFS)/* L1 Default Color Configuration */
-#define LTDC_L1BFCR(0xA0 + REG_OFS)/* L1 Blend Factors Configuration */
-#define LTDC_L1FBBCR   (0xA4 + REG_OFS)/* L1 FrameBuffer Bus Control */
-#define LTDC_L1AFBCR   (0xA8 + REG_OFS)/* L1 AuxFB Control */
-#define LTDC_L1CFBAR   (0xAC + REG_OFS)/* L1 Color FrameBuffer Address */
-#define LTDC_L1CFBLR   (0xB0 + REG_OFS)/* L1 Color FrameBuffer Length */
-#define LTDC_L1CFBLNR  (0xB4 + REG_OFS)/* L1 Color FrameBuffer Line Nb */
-#define LTDC_L1AFBAR   (0xB8 + REG_OFS)/* L1 AuxFB Address */
-#define LTDC_L1AFBLR   (0xBC + REG_OFS)/* L1 AuxFB Length */
-#define LTDC_L1AFBLNR  (0xC0 + REG_OFS)/* L1 AuxFB Line Number */
-#define LTDC_L1CLUTWR  (0xC4 + REG_OFS)/* L1 CLUT Write */
-#define LTDC_L1YS1R(0xE0 + REG_OFS)/* L1 YCbCr Scale 1 */
-#define LTDC_L1YS2R(0xE4 + REG_OFS)/* L1 YCbCr Scale 2 */
+#define LTDC_L1C0R (ldev->caps.layer_regs[0])  /* L1 configuration 0 */
+#define LTDC_L1C1R (ldev->caps.layer_regs[1])  /* L1 configuration 1 */
+#define LTDC_L1RCR (ldev->caps.layer_regs[2])  /* L1 reload control */
+#define LTDC_L1CR  (ldev->caps.layer_regs[3])  /* L1 control register 
*/
+#define LTDC_L1WHPCR   (ldev->caps.layer_regs[4])  /* L1 window horizontal 
position configuration */
+#define LTDC_L1WVPCR   (ldev->caps.layer_regs[5])  /* L1 window vertical 
position configuration */
+#define LTDC_L1CKCR(ldev->caps.layer_regs[6])  /* L1 color keying 
configuration */
+#define LTDC_L1PFCR(ldev->caps.layer_regs[7])  /* L1 pixel format 
configuration */
+#define LTDC_L1CACR(ldev->caps.layer_regs[8])  /* L1 constant alpha 
configuration */
+#define LTDC_L1DCCR(ldev->caps.layer_regs[9])  /* L1 default color 
configuration */
+#define LTDC_L1BFCR(ldev->caps.layer_regs[10]) /* L1 blending factors 
configuration */
+#define LTDC_L1BLCR(ldev->caps.layer_regs[11]) /* L1 burst length 
configuration */
+#define LTDC_L1PCR (ldev->caps.layer_regs[12]) /* L1 planar 
configuration */
+#define LTDC_L1CFBAR   (ldev->caps.layer_regs[13]) /* L1 color frame 
buffer address */
+#define LTDC_L1CFBLR   (ldev->caps.layer_regs[14]) /* L1 color frame 
buffer length */
+#define LTDC_L1CFBLNR  (ldev->caps.layer_regs[15]) /* L1 color frame 
buffer line number */
+#define LTDC_L1AFBA0R  (ldev->caps.layer_regs[16]) /* L1 auxiliary frame 
buffer address 0 */
+#define LTDC_L1AFBA1R  (ldev->caps.layer_regs[17]) /* L1 auxiliary frame 
buffer address 1 */
+#define LTDC_L1AFBLR   (ldev->caps.layer_regs[18]) /* L1 auxiliary frame 
buffer length */
+#define LTDC_L1AFBLNR  (ldev->caps.layer_regs[19]) /* L1 auxiliary frame 
buffer line number */
+#define LTDC_L1CLUTWR  (ldev->caps.layer_regs[20]) /*

[PATCH] drm/stm: remove conflicting framebuffers

2021-12-03 Thread Yannick Fertre
In case of using simplefb or another conflicting framebuffer,
call drm_aperture_remove_framebuffers() to remove memory allocated.

Signed-off-by: Yannick Fertre 
---
 drivers/gpu/drm/stm/drv.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c
index 222869b232ae..5ba46f70f081 100644
--- a/drivers/gpu/drm/stm/drv.c
+++ b/drivers/gpu/drm/stm/drv.c
@@ -14,6 +14,7 @@
 #include 
 #include 
 
+#include 
 #include 
 #include 
 #include 
@@ -193,6 +194,10 @@ static int stm_drm_platform_probe(struct platform_device 
*pdev)
if (ret)
goto err_put;
 
+   ret = drm_aperture_remove_framebuffers(false, _driver);
+   if (ret)
+   goto err_put;
+
ret = drm_dev_register(ddev, 0);
if (ret)
goto err_put;
-- 
2.17.1



[PATCH] drm: bridge: remove error message for EPROBE_DEFER in bridge_attach

2021-12-03 Thread Yannick Fertre
Probe deferred is not an error, don't print it.

Signed-off-by: Yannick Fertre 
---
 drivers/gpu/drm/drm_bridge.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index c96847fc0ebc..cef0a62ef5d0 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -288,11 +288,13 @@ int drm_bridge_attach(struct drm_encoder *encoder, struct 
drm_bridge *bridge,
list_del(>chain_node);
 
 #ifdef CONFIG_OF
-   DRM_ERROR("failed to attach bridge %pOF to encoder %s: %d\n",
- bridge->of_node, encoder->name, ret);
+   if (ret != -EPROBE_DEFER)
+   DRM_ERROR("failed to attach bridge %pOF to encoder %s: %d\n",
+ bridge->of_node, encoder->name, ret);
 #else
-   DRM_ERROR("failed to attach bridge to encoder %s: %d\n",
- encoder->name, ret);
+   if (ret != -EPROBE_DEFER)
+   DRM_ERROR("failed to attach bridge to encoder %s: %d\n",
+ encoder->name, ret);
 #endif
 
return ret;
-- 
2.17.1



Re: [PATCH] drm/stm: ltdc: attach immutable zpos property to planes

2021-09-07 Thread yannick Fertre

Hi Raphael,
thanks for the patch.

Acked-by: Yannick Fertre 
Reviewed-by: Yannick Fertre 

On 9/2/21 5:30 PM, Raphael GALLAIS-POU - foss wrote:

Defines plane ordering by hard-coding an immutable Z position from the
first plane, used as primary layer, to the next ones as overlay in order
of instantiation.

This zpos is only an information as it is not possible to modify it,
blending operations are still applied from the top to the bottom layer.

This patch helps to remove a warning message from the Android
Hardware Composer.

Signed-off-by: Raphael Gallais-Pou 
---
  drivers/gpu/drm/stm/ltdc.c | 3 +++
  1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index 195de30eb90c..bd603ef5e935 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -1024,6 +1024,8 @@ static int ltdc_crtc_init(struct drm_device *ddev, struct 
drm_crtc *crtc)
return -EINVAL;
}
  
+	drm_plane_create_zpos_immutable_property(primary, 0);

+
ret = drm_crtc_init_with_planes(ddev, crtc, primary, NULL,
_crtc_funcs, NULL);
if (ret) {
@@ -1046,6 +1048,7 @@ static int ltdc_crtc_init(struct drm_device *ddev, struct 
drm_crtc *crtc)
DRM_ERROR("Can not create overlay plane %d\n", i);
goto cleanup;
}
+   drm_plane_create_zpos_immutable_property(overlay, i);
}
  
  	return 0;




Re: [PATCH] drm/stm: ltdc: add layer alpha support

2021-09-07 Thread yannick Fertre

Hi Raphael,
thanks for the patch.

Acked-by: Yannick Fertre 
Reviewed-by: Yannick Fertre 

On 9/3/21 10:58 AM, Raphael GALLAIS-POU - foss wrote:

Android Hardware Composer supports alpha values applied to layers.
Enabling non-opaque layers for the STM CRTC could help offload GPU
resources for screen composition.

Signed-off-by: Raphael Gallais-Pou 
---
  drivers/gpu/drm/stm/ltdc.c | 4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index 195de30eb90c..e0fef8bacfa8 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -845,7 +845,7 @@ static void ltdc_plane_atomic_update(struct drm_plane 
*plane,
LXCFBLR_CFBLL | LXCFBLR_CFBP, val);
  
  	/* Specifies the constant alpha value */

-   val = CONSTA_MAX;
+   val = newstate->alpha >> 8;
reg_update_bits(ldev->regs, LTDC_L1CACR + lofs, LXCACR_CONSTA, val);
  
  	/* Specifies the blending factors */

@@ -997,6 +997,8 @@ static struct drm_plane *ltdc_plane_create(struct 
drm_device *ddev,
  
  	drm_plane_helper_add(plane, _plane_helper_funcs);
  
+	drm_plane_create_alpha_property(plane);

+
DRM_DEBUG_DRIVER("plane:%d created\n", plane->base.id);
  
  	return plane;




Re: [PATCH] drm/bridge: dw-mipi-dsi: Find the possible DSI devices

2021-07-07 Thread yannick Fertre

Hi Jagan,

Sorry for the delay. Thanks for the patch.

Tested-by: Yannick Fertre 




On 7/4/21 4:03 PM, Jagan Teki wrote:

Finding panel_or_bridge might vary based on associated
DSI devices like DSI panel, bridge, and I2C based DSI
bridge.

1. DSI panels and bridges will invoke the host attach
from probe in order to find the panel_or_bridge.

chipone_probe()
dw_mipi_dsi_host_attach().start
   dw_mipi_dsi_panel_or_bridge()
...found the panel_or_bridge...

ltdc_encoder_init().start
dw_mipi_dsi_bridge_attach().start
   dw_mipi_dsi_host_attach().start
   chipone_attach(). start

   chipone_attach(). done
   dw_mipi_dsi_host_attach().done
dw_mipi_dsi_bridge_attach(). done
ltdc_encoder_init().done

2. I2C based DSI bridge will invoke the drm_bridge_attach
from bridge attach in order to find the panel_or_bridge.

ltdc_encoder_init().start
dw_mipi_dsi_bridge_attach().start
   dw_mipi_dsi_panel_or_bridge()
...found the panel_or_bridge...
   dw_mipi_dsi_host_attach().start
   sn65dsi83_attach(). start

   sn65dsi83_attach(). done
   dw_mipi_dsi_host_attach().done
dw_mipi_dsi_bridge_attach(). done
ltdc_encoder_init().done

So, invoke the panel_or_bridge from host attach and
bridge attach in order to find all possible DSI devices.

Signed-off-by: Jagan Teki 
---
  drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 58 ++-
  1 file changed, 43 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index 6b268f9445b3..45f4515dda00 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -246,6 +246,7 @@ struct dw_mipi_dsi {
  
  	struct clk *pclk;
  
+	bool device_found;

unsigned int lane_mbps; /* per lane */
u32 channel;
u32 lanes;
@@ -309,13 +310,37 @@ static inline u32 dsi_read(struct dw_mipi_dsi *dsi, u32 
reg)
return readl(dsi->base + reg);
  }
  
+static int dw_mipi_dsi_panel_or_bridge(struct dw_mipi_dsi *dsi,

+  struct device_node *node)
+{
+   struct drm_bridge *bridge;
+   struct drm_panel *panel;
+   int ret;
+
+   ret = drm_of_find_panel_or_bridge(node, 1, 0, , );
+   if (ret)
+   return ret;
+
+   if (panel) {
+   bridge = drm_panel_bridge_add_typed(panel,
+   DRM_MODE_CONNECTOR_DSI);
+   if (IS_ERR(bridge))
+   return PTR_ERR(bridge);
+   }
+
+   dsi->panel_bridge = bridge;
+
+   if (!dsi->panel_bridge)
+   return -EPROBE_DEFER;
+
+   return 0;
+}
+
  static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host,
   struct mipi_dsi_device *device)
  {
struct dw_mipi_dsi *dsi = host_to_dsi(host);
const struct dw_mipi_dsi_plat_data *pdata = dsi->plat_data;
-   struct drm_bridge *bridge;
-   struct drm_panel *panel;
int ret;
  
  	if (device->lanes > dsi->plat_data->max_data_lanes) {

@@ -329,22 +354,14 @@ static int dw_mipi_dsi_host_attach(struct mipi_dsi_host 
*host,
dsi->format = device->format;
dsi->mode_flags = device->mode_flags;
  
-	ret = drm_of_find_panel_or_bridge(host->dev->of_node, 1, 0,

- , );
-   if (ret)
-   return ret;
+   if (!dsi->device_found) {
+   ret = dw_mipi_dsi_panel_or_bridge(dsi, host->dev->of_node);
+   if (ret)
+   return ret;
  
-	if (panel) {

-   bridge = drm_panel_bridge_add_typed(panel,
-   DRM_MODE_CONNECTOR_DSI);
-   if (IS_ERR(bridge))
-   return PTR_ERR(bridge);
+   dsi->device_found = true;
}
  
-	dsi->panel_bridge = bridge;

-
-   drm_bridge_add(>bridge);
-
if (pdata->host_ops && pdata->host_ops->attach) {
ret = pdata->host_ops->attach(pdata->priv_data, device);
if (ret < 0)
@@ -999,6 +1016,16 @@ static int dw_mipi_dsi_bridge_attach(struct drm_bridge 
*bridge,
/* Set the encoder type as caller does not know it */
bridge->encoder->encoder_type = DRM_MODE_ENCODER_DSI;
  
+	if (!dsi->device_found) {

+   int ret;
+
+   ret = dw_mipi_dsi_panel_or_bridge(dsi, dsi->dev->of_node);
+   if (ret)
+   return ret;
+
+   dsi->device_found = true;
+   }
+
/* Attach the panel-bridge to the dsi bridge */

Re: [PATCH] drm/stm: ltdc: Silence -EPROBE_DEFER till bridge attached

2021-07-07 Thread yannick Fertre

Hi Jagan,

thanks for the patch.

Tested-by: Yannick Fertre 


On 7/4/21 3:59 PM, Jagan Teki wrote:

As dw-mipi-dsi supported all possible ways to find the DSI
devices. It can take multiple iterations for ltdc to find
all components attached to the DSI bridge.

The current ltdc driver failed to find the endpoint as
it returned -EINVAL for the first iteration itself. This leads
to following error:

[    3.099289] [drm:ltdc_load] *ERROR* init encoder endpoint 0

So, check the return value and cleanup the encoder only if it's
not -EPROBE_DEFER. This make all components in the attached DSI
bridge found properly.

Signed-off-by: Jagan Teki 
---
  drivers/gpu/drm/stm/ltdc.c | 8 +---
  1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index 08b71248044d..95e983d3ffb5 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -1122,8 +1122,9 @@ static int ltdc_encoder_init(struct drm_device *ddev, 
struct drm_bridge *bridge)
  
  	ret = drm_bridge_attach(encoder, bridge, NULL, 0);

if (ret) {
-   drm_encoder_cleanup(encoder);
-   return -EINVAL;
+   if (ret != -EPROBE_DEFER)
+   drm_encoder_cleanup(encoder);
+   return ret;
}
  
  	DRM_DEBUG_DRIVER("Bridge encoder:%d created\n", encoder->base.id);

@@ -1266,7 +1267,8 @@ int ltdc_load(struct drm_device *ddev)
if (bridge) {
ret = ltdc_encoder_init(ddev, bridge);
if (ret) {
-   DRM_ERROR("init encoder endpoint %d\n", i);
+   if (ret != -EPROBE_DEFER)
+   DRM_ERROR("init encoder endpoint %d\n", 
i);
goto err;
}
}



Re: [PATCH] drm/stm: ltdc: improve pm_runtime to stop clocks

2021-07-06 Thread yannick Fertre

Hi Raphaël,

thanks for the patch.

Tested-by: Yannick Fertre 



On 6/29/21 1:58 PM, Raphael GALLAIS-POU - foss wrote:

Bugzilla ticket: https://intbugzilla.st.com/show_bug.cgi?id=60620
Gerrit patch: https://gerrit.st.com/c/mpu/oe/st/linux-stm32/+/208093/

In the LTDC driver, pm_runtime_get_sync was wrongly used and caused the
LTDC pixel clock to be systematically enabled in the clock summary.

After one simple use of the LTDC by activating and deactivating,
the clock summary results as below:

~# cat /sys/kernel/debug/clk/clk_summary | grep ltdc
 ltdc_px   1102970  0 0 
 5 N
   ltdc000   13325  0 0 
 5 N

By doing so, pm_runtime_get_sync only increments the clock counter when
the driver was in not active, displaying the right information when the
LTDC is not in use, resulting of the below clock summary after deactivation
of the LTDC.

~# cat /sys/kernel/debug/clk/clk_summary | grep ltdc
 ltdc_px   0002970  0 0 
 5 N
   ltdc000   13325  0 0 
 5 N

The clocks are activated either by the crtc_set_nofb function or
by the crtc_atomic_enable function. A check of pm_runtime activity must
be done before set clocks on. This check must also be done for others
functions which access registers.

Signed-off-by: Raphael Gallais-Pou 
---
  drivers/gpu/drm/stm/ltdc.c | 21 -
  1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index 08b71248044d..bf9d18023698 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -425,10 +425,17 @@ static void ltdc_crtc_atomic_enable(struct drm_crtc *crtc,
  {
struct ltdc_device *ldev = crtc_to_ltdc(crtc);
struct drm_device *ddev = crtc->dev;
+   int ret;
  
  	DRM_DEBUG_DRIVER("\n");
  
-	pm_runtime_get_sync(ddev->dev);

+   if (!pm_runtime_active(ddev->dev)) {
+   ret = pm_runtime_get_sync(ddev->dev);
+   if (ret) {
+   DRM_ERROR("Failed to set mode, cannot get sync\n");
+   return;
+   }
+   }
  
  	/* Sets the background color value */

reg_write(ldev->regs, LTDC_BCCR, BCCR_BCBLACK);
@@ -783,6 +790,7 @@ static void ltdc_plane_atomic_update(struct drm_plane 
*plane,
struct drm_plane_state *newstate = drm_atomic_get_new_plane_state(state,
  
plane);
struct drm_framebuffer *fb = newstate->fb;
+   struct drm_device *ddev = plane->dev;
u32 lofs = plane->index * LAY_OFS;
u32 x0 = newstate->crtc_x;
u32 x1 = newstate->crtc_x + newstate->crtc_w - 1;
@@ -792,6 +800,11 @@ static void ltdc_plane_atomic_update(struct drm_plane 
*plane,
u32 val, pitch_in_bytes, line_length, paddr, ahbp, avbp, bpcr;
enum ltdc_pix_fmt pf;
  
+	if (!pm_runtime_active(ddev->dev)) {

+   DRM_DEBUG_DRIVER("crtc not activated");
+   return;
+   }
+
if (!newstate->crtc || !fb) {
DRM_DEBUG_DRIVER("fb or crtc NULL");
return;
@@ -897,8 +910,14 @@ static void ltdc_plane_atomic_disable(struct drm_plane 
*plane,
struct drm_plane_state *oldstate = drm_atomic_get_old_plane_state(state,
  
plane);
struct ltdc_device *ldev = plane_to_ltdc(plane);
+   struct drm_device *ddev = plane->dev;
u32 lofs = plane->index * LAY_OFS;
  
+	if (!pm_runtime_active(ddev->dev)) {

+   DRM_DEBUG_DRIVER("crtc already deactivated");
+   return;
+   }
+
/* disable layer */
reg_clear(ldev->regs, LTDC_L1CR + lofs, LXCR_LEN);
  



Re: [PATCH v4 19/27] drm/stm: Don't set struct drm_device.irq_enabled

2021-06-29 Thread yannick Fertre

Hello Thomas,
thanks for the patch.

Tested-by: Yannick Fertre 

Best regards


On 6/25/21 10:22 AM, Thomas Zimmermann wrote:

The field drm_device.irq_enabled is only used by legacy drivers
with userspace modesetting. Don't set it in stm.

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Laurent Pinchart 
Acked-by: Daniel Vetter 
---
  drivers/gpu/drm/stm/ltdc.c | 3 ---
  1 file changed, 3 deletions(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index 08b71248044d..e9c5a52f041a 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -1339,9 +1339,6 @@ int ltdc_load(struct drm_device *ddev)
goto err;
}
  
-	/* Allow usage of vblank without having to call drm_irq_install */

-   ddev->irq_enabled = 1;
-
clk_disable_unprepare(ldev->pixel_clk);
  
  	pinctrl_pm_select_sleep_state(ddev->dev);




Re: [PATCH] drm/stm: Remove usage of drm_display_mode_to_videomode()

2021-05-28 Thread yannick Fertre



Hi Philippe,
I have already reviewed this patch on January 7, 2020.
(https://lore.kernel.org/dri-devel/0ab4ee45-4437-3b02-cf63-0e3b1b539...@st.com/)
Could you please review it and merge it?

Best regards

Yannick

On 5/28/21 10:05 AM, Yannick Fertre wrote:

There is not much value in the extra conversion step, the calculations
required for the LTDC IP are different than what is used in the
drm_display_mode_to_videomode(), so just do the right ones in the LTDC
driver right away.

Signed-off-by: Marek Vasut 
Signed-off-by: Yannick Fertre 
---
  drivers/gpu/drm/stm/ltdc.c | 32 +---
  1 file changed, 17 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index e99771b947b6..d113b9be12c0 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -570,31 +570,33 @@ static void ltdc_crtc_mode_set_nofb(struct drm_crtc *crtc)
}
}
  
-	drm_display_mode_to_videomode(mode, );

-
DRM_DEBUG_DRIVER("CRTC:%d mode:%s\n", crtc->base.id, mode->name);
-   DRM_DEBUG_DRIVER("Video mode: %dx%d", vm.hactive, vm.vactive);
+   DRM_DEBUG_DRIVER("Video mode: %dx%d", mode->hdisplay, mode->vdisplay);
DRM_DEBUG_DRIVER(" hfp %d hbp %d hsl %d vfp %d vbp %d vsl %d\n",
-vm.hfront_porch, vm.hback_porch, vm.hsync_len,
-vm.vfront_porch, vm.vback_porch, vm.vsync_len);
+mode->hsync_start - mode->hdisplay,
+mode->htotal - mode->hsync_end,
+mode->hsync_end - mode->hsync_start,
+mode->vsync_start - mode->vdisplay,
+mode->vtotal - mode->vsync_end,
+mode->vsync_end - mode->vsync_start);
  
  	/* Convert video timings to ltdc timings */

-   hsync = vm.hsync_len - 1;
-   vsync = vm.vsync_len - 1;
-   accum_hbp = hsync + vm.hback_porch;
-   accum_vbp = vsync + vm.vback_porch;
-   accum_act_w = accum_hbp + vm.hactive;
-   accum_act_h = accum_vbp + vm.vactive;
-   total_width = accum_act_w + vm.hfront_porch;
-   total_height = accum_act_h + vm.vfront_porch;
+   hsync = mode->hsync_end - mode->hsync_start - 1;
+   vsync = mode->vsync_end - mode->vsync_start - 1;
+   accum_hbp = mode->htotal - mode->hsync_start - 1;
+   accum_vbp = mode->vtotal - mode->vsync_start - 1;
+   accum_act_w = accum_hbp + mode->hdisplay;
+   accum_act_h = accum_vbp + mode->vdisplay;
+   total_width = mode->htotal - 1;
+   total_height = mode->vtotal - 1;
  
  	/* Configures the HS, VS, DE and PC polarities. Default Active Low */

val = 0;
  
-	if (vm.flags & DISPLAY_FLAGS_HSYNC_HIGH)

+   if (mode->flags & DRM_MODE_FLAG_PHSYNC)
val |= GCR_HSPOL;
  
-	if (vm.flags & DISPLAY_FLAGS_VSYNC_HIGH)

+   if (mode->flags & DRM_MODE_FLAG_PVSYNC)
val |= GCR_VSPOL;
  
  	if (bus_flags & DRM_BUS_FLAG_DE_LOW)




[PATCH] drm/stm: Remove usage of drm_display_mode_to_videomode()

2021-05-28 Thread Yannick Fertre
There is not much value in the extra conversion step, the calculations
required for the LTDC IP are different than what is used in the
drm_display_mode_to_videomode(), so just do the right ones in the LTDC
driver right away.

Signed-off-by: Marek Vasut 
Signed-off-by: Yannick Fertre 
---
 drivers/gpu/drm/stm/ltdc.c | 32 +---
 1 file changed, 17 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index e99771b947b6..d113b9be12c0 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -570,31 +570,33 @@ static void ltdc_crtc_mode_set_nofb(struct drm_crtc *crtc)
}
}
 
-   drm_display_mode_to_videomode(mode, );
-
DRM_DEBUG_DRIVER("CRTC:%d mode:%s\n", crtc->base.id, mode->name);
-   DRM_DEBUG_DRIVER("Video mode: %dx%d", vm.hactive, vm.vactive);
+   DRM_DEBUG_DRIVER("Video mode: %dx%d", mode->hdisplay, mode->vdisplay);
DRM_DEBUG_DRIVER(" hfp %d hbp %d hsl %d vfp %d vbp %d vsl %d\n",
-vm.hfront_porch, vm.hback_porch, vm.hsync_len,
-vm.vfront_porch, vm.vback_porch, vm.vsync_len);
+mode->hsync_start - mode->hdisplay,
+mode->htotal - mode->hsync_end,
+mode->hsync_end - mode->hsync_start,
+mode->vsync_start - mode->vdisplay,
+mode->vtotal - mode->vsync_end,
+mode->vsync_end - mode->vsync_start);
 
/* Convert video timings to ltdc timings */
-   hsync = vm.hsync_len - 1;
-   vsync = vm.vsync_len - 1;
-   accum_hbp = hsync + vm.hback_porch;
-   accum_vbp = vsync + vm.vback_porch;
-   accum_act_w = accum_hbp + vm.hactive;
-   accum_act_h = accum_vbp + vm.vactive;
-   total_width = accum_act_w + vm.hfront_porch;
-   total_height = accum_act_h + vm.vfront_porch;
+   hsync = mode->hsync_end - mode->hsync_start - 1;
+   vsync = mode->vsync_end - mode->vsync_start - 1;
+   accum_hbp = mode->htotal - mode->hsync_start - 1;
+   accum_vbp = mode->vtotal - mode->vsync_start - 1;
+   accum_act_w = accum_hbp + mode->hdisplay;
+   accum_act_h = accum_vbp + mode->vdisplay;
+   total_width = mode->htotal - 1;
+   total_height = mode->vtotal - 1;
 
/* Configures the HS, VS, DE and PC polarities. Default Active Low */
val = 0;
 
-   if (vm.flags & DISPLAY_FLAGS_HSYNC_HIGH)
+   if (mode->flags & DRM_MODE_FLAG_PHSYNC)
val |= GCR_HSPOL;
 
-   if (vm.flags & DISPLAY_FLAGS_VSYNC_HIGH)
+   if (mode->flags & DRM_MODE_FLAG_PVSYNC)
val |= GCR_VSPOL;
 
if (bus_flags & DRM_BUS_FLAG_DE_LOW)
-- 
2.17.1



Re: [PATCH 2/2] drm/stm: dsi: Use dev_ based logging

2021-03-08 Thread yannick Fertre

Tested-by: Yannick Fertre 

On 2/22/21 10:23 AM, Raphael GALLAIS-POU - foss wrote:

From: Yannick Fertre 

Standardize on the dev_ based logging.

Signed-off-by: Raphael Gallais-Pou 
Signed-off-by: Yannick Fertre 
---
  drivers/gpu/drm/stm/dw_mipi_dsi-stm.c | 49 ++-
  1 file changed, 26 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c 
b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
index 8399d337589d..a7226bb3d0e8 100644
--- a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
+++ b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
@@ -76,6 +76,7 @@ enum dsi_color {
  
  struct dw_mipi_dsi_stm {

void __iomem *base;
+   struct device *dev;
struct clk *pllref_clk;
struct dw_mipi_dsi *dsi;
u32 hw_version;
@@ -110,7 +111,8 @@ static inline void dsi_update_bits(struct dw_mipi_dsi_stm 
*dsi, u32 reg,
dsi_write(dsi, reg, (dsi_read(dsi, reg) & ~mask) | val);
  }
  
-static enum dsi_color dsi_color_from_mipi(enum mipi_dsi_pixel_format fmt)

+static enum dsi_color dsi_color_from_mipi(struct dw_mipi_dsi_stm *dsi,
+ enum mipi_dsi_pixel_format fmt)
  {
switch (fmt) {
case MIPI_DSI_FMT_RGB888:
@@ -122,7 +124,7 @@ static enum dsi_color dsi_color_from_mipi(enum 
mipi_dsi_pixel_format fmt)
case MIPI_DSI_FMT_RGB565:
return DSI_RGB565_CONF1;
default:
-   DRM_DEBUG_DRIVER("MIPI color invalid, so we use rgb888\n");
+   dev_dbg(dsi->dev, "MIPI color invalid, so we use rgb888\n");
}
return DSI_RGB888;
  }
@@ -205,14 +207,14 @@ static int dw_mipi_dsi_phy_init(void *priv_data)
ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & WISR_RRS,
 SLEEP_US, TIMEOUT_US);
if (ret)
-   DRM_DEBUG_DRIVER("!TIMEOUT! waiting REGU, let's continue\n");
+   dev_dbg(dsi->dev, "!TIMEOUT! waiting REGU, let's continue\n");
  
  	/* Enable the DSI PLL & wait for its lock */

dsi_set(dsi, DSI_WRPCR, WRPCR_PLLEN);
ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & WISR_PLLLS,
 SLEEP_US, TIMEOUT_US);
if (ret)
-   DRM_DEBUG_DRIVER("!TIMEOUT! waiting PLL, let's continue\n");
+   dev_dbg(dsi->dev, "!TIMEOUT! waiting PLL, let's continue\n");
  
  	return 0;

  }
@@ -221,7 +223,7 @@ static void dw_mipi_dsi_phy_power_on(void *priv_data)
  {
struct dw_mipi_dsi_stm *dsi = priv_data;
  
-	DRM_DEBUG_DRIVER("\n");

+   dev_dbg(dsi->dev, "\n");
  
  	/* Enable the DSI wrapper */

dsi_set(dsi, DSI_WCR, WCR_DSIEN);
@@ -231,7 +233,7 @@ static void dw_mipi_dsi_phy_power_off(void *priv_data)
  {
struct dw_mipi_dsi_stm *dsi = priv_data;
  
-	DRM_DEBUG_DRIVER("\n");

+   dev_dbg(dsi->dev, "\n");
  
  	/* Disable the DSI wrapper */

dsi_clear(dsi, DSI_WCR, WCR_DSIEN);
@@ -267,11 +269,11 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct 
drm_display_mode *mode,
  
  	if (pll_out_khz > dsi->lane_max_kbps) {

pll_out_khz = dsi->lane_max_kbps;
-   DRM_WARN("Warning max phy mbps is used\n");
+   dev_warn(dsi->dev, "Warning max phy mbps is used\n");
}
if (pll_out_khz < dsi->lane_min_kbps) {
pll_out_khz = dsi->lane_min_kbps;
-   DRM_WARN("Warning min phy mbps is used\n");
+   dev_warn(dsi->dev, "Warning min phy mbps is used\n");
}
  
  	/* Compute best pll parameters */

@@ -281,7 +283,7 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct 
drm_display_mode *mode,
ret = dsi_pll_get_params(dsi, pll_in_khz, pll_out_khz,
 , , );
if (ret)
-   DRM_WARN("Warning dsi_pll_get_params(): bad params\n");
+   dev_warn(dsi->dev, "Warning dsi_pll_get_params(): bad 
params\n");
  
  	/* Get the adjusted pll out value */

pll_out_khz = dsi_pll_get_clkout_khz(pll_in_khz, idf, ndiv, odf);
@@ -299,13 +301,12 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct 
drm_display_mode *mode,
  
  	/* Select the color coding */

dsi_update_bits(dsi, DSI_WCFGR, WCFGR_COLMUX,
-   dsi_color_from_mipi(format) << 1);
+   dsi_color_from_mipi(dsi, format) << 1);
  
  	*lane_mbps = pll_out_khz / 1000;
  
-	DRM_DEBUG_DRIVER("pll_in %ukHz pll_out %ukHz lane_mbps %uMHz\n",

-pll_in_khz, pll_out_khz, *lane_mbps);
-
+   dev_dbg(dsi->dev, "pll_in %ukHz pll_out %ukHz lane_mbps %uMHz\n",
+   pll_in_khz, pll_out_khz, *lane_mbps);
return 0;
  }
  
@@ -352,11 +3

Re: [PATCH 1/2] drm/stm: dsi: Avoid printing errors for -EPROBE_DEFER

2021-03-08 Thread yannick Fertre

Tested-by: Yannick Fertre 

On 2/22/21 10:22 AM, Raphael GALLAIS-POU - foss wrote:

From: Yannick Fertre 

Don't print error when probe deferred error is returned.

Signed-off-by: Raphael Gallais-Pou 
Signed-off-by: Yannick Fertre 
---
  drivers/gpu/drm/stm/dw_mipi_dsi-stm.c | 9 +++--
  1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c 
b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
index 2e1f2664495d..8399d337589d 100644
--- a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
+++ b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
@@ -363,8 +363,7 @@ static int dw_mipi_dsi_stm_probe(struct platform_device 
*pdev)
dsi->vdd_supply = devm_regulator_get(dev, "phy-dsi");
if (IS_ERR(dsi->vdd_supply)) {
ret = PTR_ERR(dsi->vdd_supply);
-   if (ret != -EPROBE_DEFER)
-   DRM_ERROR("Failed to request regulator: %d\n", ret);
+   dev_err_probe(dev, ret, "Failed to request regulator\n");
return ret;
}
  
@@ -377,9 +376,7 @@ static int dw_mipi_dsi_stm_probe(struct platform_device *pdev)

dsi->pllref_clk = devm_clk_get(dev, "ref");
if (IS_ERR(dsi->pllref_clk)) {
ret = PTR_ERR(dsi->pllref_clk);
-   if (ret != -EPROBE_DEFER)
-   DRM_ERROR("Unable to get pll reference clock: %d\n",
- ret);
+   dev_err_probe(dev, ret, "Unable to get pll reference clock\n");
goto err_clk_get;
}
  
@@ -419,7 +416,7 @@ static int dw_mipi_dsi_stm_probe(struct platform_device *pdev)

dsi->dsi = dw_mipi_dsi_probe(pdev, _mipi_dsi_stm_plat_data);
if (IS_ERR(dsi->dsi)) {
ret = PTR_ERR(dsi->dsi);
-   DRM_ERROR("Failed to initialize mipi dsi host: %d\n", ret);
+   dev_err_probe(dev, ret, "Failed to initialize mipi dsi host\n");
goto err_dsi_probe;
}
  


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] drm/stm: ltdc: Use simple encoder

2021-03-04 Thread yannick Fertre

Hi Thomas,
I wait a few days before merging it.
Thank you for your help.

Best regards

Yannick


On 3/4/21 9:21 AM, Thomas Zimmermann wrote:

Hi,

shall I merge this patch?

Am 02.03.21 um 18:57 schrieb Jagan Teki:

STM ltdc driver uses an empty implementation for its encoder.
Replace the code with the generic simple encoder.

Signed-off-by: Jagan Teki 
---
  drivers/gpu/drm/stm/ltdc.c | 12 ++--
  1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index 7812094f93d6..aeeb43524ca0 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -31,6 +31,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
@@ -1020,14 +1021,6 @@ static int ltdc_crtc_init(struct drm_device 
*ddev, struct drm_crtc *crtc)

  return ret;
  }
-/*
- * DRM_ENCODER
- */
-
-static const struct drm_encoder_funcs ltdc_encoder_funcs = {
-    .destroy = drm_encoder_cleanup,
-};
-
  static void ltdc_encoder_disable(struct drm_encoder *encoder)
  {
  struct drm_device *ddev = encoder->dev;
@@ -1088,8 +1081,7 @@ static int ltdc_encoder_init(struct drm_device 
*ddev, struct drm_bridge *bridge)

  encoder->possible_crtcs = CRTC_MASK;
  encoder->possible_clones = 0;    /* No cloning support */
-    drm_encoder_init(ddev, encoder, _encoder_funcs,
- DRM_MODE_ENCODER_DPI, NULL);
+    drm_simple_encoder_init(ddev, encoder, DRM_MODE_ENCODER_DPI);
  drm_encoder_helper_add(encoder, _encoder_helper_funcs);




___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] drm/stm: ltdc: Use simple encoder

2021-03-03 Thread yannick Fertre

Thanks Jagan for the patch.

Tested-by: Yannick Fertre 


On 3/2/21 6:57 PM, Jagan Teki wrote:

STM ltdc driver uses an empty implementation for its encoder.
Replace the code with the generic simple encoder.

Signed-off-by: Jagan Teki 
---
  drivers/gpu/drm/stm/ltdc.c | 12 ++--
  1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index 7812094f93d6..aeeb43524ca0 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -31,6 +31,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  
  #include 

@@ -1020,14 +1021,6 @@ static int ltdc_crtc_init(struct drm_device *ddev, 
struct drm_crtc *crtc)
return ret;
  }
  
-/*

- * DRM_ENCODER
- */
-
-static const struct drm_encoder_funcs ltdc_encoder_funcs = {
-   .destroy = drm_encoder_cleanup,
-};
-
  static void ltdc_encoder_disable(struct drm_encoder *encoder)
  {
struct drm_device *ddev = encoder->dev;
@@ -1088,8 +1081,7 @@ static int ltdc_encoder_init(struct drm_device *ddev, 
struct drm_bridge *bridge)
encoder->possible_crtcs = CRTC_MASK;
encoder->possible_clones = 0;/* No cloning support */
  
-	drm_encoder_init(ddev, encoder, _encoder_funcs,

-DRM_MODE_ENCODER_DPI, NULL);
+   drm_simple_encoder_init(ddev, encoder, DRM_MODE_ENCODER_DPI);
  
  	drm_encoder_helper_add(encoder, _encoder_helper_funcs);
  


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] drm/bridge: dw-mipi-dsi: Move drm_bridge_add into probe

2021-02-15 Thread yannick Fertre

Hello Jagan, I tested your patch on the stm32mp1 board.
Unfortunately, the dsi panel does not probe well with this patch. The 
problem is due to the panel which is placed in the node of the dsi 
bridge (no problem with i2c devices).


Regarding component bindings for stm drivers, I am currently working on 
a new version.


Best regards

Yannick



On 2/3/21 10:13 AM, Jagan Teki wrote:

Usual I2C configured DSI bridge drivers have drm_bridge_add
in probe and mipi_dsi_attach in bridge attach functions.

With, this approach the drm pipeline is unable to find the
dsi bridge in stm drm drivers since the dw-mipi-dsi bridge is
adding drm bridge during bridge attach operations instead of
the probe.

This specific issue may not encounter for rockchip drm dsi
drivers, since rockchip drm uses component binding operations,
unlike stm drm drivers.

So, possible solutions are
1. Move drm_bridge_add into the dw-mipi-dsi probe.
2. Add mipi_dsi_attach in the bridge drivers probe.
3. Add component binding operations for stm drm drivers.

Option 1 is a relatively possible solution as most of the
mainline drm dsi with bridge drivers have a similar approach
to their dsi host vs bridge registration.

Signed-off-by: Jagan Teki 
---
  drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 35 +--
  1 file changed, 17 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index 6b268f9445b3..8a535041f071 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -314,8 +314,6 @@ static int dw_mipi_dsi_host_attach(struct mipi_dsi_host 
*host,
  {
struct dw_mipi_dsi *dsi = host_to_dsi(host);
const struct dw_mipi_dsi_plat_data *pdata = dsi->plat_data;
-   struct drm_bridge *bridge;
-   struct drm_panel *panel;
int ret;
  
  	if (device->lanes > dsi->plat_data->max_data_lanes) {

@@ -329,22 +327,6 @@ static int dw_mipi_dsi_host_attach(struct mipi_dsi_host 
*host,
dsi->format = device->format;
dsi->mode_flags = device->mode_flags;
  
-	ret = drm_of_find_panel_or_bridge(host->dev->of_node, 1, 0,

- , );
-   if (ret)
-   return ret;
-
-   if (panel) {
-   bridge = drm_panel_bridge_add_typed(panel,
-   DRM_MODE_CONNECTOR_DSI);
-   if (IS_ERR(bridge))
-   return PTR_ERR(bridge);
-   }
-
-   dsi->panel_bridge = bridge;
-
-   drm_bridge_add(>bridge);
-
if (pdata->host_ops && pdata->host_ops->attach) {
ret = pdata->host_ops->attach(pdata->priv_data, device);
if (ret < 0)
@@ -1105,6 +1087,8 @@ __dw_mipi_dsi_probe(struct platform_device *pdev,
struct device *dev = >dev;
struct reset_control *apb_rst;
struct dw_mipi_dsi *dsi;
+   struct drm_bridge *bridge;
+   struct drm_panel *panel;
int ret;
  
  	dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);

@@ -1167,6 +1151,20 @@ __dw_mipi_dsi_probe(struct platform_device *pdev,
dw_mipi_dsi_debugfs_init(dsi);
pm_runtime_enable(dev);
  
+	ret = drm_of_find_panel_or_bridge(dev->of_node, 1, 0,

+ , );
+   if (ret)
+   return ERR_PTR(ret);
+
+   if (panel) {
+   bridge = drm_panel_bridge_add_typed(panel,
+   DRM_MODE_CONNECTOR_DSI);
+   if (IS_ERR(bridge))
+   return ERR_PTR(-ENODEV);
+   }
+
+   dsi->panel_bridge = bridge;
+
dsi->dsi_host.ops = _mipi_dsi_host_ops;
dsi->dsi_host.dev = dev;
ret = mipi_dsi_host_register(>dsi_host);
@@ -1181,6 +1179,7 @@ __dw_mipi_dsi_probe(struct platform_device *pdev,
  #ifdef CONFIG_OF
dsi->bridge.of_node = pdev->dev.of_node;
  #endif
+   drm_bridge_add(>bridge);
  
  	return dsi;

  }


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH V4] drm/stm: Fix bus_flags handling

2021-01-28 Thread yannick Fertre

Hi Marek,
Thanks for the patch.

Tested-by: Yannick Fertre 



On 1/27/21 12:07 PM, Marek Vasut wrote:

The drm_display_mode_to_videomode() does not populate DISPLAY_FLAGS_DE_LOW
or DISPLAY_FLAGS_PIXDATA_NEGEDGE flags in struct videomode. Therefore, no
matter what polarity the next bridge or display might require, these flags
are never set, and thus the LTDC GCR_DEPOL and GCR_PCPOL bits are never set,
and the LTDC behaves as if both DISPLAY_FLAGS_PIXDATA_POSEDGE and
DISPLAY_FLAGS_DE_HIGH were always set.

The fix for this problem is taken almost verbatim from MXSFB driver. In
case there is a bridge attached to the LTDC, the bridge might have extra
polarity requirements, so extract bus_flags from the bridge and use them
for LTDC configuration. Otherwise, extract bus_flags from the connector,
which is the display.

Fixes: b759012c5fa7 ("drm/stm: Add STM32 LTDC driver")
Signed-off-by: Marek Vasut 
Signed-off-by: Yannick Fertre 
Cc: Alexandre Torgue 
Cc: Antonio Borneo 
Cc: Benjamin Gaignard 
Cc: Maxime Coquelin 
Cc: Philippe Cornu 
Cc: Sam Ravnborg 
Cc: Vincent Abriou 
Cc: Yannick Fertre 
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-st...@st-md-mailman.stormreply.com
To: dri-devel@lists.freedesktop.org
---
V2: Check if ldev->bridge->timings is non-NULL before accessing it
V3: get bus_flags from connector (from Yannick)
 - Display controller could support several connectors (not connected at
   the same time). ie: stm32mp15c-DK2 board have 2 connectors (HDMI + DSI).
   Driver check which connector is connected to get the bus flag.
V4: get bridge from encoder (from Yannick)
---
  drivers/gpu/drm/stm/ltdc.c | 33 +++--
  1 file changed, 31 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index 6e28e6b60e72..acc9f6694eb6 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -544,13 +544,42 @@ static void ltdc_crtc_mode_set_nofb(struct drm_crtc *crtc)
  {
struct ltdc_device *ldev = crtc_to_ltdc(crtc);
struct drm_device *ddev = crtc->dev;
+   struct drm_connector_list_iter iter;
+   struct drm_connector *connector = NULL;
+   struct drm_encoder *encoder = NULL;
+   struct drm_bridge *bridge = NULL;
struct drm_display_mode *mode = >state->adjusted_mode;
struct videomode vm;
u32 hsync, vsync, accum_hbp, accum_vbp, accum_act_w, accum_act_h;
u32 total_width, total_height;
+   u32 bus_flags = 0;
u32 val;
int ret;
  
+	/* get encoder from crtc */

+   drm_for_each_encoder(encoder, ddev)
+   if (encoder->crtc == crtc)
+   break;
+
+   if (encoder) {
+   /* get bridge from encoder */
+   list_for_each_entry(bridge, >bridge_chain, chain_node)
+   if (bridge->encoder == encoder)
+   break;
+
+   /* Get the connector from encoder */
+   drm_connector_list_iter_begin(ddev, );
+   drm_for_each_connector_iter(connector, )
+   if (connector->encoder == encoder)
+   break;
+   drm_connector_list_iter_end();
+   }
+
+   if (bridge && bridge->timings)
+   bus_flags = bridge->timings->input_bus_flags;
+   else if (connector)
+   bus_flags = connector->display_info.bus_flags;
+
if (!pm_runtime_active(ddev->dev)) {
ret = pm_runtime_get_sync(ddev->dev);
if (ret) {
@@ -586,10 +615,10 @@ static void ltdc_crtc_mode_set_nofb(struct drm_crtc *crtc)
if (vm.flags & DISPLAY_FLAGS_VSYNC_HIGH)
val |= GCR_VSPOL;
  
-	if (vm.flags & DISPLAY_FLAGS_DE_LOW)

+   if (bus_flags & DRM_BUS_FLAG_DE_LOW)
val |= GCR_DEPOL;
  
-	if (vm.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)

+   if (bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)
val |= GCR_PCPOL;
  
  	reg_update_bits(ldev->regs, LTDC_GCR,



___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] ARM: multi_v7_defconfig: add STM32 CEC support

2021-01-15 Thread Yannick Fertre
Enable CEC support for STMicroelectronics as loadable module.

Signed-off-by: Yannick Fertre 
---
 arch/arm/configs/multi_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/multi_v7_defconfig 
b/arch/arm/configs/multi_v7_defconfig
index c5f25710fedc..05cc0607a9ad 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -656,6 +656,7 @@ CONFIG_V4L_TEST_DRIVERS=y
 CONFIG_VIDEO_VIVID=m
 CONFIG_CEC_PLATFORM_DRIVERS=y
 CONFIG_CEC_SAMSUNG_S5P=m
+CONFIG_CEC_STM32=m
 CONFIG_VIDEO_ADV7180=m
 CONFIG_VIDEO_ADV7604=m
 CONFIG_VIDEO_ADV7604_CEC=y
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] drm/stm: Remove usage of drm_display_mode_to_videomode()

2021-01-07 Thread Yannick FERTRE
Hi Marek,
thanks for the patch. It works fine on stm32mp1 eval board with bridge 
DSI & DPI panel.

Tested-by: Yannick Fertré 

Best regards

On 12/24/20 7:20 AM, Marek Vasut wrote:
> There is not much value in the extra conversion step, the calculations
> required for the LTDC IP are different than what is used in the
> drm_display_mode_to_videomode(), so just do the right ones in the LTDC
> driver right away.
> 
> Signed-off-by: Marek Vasut 
> Cc: Alexandre Torgue 
> Cc: Antonio Borneo 
> Cc: Benjamin Gaignard 
> Cc: Maxime Coquelin 
> Cc: Philippe Cornu 
> Cc: Sam Ravnborg 
> Cc: Vincent Abriou 
> Cc: Yannick Fertre 
> Cc: linux-arm-ker...@lists.infradead.org
> Cc: linux-st...@st-md-mailman.stormreply.com
> To: dri-devel@lists.freedesktop.org
> ---
>   drivers/gpu/drm/stm/ltdc.c | 33 +
>   1 file changed, 17 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
> index 22c7e9fa5ab7..e8fc8fc50d94 100644
> --- a/drivers/gpu/drm/stm/ltdc.c
> +++ b/drivers/gpu/drm/stm/ltdc.c
> @@ -545,7 +545,6 @@ static void ltdc_crtc_mode_set_nofb(struct drm_crtc *crtc)
>   struct ltdc_device *ldev = crtc_to_ltdc(crtc);
>   struct drm_device *ddev = crtc->dev;
>   struct drm_display_mode *mode = >state->adjusted_mode;
> - struct videomode vm;
>   u32 bus_flags = 0;
>   u32 hsync, vsync, accum_hbp, accum_vbp, accum_act_w, accum_act_h;
>   u32 total_width, total_height;
> @@ -565,31 +564,33 @@ static void ltdc_crtc_mode_set_nofb(struct drm_crtc 
> *crtc)
>   }
>   }
>   
> - drm_display_mode_to_videomode(mode, );
> -
>   DRM_DEBUG_DRIVER("CRTC:%d mode:%s\n", crtc->base.id, mode->name);
> - DRM_DEBUG_DRIVER("Video mode: %dx%d", vm.hactive, vm.vactive);
> + DRM_DEBUG_DRIVER("Video mode: %dx%d", mode->hdisplay, mode->vdisplay);
>   DRM_DEBUG_DRIVER(" hfp %d hbp %d hsl %d vfp %d vbp %d vsl %d\n",
> -  vm.hfront_porch, vm.hback_porch, vm.hsync_len,
> -  vm.vfront_porch, vm.vback_porch, vm.vsync_len);
> +  mode->hsync_start - mode->hdisplay,
> +  mode->htotal - mode->hsync_end,
> +  mode->hsync_end - mode->hsync_start,
> +  mode->vsync_start - mode->vdisplay,
> +  mode->vtotal - mode->vsync_end,
> +  mode->vsync_end - mode->vsync_start);
>   
>   /* Convert video timings to ltdc timings */
> - hsync = vm.hsync_len - 1;
> - vsync = vm.vsync_len - 1;
> - accum_hbp = hsync + vm.hback_porch;
> - accum_vbp = vsync + vm.vback_porch;
> - accum_act_w = accum_hbp + vm.hactive;
> - accum_act_h = accum_vbp + vm.vactive;
> - total_width = accum_act_w + vm.hfront_porch;
> - total_height = accum_act_h + vm.vfront_porch;
> + hsync = mode->hsync_end - mode->hsync_start - 1;
> + vsync = mode->vsync_end - mode->vsync_start - 1;
> + accum_hbp = mode->htotal - mode->hsync_start - 1;
> + accum_vbp = mode->vtotal - mode->vsync_start - 1;
> + accum_act_w = accum_hbp + mode->hdisplay;
> + accum_act_h = accum_vbp + mode->vdisplay;
> + total_width = mode->htotal - 1;
> + total_height = mode->vtotal - 1;
>   
>   /* Configures the HS, VS, DE and PC polarities. Default Active Low */
>   val = 0;
>   
> - if (vm.flags & DISPLAY_FLAGS_HSYNC_HIGH)
> + if (mode->flags & DRM_MODE_FLAG_PHSYNC)
>   val |= GCR_HSPOL;
>   
> - if (vm.flags & DISPLAY_FLAGS_VSYNC_HIGH)
> + if (mode->flags & DRM_MODE_FLAG_PVSYNC)
>   val |= GCR_VSPOL;
>   
>   if (bus_flags & DRM_BUS_FLAG_DE_LOW)
> 
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH V2] drm/stm: Fix bus_flags handling

2021-01-07 Thread Yannick FERTRE
Hi Marek,
thanks for the patch. It works fine on stm32mp1 eval board with bridge 
DSI & DPI panel.

Tested-by: Yannick Fertré 

Best regards

On 12/24/20 7:19 AM, Marek Vasut wrote:
> The drm_display_mode_to_videomode() does not populate DISPLAY_FLAGS_DE_LOW
> or DISPLAY_FLAGS_PIXDATA_NEGEDGE flags in struct videomode. Therefore, no
> matter what polarity the next bridge or display might require, these flags
> are never set, and thus the LTDC GCR_DEPOL and GCR_PCPOL bits are never set,
> and the LTDC behaves as if both DISPLAY_FLAGS_PIXDATA_POSEDGE and
> DISPLAY_FLAGS_DE_HIGH were always set.
> 
> The fix for this problem is taken almost verbatim from MXSFB driver. In
> case there is a bridge attached to the LTDC, the bridge might have extra
> polarity requirements, so extract bus_flags from the bridge and use them
> for LTDC configuration. Otherwise, extract bus_flags from the connector,
> which is the display.
> 
> Fixes: b759012c5fa7 ("drm/stm: Add STM32 LTDC driver")
> Signed-off-by: Marek Vasut 
> Cc: Alexandre Torgue 
> Cc: Antonio Borneo 
> Cc: Benjamin Gaignard 
> Cc: Maxime Coquelin 
> Cc: Philippe Cornu 
> Cc: Sam Ravnborg 
> Cc: Vincent Abriou 
> Cc: Yannick Fertre 
> Cc: linux-arm-ker...@lists.infradead.org
> Cc: linux-st...@st-md-mailman.stormreply.com
> To: dri-devel@lists.freedesktop.org
> ---
> V2: Check if ldev->bridge->timings is non-NULL before accessing it
> ---
>   drivers/gpu/drm/stm/ltdc.c | 22 --
>   drivers/gpu/drm/stm/ltdc.h |  2 ++
>   2 files changed, 22 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
> index 1c9f18b4adfc..22c7e9fa5ab7 100644
> --- a/drivers/gpu/drm/stm/ltdc.c
> +++ b/drivers/gpu/drm/stm/ltdc.c
> @@ -546,11 +546,17 @@ static void ltdc_crtc_mode_set_nofb(struct drm_crtc 
> *crtc)
>   struct drm_device *ddev = crtc->dev;
>   struct drm_display_mode *mode = >state->adjusted_mode;
>   struct videomode vm;
> + u32 bus_flags = 0;
>   u32 hsync, vsync, accum_hbp, accum_vbp, accum_act_w, accum_act_h;
>   u32 total_width, total_height;
>   u32 val;
>   int ret;
>   
> + if (ldev->bridge && ldev->bridge->timings)
> + bus_flags = ldev->bridge->timings->input_bus_flags;
> + else if (ldev->connector)
> + bus_flags = ldev->connector->display_info.bus_flags;
> +
>   if (!pm_runtime_active(ddev->dev)) {
>   ret = pm_runtime_get_sync(ddev->dev);
>   if (ret) {
> @@ -586,10 +592,10 @@ static void ltdc_crtc_mode_set_nofb(struct drm_crtc 
> *crtc)
>   if (vm.flags & DISPLAY_FLAGS_VSYNC_HIGH)
>   val |= GCR_VSPOL;
>   
> - if (vm.flags & DISPLAY_FLAGS_DE_LOW)
> + if (bus_flags & DRM_BUS_FLAG_DE_LOW)
>   val |= GCR_DEPOL;
>   
> - if (vm.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
> + if (bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)
>   val |= GCR_PCPOL;
>   
>   reg_update_bits(ldev->regs, LTDC_GCR,
> @@ -1098,6 +1104,8 @@ static const struct drm_encoder_helper_funcs 
> ltdc_encoder_helper_funcs = {
>   
>   static int ltdc_encoder_init(struct drm_device *ddev, struct drm_bridge 
> *bridge)
>   {
> + struct ltdc_device *ldev = ddev->dev_private;
> + struct drm_connector_list_iter iter;
>   struct drm_encoder *encoder;
>   int ret;
>   
> @@ -1119,6 +1127,16 @@ static int ltdc_encoder_init(struct drm_device *ddev, 
> struct drm_bridge *bridge)
>   return -EINVAL;
>   }
>   
> + ldev->bridge = bridge;
> +
> + /*
> +  * Get hold of the connector. This is a bit of a hack, until the bridge
> +  * API gives us bus flags and formats.
> +  */
> + drm_connector_list_iter_begin(ddev, );
> + ldev->connector = drm_connector_list_iter_next();
> + drm_connector_list_iter_end();
> +
>   DRM_DEBUG_DRIVER("Bridge encoder:%d created\n", encoder->base.id);
>   
>   return 0;
> diff --git a/drivers/gpu/drm/stm/ltdc.h b/drivers/gpu/drm/stm/ltdc.h
> index f153b908c70e..d0d2c81de29a 100644
> --- a/drivers/gpu/drm/stm/ltdc.h
> +++ b/drivers/gpu/drm/stm/ltdc.h
> @@ -38,6 +38,8 @@ struct ltdc_device {
>   u32 irq_status;
>   struct fps_info plane_fpsi[LTDC_MAX_LAYER];
>   struct drm_atomic_state *suspend_state;
> + struct drm_bridge *bridge;
> + struct drm_connector *connector;
>   };
>   
>   int ltdc_load(struct drm_device *ddev);
> 
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] drm/stm: Enable RPM during fbdev registration

2020-11-06 Thread Yannick FERTRE
Hi Marek,

On 11/5/20 10:45 AM, Marek Vasut wrote:
> On 11/5/20 10:39 AM, Daniel Vetter wrote:
>> On Wed, Nov 04, 2020 at 01:52:00PM +0100, Marek Vasut wrote:
>>> Enable runtime PM before registering the fbdev emulation and disable it
>>> afterward, otherwise register access to the LTDC IP during the fbdev
>>> emulation registration might hang the system.
>>>
>>> The problem happens because RPM is activated at the end of ltdc_load(),
>>> but the fbdev emulation registration happens only after that, and ends
>>> up calling ltdc_crtc_mode_set_nofb(), which checks whether RPM is active
>>> and only if it is not active, calls pm_runtime_get_sync() to enable the
>>> clock and so on. If the clock are not enabled, any register access in
>>> ltdc_crtc_mode_set_nofb() could hang the platform completely.
>>>
>>> This patch makes sure that ltdc_crtc_mode_set_nofb() is called within
>>> pm_runtime_get_sync(), so with clock enabled.
> 
> [...]
> 
>> This looks like you're papering over a bug in your modeset code. If
>> userspace later on does a setpar on the fbdev chardev, the exact same
>> thing could happen. You need to fix your modeset code to avoid this, not
>> sprinkle temporary rpm_get/put all over some top level entry points,
>> because you can't even patch those all.
> 
> I have a feeling all those pm_runtime_active() checks in the driver 
> might be the root cause of this ? I wonder why the code doesn't use 
> pm_runtime_{get,put}_sync() only when accessing registers. Thoughts?

First line of function ltdc_crtc_mode_set_nofb check the pm_runtime to 
avoid to access registers without clock enabled.



static void ltdc_crtc_mode_set_nofb(struct drm_crtc *crtc)
{
...
if (!pm_runtime_active(ddev->dev)) {
ret = pm_runtime_get_sync(ddev->dev);

I test the fb with framebuffer console, & it works fine on my side.
Do you test fb on a old kernel?
How can I reproduce your issue?

Best regards

Yannick
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2] drm/stm: dsi: Use dev_ based logging

2020-10-13 Thread Yannick Fertre
Standardize on the dev_ based logging.

Signed-off-by: Yannick Fertre 
---
Changes in v2:
- restore function dsi_color_from_mipi.
- reword commit.

 drivers/gpu/drm/stm/dw_mipi_dsi-stm.c | 55 ++-
 1 file changed, 29 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c 
b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
index 164f79ef6269..a5a87c89aa07 100644
--- a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
+++ b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
@@ -76,6 +76,7 @@ enum dsi_color {
 
 struct dw_mipi_dsi_stm {
void __iomem *base;
+   struct device *dev;
struct clk *pllref_clk;
struct dw_mipi_dsi *dsi;
u32 hw_version;
@@ -110,7 +111,8 @@ static inline void dsi_update_bits(struct dw_mipi_dsi_stm 
*dsi, u32 reg,
dsi_write(dsi, reg, (dsi_read(dsi, reg) & ~mask) | val);
 }
 
-static enum dsi_color dsi_color_from_mipi(enum mipi_dsi_pixel_format fmt)
+static enum dsi_color dsi_color_from_mipi(struct dw_mipi_dsi_stm *dsi,
+ enum mipi_dsi_pixel_format fmt)
 {
switch (fmt) {
case MIPI_DSI_FMT_RGB888:
@@ -122,7 +124,7 @@ static enum dsi_color dsi_color_from_mipi(enum 
mipi_dsi_pixel_format fmt)
case MIPI_DSI_FMT_RGB565:
return DSI_RGB565_CONF1;
default:
-   DRM_DEBUG_DRIVER("MIPI color invalid, so we use rgb888\n");
+   dev_dbg(dsi->dev, "MIPI color invalid, so we use rgb888\n");
}
return DSI_RGB888;
 }
@@ -205,14 +207,14 @@ static int dw_mipi_dsi_phy_init(void *priv_data)
ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & WISR_RRS,
 SLEEP_US, TIMEOUT_US);
if (ret)
-   DRM_DEBUG_DRIVER("!TIMEOUT! waiting REGU, let's continue\n");
+   dev_dbg(dsi->dev, "!TIMEOUT! waiting REGU, let's continue\n");
 
/* Enable the DSI PLL & wait for its lock */
dsi_set(dsi, DSI_WRPCR, WRPCR_PLLEN);
ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & WISR_PLLLS,
 SLEEP_US, TIMEOUT_US);
if (ret)
-   DRM_DEBUG_DRIVER("!TIMEOUT! waiting PLL, let's continue\n");
+   dev_dbg(dsi->dev, "!TIMEOUT! waiting PLL, let's continue\n");
 
return 0;
 }
@@ -221,7 +223,7 @@ static void dw_mipi_dsi_phy_power_on(void *priv_data)
 {
struct dw_mipi_dsi_stm *dsi = priv_data;
 
-   DRM_DEBUG_DRIVER("\n");
+   dev_dbg(dsi->dev, "\n");
 
/* Enable the DSI wrapper */
dsi_set(dsi, DSI_WCR, WCR_DSIEN);
@@ -231,7 +233,7 @@ static void dw_mipi_dsi_phy_power_off(void *priv_data)
 {
struct dw_mipi_dsi_stm *dsi = priv_data;
 
-   DRM_DEBUG_DRIVER("\n");
+   dev_dbg(dsi->dev, "\n");
 
/* Disable the DSI wrapper */
dsi_clear(dsi, DSI_WCR, WCR_DSIEN);
@@ -267,11 +269,11 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct 
drm_display_mode *mode,
 
if (pll_out_khz > dsi->lane_max_kbps) {
pll_out_khz = dsi->lane_max_kbps;
-   DRM_WARN("Warning max phy mbps is used\n");
+   dev_warn(dsi->dev, "Warning max phy mbps is used\n");
}
if (pll_out_khz < dsi->lane_min_kbps) {
pll_out_khz = dsi->lane_min_kbps;
-   DRM_WARN("Warning min phy mbps is used\n");
+   dev_warn(dsi->dev, "Warning min phy mbps is used\n");
}
 
/* Compute best pll parameters */
@@ -281,7 +283,7 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct 
drm_display_mode *mode,
ret = dsi_pll_get_params(dsi, pll_in_khz, pll_out_khz,
 , , );
if (ret)
-   DRM_WARN("Warning dsi_pll_get_params(): bad params\n");
+   dev_warn(dsi->dev, "Warning dsi_pll_get_params(): bad 
params\n");
 
/* Get the adjusted pll out value */
pll_out_khz = dsi_pll_get_clkout_khz(pll_in_khz, idf, ndiv, odf);
@@ -299,12 +301,12 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct 
drm_display_mode *mode,
 
/* Select the color coding */
dsi_update_bits(dsi, DSI_WCFGR, WCFGR_COLMUX,
-   dsi_color_from_mipi(format) << 1);
+   dsi_color_from_mipi(dsi, format) << 1);
 
*lane_mbps = pll_out_khz / 1000;
 
-   DRM_DEBUG_DRIVER("pll_in %ukHz pll_out %ukHz lane_mbps %uMHz\n",
-pll_in_khz, pll_out_khz, *lane_mbps);
+   dev_dbg(dsi->dev, "pll_in %ukHz pll_out %ukHz lane_mbps %uMHz\n", 
pll_in_khz, pll_out_khz,
+   *lane_mbps);
 
return 0;
 }
@@ -352,11 +354,13 @@ static int dw_mipi_dsi_stm

Re: [PATCH] drm/stm: dsi: Use dev_ based logging

2020-10-13 Thread Yannick FERTRE
Hi Sam,
thanks for the review. I'll send a new patch with the revert of function 
dsi_color_from_mipi.

Best regards

Yannick

On 9/25/20 4:51 PM, Sam Ravnborg wrote:
> Hi Yannick.
> 
> On Fri, Sep 25, 2020 at 12:22:33PM +0200, Yannick Fertre wrote:
>> Standardize on the dev_ based logging and drop the include of drm_print.h.
> The patchs filas to drop the include mentioned here.
> 
>> Remove useless dsi_color_from_mipi function.
> IMO the dsi_color_from_mipi() was nice, and inlining the helper
> is no gain for readability.
> 
>       Sam
> 
>>
>> Signed-off-by: Yannick Fertre 
>> ---
>>   drivers/gpu/drm/stm/dw_mipi_dsi-stm.c | 87 ++-
>>   1 file changed, 45 insertions(+), 42 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c 
>> b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
>> index 164f79ef6269..93fa8bfd3127 100644
>> --- a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
>> +++ b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
>> @@ -76,6 +76,7 @@ enum dsi_color {
>>   
>>   struct dw_mipi_dsi_stm {
>>  void __iomem *base;
>> +struct device *dev;
>>  struct clk *pllref_clk;
>>  struct dw_mipi_dsi *dsi;
>>  u32 hw_version;
>> @@ -110,23 +111,6 @@ static inline void dsi_update_bits(struct 
>> dw_mipi_dsi_stm *dsi, u32 reg,
>>  dsi_write(dsi, reg, (dsi_read(dsi, reg) & ~mask) | val);
>>   }
>>   
>> -static enum dsi_color dsi_color_from_mipi(enum mipi_dsi_pixel_format fmt)
>> -{
>> -switch (fmt) {
>> -case MIPI_DSI_FMT_RGB888:
>> -return DSI_RGB888;
>> -case MIPI_DSI_FMT_RGB666:
>> -return DSI_RGB666_CONF2;
>> -case MIPI_DSI_FMT_RGB666_PACKED:
>> -return DSI_RGB666_CONF1;
>> -case MIPI_DSI_FMT_RGB565:
>> -return DSI_RGB565_CONF1;
>> -default:
>> -DRM_DEBUG_DRIVER("MIPI color invalid, so we use rgb888\n");
>> -}
>> -return DSI_RGB888;
>> -}
>> -
>>   static int dsi_pll_get_clkout_khz(int clkin_khz, int idf, int ndiv, int 
>> odf)
>>   {
>>  int divisor = idf * odf;
>> @@ -205,14 +189,14 @@ static int dw_mipi_dsi_phy_init(void *priv_data)
>>  ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & WISR_RRS,
>>   SLEEP_US, TIMEOUT_US);
>>  if (ret)
>> -DRM_DEBUG_DRIVER("!TIMEOUT! waiting REGU, let's continue\n");
>> +dev_dbg(dsi->dev, "!TIMEOUT! waiting REGU, let's continue\n");
>>   
>>  /* Enable the DSI PLL & wait for its lock */
>>  dsi_set(dsi, DSI_WRPCR, WRPCR_PLLEN);
>>  ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & WISR_PLLLS,
>>   SLEEP_US, TIMEOUT_US);
>>  if (ret)
>> -DRM_DEBUG_DRIVER("!TIMEOUT! waiting PLL, let's continue\n");
>> +dev_dbg(dsi->dev, "!TIMEOUT! waiting PLL, let's continue\n");
>>   
>>  return 0;
>>   }
>> @@ -221,7 +205,7 @@ static void dw_mipi_dsi_phy_power_on(void *priv_data)
>>   {
>>  struct dw_mipi_dsi_stm *dsi = priv_data;
>>   
>> -DRM_DEBUG_DRIVER("\n");
>> +dev_dbg(dsi->dev, "\n");
>>   
>>  /* Enable the DSI wrapper */
>>  dsi_set(dsi, DSI_WCR, WCR_DSIEN);
>> @@ -231,7 +215,7 @@ static void dw_mipi_dsi_phy_power_off(void *priv_data)
>>   {
>>  struct dw_mipi_dsi_stm *dsi = priv_data;
>>   
>> -DRM_DEBUG_DRIVER("\n");
>> +dev_dbg(dsi->dev, "\n");
>>   
>>  /* Disable the DSI wrapper */
>>  dsi_clear(dsi, DSI_WCR, WCR_DSIEN);
>> @@ -244,6 +228,7 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct 
>> drm_display_mode *mode,
>>   {
>>  struct dw_mipi_dsi_stm *dsi = priv_data;
>>  unsigned int idf, ndiv, odf, pll_in_khz, pll_out_khz;
>> +enum mipi_dsi_pixel_format fmt;
>>  int ret, bpp;
>>  u32 val;
>>   
>> @@ -267,11 +252,11 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const 
>> struct drm_display_mode *mode,
>>   
>>  if (pll_out_khz > dsi->lane_max_kbps) {
>>  pll_out_khz = dsi->lane_max_kbps;
>> -DRM_WARN("Warning max phy mbps is used\n");
>> +dev_warn(dsi->dev, "Warning max phy mbps is used\n");
>>  }
>>  if (pll_out_khz < dsi->lane_min_kbps) {
>>  pll_out_khz = dsi->lane_min_kbps

Re: [PATCH] drm/stm: dsi: Use dev_ based logging

2020-09-28 Thread Yannick FERTRE



On 9/25/20 4:51 PM, Sam Ravnborg wrote:
> Hi Yannick.
> 
> On Fri, Sep 25, 2020 at 12:22:33PM +0200, Yannick Fertre wrote:
>> Standardize on the dev_ based logging and drop the include of drm_print.h.
> The patchs filas to drop the include mentioned here.
> 
>> Remove useless dsi_color_from_mipi function.
> IMO the dsi_color_from_mipi() was nice, and inlining the helper
> is no gain for readability.
> 
>   Sam
> 
Hi,
I will restore the dsi_color_from_mipi() fucntion & introduce a new 
parameter (dev) which is necessary for call of dev_err.
Yannick

>>
>> Signed-off-by: Yannick Fertre 
>> ---
>>   drivers/gpu/drm/stm/dw_mipi_dsi-stm.c | 87 ++-
>>   1 file changed, 45 insertions(+), 42 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c 
>> b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
>> index 164f79ef6269..93fa8bfd3127 100644
>> --- a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
>> +++ b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
>> @@ -76,6 +76,7 @@ enum dsi_color {
>>   
>>   struct dw_mipi_dsi_stm {
>>  void __iomem *base;
>> +struct device *dev;
>>  struct clk *pllref_clk;
>>  struct dw_mipi_dsi *dsi;
>>  u32 hw_version;
>> @@ -110,23 +111,6 @@ static inline void dsi_update_bits(struct 
>> dw_mipi_dsi_stm *dsi, u32 reg,
>>  dsi_write(dsi, reg, (dsi_read(dsi, reg) & ~mask) | val);
>>   }
>>   
>> -static enum dsi_color dsi_color_from_mipi(enum mipi_dsi_pixel_format fmt)
>> -{
>> -switch (fmt) {
>> -case MIPI_DSI_FMT_RGB888:
>> -return DSI_RGB888;
>> -case MIPI_DSI_FMT_RGB666:
>> -return DSI_RGB666_CONF2;
>> -case MIPI_DSI_FMT_RGB666_PACKED:
>> -return DSI_RGB666_CONF1;
>> -case MIPI_DSI_FMT_RGB565:
>> -return DSI_RGB565_CONF1;
>> -default:
>> -DRM_DEBUG_DRIVER("MIPI color invalid, so we use rgb888\n");
>> -}
>> -return DSI_RGB888;
>> -}
>> -
>>   static int dsi_pll_get_clkout_khz(int clkin_khz, int idf, int ndiv, int 
>> odf)
>>   {
>>  int divisor = idf * odf;
>> @@ -205,14 +189,14 @@ static int dw_mipi_dsi_phy_init(void *priv_data)
>>  ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & WISR_RRS,
>>   SLEEP_US, TIMEOUT_US);
>>  if (ret)
>> -DRM_DEBUG_DRIVER("!TIMEOUT! waiting REGU, let's continue\n");
>> +dev_dbg(dsi->dev, "!TIMEOUT! waiting REGU, let's continue\n");
>>   
>>  /* Enable the DSI PLL & wait for its lock */
>>  dsi_set(dsi, DSI_WRPCR, WRPCR_PLLEN);
>>  ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & WISR_PLLLS,
>>   SLEEP_US, TIMEOUT_US);
>>  if (ret)
>> -DRM_DEBUG_DRIVER("!TIMEOUT! waiting PLL, let's continue\n");
>> +dev_dbg(dsi->dev, "!TIMEOUT! waiting PLL, let's continue\n");
>>   
>>  return 0;
>>   }
>> @@ -221,7 +205,7 @@ static void dw_mipi_dsi_phy_power_on(void *priv_data)
>>   {
>>  struct dw_mipi_dsi_stm *dsi = priv_data;
>>   
>> -DRM_DEBUG_DRIVER("\n");
>> +dev_dbg(dsi->dev, "\n");
>>   
>>  /* Enable the DSI wrapper */
>>  dsi_set(dsi, DSI_WCR, WCR_DSIEN);
>> @@ -231,7 +215,7 @@ static void dw_mipi_dsi_phy_power_off(void *priv_data)
>>   {
>>  struct dw_mipi_dsi_stm *dsi = priv_data;
>>   
>> -DRM_DEBUG_DRIVER("\n");
>> +dev_dbg(dsi->dev, "\n");
>>   
>>  /* Disable the DSI wrapper */
>>  dsi_clear(dsi, DSI_WCR, WCR_DSIEN);
>> @@ -244,6 +228,7 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct 
>> drm_display_mode *mode,
>>   {
>>  struct dw_mipi_dsi_stm *dsi = priv_data;
>>  unsigned int idf, ndiv, odf, pll_in_khz, pll_out_khz;
>> +enum mipi_dsi_pixel_format fmt;
>>  int ret, bpp;
>>  u32 val;
>>   
>> @@ -267,11 +252,11 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const 
>> struct drm_display_mode *mode,
>>   
>>  if (pll_out_khz > dsi->lane_max_kbps) {
>>  pll_out_khz = dsi->lane_max_kbps;
>> -DRM_WARN("Warning max phy mbps is used\n");
>> +dev_warn(dsi->dev, "Warning max phy mbps is used\n");
>>  }
>>  if (pll_out_khz < dsi->lane_min_kbps) {
>>  pll_out_khz = 

Re: [PATCH] drm/stm: dsi: Use dev_ based logging

2020-09-28 Thread Yannick FERTRE



On 9/25/20 2:02 PM, Joe Perches wrote:
> On Fri, 2020-09-25 at 12:22 +0200, Yannick Fertre wrote:
>> Standardize on the dev_ based logging and drop the include of drm_print.h.
>> Remove useless dsi_color_from_mipi function.
> []
>> diff --git a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c 
>> b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
> []
>> -DRM_DEBUG_DRIVER("pll_in %ukHz pll_out %ukHz lane_mbps %uMHz\n",
>> - pll_in_khz, pll_out_khz, *lane_mbps);
>> +dev_dbg(dsi->dev, "pll_in %ukHz pll_out %ukHz lane_mbps %uMHz\n", 
>> pll_in_khz, pll_out_khz,
>> +*lane_mbps);
> 
> The line wrapping change here is pretty pointless and IMO
> makes the code harder to read.

Hi,
ok, I will restore the line wrapping.

Best regards

Yannick
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/panel: rm68200: fix mode to 50fps

2020-09-25 Thread Yannick Fertre
Compute new timings to get a framerate of 50fps with a pixel clock
@54Mhz.

Signed-off-by: Yannick Fertre 
---
 drivers/gpu/drm/panel/panel-raydium-rm68200.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-raydium-rm68200.c 
b/drivers/gpu/drm/panel/panel-raydium-rm68200.c
index 2b9e48b0a491..412c0dbcb2b6 100644
--- a/drivers/gpu/drm/panel/panel-raydium-rm68200.c
+++ b/drivers/gpu/drm/panel/panel-raydium-rm68200.c
@@ -82,15 +82,15 @@ struct rm68200 {
 };
 
 static const struct drm_display_mode default_mode = {
-   .clock = 52582,
+   .clock = 54000,
.hdisplay = 720,
-   .hsync_start = 720 + 38,
-   .hsync_end = 720 + 38 + 8,
-   .htotal = 720 + 38 + 8 + 38,
+   .hsync_start = 720 + 48,
+   .hsync_end = 720 + 48 + 9,
+   .htotal = 720 + 48 + 9 + 48,
.vdisplay = 1280,
.vsync_start = 1280 + 12,
-   .vsync_end = 1280 + 12 + 4,
-   .vtotal = 1280 + 12 + 4 + 12,
+   .vsync_end = 1280 + 12 + 5,
+   .vtotal = 1280 + 12 + 5 + 12,
.flags = 0,
.width_mm = 68,
.height_mm = 122,
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/stm: dsi: Use dev_ based logging

2020-09-25 Thread Yannick Fertre
Standardize on the dev_ based logging and drop the include of drm_print.h.
Remove useless dsi_color_from_mipi function.

Signed-off-by: Yannick Fertre 
---
 drivers/gpu/drm/stm/dw_mipi_dsi-stm.c | 87 ++-
 1 file changed, 45 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c 
b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
index 164f79ef6269..93fa8bfd3127 100644
--- a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
+++ b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
@@ -76,6 +76,7 @@ enum dsi_color {
 
 struct dw_mipi_dsi_stm {
void __iomem *base;
+   struct device *dev;
struct clk *pllref_clk;
struct dw_mipi_dsi *dsi;
u32 hw_version;
@@ -110,23 +111,6 @@ static inline void dsi_update_bits(struct dw_mipi_dsi_stm 
*dsi, u32 reg,
dsi_write(dsi, reg, (dsi_read(dsi, reg) & ~mask) | val);
 }
 
-static enum dsi_color dsi_color_from_mipi(enum mipi_dsi_pixel_format fmt)
-{
-   switch (fmt) {
-   case MIPI_DSI_FMT_RGB888:
-   return DSI_RGB888;
-   case MIPI_DSI_FMT_RGB666:
-   return DSI_RGB666_CONF2;
-   case MIPI_DSI_FMT_RGB666_PACKED:
-   return DSI_RGB666_CONF1;
-   case MIPI_DSI_FMT_RGB565:
-   return DSI_RGB565_CONF1;
-   default:
-   DRM_DEBUG_DRIVER("MIPI color invalid, so we use rgb888\n");
-   }
-   return DSI_RGB888;
-}
-
 static int dsi_pll_get_clkout_khz(int clkin_khz, int idf, int ndiv, int odf)
 {
int divisor = idf * odf;
@@ -205,14 +189,14 @@ static int dw_mipi_dsi_phy_init(void *priv_data)
ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & WISR_RRS,
 SLEEP_US, TIMEOUT_US);
if (ret)
-   DRM_DEBUG_DRIVER("!TIMEOUT! waiting REGU, let's continue\n");
+   dev_dbg(dsi->dev, "!TIMEOUT! waiting REGU, let's continue\n");
 
/* Enable the DSI PLL & wait for its lock */
dsi_set(dsi, DSI_WRPCR, WRPCR_PLLEN);
ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & WISR_PLLLS,
 SLEEP_US, TIMEOUT_US);
if (ret)
-   DRM_DEBUG_DRIVER("!TIMEOUT! waiting PLL, let's continue\n");
+   dev_dbg(dsi->dev, "!TIMEOUT! waiting PLL, let's continue\n");
 
return 0;
 }
@@ -221,7 +205,7 @@ static void dw_mipi_dsi_phy_power_on(void *priv_data)
 {
struct dw_mipi_dsi_stm *dsi = priv_data;
 
-   DRM_DEBUG_DRIVER("\n");
+   dev_dbg(dsi->dev, "\n");
 
/* Enable the DSI wrapper */
dsi_set(dsi, DSI_WCR, WCR_DSIEN);
@@ -231,7 +215,7 @@ static void dw_mipi_dsi_phy_power_off(void *priv_data)
 {
struct dw_mipi_dsi_stm *dsi = priv_data;
 
-   DRM_DEBUG_DRIVER("\n");
+   dev_dbg(dsi->dev, "\n");
 
/* Disable the DSI wrapper */
dsi_clear(dsi, DSI_WCR, WCR_DSIEN);
@@ -244,6 +228,7 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct 
drm_display_mode *mode,
 {
struct dw_mipi_dsi_stm *dsi = priv_data;
unsigned int idf, ndiv, odf, pll_in_khz, pll_out_khz;
+   enum mipi_dsi_pixel_format fmt;
int ret, bpp;
u32 val;
 
@@ -267,11 +252,11 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct 
drm_display_mode *mode,
 
if (pll_out_khz > dsi->lane_max_kbps) {
pll_out_khz = dsi->lane_max_kbps;
-   DRM_WARN("Warning max phy mbps is used\n");
+   dev_warn(dsi->dev, "Warning max phy mbps is used\n");
}
if (pll_out_khz < dsi->lane_min_kbps) {
pll_out_khz = dsi->lane_min_kbps;
-   DRM_WARN("Warning min phy mbps is used\n");
+   dev_warn(dsi->dev, "Warning min phy mbps is used\n");
}
 
/* Compute best pll parameters */
@@ -281,7 +266,7 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct 
drm_display_mode *mode,
ret = dsi_pll_get_params(dsi, pll_in_khz, pll_out_khz,
 , , );
if (ret)
-   DRM_WARN("Warning dsi_pll_get_params(): bad params\n");
+   dev_warn(dsi->dev, "Warning dsi_pll_get_params(): bad 
params\n");
 
/* Get the adjusted pll out value */
pll_out_khz = dsi_pll_get_clkout_khz(pll_in_khz, idf, ndiv, odf);
@@ -297,14 +282,31 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct 
drm_display_mode *mode,
/* Select video mode by resetting DSIM bit */
dsi_clear(dsi, DSI_WCFGR, WCFGR_DSIM);
 
+   switch (format) {
+   case MIPI_DSI_FMT_RGB888:
+   fmt = DSI_RGB888;
+   break;
+   case MIPI_DSI_FMT_RGB666:
+   fmt = DSI_RGB666_CONF2;
+   break;
+   case MIPI_DSI_FMT_RGB666_PACKED:
+   fmt = D

[PATCH v2] drm/panel: otm8009a: allow using non-continuous dsi clock

2020-09-22 Thread Yannick Fertre
From: Antonio Borneo 

The panel is able to work when dsi clock is non-continuous, thus
the system power consumption can be reduced using such feature.

Add MIPI_DSI_CLOCK_NON_CONTINUOUS to panel's mode_flags.

Changes in v2:
  - Added my signed-off

Signed-off-by: Antonio Borneo 
Signed-off-by: Yannick Fertre 
---
 drivers/gpu/drm/panel/panel-orisetech-otm8009a.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c 
b/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c
index b6e377aa1131..6ac1accade80 100644
--- a/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c
+++ b/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c
@@ -452,7 +452,7 @@ static int otm8009a_probe(struct mipi_dsi_device *dsi)
dsi->lanes = 2;
dsi->format = MIPI_DSI_FMT_RGB888;
dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
- MIPI_DSI_MODE_LPM;
+ MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS;
 
drm_panel_init(>panel, dev, _drm_funcs,
   DRM_MODE_CONNECTOR_DSI);
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2] drm/panel: otm8009a: remove hack to force commands in HS

2020-09-22 Thread Yannick Fertre
From: Antonio Borneo 

The panel is able to receive commands in LP. The current hack to
force backlight commands in HS was due to workaround an incorrect
settings on DSI controller that prevents sending LP commands while
video out was active.

Remove the hack that forces HS commands.

Changes in v2:
  - Added my signed-off

Signed-off-by: Antonio Borneo 
Signed-off-by: Yannick Fertre 
---
 .../gpu/drm/panel/panel-orisetech-otm8009a.c   | 18 ++
 1 file changed, 2 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c 
b/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c
index 6ac1accade80..f80b44a8a700 100644
--- a/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c
+++ b/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c
@@ -99,20 +99,6 @@ static void otm8009a_dcs_write_buf(struct otm8009a *ctx, 
const void *data,
dev_warn(ctx->dev, "mipi dsi dcs write buffer failed\n");
 }
 
-static void otm8009a_dcs_write_buf_hs(struct otm8009a *ctx, const void *data,
- size_t len)
-{
-   struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
-
-   /* data will be sent in dsi hs mode (ie. no lpm) */
-   dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
-
-   otm8009a_dcs_write_buf(ctx, data, len);
-
-   /* restore back the dsi lpm mode */
-   dsi->mode_flags |= MIPI_DSI_MODE_LPM;
-}
-
 #define dcs_write_seq(ctx, seq...) \
 ({ \
static const u8 d[] = { seq };  \
@@ -400,7 +386,7 @@ static int otm8009a_backlight_update_status(struct 
backlight_device *bd)
 */
data[0] = MIPI_DCS_SET_DISPLAY_BRIGHTNESS;
data[1] = bd->props.brightness;
-   otm8009a_dcs_write_buf_hs(ctx, data, ARRAY_SIZE(data));
+   otm8009a_dcs_write_buf(ctx, data, ARRAY_SIZE(data));
 
/* set Brightness Control & Backlight on */
data[1] = 0x24;
@@ -412,7 +398,7 @@ static int otm8009a_backlight_update_status(struct 
backlight_device *bd)
 
/* Update Brightness Control & Backlight */
data[0] = MIPI_DCS_WRITE_CONTROL_DISPLAY;
-   otm8009a_dcs_write_buf_hs(ctx, data, ARRAY_SIZE(data));
+   otm8009a_dcs_write_buf(ctx, data, ARRAY_SIZE(data));
 
return 0;
 }
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/panel: rm68200: allow using non-continuous dsi clock

2020-09-18 Thread Yannick Fertre
The panel is able to work when dsi clock is non-continuous, thus
the system power consumption can be reduced using such feature.

Add MIPI_DSI_CLOCK_NON_CONTINUOUS to panel's mode_flags.

Signed-off-by: Antonio Borneo 
Signed-off-by: Yannick Fertre 
---
 drivers/gpu/drm/panel/panel-raydium-rm68200.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/panel/panel-raydium-rm68200.c 
b/drivers/gpu/drm/panel/panel-raydium-rm68200.c
index f908eeafb1af..2b9e48b0a491 100644
--- a/drivers/gpu/drm/panel/panel-raydium-rm68200.c
+++ b/drivers/gpu/drm/panel/panel-raydium-rm68200.c
@@ -391,7 +391,7 @@ static int rm68200_probe(struct mipi_dsi_device *dsi)
dsi->lanes = 2;
dsi->format = MIPI_DSI_FMT_RGB888;
dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
- MIPI_DSI_MODE_LPM;
+ MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS;
 
drm_panel_init(>panel, dev, _drm_funcs,
   DRM_MODE_CONNECTOR_DSI);
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/bridge/synopsys: dsi: fix initialization sequence

2020-09-18 Thread Yannick Fertre
The current driver calls drm_bridge_add(), to add the dsi bridge
to the global bridge list, in dw_mipi_dsi_host_attach().
Thus, it relies on the probing of panel or bridge sub-nodes to
trigger the execution of dsi host attach() that will, in turn,
call dw_mipi_dsi_host_attach().
This causes an incomplete driver initialization if the panel or
the next bridge is not present as sub-node, e.g. because it is an
i2c device, thus sub-node of the respective i2c controller.

Move the relevant code from host attach() to probe(), and the
corresponding code from detach() to remove().

Signed-off-by: Antonio Borneo 
Signed-off-by: Yannick Fertre 
---
 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 73 ---
 1 file changed, 48 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index 6b268f9445b3..aa74abddc79f 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -314,9 +314,7 @@ static int dw_mipi_dsi_host_attach(struct mipi_dsi_host 
*host,
 {
struct dw_mipi_dsi *dsi = host_to_dsi(host);
const struct dw_mipi_dsi_plat_data *pdata = dsi->plat_data;
-   struct drm_bridge *bridge;
-   struct drm_panel *panel;
-   int ret;
+   int ret = -ENODEV;
 
if (device->lanes > dsi->plat_data->max_data_lanes) {
dev_err(dsi->dev, "the number of data lanes(%u) is too many\n",
@@ -329,22 +327,6 @@ static int dw_mipi_dsi_host_attach(struct mipi_dsi_host 
*host,
dsi->format = device->format;
dsi->mode_flags = device->mode_flags;
 
-   ret = drm_of_find_panel_or_bridge(host->dev->of_node, 1, 0,
- , );
-   if (ret)
-   return ret;
-
-   if (panel) {
-   bridge = drm_panel_bridge_add_typed(panel,
-   DRM_MODE_CONNECTOR_DSI);
-   if (IS_ERR(bridge))
-   return PTR_ERR(bridge);
-   }
-
-   dsi->panel_bridge = bridge;
-
-   drm_bridge_add(>bridge);
-
if (pdata->host_ops && pdata->host_ops->attach) {
ret = pdata->host_ops->attach(pdata->priv_data, device);
if (ret < 0)
@@ -367,10 +349,6 @@ static int dw_mipi_dsi_host_detach(struct mipi_dsi_host 
*host,
return ret;
}
 
-   drm_of_panel_bridge_remove(host->dev->of_node, 1, 0);
-
-   drm_bridge_remove(>bridge);
-
return 0;
 }
 
@@ -1105,6 +1083,9 @@ __dw_mipi_dsi_probe(struct platform_device *pdev,
struct device *dev = >dev;
struct reset_control *apb_rst;
struct dw_mipi_dsi *dsi;
+   struct drm_bridge *bridge;
+   struct drm_panel *panel;
+   int i, nb_endpoints;
int ret;
 
dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
@@ -1172,8 +1153,7 @@ __dw_mipi_dsi_probe(struct platform_device *pdev,
ret = mipi_dsi_host_register(>dsi_host);
if (ret) {
dev_err(dev, "Failed to register MIPI host: %d\n", ret);
-   dw_mipi_dsi_debugfs_remove(dsi);
-   return ERR_PTR(ret);
+   goto err_pmr_enable;
}
 
dsi->bridge.driver_private = dsi;
@@ -1182,11 +1162,54 @@ __dw_mipi_dsi_probe(struct platform_device *pdev,
dsi->bridge.of_node = pdev->dev.of_node;
 #endif
 
+   /* Get number of endpoints */
+   nb_endpoints = of_graph_get_endpoint_count(pdev->dev.of_node);
+   if (!nb_endpoints) {
+   ret = -ENODEV;
+   goto err_host_reg;
+   }
+
+   for (i = 1; i < nb_endpoints; i++) {
+   ret = drm_of_find_panel_or_bridge(pdev->dev.of_node, i, 0,
+ , );
+   if (!ret)
+   break;
+   else if (ret == -EPROBE_DEFER)
+   goto err_host_reg;
+   }
+
+   /* check if an error is returned >> no panel or bridge detected */
+   if (ret)
+   goto err_host_reg;
+
+   if (panel) {
+   bridge = drm_panel_bridge_add_typed(panel, 
DRM_MODE_CONNECTOR_DSI);
+   if (IS_ERR(bridge)) {
+   ret = PTR_ERR(bridge);
+   goto err_host_reg;
+   }
+   }
+
+   dsi->panel_bridge = bridge;
+
+   drm_bridge_add(>bridge);
+
return dsi;
+
+err_host_reg:
+   mipi_dsi_host_unregister(>dsi_host);
+
+err_pmr_enable:
+   pm_runtime_disable(dev);
+   dw_mipi_dsi_debugfs_remove(dsi);
+
+   return ERR_PTR(ret);
 }
 
 static void __dw_mipi_dsi_remove(struct dw_mipi_dsi *dsi)
 {
+   drm_bridge_remove(>bridge);
+   drm_panel_bridge_remove(dsi->panel_bridge);
mipi_dsi_host_unregister

[PATCH] drm/panel: otm8009a: remove hack to force commands in HS

2020-09-18 Thread Yannick Fertre
From: Antonio Borneo 

The panel is able to receive commands in LP. The current hack to
force backlight commands in HS was due to workaround an incorrect
settings on DSI controller that prevents sending LP commands while
video out was active.

Remove the hack that forces HS commands.

Signed-off-by: Antonio Borneo 
---
 .../gpu/drm/panel/panel-orisetech-otm8009a.c   | 18 ++
 1 file changed, 2 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c 
b/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c
index 6ac1accade80..f80b44a8a700 100644
--- a/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c
+++ b/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c
@@ -99,20 +99,6 @@ static void otm8009a_dcs_write_buf(struct otm8009a *ctx, 
const void *data,
dev_warn(ctx->dev, "mipi dsi dcs write buffer failed\n");
 }
 
-static void otm8009a_dcs_write_buf_hs(struct otm8009a *ctx, const void *data,
- size_t len)
-{
-   struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
-
-   /* data will be sent in dsi hs mode (ie. no lpm) */
-   dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
-
-   otm8009a_dcs_write_buf(ctx, data, len);
-
-   /* restore back the dsi lpm mode */
-   dsi->mode_flags |= MIPI_DSI_MODE_LPM;
-}
-
 #define dcs_write_seq(ctx, seq...) \
 ({ \
static const u8 d[] = { seq };  \
@@ -400,7 +386,7 @@ static int otm8009a_backlight_update_status(struct 
backlight_device *bd)
 */
data[0] = MIPI_DCS_SET_DISPLAY_BRIGHTNESS;
data[1] = bd->props.brightness;
-   otm8009a_dcs_write_buf_hs(ctx, data, ARRAY_SIZE(data));
+   otm8009a_dcs_write_buf(ctx, data, ARRAY_SIZE(data));
 
/* set Brightness Control & Backlight on */
data[1] = 0x24;
@@ -412,7 +398,7 @@ static int otm8009a_backlight_update_status(struct 
backlight_device *bd)
 
/* Update Brightness Control & Backlight */
data[0] = MIPI_DCS_WRITE_CONTROL_DISPLAY;
-   otm8009a_dcs_write_buf_hs(ctx, data, ARRAY_SIZE(data));
+   otm8009a_dcs_write_buf(ctx, data, ARRAY_SIZE(data));
 
return 0;
 }
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/panel: otm8009a: allow using non-continuous dsi clock

2020-09-18 Thread Yannick Fertre
From: Antonio Borneo 

The panel is able to work when dsi clock is non-continuous, thus
the system power consumption can be reduced using such feature.

Add MIPI_DSI_CLOCK_NON_CONTINUOUS to panel's mode_flags.

Signed-off-by: Antonio Borneo 
---
 drivers/gpu/drm/panel/panel-orisetech-otm8009a.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c 
b/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c
index b6e377aa1131..6ac1accade80 100644
--- a/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c
+++ b/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c
@@ -452,7 +452,7 @@ static int otm8009a_probe(struct mipi_dsi_device *dsi)
dsi->lanes = 2;
dsi->format = MIPI_DSI_FMT_RGB888;
dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
- MIPI_DSI_MODE_LPM;
+ MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS;
 
drm_panel_init(>panel, dev, _drm_funcs,
   DRM_MODE_CONNECTOR_DSI);
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/stm: dsi: Avoid printing errors for -EPROBE_DEFER

2020-09-18 Thread Yannick Fertre
Don't print error when probe deferred error is returned.

Signed-off-by: Yannick Fertre 
---
 drivers/gpu/drm/stm/dw_mipi_dsi-stm.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c 
b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
index 2e1f2664495d..164f79ef6269 100644
--- a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
+++ b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
@@ -419,7 +419,8 @@ static int dw_mipi_dsi_stm_probe(struct platform_device 
*pdev)
dsi->dsi = dw_mipi_dsi_probe(pdev, _mipi_dsi_stm_plat_data);
if (IS_ERR(dsi->dsi)) {
ret = PTR_ERR(dsi->dsi);
-   DRM_ERROR("Failed to initialize mipi dsi host: %d\n", ret);
+   if (ret != -EPROBE_DEFER)
+   DRM_ERROR("Failed to initialize mipi dsi host: %d\n", 
ret);
goto err_dsi_probe;
}
 
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2] drm/bridge/synopsys: dsi: allow LP commands in video mode

2020-07-08 Thread Yannick Fertre
From: Antonio Borneo 

Current code only sends LP commands in command mode.

Allows sending LP commands also in video mode by setting the
proper flag in DSI_VID_MODE_CFG.

Signed-off-by: Antonio Borneo 
---
 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index 1a24ea648ef8..e9a0f42ff99f 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -89,6 +89,7 @@
 #define VID_MODE_TYPE_NON_BURST_SYNC_EVENTS0x1
 #define VID_MODE_TYPE_BURST0x2
 #define VID_MODE_TYPE_MASK 0x3
+#define ENABLE_LOW_POWER_CMD   BIT(15)
 #define VID_MODE_VPG_ENABLEBIT(16)
 #define VID_MODE_VPG_HORIZONTALBIT(24)
 
@@ -376,6 +377,13 @@ static void dw_mipi_message_config(struct dw_mipi_dsi *dsi,
 
dsi_write(dsi, DSI_LPCLK_CTRL, lpm ? 0 : PHY_TXREQUESTCLKHS);
dsi_write(dsi, DSI_CMD_MODE_CFG, val);
+
+   val = dsi_read(dsi, DSI_VID_MODE_CFG);
+   if (lpm)
+   val |= ENABLE_LOW_POWER_CMD;
+   else
+   val &= ~ENABLE_LOW_POWER_CMD;
+   dsi_write(dsi, DSI_VID_MODE_CFG, val);
 }
 
 static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/bridge/synopsys: dsi: add support for non-continuous HS clock

2020-07-01 Thread Yannick Fertre
From: Antonio Borneo 

Current code enables the HS clock when video mode is started or to
send out a HS command, and disables the HS clock to send out a LP
command. This is not what DSI spec specify.

Enable HS clock either in command and in video mode.
Set automatic HS clock management for panels and devices that
support non-continuous HS clock.

Signed-off-by: Antonio Borneo 
---
 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index d580b2aa4ce9..979acaa90d00 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -365,7 +365,6 @@ static void dw_mipi_message_config(struct dw_mipi_dsi *dsi,
if (lpm)
val |= CMD_MODE_ALL_LP;
 
-   dsi_write(dsi, DSI_LPCLK_CTRL, lpm ? 0 : PHY_TXREQUESTCLKHS);
dsi_write(dsi, DSI_CMD_MODE_CFG, val);
 }
 
@@ -541,16 +540,22 @@ static void dw_mipi_dsi_video_mode_config(struct 
dw_mipi_dsi *dsi)
 static void dw_mipi_dsi_set_mode(struct dw_mipi_dsi *dsi,
 unsigned long mode_flags)
 {
+   u32 val;
+
dsi_write(dsi, DSI_PWR_UP, RESET);
 
if (mode_flags & MIPI_DSI_MODE_VIDEO) {
dsi_write(dsi, DSI_MODE_CFG, ENABLE_VIDEO_MODE);
dw_mipi_dsi_video_mode_config(dsi);
-   dsi_write(dsi, DSI_LPCLK_CTRL, PHY_TXREQUESTCLKHS);
} else {
dsi_write(dsi, DSI_MODE_CFG, ENABLE_CMD_MODE);
}
 
+   val = PHY_TXREQUESTCLKHS;
+   if (dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)
+   val |= AUTO_CLKLANE_CTRL;
+   dsi_write(dsi, DSI_LPCLK_CTRL, val);
+
dsi_write(dsi, DSI_PWR_UP, POWERUP);
 }
 
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/bridge/synopsys: dsi: allow LP commands in video mode

2020-07-01 Thread Yannick Fertre
From: Antonio Borneo 

Current code only sends LP commands in command mode.

Allows sending LP commands also in video mode by setting the
proper flag in DSI_VID_MODE_CFG.

Signed-off-by: Antonio Borneo 
---
 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index d580b2aa4ce9..0cd43e7a69bb 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -367,6 +367,13 @@ static void dw_mipi_message_config(struct dw_mipi_dsi *dsi,
 
dsi_write(dsi, DSI_LPCLK_CTRL, lpm ? 0 : PHY_TXREQUESTCLKHS);
dsi_write(dsi, DSI_CMD_MODE_CFG, val);
+
+   val = dsi_read(dsi, DSI_VID_MODE_CFG);
+   if (lpm)
+   val |= ENABLE_LOW_POWER_CMD;
+   else
+   val &= ~ENABLE_LOW_POWER_CMD;
+   dsi_write(dsi, DSI_VID_MODE_CFG, val);
 }
 
 static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/bridge/synopsys: dsi: allows LP commands in video mode

2020-07-01 Thread Yannick Fertre
From: Antonio Borneo 

Current code only sends LP commands in command mode.

Allows sending LP commands also in video mode by setting the
proper flag in DSI_VID_MODE_CFG.

Signed-off-by: Antonio Borneo 
Change-Id: Ib78fa37bcc7559ce63017acd6ee0bbf00c61a397
Reviewed-on: https://gerrit.st.com/c/mpu/oe/st/linux-stm32/+/153242
Reviewed-by: CITOOLS 
Reviewed-by: CIBUILD 
Reviewed-by: Yannick FERTRE 
Reviewed-by: Philippe CORNU 
Tested-by: Yannick FERTRE 
---
 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index d580b2aa4ce9..0cd43e7a69bb 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -367,6 +367,13 @@ static void dw_mipi_message_config(struct dw_mipi_dsi *dsi,
 
dsi_write(dsi, DSI_LPCLK_CTRL, lpm ? 0 : PHY_TXREQUESTCLKHS);
dsi_write(dsi, DSI_CMD_MODE_CFG, val);
+
+   val = dsi_read(dsi, DSI_VID_MODE_CFG);
+   if (lpm)
+   val |= ENABLE_LOW_POWER_CMD;
+   else
+   val &= ~ENABLE_LOW_POWER_CMD;
+   dsi_write(dsi, DSI_VID_MODE_CFG, val);
 }
 
 static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/bridge/synopsys: dsi: allows LP commands in video mode

2020-07-01 Thread Yannick Fertre
From: Antonio Borneo 

Current code only sends LP commands in command mode.

Allows sending LP commands also in video mode by setting the
proper flag in DSI_VID_MODE_CFG.

Signed-off-by: Antonio Borneo 
Change-Id: Ib78fa37bcc7559ce63017acd6ee0bbf00c61a397
Reviewed-on: https://gerrit.st.com/c/mpu/oe/st/linux-stm32/+/153242
Reviewed-by: CITOOLS 
Reviewed-by: CIBUILD 
Reviewed-by: Yannick FERTRE 
Reviewed-by: Philippe CORNU 
Tested-by: Yannick FERTRE 
---
 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index d580b2aa4ce9..0cd43e7a69bb 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -367,6 +367,13 @@ static void dw_mipi_message_config(struct dw_mipi_dsi *dsi,
 
dsi_write(dsi, DSI_LPCLK_CTRL, lpm ? 0 : PHY_TXREQUESTCLKHS);
dsi_write(dsi, DSI_CMD_MODE_CFG, val);
+
+   val = dsi_read(dsi, DSI_VID_MODE_CFG);
+   if (lpm)
+   val |= ENABLE_LOW_POWER_CMD;
+   else
+   val &= ~ENABLE_LOW_POWER_CMD;
+   dsi_write(dsi, DSI_VID_MODE_CFG, val);
 }
 
 static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/bridge/synopsys: dsi: allow sending longer LP commands

2020-07-01 Thread Yannick Fertre
From: Antonio Borneo 

Current code does not properly computes the max length of LP
commands that can be send during H or V sync, and rely on static
values.
Limiting the max LP length to 4 byte during the V-sync is overly
conservative.

Relax the limit and allows longer LP commands (16 bytes) to be
sent during V-sync.

Signed-off-by: Antonio Borneo 
---
 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index d580b2aa4ce9..1a24ea648ef8 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -360,6 +360,15 @@ static void dw_mipi_message_config(struct dw_mipi_dsi *dsi,
bool lpm = msg->flags & MIPI_DSI_MSG_USE_LPM;
u32 val = 0;
 
+   /*
+* TODO dw drv improvements
+* largest packet sizes during hfp or during vsa/vpb/vfp
+* should be computed according to byte lane, lane number and only
+* if sending lp cmds in high speed is enable (PHY_TXREQUESTCLKHS)
+*/
+   dsi_write(dsi, DSI_DPI_LP_CMD_TIM, OUTVACT_LPCMD_TIME(16)
+ | INVACT_LPCMD_TIME(4));
+
if (msg->flags & MIPI_DSI_MSG_REQ_ACK)
val |= ACK_RQST_EN;
if (lpm)
@@ -611,14 +620,6 @@ static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi,
dsi_write(dsi, DSI_DPI_VCID, DPI_VCID(dsi->channel));
dsi_write(dsi, DSI_DPI_COLOR_CODING, color);
dsi_write(dsi, DSI_DPI_CFG_POL, val);
-   /*
-* TODO dw drv improvements
-* largest packet sizes during hfp or during vsa/vpb/vfp
-* should be computed according to byte lane, lane number and only
-* if sending lp cmds in high speed is enable (PHY_TXREQUESTCLKHS)
-*/
-   dsi_write(dsi, DSI_DPI_LP_CMD_TIM, OUTVACT_LPCMD_TIME(4)
- | INVACT_LPCMD_TIME(4));
 }
 
 static void dw_mipi_dsi_packet_handler_config(struct dw_mipi_dsi *dsi)
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] drm/stm: repair runtime power management

2020-07-01 Thread Yannick FERTRE


On 3/9/20 12:57 PM, Marek Vasut wrote:
> On 3/9/20 11:35 AM, Yannick FERTRE wrote:
>> Hello Marek,
> 
> Hi,
> 
> (please stop top-posting)
> 
>> Thank for your patch. Pm_runtime_put_sync is also done into function 
>> ltdc_crtc_mode_fixup.
>> To avoid several call of Pm_runtime_put_sync, it could be better to check 
>> pm_runtime activity:
>>
>> +int ret;
>>   
>>  DRM_DEBUG_DRIVER("\n");
>>   
>> +if (!pm_runtime_active(ddev->dev)) {
>> +ret = pm_runtime_get_sync(ddev->dev);
>> +if (ret) {
>> +DRM_ERROR("Failed to enable crtc, cannot get sync\n");
>> +return;
>> +}
>> +}
>> +
> 
> Where should this go ? And wouldn't that only hide nastier PM imbalance
> issues ?
Hi Marek,
I tested the patch &  it generate an error when I try wake up / sleep 
the board STM32MP1 DK2 with weston application.
It need an additional patch 
drm-stm-ltdc-remove-call-of-pm-runtime-functions.

Thanks for the patch.

Tested-by: Yannick Fertre 


> 
>>   Best regards
>>
>> Yannick Fertré
>>
>>
>> -Original Message-
>> From: Marek Vasut 
>> Sent: samedi 29 février 2020 23:17
>> To: dri-devel@lists.freedesktop.org
>> Cc: Marek Vasut ; Yannick FERTRE ; 
>> Philippe CORNU ; Benjamin Gaignard 
>> ; Vincent ABRIOU ; 
>> Maxime Coquelin ; Alexandre TORGUE 
>> ; linux-st...@st-md-mailman.stormreply.com; 
>> linux-arm-ker...@lists.infradead.org
>> Subject: [PATCH] drm/stm: repair runtime power management
>>
>> Add missing pm_runtime_get_sync() into ltdc_crtc_atomic_enable() to match 
>> pm_runtime_put_sync() in ltdc_crtc_atomic_disable(), otherwise the LTDC 
>> might suspend via runtime PM, disable clock, and then fail to resume later 
>> on.
>>
>> The test which triggers it is roughly -- run qt5 application which uses 
>> eglfs platform and etnaviv, stop the application, sleep for 15 minutes, run 
>> the application again. This leads to a timeout waiting for vsync, because 
>> the LTDC has suspended, but did not resume.
>>
>> Fixes: 35ab6cfbf211 ("drm/stm: support runtime power management")
>> Signed-off-by: Marek Vasut 
>> Cc: Yannick Fertré 
>> Cc: Philippe Cornu 
>> Cc: Benjamin Gaignard 
>> Cc: Vincent Abriou 
>> Cc: Maxime Coquelin 
>> Cc: Alexandre Torgue 
>> To: dri-devel@lists.freedesktop.org
>> Cc: linux-st...@st-md-mailman.stormreply.com
>> Cc: linux-arm-ker...@lists.infradead.org
>> ---
>> [ cut here ]
>> WARNING: CPU: 0 PID: 297 at drivers/gpu/drm/drm_atomic_helper.c:1494 
>> drm_atomic_helper_wait_for_vblanks+0x1dc/0x200
>> [CRTC:35:crtc-0] vblank wait timed out
>> Modules linked in:
>> CPU: 0 PID: 297 Comm: QSGRenderThread Not tainted 
>> 5.6.0-rc3-next-20200228-00010-g318bf0fc08ef #2 Hardware name: STM32 (Device 
>> Tree Support) [] (unwind_backtrace) from [] 
>> (show_stack+0x10/0x14) [] (show_stack) from [] 
>> (dump_stack+0xb4/0xd0) [] (dump_stack) from [] 
>> (__warn+0xd4/0xf0) [] (__warn) from [] 
>> (warn_slowpath_fmt+0x78/0xa8) [] (warn_slowpath_fmt) from 
>> [] (drm_atomic_helper_wait_for_vblanks+0x1dc/0x200)
>> [] (drm_atomic_helper_wait_for_vblanks) from [] 
>> (drm_atomic_helper_commit_tail+0
>> x50/0x60)
>> [] (drm_atomic_helper_commit_tail) from [] 
>> (commit_tail+0x12c/0x13c) [] (commit_tail) from [] 
>> (drm_atomic_helper_commit+0xf4/0x100)
>> [] (drm_atomic_helper_commit) from [] 
>> (drm_atomic_helper_set_config+0x58/0x6c)
>> [] (drm_atomic_helper_set_config) from [] 
>> (drm_mode_setcrtc+0x450/0x550) [] (drm_mode_setcrtc) from 
>> [] (drm_ioctl_kernel+0x90/0xe8) [] (drm_ioctl_kernel) 
>> from [] (drm_ioctl+0x2e4/0x32c) [] (drm_ioctl) from 
>> [] (vfs_ioctl+0x20/0x38) [] (vfs_ioctl) from 
>> [] (ksys_ioctl+0xbc/0x7b0) [] (ksys_ioctl) from 
>> [] (ret_fast_syscall+0x0/0x54) Exception stack(0xee8f3fa8 to 
>> 0xee8f3ff0)
>> 3fa0:   0005 adcbeb18 0005 c06864a2 adcbeb18 0001
>> 3fc0: 0005 adcbeb18 c06864a2 0036 0029 0023 0023 0007
>> 3fe0: b113b098 adcbeafc b1125413 b6155cf8 ---[ end trace 2ad5ba954ceb767a 
>> ]---
>> ---
>>   drivers/gpu/drm/stm/ltdc.c | 3 +++
>>   1 file changed, 3 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c index 
>> 99bf93e8b36f..301de0498078 100644
>> --- a/drivers/gpu/drm/stm/ltdc.c
>> +++ b/drivers/gpu/drm/stm/ltdc.c
>> @@ -425,9 +425,12 @@ static void ltdc_crtc_atomic_enable(struct drm_crtc 
>> *crtc,
>>  struct drm_crtc_state *old_state)  {
>>  struct ltdc_device *ldev = crtc_to_ltdc(crtc);
>> +struct drm_device *ddev = crtc->dev;
>>   
>>  DRM_DEBUG_DRIVER("\n");
>>   
>> +pm_runtime_get_sync(ddev->dev);
>> +
>>  /* Sets the background color value */
>>  reg_write(ldev->regs, LTDC_BCCR, BCCR_BCBLACK);
>>   
>> --
>> 2.25.0
>>
> 
> 
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/stm: ltdc: remove call of pm-runtime functions

2020-07-01 Thread Yannick Fertre
It is not necessary to suspend or stop the ltdc clocks
to modify the pixel clock.

Signed-off-by: Yannick Fertre 
---
 drivers/gpu/drm/stm/ltdc.c | 16 
 1 file changed, 16 deletions(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index 3f590d916e91..6e28f707092f 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -506,15 +506,7 @@ static bool ltdc_crtc_mode_fixup(struct drm_crtc *crtc,
 struct drm_display_mode *adjusted_mode)
 {
struct ltdc_device *ldev = crtc_to_ltdc(crtc);
-   struct drm_device *ddev = crtc->dev;
int rate = mode->clock * 1000;
-   bool runtime_active;
-   int ret;
-
-   runtime_active = pm_runtime_active(ddev->dev);
-
-   if (runtime_active)
-   pm_runtime_put_sync(ddev->dev);
 
if (clk_set_rate(ldev->pixel_clk, rate) < 0) {
DRM_ERROR("Cannot set rate (%dHz) for pixel clk\n", rate);
@@ -523,14 +515,6 @@ static bool ltdc_crtc_mode_fixup(struct drm_crtc *crtc,
 
adjusted_mode->clock = clk_get_rate(ldev->pixel_clk) / 1000;
 
-   if (runtime_active) {
-   ret = pm_runtime_get_sync(ddev->dev);
-   if (ret) {
-   DRM_ERROR("Failed to fixup mode, cannot get sync\n");
-   return false;
-   }
-   }
-
DRM_DEBUG_DRIVER("requested clock %dkHz, adjusted clock %dkHz\n",
 mode->clock, adjusted_mode->clock);
 
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v2] drm/bridge: dw-mipi-dsi.c: Add VPG runtime config through debugfs

2020-06-24 Thread Yannick FERTRE
Hello Angelo,
thanks for the patch.
Tested-by: Yannick Fertre 
Tested OK on STM32MP1-DISCO, DSI v1.31

Best regards


On 4/6/20 3:49 PM, Angelo Ribeiro wrote:
> Add support for the video pattern generator (VPG) BER pattern mode and
> configuration in runtime.
> 
> This enables using the debugfs interface to manipulate the VPG after
> the pipeline is set.
> Also, enables the usage of the VPG BER pattern.
> 
> Changes in v2:
>- Added VID_MODE_VPG_MODE
>- Solved incompatible return type on __get and __set
> 
> Reported-by: kbuild test robot 
> Reported-by: Adrian Pop 
> Cc: Gustavo Pimentel 
> Cc: Joao Pinto 
> Cc: Jose Abreu 
> Signed-off-by: Angelo Ribeiro 
> ---
>   drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 98 
> ---
>   1 file changed, 90 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
> b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> index b18351b..9de3645 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> @@ -91,6 +91,7 @@
>   #define VID_MODE_TYPE_BURST 0x2
>   #define VID_MODE_TYPE_MASK  0x3
>   #define VID_MODE_VPG_ENABLE BIT(16)
> +#define VID_MODE_VPG_MODEBIT(20)
>   #define VID_MODE_VPG_HORIZONTAL BIT(24)
>   
>   #define DSI_VID_PKT_SIZE0x3c
> @@ -221,6 +222,21 @@
>   #define PHY_STATUS_TIMEOUT_US   1
>   #define CMD_PKT_STATUS_TIMEOUT_US   2
>   
> +#ifdef CONFIG_DEBUG_FS
> +#define VPG_DEFS(name, dsi) \
> + ((void __force *)&((*dsi).vpg_defs.name))
> +
> +#define REGISTER(name, mask, dsi) \
> + { #name, VPG_DEFS(name, dsi), mask, dsi }
> +
> +struct debugfs_entries {
> + const char  *name;
> + bool*reg;
> + u32 mask;
> + struct dw_mipi_dsi  *dsi;
> +};
> +#endif /* CONFIG_DEBUG_FS */
> +
>   struct dw_mipi_dsi {
>   struct drm_bridge bridge;
>   struct mipi_dsi_host dsi_host;
> @@ -238,9 +254,12 @@ struct dw_mipi_dsi {
>   
>   #ifdef CONFIG_DEBUG_FS
>   struct dentry *debugfs;
> -
> - bool vpg;
> - bool vpg_horizontal;
> + struct debugfs_entries *debugfs_vpg;
> + struct {
> + bool vpg;
> + bool vpg_horizontal;
> + bool vpg_ber_pattern;
> + } vpg_defs;
>   #endif /* CONFIG_DEBUG_FS */
>   
>   struct dw_mipi_dsi *master; /* dual-dsi master ptr */
> @@ -530,9 +549,11 @@ static void dw_mipi_dsi_video_mode_config(struct 
> dw_mipi_dsi *dsi)
>   val |= VID_MODE_TYPE_NON_BURST_SYNC_EVENTS;
>   
>   #ifdef CONFIG_DEBUG_FS
> - if (dsi->vpg) {
> + if (dsi->vpg_defs.vpg) {
>   val |= VID_MODE_VPG_ENABLE;
> - val |= dsi->vpg_horizontal ? VID_MODE_VPG_HORIZONTAL : 0;
> + val |= dsi->vpg_defs.vpg_horizontal ?
> +VID_MODE_VPG_HORIZONTAL : 0;
> + val |= dsi->vpg_defs.vpg_ber_pattern ? VID_MODE_VPG_MODE : 0;
>   }
>   #endif /* CONFIG_DEBUG_FS */
>   
> @@ -961,6 +982,68 @@ static const struct drm_bridge_funcs 
> dw_mipi_dsi_bridge_funcs = {
>   
>   #ifdef CONFIG_DEBUG_FS
>   
> +int dw_mipi_dsi_debugfs_write(void *data, u64 val)
> +{
> + struct debugfs_entries *vpg = data;
> + struct dw_mipi_dsi *dsi;
> + u32 mode_cfg;
> +
> + if (!vpg)
> + return -ENODEV;
> +
> + dsi = vpg->dsi;
> +
> + *vpg->reg = (bool)val;
> +
> + mode_cfg = dsi_read(dsi, DSI_VID_MODE_CFG);
> +
> + if (*vpg->reg)
> + mode_cfg |= vpg->mask;
> + else
> + mode_cfg &= ~vpg->mask;
> +
> + dsi_write(dsi, DSI_VID_MODE_CFG, mode_cfg);
> +
> + return 0;
> +}
> +
> +int dw_mipi_dsi_debugfs_show(void *data, u64 *val)
> +{
> + struct debugfs_entries *vpg = data;
> +
> + if (!vpg)
> + return -ENODEV;
> +
> + *val = *vpg->reg;
> +
> + return 0;
> +}
> +
> +DEFINE_DEBUGFS_ATTRIBUTE(fops_x32, dw_mipi_dsi_debugfs_show,
> +  dw_mipi_dsi_debugfs_write, "%llu\n");
> +
> +static void debugfs_create_files(void *data)
> +{
> + struct dw_mipi_dsi *dsi = data;
> + struct debugfs_entries debugfs[] = {
> + REGISTER(vpg, VID_MODE_VPG_ENABLE, dsi),
> + REGISTER(vpg_horizontal, VID_MODE_VPG_HORIZONTAL, dsi),
> + REGISTER(vpg_ber_pattern, VID_MODE_VPG_MODE, dsi),
> + };
> +

Re: [PATCH] drm/bridge: dw-mipi-dsi.c: remove unused header file

2020-06-24 Thread Yannick FERTRE
Hello Angelo,
thank for patch.

Reviewed-by: Yannick Fertre 



On 4/3/20 3:30 PM, Angelo Ribeiro wrote:
> dw-mipi-dsi does not use any definition from drm_probe_helper.
> 
> Coverity output:
> Event unnecessary_header:
> Including .../include/drm/drm_probe_helper.h does not provide any
> needed symbols.
> 
> Cc: Gustavo Pimentel 
> Cc: Joao Pinto 
> Cc: Jose Abreu 
> Signed-off-by: Angelo Ribeiro 
> ---
>   drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 1 -
>   1 file changed, 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
> b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> index 024acad..582635d 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> @@ -27,7 +27,6 @@
>   #include 
>   #include 
>   #include 
> -#include 
>   
>   #define HWVER_131   0x31333100  /* IP version 1.31 */
>   
> 
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v9 03/11] drm: bridge: dw_mipi_dsi: add dsi v1.01 support

2020-06-10 Thread Yannick FERTRE
Hi Adrian,

thanks for the pach: tested on stm32mp1.

Tested-by: Yannick Fertré 

On 6/9/20 7:49 PM, Adrian Ratiu wrote:
> The Synopsis MIPI DSI v1.01 host controller is quite widely used
> on platforms like i.mx6 and is not very different from the other
> versions like the 1.31/1.30 used on rockchip/stm. The protocols
> appear to be the same, only the register layout is different and
> the newer versions have new features symbolized by new registers
> so adding support for it is just a matter of defining the new
> layout and adding a couple of dsi version checks.
>
> Tested-by: Adrian Pop 
> Tested-by: Arnaud Ferraris 
> Signed-off-by: Adrian Ratiu 
> ---
> Changes since v7:
>- Minor commit msg rewording for consistency
>
> Changes since v5:
>- Fixed cfg_phy_status range from [0,0] to [0,2]
>
> New in v5.
> ---
>   drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 125 +-
>   1 file changed, 119 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
> b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> index f453df4eb5072..16fd87055e7b7 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> @@ -32,6 +32,7 @@
>   
>   #define HWVER_131   0x31333100  /* IP version 1.31 */
>   #define HWVER_130   0x31333000  /* IP version 1.30 */
> +#define HWVER_1010x31303000  /* IP version 1.01 */
>   
>   #define DSI_VERSION 0x00
>   #define VERSION GENMASK(31, 8)
> @@ -100,6 +101,25 @@
>   #define DSI_EDPI_CMD_SIZE   0x64
>   
>   #define DSI_CMD_MODE_CFG0x68
> +
> +#define DSI_DPI_CFG  0x0c
> +#define DSI_TMR_LINE_CFG 0x28
> +#define DSI_VTIMING_CFG  0x2c
> +#define DSI_PHY_TMR_CFG_V101 0x30
> +#define DSI_PHY_IF_CFG_V101  0x58
> +#define DSI_PHY_IF_CTRL  0x5c
> +#define DSI_PHY_RSTZ_V1010x54
> +#define DSI_PHY_STATUS_V101  0x60
> +#define DSI_PHY_TST_CTRL0_V101   0x64
> +#define DSI_GEN_HDR_V101 0x34
> +#define DSI_GEN_PLD_DATA_V1010x38
> +#define DSI_CMD_MODE_CFG_V1010x24
> +#define DSI_CMD_PKT_STATUS_V101  0x3c
> +#define DSI_VID_PKT_CFG  0x20
> +#define DSI_VID_MODE_CFG_V1010x1c
> +#define DSI_TO_CNT_CFG_V101  0x40
> +#define DSI_PCKHDL_CFG_V101  0x18
> +
>   #define MAX_RD_PKT_SIZE_LP  BIT(24)
>   #define DCS_LW_TX_LPBIT(19)
>   #define DCS_SR_0P_TX_LP BIT(18)
> @@ -127,6 +147,33 @@
>GEN_SW_1P_TX_LP | \
>GEN_SW_0P_TX_LP)
>   
> +#define EN_TEAR_FX_V101  BIT(14)
> +#define DCS_LW_TX_LP_V101BIT(12)
> +#define GEN_LW_TX_LP_V101BIT(11)
> +#define MAX_RD_PKT_SIZE_LP_V101  BIT(10)
> +#define DCS_SW_2P_TX_LP_V101 BIT(9)
> +#define DCS_SW_1P_TX_LP_V101 BIT(8)
> +#define DCS_SW_0P_TX_LP_V101 BIT(7)
> +#define GEN_SR_2P_TX_LP_V101 BIT(6)
> +#define GEN_SR_1P_TX_LP_V101 BIT(5)
> +#define GEN_SR_0P_TX_LP_V101 BIT(4)
> +#define GEN_SW_2P_TX_LP_V101 BIT(3)
> +#define GEN_SW_1P_TX_LP_V101 BIT(2)
> +#define GEN_SW_0P_TX_LP_V101 BIT(1)
> +
> +#define CMD_MODE_ALL_LP_V101 (DCS_LW_TX_LP_V101 | \
> +  GEN_LW_TX_LP_V101 | \
> +  MAX_RD_PKT_SIZE_LP_V101 | \
> +  DCS_SW_2P_TX_LP_V101 | \
> +  DCS_SW_1P_TX_LP_V101 | \
> +  DCS_SW_0P_TX_LP_V101 | \
> +  GEN_SR_2P_TX_LP_V101 | \
> +  GEN_SR_1P_TX_LP_V101 | \
> +  GEN_SR_0P_TX_LP_V101 | \
> +  GEN_SW_2P_TX_LP_V101 | \
> +  GEN_SW_1P_TX_LP_V101 | \
> +  GEN_SW_0P_TX_LP_V101)
> +
>   #define DSI_GEN_HDR 0x6c
>   #define DSI_GEN_PLD_DATA0x70
>   
> @@ -165,6 +212,11 @@
>   #define DSI_INT_MSK00xc4
>   #define DSI_INT_MSK10xc8
>   
> +#define DSI_ERROR_ST0_V101   0x44
> +#define DSI_ERROR_ST1_V101   0x48
> +#define DSI_ERROR_MSK0_V101  0x4c
> +#define DSI_ERROR_MSK1_V101  0x50
> +
>   #define DSI_PHY_TMR_RD_CFG  0xf4
>   
>   #define PHY_STATUS_TIMEOUT_US   1
> @@ -359,6 +411,49 @@ static const struct dw_mipi_dsi_variant 
> dw_mipi_dsi_v130_v131_layout = {
>   .cfg_gen_payload =  REG_FIELD(DSI_GEN_PLD_DATA, 0, 31),
>   };
>   
> 

Re: [PATCH v9 09/11] drm: bridge: dw-mipi-dsi: split low power cfg register into fields

2020-06-10 Thread Yannick FERTRE
Hi Adrian,

thanks for the pach: tested on stm32mp1.

Tested-by: Yannick Fertré 

On 6/9/20 7:49 PM, Adrian Ratiu wrote:
> According to the Host Registers documentation for IMX, STM and RK
> the LP cfg register should not be written entirely in one go because
> some bits are reserved and should be kept to reset values, for eg.
> BIT(15) which is reserved in all versions.
>
> This also cleans up the code by removing the the ugly defines
> and making field ranges & values written more explicit.
>
> Tested-by: Adrian Pop 
> Tested-by: Arnaud Ferraris 
> Signed-off-by: Adrian Ratiu 
> ---
> New in v6.
> ---
>   drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 105 ++
>   1 file changed, 33 insertions(+), 72 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
> b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> index 70df0578cbe7b..1e47d40b5becb 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> @@ -120,60 +120,6 @@
>   #define DSI_TO_CNT_CFG_V101 0x40
>   #define DSI_PCKHDL_CFG_V101 0x18
>   
> -#define MAX_RD_PKT_SIZE_LP   BIT(24)
> -#define DCS_LW_TX_LP BIT(19)
> -#define DCS_SR_0P_TX_LP  BIT(18)
> -#define DCS_SW_1P_TX_LP  BIT(17)
> -#define DCS_SW_0P_TX_LP  BIT(16)
> -#define GEN_LW_TX_LP BIT(14)
> -#define GEN_SR_2P_TX_LP  BIT(13)
> -#define GEN_SR_1P_TX_LP  BIT(12)
> -#define GEN_SR_0P_TX_LP  BIT(11)
> -#define GEN_SW_2P_TX_LP  BIT(10)
> -#define GEN_SW_1P_TX_LP  BIT(9)
> -#define GEN_SW_0P_TX_LP  BIT(8)
> -#define TEAR_FX_EN   BIT(0)
> -
> -#define CMD_MODE_ALL_LP  (MAX_RD_PKT_SIZE_LP | \
> -  DCS_LW_TX_LP | \
> -  DCS_SR_0P_TX_LP | \
> -  DCS_SW_1P_TX_LP | \
> -  DCS_SW_0P_TX_LP | \
> -  GEN_LW_TX_LP | \
> -  GEN_SR_2P_TX_LP | \
> -  GEN_SR_1P_TX_LP | \
> -  GEN_SR_0P_TX_LP | \
> -  GEN_SW_2P_TX_LP | \
> -  GEN_SW_1P_TX_LP | \
> -  GEN_SW_0P_TX_LP)
> -
> -#define EN_TEAR_FX_V101  BIT(14)
> -#define DCS_LW_TX_LP_V101BIT(12)
> -#define GEN_LW_TX_LP_V101BIT(11)
> -#define MAX_RD_PKT_SIZE_LP_V101  BIT(10)
> -#define DCS_SW_2P_TX_LP_V101 BIT(9)
> -#define DCS_SW_1P_TX_LP_V101 BIT(8)
> -#define DCS_SW_0P_TX_LP_V101 BIT(7)
> -#define GEN_SR_2P_TX_LP_V101 BIT(6)
> -#define GEN_SR_1P_TX_LP_V101 BIT(5)
> -#define GEN_SR_0P_TX_LP_V101 BIT(4)
> -#define GEN_SW_2P_TX_LP_V101 BIT(3)
> -#define GEN_SW_1P_TX_LP_V101 BIT(2)
> -#define GEN_SW_0P_TX_LP_V101 BIT(1)
> -
> -#define CMD_MODE_ALL_LP_V101 (DCS_LW_TX_LP_V101 | \
> -  GEN_LW_TX_LP_V101 | \
> -  MAX_RD_PKT_SIZE_LP_V101 | \
> -  DCS_SW_2P_TX_LP_V101 | \
> -  DCS_SW_1P_TX_LP_V101 | \
> -  DCS_SW_0P_TX_LP_V101 | \
> -  GEN_SR_2P_TX_LP_V101 | \
> -  GEN_SR_1P_TX_LP_V101 | \
> -  GEN_SR_0P_TX_LP_V101 | \
> -  GEN_SW_2P_TX_LP_V101 | \
> -  GEN_SW_1P_TX_LP_V101 | \
> -  GEN_SW_0P_TX_LP_V101)
> -
>   #define DSI_GEN_HDR 0x6c
>   #define DSI_GEN_PLD_DATA0x70
>   
> @@ -257,7 +203,11 @@ struct dw_mipi_dsi {
>   struct regmap_field *field_dpi_vsync_active_low;
>   struct regmap_field *field_dpi_hsync_active_low;
>   struct regmap_field *field_cmd_mode_ack_rqst_en;
> - struct regmap_field *field_cmd_mode_all_lp_en;
> + struct regmap_field *field_cmd_mode_gen_sw_sr_en;
> + struct regmap_field *field_cmd_mode_dcs_sw_sr_en;
> + struct regmap_field *field_cmd_mode_gen_lw_en;
> + struct regmap_field *field_cmd_mode_dcs_lw_en;
> + struct regmap_field *field_cmd_mode_max_rd_pkt_size;
>   struct regmap_field *field_cmd_mode_en;
>   struct regmap_field *field_cmd_pkt_status;
>   struct regmap_field *field_vid_mode_en;
> @@ -315,7 +265,11 @@ struct dw_mipi_dsi_variant {
>   struct reg_fieldcfg_dpi_hsync_active_low;
>   struct reg_fieldcfg_cmd_mode_en;
>   

Re: [PATCH v9 10/11] drm: bridge: dw-mipi-dsi: fix bad register field offsets

2020-06-10 Thread Yannick FERTRE
Hi Adrian,

thanks for the pach: tested on stm32mp1.

Tested-by: Yannick Fertré 

On 6/9/20 7:49 PM, Adrian Ratiu wrote:
> According to the DSI Host Registers sections available in the IMX,
> STM and RK ref manuals for 1.01, 1.30 and 1.31, the register fields
> are smaller or bigger than what's coded in the driver, leading to
> r/w in reserved spaces which might cause undefined behaviours.
>
> Tested-by: Adrian Pop 
> Tested-by: Arnaud Ferraris 
> Signed-off-by: Adrian Ratiu 
> ---
> New in v6.
> ---
>   drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 46 +--
>   1 file changed, 23 insertions(+), 23 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
> b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> index 1e47d40b5becb..d274216c5a7c2 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> @@ -316,7 +316,7 @@ struct dw_mipi_dsi_variant {
>   static const struct dw_mipi_dsi_variant dw_mipi_dsi_v130_v131_layout = {
>   .cfg_dpi_color_coding = REG_FIELD(DSI_DPI_COLOR_CODING, 0, 3),
>   .cfg_dpi_18loosely_en = REG_FIELD(DSI_DPI_COLOR_CODING, 8, 8),
> - .cfg_dpi_vid =  REG_FIELD(DSI_DPI_VCID, 0, 2),
> + .cfg_dpi_vid =  REG_FIELD(DSI_DPI_VCID, 0, 1),
>   .cfg_dpi_vsync_active_low = REG_FIELD(DSI_DPI_CFG_POL, 1, 1),
>   .cfg_dpi_hsync_active_low = REG_FIELD(DSI_DPI_CFG_POL, 2, 2),
>   .cfg_cmd_mode_ack_rqst_en = REG_FIELD(DSI_CMD_MODE_CFG, 1, 1),
> @@ -325,29 +325,29 @@ static const struct dw_mipi_dsi_variant 
> dw_mipi_dsi_v130_v131_layout = {
>   .cfg_cmd_mode_dcs_sw_sr_en =REG_FIELD(DSI_CMD_MODE_CFG, 16, 18),
>   .cfg_cmd_mode_dcs_lw_en =   REG_FIELD(DSI_CMD_MODE_CFG, 19, 19),
>   .cfg_cmd_mode_max_rd_pkt_size = REG_FIELD(DSI_CMD_MODE_CFG, 24, 24),
> - .cfg_cmd_mode_en =  REG_FIELD(DSI_MODE_CFG, 0, 31),
> - .cfg_cmd_pkt_status =   REG_FIELD(DSI_CMD_PKT_STATUS, 0, 31),
> - .cfg_vid_mode_en =  REG_FIELD(DSI_MODE_CFG, 0, 31),
> + .cfg_cmd_mode_en =  REG_FIELD(DSI_MODE_CFG, 0, 0),
> + .cfg_cmd_pkt_status =   REG_FIELD(DSI_CMD_PKT_STATUS, 0, 6),
> + .cfg_vid_mode_en =  REG_FIELD(DSI_MODE_CFG, 0, 0),
>   .cfg_vid_mode_type =REG_FIELD(DSI_VID_MODE_CFG, 0, 1),
>   .cfg_vid_mode_low_power =   REG_FIELD(DSI_VID_MODE_CFG, 8, 13),
>   .cfg_vid_mode_vpg_en =  REG_FIELD(DSI_VID_MODE_CFG, 16, 16),
>   .cfg_vid_mode_vpg_horiz =   REG_FIELD(DSI_VID_MODE_CFG, 24, 24),
> - .cfg_vid_pkt_size = REG_FIELD(DSI_VID_PKT_SIZE, 0, 10),
> - .cfg_vid_hsa_time = REG_FIELD(DSI_VID_HSA_TIME, 0, 31),
> - .cfg_vid_hbp_time = REG_FIELD(DSI_VID_HBP_TIME, 0, 31),
> - .cfg_vid_hline_time =   REG_FIELD(DSI_VID_HLINE_TIME, 0, 31),
> - .cfg_vid_vsa_time = REG_FIELD(DSI_VID_VSA_LINES, 0, 31),
> - .cfg_vid_vbp_time = REG_FIELD(DSI_VID_VBP_LINES, 0, 31),
> - .cfg_vid_vfp_time = REG_FIELD(DSI_VID_VFP_LINES, 0, 31),
> - .cfg_vid_vactive_time = REG_FIELD(DSI_VID_VACTIVE_LINES, 0, 31),
> + .cfg_vid_pkt_size = REG_FIELD(DSI_VID_PKT_SIZE, 0, 13),
> + .cfg_vid_hsa_time = REG_FIELD(DSI_VID_HSA_TIME, 0, 11),
> + .cfg_vid_hbp_time = REG_FIELD(DSI_VID_HBP_TIME, 0, 11),
> + .cfg_vid_hline_time =   REG_FIELD(DSI_VID_HLINE_TIME, 0, 14),
> + .cfg_vid_vsa_time = REG_FIELD(DSI_VID_VSA_LINES, 0, 9),
> + .cfg_vid_vbp_time = REG_FIELD(DSI_VID_VBP_LINES, 0, 9),
> + .cfg_vid_vfp_time = REG_FIELD(DSI_VID_VFP_LINES, 0, 9),
> + .cfg_vid_vactive_time = REG_FIELD(DSI_VID_VACTIVE_LINES, 0, 13),
>   .cfg_phy_txrequestclkhs =   REG_FIELD(DSI_LPCLK_CTRL, 0, 0),
> - .cfg_phy_bta_time = REG_FIELD(DSI_BTA_TO_CNT, 0, 31),
> - .cfg_phy_max_rd_time =  REG_FIELD(DSI_PHY_TMR_CFG, 0, 15),
> + .cfg_phy_bta_time = REG_FIELD(DSI_BTA_TO_CNT, 0, 15),
> + .cfg_phy_max_rd_time =  REG_FIELD(DSI_PHY_TMR_CFG, 0, 14),
>   .cfg_phy_lp2hs_time =   REG_FIELD(DSI_PHY_TMR_CFG, 16, 23),
>   .cfg_phy_hs2lp_time =   REG_FIELD(DSI_PHY_TMR_CFG, 24, 31),
> - .cfg_phy_max_rd_time_v131 = REG_FIELD(DSI_PHY_TMR_RD_CFG, 0, 15),
> - .cfg_phy_lp2hs_time_v131 =  REG_FIELD(DSI_PHY_TMR_CFG, 0, 15),
> - .cfg_phy_hs2lp_time_v131 =  REG_FIELD(DSI_PHY_TMR_CFG, 16, 31),
> + .cfg_phy_max_rd_time_v131 = REG_FIELD(DSI_PHY_TMR_RD_CFG, 0, 14),
> + .cfg_phy_lp2hs_time_v131 =  REG_FIELD(DSI_PHY_TMR_CFG, 0, 9),
> + .cfg_phy_hs2lp_time_v131 =  REG_FIELD(DSI_PHY_TMR_CFG, 16, 25),
>   .cfg_phy_clklp2hs_time =REG_FIELD(DSI_PHY_TMR_LPCLK_CFG, 0, 15),
>   .cfg_phy_clkhs2lp_time =REG_FIELD(DSI_PHY_TMR_LPCLK_CFG, 

Re: [PATCH v9 04/11] drm: bridge: dw_mipi_dsi: remove bind/unbind API

2020-06-10 Thread Yannick FERTRE
Hi Adrian,

thanks for the pach: tested on stm32mp1.

Tested-by: Yannick Fertré 

On 6/9/20 7:49 PM, Adrian Ratiu wrote:
> The DW mipi-dsi bind/unbind API was only used to attach the bridge to
> the encoder in the Rockchip driver, but with the addition of i.MX6 it
> gets more complicated because the i.MX6 part of the bridge is another
> bridge in itself which needs to daisy chain to the dw-mipi-dsi core.
>
> So, instead of extending this API to allow daisy-chaining bridges and
> risk having trouble with multiple connectors added by various bridges
> just delete it and let the DW core bridge be accesed by SoC-specific
> parts via the of_drm_find_bridge() API.
>
> This just fixes the Rockchip driver for the bind() deprecation, it
> doesn't convert it to a proper bridge daisy-chain with simple encoder
> and bridge .attach call-backs, that refactoring work should be done
> separately (and the i.MX6 driver can be used as reference).
>
> Suggested-by: Laurent Pinchart 
> Signed-off-by: Adrian Ratiu 
> ---
> New in v9.
> ---
>   drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 22 ---
>   .../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c   |  7 +++---
>   2 files changed, 3 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
> b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> index 16fd87055e7b7..70df0578cbe7b 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> @@ -1453,28 +1453,6 @@ void dw_mipi_dsi_remove(struct dw_mipi_dsi *dsi)
>   }
>   EXPORT_SYMBOL_GPL(dw_mipi_dsi_remove);
>   
> -/*
> - * Bind/unbind API, used from platforms based on the component framework.
> - */
> -int dw_mipi_dsi_bind(struct dw_mipi_dsi *dsi, struct drm_encoder *encoder)
> -{
> - int ret;
> -
> - ret = drm_bridge_attach(encoder, >bridge, NULL, 0);
> - if (ret) {
> - DRM_ERROR("Failed to initialize bridge with drm\n");
> - return ret;
> - }
> -
> - return ret;
> -}
> -EXPORT_SYMBOL_GPL(dw_mipi_dsi_bind);
> -
> -void dw_mipi_dsi_unbind(struct dw_mipi_dsi *dsi)
> -{
> -}
> -EXPORT_SYMBOL_GPL(dw_mipi_dsi_unbind);
> -
>   MODULE_AUTHOR("Chris Zhong ");
>   MODULE_AUTHOR("Philippe Cornu ");
>   MODULE_DESCRIPTION("DW MIPI DSI host controller driver");
> diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c 
> b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
> index 3feff0c45b3f7..86f87c7ea03cf 100644
> --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
> @@ -876,6 +876,7 @@ static int dw_mipi_dsi_rockchip_bind(struct device *dev,
>   {
>   struct dw_mipi_dsi_rockchip *dsi = dev_get_drvdata(dev);
>   struct drm_device *drm_dev = data;
> + struct drm_bridge *dw_bridge = of_drm_find_bridge(dev->of_node);
>   struct device *second;
>   bool master1, master2;
>   int ret;
> @@ -929,9 +930,9 @@ static int dw_mipi_dsi_rockchip_bind(struct device *dev,
>   return ret;
>   }
>   
> - ret = dw_mipi_dsi_bind(dsi->dmd, >encoder);
> + ret = drm_bridge_attach(>encoder, dw_bridge, NULL, 0);
>   if (ret) {
> - DRM_DEV_ERROR(dev, "Failed to bind: %d\n", ret);
> + DRM_DEV_ERROR(dev, "Failed to attach DW DSI bridge: %d\n", ret);
>   return ret;
>   }
>   
> @@ -947,8 +948,6 @@ static void dw_mipi_dsi_rockchip_unbind(struct device 
> *dev,
>   if (dsi->is_slave)
>   return;
>   
> - dw_mipi_dsi_unbind(dsi->dmd);
> -
>   clk_disable_unprepare(dsi->pllref_clk);
>   }
>   
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


RE: [PATCH] drm/stm: repair runtime power management

2020-03-09 Thread Yannick FERTRE
Hello Marek,
Thank for your patch. Pm_runtime_put_sync is also done into function 
ltdc_crtc_mode_fixup.
To avoid several call of Pm_runtime_put_sync, it could be better to check 
pm_runtime activity:

+   int ret;
 
DRM_DEBUG_DRIVER("\n");
 
+   if (!pm_runtime_active(ddev->dev)) {
+   ret = pm_runtime_get_sync(ddev->dev);
+   if (ret) {
+   DRM_ERROR("Failed to enable crtc, cannot get sync\n");
+   return;
+   }
+   }
+

 Best regards

Yannick Fertré


-Original Message-
From: Marek Vasut  
Sent: samedi 29 février 2020 23:17
To: dri-devel@lists.freedesktop.org
Cc: Marek Vasut ; Yannick FERTRE ; 
Philippe CORNU ; Benjamin Gaignard 
; Vincent ABRIOU ; Maxime 
Coquelin ; Alexandre TORGUE 
; linux-st...@st-md-mailman.stormreply.com; 
linux-arm-ker...@lists.infradead.org
Subject: [PATCH] drm/stm: repair runtime power management

Add missing pm_runtime_get_sync() into ltdc_crtc_atomic_enable() to match 
pm_runtime_put_sync() in ltdc_crtc_atomic_disable(), otherwise the LTDC might 
suspend via runtime PM, disable clock, and then fail to resume later on.

The test which triggers it is roughly -- run qt5 application which uses eglfs 
platform and etnaviv, stop the application, sleep for 15 minutes, run the 
application again. This leads to a timeout waiting for vsync, because the LTDC 
has suspended, but did not resume.

Fixes: 35ab6cfbf211 ("drm/stm: support runtime power management")
Signed-off-by: Marek Vasut 
Cc: Yannick Fertré 
Cc: Philippe Cornu 
Cc: Benjamin Gaignard 
Cc: Vincent Abriou 
Cc: Maxime Coquelin 
Cc: Alexandre Torgue 
To: dri-devel@lists.freedesktop.org
Cc: linux-st...@st-md-mailman.stormreply.com
Cc: linux-arm-ker...@lists.infradead.org
---
[ cut here ]
WARNING: CPU: 0 PID: 297 at drivers/gpu/drm/drm_atomic_helper.c:1494 
drm_atomic_helper_wait_for_vblanks+0x1dc/0x200
[CRTC:35:crtc-0] vblank wait timed out
Modules linked in:
CPU: 0 PID: 297 Comm: QSGRenderThread Not tainted 
5.6.0-rc3-next-20200228-00010-g318bf0fc08ef #2 Hardware name: STM32 (Device 
Tree Support) [] (unwind_backtrace) from [] 
(show_stack+0x10/0x14) [] (show_stack) from [] 
(dump_stack+0xb4/0xd0) [] (dump_stack) from [] 
(__warn+0xd4/0xf0) [] (__warn) from [] 
(warn_slowpath_fmt+0x78/0xa8) [] (warn_slowpath_fmt) from 
[] (drm_atomic_helper_wait_for_vblanks+0x1dc/0x200)
[] (drm_atomic_helper_wait_for_vblanks) from [] 
(drm_atomic_helper_commit_tail+0
x50/0x60)
[] (drm_atomic_helper_commit_tail) from [] 
(commit_tail+0x12c/0x13c) [] (commit_tail) from [] 
(drm_atomic_helper_commit+0xf4/0x100)
[] (drm_atomic_helper_commit) from [] 
(drm_atomic_helper_set_config+0x58/0x6c)
[] (drm_atomic_helper_set_config) from [] 
(drm_mode_setcrtc+0x450/0x550) [] (drm_mode_setcrtc) from 
[] (drm_ioctl_kernel+0x90/0xe8) [] (drm_ioctl_kernel) from 
[] (drm_ioctl+0x2e4/0x32c) [] (drm_ioctl) from [] 
(vfs_ioctl+0x20/0x38) [] (vfs_ioctl) from [] 
(ksys_ioctl+0xbc/0x7b0) [] (ksys_ioctl) from [] 
(ret_fast_syscall+0x0/0x54) Exception stack(0xee8f3fa8 to 0xee8f3ff0)
3fa0:   0005 adcbeb18 0005 c06864a2 adcbeb18 0001
3fc0: 0005 adcbeb18 c06864a2 0036 0029 0023 0023 0007
3fe0: b113b098 adcbeafc b1125413 b6155cf8 ---[ end trace 2ad5ba954ceb767a ]---
---
 drivers/gpu/drm/stm/ltdc.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c index 
99bf93e8b36f..301de0498078 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -425,9 +425,12 @@ static void ltdc_crtc_atomic_enable(struct drm_crtc *crtc,
struct drm_crtc_state *old_state)  {
struct ltdc_device *ldev = crtc_to_ltdc(crtc);
+   struct drm_device *ddev = crtc->dev;
 
DRM_DEBUG_DRIVER("\n");
 
+   pm_runtime_get_sync(ddev->dev);
+
/* Sets the background color value */
reg_write(ldev->regs, LTDC_BCCR, BCCR_BCBLACK);
 
--
2.25.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/stm: ltdc: check number of endpoints

2020-02-28 Thread Yannick Fertre
Number of endpoints could exceed the fix value MAX_ENDPOINTS(2).
Instead of increase simply this value, the number of endpoint
could be read from device tree. Load sequence has been a little
rework to take care of several panel or bridge which can be
connected/disconnected or enable/disable.

Signed-off-by: Yannick Fertre 
---
 drivers/gpu/drm/stm/ltdc.c | 102 +++--
 1 file changed, 52 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index df585fe..f894968 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -42,8 +42,6 @@

 #define MAX_IRQ 4

-#define MAX_ENDPOINTS 2
-
 #define HWVER_10200 0x010200
 #define HWVER_10300 0x010300
 #define HWVER_20101 0x020101
@@ -1201,36 +1199,20 @@ int ltdc_load(struct drm_device *ddev)
struct ltdc_device *ldev = ddev->dev_private;
struct device *dev = ddev->dev;
struct device_node *np = dev->of_node;
-   struct drm_bridge *bridge[MAX_ENDPOINTS] = {NULL};
-   struct drm_panel *panel[MAX_ENDPOINTS] = {NULL};
+   struct drm_bridge *bridge;
+   struct drm_panel *panel;
struct drm_crtc *crtc;
struct reset_control *rstc;
struct resource *res;
-   int irq, ret, i, endpoint_not_ready = -ENODEV;
+   int irq, i, nb_endpoints;
+   int ret = -ENODEV;

DRM_DEBUG_DRIVER("\n");

-   /* Get endpoints if any */
-   for (i = 0; i < MAX_ENDPOINTS; i++) {
-   ret = drm_of_find_panel_or_bridge(np, 0, i, [i],
- [i]);
-
-   /*
-* If at least one endpoint is -EPROBE_DEFER, defer probing,
-* else if at least one endpoint is ready, continue probing.
-*/
-   if (ret == -EPROBE_DEFER)
-   return ret;
-   else if (!ret)
-   endpoint_not_ready = 0;
-   }
-
-   if (endpoint_not_ready)
-   return endpoint_not_ready;
-
-   rstc = devm_reset_control_get_exclusive(dev, NULL);
-
-   mutex_init(>err_lock);
+   /* Get number of endpoints */
+   nb_endpoints = of_graph_get_endpoint_count(np);
+   if (!nb_endpoints)
+   return -ENODEV;

ldev->pixel_clk = devm_clk_get(dev, "lcd");
if (IS_ERR(ldev->pixel_clk)) {
@@ -1244,6 +1226,43 @@ int ltdc_load(struct drm_device *ddev)
return -ENODEV;
}

+   /* Get endpoints if any */
+   for (i = 0; i < nb_endpoints; i++) {
+   ret = drm_of_find_panel_or_bridge(np, 0, i, , );
+
+   /*
+* If at least one endpoint is -ENODEV, continue probing,
+* else if at least one endpoint returned an error
+* (ie -EPROBE_DEFER) then stop probing.
+*/
+   if (ret == -ENODEV)
+   continue;
+   else if (ret)
+   goto err;
+
+   if (panel) {
+   bridge = drm_panel_bridge_add_typed(panel,
+   
DRM_MODE_CONNECTOR_DPI);
+   if (IS_ERR(bridge)) {
+   DRM_ERROR("panel-bridge endpoint %d\n", i);
+   ret = PTR_ERR(bridge);
+   goto err;
+   }
+   }
+
+   if (bridge) {
+   ret = ltdc_encoder_init(ddev, bridge);
+   if (ret) {
+   DRM_ERROR("init encoder endpoint %d\n", i);
+   goto err;
+   }
+   }
+   }
+
+   rstc = devm_reset_control_get_exclusive(dev, NULL);
+
+   mutex_init(>err_lock);
+
if (!IS_ERR(rstc)) {
reset_control_assert(rstc);
usleep_range(10, 20);
@@ -1285,27 +1304,7 @@ int ltdc_load(struct drm_device *ddev)
DRM_ERROR("Failed to register LTDC interrupt\n");
goto err;
}
-   }

-   /* Add endpoints panels or bridges if any */
-   for (i = 0; i < MAX_ENDPOINTS; i++) {
-   if (panel[i]) {
-   bridge[i] = drm_panel_bridge_add_typed(panel[i],
-  
DRM_MODE_CONNECTOR_DPI);
-   if (IS_ERR(bridge[i])) {
-   DRM_ERROR("panel-bridge endpoint %d\n", i);
-   ret = PTR_ERR(bridge[i]);
-   goto err;
-   }
-   }
-
-   if (bridge[i]) {
-   ret = ltdc_encoder_init(ddev, bridge[i]);
-   if (ret) {
- 

[PATCH] drm/bridge/synopsys: dsi: missing post disable

2020-01-21 Thread Yannick Fertre
From: Yannick Fertré 

Sometime the post_disable function is missing (not registered).

Signed-off-by: Yannick Fertré 
---
 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index b18351b..12823ae 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -824,7 +824,8 @@ static void dw_mipi_dsi_bridge_post_disable(struct 
drm_bridge *bridge)
 * This needs to be fixed in the drm_bridge framework and the API
 * needs to be updated to manage our own call chains...
 */
-   dsi->panel_bridge->funcs->post_disable(dsi->panel_bridge);
+   if (dsi->panel_bridge->funcs->post_disable)
+   dsi->panel_bridge->funcs->post_disable(dsi->panel_bridge);
 
if (phy_ops->power_off)
phy_ops->power_off(dsi->plat_data->priv_data);
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/stm: dsi: stm mipi dsi doesn't print error on probe deferral

2020-01-21 Thread Yannick Fertre
From: Etienne Carriere 

Change DSI driver to not print an error trace when probe
is deferred for a clock resource.

Signed-off-by: Etienne Carriere 
---
 drivers/gpu/drm/stm/dw_mipi_dsi-stm.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c 
b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
index 4b16563..2e1f266 100644
--- a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
+++ b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
@@ -377,7 +377,9 @@ static int dw_mipi_dsi_stm_probe(struct platform_device 
*pdev)
dsi->pllref_clk = devm_clk_get(dev, "ref");
if (IS_ERR(dsi->pllref_clk)) {
ret = PTR_ERR(dsi->pllref_clk);
-   DRM_ERROR("Unable to get pll reference clock: %d\n", ret);
+   if (ret != -EPROBE_DEFER)
+   DRM_ERROR("Unable to get pll reference clock: %d\n",
+ ret);
goto err_clk_get;
}
 
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/stm: ltdc: check number of endpoints

2020-01-21 Thread Yannick Fertre
Number of endpoints could exceed the fix value MAX_ENDPOINTS(2).
Instead of increase simply this value, the number of endpoint
could be read from device tree. Load sequence has been a little
rework to take care of several panel or bridge which can be
connected/disconnected or enable/disable.

Signed-off-by: Yannick Fertré 
---
 drivers/gpu/drm/stm/ltdc.c | 104 ++---
 1 file changed, 52 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index c2815e8..dba8e7f 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -42,8 +42,6 @@
 
 #define MAX_IRQ 4
 
-#define MAX_ENDPOINTS 2
-
 #define HWVER_10200 0x010200
 #define HWVER_10300 0x010300
 #define HWVER_20101 0x020101
@@ -1190,36 +1188,20 @@ int ltdc_load(struct drm_device *ddev)
struct ltdc_device *ldev = ddev->dev_private;
struct device *dev = ddev->dev;
struct device_node *np = dev->of_node;
-   struct drm_bridge *bridge[MAX_ENDPOINTS] = {NULL};
-   struct drm_panel *panel[MAX_ENDPOINTS] = {NULL};
+   struct drm_bridge *bridge;
+   struct drm_panel *panel;
struct drm_crtc *crtc;
struct reset_control *rstc;
struct resource *res;
-   int irq, ret, i, endpoint_not_ready = -ENODEV;
+   int irq, i, nb_endpoints;
+   int ret = -ENODEV;
 
DRM_DEBUG_DRIVER("\n");
 
-   /* Get endpoints if any */
-   for (i = 0; i < MAX_ENDPOINTS; i++) {
-   ret = drm_of_find_panel_or_bridge(np, 0, i, [i],
- [i]);
-
-   /*
-* If at least one endpoint is -EPROBE_DEFER, defer probing,
-* else if at least one endpoint is ready, continue probing.
-*/
-   if (ret == -EPROBE_DEFER)
-   return ret;
-   else if (!ret)
-   endpoint_not_ready = 0;
-   }
-
-   if (endpoint_not_ready)
-   return endpoint_not_ready;
-
-   rstc = devm_reset_control_get_exclusive(dev, NULL);
-
-   mutex_init(>err_lock);
+   /* Get number of endpoints */
+   nb_endpoints = of_graph_get_endpoint_count(np);
+   if (!nb_endpoints)
+   return -ENODEV;
 
ldev->pixel_clk = devm_clk_get(dev, "lcd");
if (IS_ERR(ldev->pixel_clk)) {
@@ -1233,6 +1215,43 @@ int ltdc_load(struct drm_device *ddev)
return -ENODEV;
}
 
+   /* Get endpoints if any */
+   for (i = 0; i < nb_endpoints; i++) {
+   ret = drm_of_find_panel_or_bridge(np, 0, i, , );
+
+   /*
+* If at least one endpoint is -ENODEV, continue probing,
+* else if at least one endpoint returned an error
+* (ie -EPROBE_DEFER) then stop probing.
+*/
+   if (ret == -ENODEV)
+   continue;
+   else if (ret)
+   goto err;
+
+   if (panel) {
+   bridge = drm_panel_bridge_add_typed(panel,
+   
DRM_MODE_CONNECTOR_DPI);
+   if (IS_ERR(bridge)) {
+   DRM_ERROR("panel-bridge endpoint %d\n", i);
+   ret = PTR_ERR(bridge);
+   goto err;
+   }
+   }
+
+   if (bridge) {
+   ret = ltdc_encoder_init(ddev, bridge);
+   if (ret) {
+   DRM_ERROR("init encoder endpoint %d\n", i);
+   goto err;
+   }
+   }
+   }
+
+   rstc = devm_reset_control_get_exclusive(dev, NULL);
+
+   mutex_init(>err_lock);
+
if (!IS_ERR(rstc)) {
reset_control_assert(rstc);
usleep_range(10, 20);
@@ -1268,7 +1287,6 @@ int ltdc_load(struct drm_device *ddev)
}
}
 
-
ret = ltdc_get_caps(ddev);
if (ret) {
DRM_ERROR("hardware identifier (0x%08x) not supported!\n",
@@ -1278,27 +1296,6 @@ int ltdc_load(struct drm_device *ddev)
 
DRM_DEBUG_DRIVER("ltdc hw version 0x%08x\n", ldev->caps.hw_version);
 
-   /* Add endpoints panels or bridges if any */
-   for (i = 0; i < MAX_ENDPOINTS; i++) {
-   if (panel[i]) {
-   bridge[i] = drm_panel_bridge_add_typed(panel[i],
-  
DRM_MODE_CONNECTOR_DPI);
-   if (IS_ERR(bridge[i])) {
-   DRM_ERROR("panel-bridge endpoint %d\n", i);
-   ret = PTR_ERR(bridge[i]);
-   goto err;
-   }
-   }
-
-   if (bridge[i]) {
-   ret = 

[PATCH] drm/stm: ltdc: add number of interrupts

2020-01-21 Thread Yannick Fertre
The number of interrupts depends on the ltdc version.
Don't try to get interrupt which not exist, avoiding
kernel warning messages.

Signed-off-by: Yannick Fertre 
---
 drivers/gpu/drm/stm/ltdc.c | 30 +++---
 drivers/gpu/drm/stm/ltdc.h |  1 +
 2 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index c2815e8..58092b0 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -1146,12 +1146,14 @@ static int ltdc_get_caps(struct drm_device *ddev)
ldev->caps.pad_max_freq_hz = 9000;
if (ldev->caps.hw_version == HWVER_10200)
ldev->caps.pad_max_freq_hz = 6500;
+   ldev->caps.nb_irq = 2;
break;
case HWVER_20101:
ldev->caps.reg_ofs = REG_OFS_4;
ldev->caps.pix_fmt_hw = ltdc_pix_fmt_a1;
ldev->caps.non_alpha_only_l1 = false;
ldev->caps.pad_max_freq_hz = 15000;
+   ldev->caps.nb_irq = 4;
break;
default:
return -ENODEV;
@@ -1251,13 +1253,21 @@ int ltdc_load(struct drm_device *ddev)
reg_clear(ldev->regs, LTDC_IER,
  IER_LIE | IER_RRIE | IER_FUIE | IER_TERRIE);
 
-   for (i = 0; i < MAX_IRQ; i++) {
+   ret = ltdc_get_caps(ddev);
+   if (ret) {
+   DRM_ERROR("hardware identifier (0x%08x) not supported!\n",
+ ldev->caps.hw_version);
+   goto err;
+   }
+
+   DRM_DEBUG_DRIVER("ltdc hw version 0x%08x\n", ldev->caps.hw_version);
+
+   for (i = 0; i < ldev->caps.nb_irq; i++) {
irq = platform_get_irq(pdev, i);
-   if (irq == -EPROBE_DEFER)
+   if (irq < 0) {
+   ret = irq;
goto err;
-
-   if (irq < 0)
-   continue;
+   }
 
ret = devm_request_threaded_irq(dev, irq, ltdc_irq,
ltdc_irq_thread, IRQF_ONESHOT,
@@ -1268,16 +1278,6 @@ int ltdc_load(struct drm_device *ddev)
}
}
 
-
-   ret = ltdc_get_caps(ddev);
-   if (ret) {
-   DRM_ERROR("hardware identifier (0x%08x) not supported!\n",
- ldev->caps.hw_version);
-   goto err;
-   }
-
-   DRM_DEBUG_DRIVER("ltdc hw version 0x%08x\n", ldev->caps.hw_version);
-
/* Add endpoints panels or bridges if any */
for (i = 0; i < MAX_ENDPOINTS; i++) {
if (panel[i]) {
diff --git a/drivers/gpu/drm/stm/ltdc.h b/drivers/gpu/drm/stm/ltdc.h
index a1ad0ae..310e87f 100644
--- a/drivers/gpu/drm/stm/ltdc.h
+++ b/drivers/gpu/drm/stm/ltdc.h
@@ -19,6 +19,7 @@ struct ltdc_caps {
const u32 *pix_fmt_hw;  /* supported pixel formats */
bool non_alpha_only_l1; /* non-native no-alpha formats on layer 1 */
int pad_max_freq_hz;/* max frequency supported by pad */
+   int nb_irq; /* number of hardware interrupts */
 };
 
 #define LTDC_MAX_LAYER 4
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/stm: ltdc: check crtc state before enabling LIE

2020-01-21 Thread Yannick Fertre
Following investigations of a hardware bug, the LIE interrupt
can occur while the display controller is not activated.
LIE interrupt (vblank) don't have to be set if the CRTC is not
enabled.

Signed-off-by: Yannick Fertre 
---
 drivers/gpu/drm/stm/ltdc.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index c2815e8..ea654c7 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -648,9 +648,14 @@ static const struct drm_crtc_helper_funcs 
ltdc_crtc_helper_funcs = {
 static int ltdc_crtc_enable_vblank(struct drm_crtc *crtc)
 {
struct ltdc_device *ldev = crtc_to_ltdc(crtc);
+   struct drm_crtc_state *state = crtc->state;
 
DRM_DEBUG_DRIVER("\n");
-   reg_set(ldev->regs, LTDC_IER, IER_LIE);
+
+   if (state->enable)
+   reg_set(ldev->regs, LTDC_IER, IER_LIE);
+   else
+   return -EPERM;
 
return 0;
 }
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/stm: ltdc: enable/disable depends on encoder

2020-01-20 Thread Yannick Fertre
From: Yannick Fertré 

When connected to a dsi host, the ltdc display controller
must send frames only after the end of the dsi panel
initialization to avoid errors when the dsi host sends
commands to the dsi panel (dsi px fifo full).
To avoid this issue, the display controller must be
enabled/disabled when the encoder is enabled/disabled.

Signed-off-by: Yannick Fertré 
---
 drivers/gpu/drm/stm/ltdc.c | 14 --
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index 719dfc5..9ef125d 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -437,9 +437,6 @@ static void ltdc_crtc_atomic_enable(struct drm_crtc *crtc,
/* Commit shadow registers = update planes at next vblank */
reg_set(ldev->regs, LTDC_SRCR, SRCR_VBR);
 
-   /* Enable LTDC */
-   reg_set(ldev->regs, LTDC_GCR, GCR_LTDCEN);
-
drm_crtc_vblank_on(crtc);
 }
 
@@ -453,9 +450,6 @@ static void ltdc_crtc_atomic_disable(struct drm_crtc *crtc,
 
drm_crtc_vblank_off(crtc);
 
-   /* disable LTDC */
-   reg_clear(ldev->regs, LTDC_GCR, GCR_LTDCEN);
-
/* disable IRQ */
reg_clear(ldev->regs, LTDC_IER, IER_RRIE | IER_FUIE | IER_TERRIE);
 
@@ -1058,9 +1052,13 @@ static const struct drm_encoder_funcs ltdc_encoder_funcs 
= {
 static void ltdc_encoder_disable(struct drm_encoder *encoder)
 {
struct drm_device *ddev = encoder->dev;
+   struct ltdc_device *ldev = ddev->dev_private;
 
DRM_DEBUG_DRIVER("\n");
 
+   /* Disable LTDC */
+   reg_clear(ldev->regs, LTDC_GCR, GCR_LTDCEN);
+
/* Set to sleep state the pinctrl whatever type of encoder */
pinctrl_pm_select_sleep_state(ddev->dev);
 }
@@ -1068,6 +1066,7 @@ static void ltdc_encoder_disable(struct drm_encoder 
*encoder)
 static void ltdc_encoder_enable(struct drm_encoder *encoder)
 {
struct drm_device *ddev = encoder->dev;
+   struct ltdc_device *ldev = ddev->dev_private;
 
DRM_DEBUG_DRIVER("\n");
 
@@ -1078,6 +1077,9 @@ static void ltdc_encoder_enable(struct drm_encoder 
*encoder)
 */
if (encoder->encoder_type == DRM_MODE_ENCODER_DPI)
pinctrl_pm_select_default_state(ddev->dev);
+
+   /* Enable LTDC */
+   reg_set(ldev->regs, LTDC_GCR, GCR_LTDCEN);
 }
 
 static const struct drm_encoder_helper_funcs ltdc_encoder_helper_funcs = {
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 23/23] drm: Cleanup VBLANK callbacks in struct drm_driver

2020-01-14 Thread Yannick FERTRE
Thanks for the patch.

Tested-by: Yannick Fertré 

BR
Yannick Fertré


On 1/10/20 10:21 AM, Thomas Zimmermann wrote:

All non-legacy users of VBLANK functions in struct drm_driver have been
converted to use the respective interfaces in struct drm_crtc_funcs. The
remaining users of VBLANK callbacks in struct drm_driver are legacy drivers
with userspace modesetting.

There are no users left of get_vblank_timestamp(), so the callback is
being removed. The other VBLANK callbacks are being moved to the legacy
section at the end of struct drm_driver.

Signed-off-by: Thomas Zimmermann 

---
 drivers/gpu/drm/drm_vblank.c |  39 +-
 include/drm/drm_drv.h| 101 ++-
 2 files changed, 17 insertions(+), 123 deletions(-)

diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 7cf436a4b908..ceff68474d4d 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -138,10 +138,9 @@ static u32 __get_vblank_counter(struct drm_device *dev, 
unsigned int pipe)

if (crtc->funcs->get_vblank_counter)
return crtc->funcs->get_vblank_counter(crtc);
-   }
-
-   if (dev->driver->get_vblank_counter)
+   } else if (dev->driver->get_vblank_counter) {
return dev->driver->get_vblank_counter(dev, pipe);
+   }

return drm_vblank_no_hw_counter(dev, pipe);
 }
@@ -334,8 +333,7 @@ u64 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc)
unsigned long flags;

WARN_ONCE(drm_debug_enabled(DRM_UT_VBL) &&
- !crtc->funcs->get_vblank_timestamp &&
- !dev->driver->get_vblank_timestamp,
+ !crtc->funcs->get_vblank_timestamp,
  "This function requires support for accurate vblank 
timestamps.");

spin_lock_irqsave(>vblank_time_lock, flags);
@@ -357,13 +355,11 @@ static void __disable_vblank(struct drm_device *dev, 
unsigned int pipe)
if (WARN_ON(!crtc))
return;

-   if (crtc->funcs->disable_vblank) {
+   if (crtc->funcs->disable_vblank)
crtc->funcs->disable_vblank(crtc);
-   return;
-   }
+   } else {
+   dev->driver->disable_vblank(dev, pipe);
}
-
-   dev->driver->disable_vblank(dev, pipe);
 }

 /*
@@ -791,9 +787,6 @@ drm_get_last_vbltimestamp(struct drm_device *dev, unsigned 
int pipe,

ret = crtc->funcs->get_vblank_timestamp(crtc, _error,
tvblank, in_vblank_irq);
-   } else if (dev->driver->get_vblank_timestamp && (max_error > 0)) {
-   ret = dev->driver->get_vblank_timestamp(dev, pipe, _error,
-   tvblank, in_vblank_irq);
}

/* GPU high precision timestamp query unsupported or failed.
@@ -1016,9 +1009,11 @@ static int __enable_vblank(struct drm_device *dev, 
unsigned int pipe)

if (crtc->funcs->enable_vblank)
return crtc->funcs->enable_vblank(crtc);
+   } else if (dev->driver->enable_vblank) {
+   return dev->driver->enable_vblank(dev, pipe);
}

-   return dev->driver->enable_vblank(dev, pipe);
+   return -EINVAL;
 }

 static int drm_vblank_enable(struct drm_device *dev, unsigned int pipe)
@@ -1109,13 +1104,10 @@ static bool __vblank_disable_immediate(struct 
drm_device *dev, unsigned int pipe
return false;

crtc = drm_crtc_from_index(dev, pipe);
-   if (crtc && crtc->funcs->get_vblank_timestamp)
-   return true;
-
-   if (dev->driver->get_vblank_timestamp)
-   return true;
+   if (!crtc || !crtc->funcs->get_vblank_timestamp)
+   return false;

-   return false;
+   return true;
 }

 static void drm_vblank_put(struct drm_device *dev, unsigned int pipe)
@@ -1798,7 +1790,6 @@ static void drm_handle_vblank_events(struct drm_device 
*dev, unsigned int pipe)
struct drm_pending_vblank_event *e, *t;
ktime_t now;
u64 seq;
-   bool high_prec;

assert_spin_locked(>event_lock);

@@ -1818,10 +1809,8 @@ static void drm_handle_vblank_events(struct drm_device 
*dev, unsigned int pipe)
send_vblank_event(dev, e, seq, now);
}

-   high_prec = crtc->funcs->get_vblank_timestamp ||
-   dev->driver->get_vblank_timestamp;
-
-   trace_drm_vblank_event(pipe, seq, now, high_prec);
+   trace_drm_vblank_event(pipe, seq, now,
+  crtc->funcs->get_vblank_timestamp != NULL);
 }

 /**
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index b704e252f3b2..e290b3aca6eb 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -268,104 +268,6 @@ struct drm_driver {
 */
void 

Re: [PATCH 19/23] drm/stm: Convert to CRTC VBLANK callbacks

2020-01-14 Thread Yannick FERTRE
Thanks for the patch.

Tested-by: Yannick Fertré 

BR
Yannick Fertré


On 1/10/20 10:21 AM, Thomas Zimmermann wrote:

VBLANK callbacks in struct drm_driver are deprecated in favor of
their equivalents in struct drm_crtc_funcs. Convert stm over.

Signed-off-by: Thomas Zimmermann 

---
 drivers/gpu/drm/stm/drv.c  | 1 -
 drivers/gpu/drm/stm/ltdc.c | 1 +
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c
index 486985604109..ea9fcbdc68b3 100644
--- a/drivers/gpu/drm/stm/drv.c
+++ b/drivers/gpu/drm/stm/drv.c
@@ -72,7 +72,6 @@ static struct drm_driver drv_driver = {
.gem_prime_vmap = drm_gem_cma_prime_vmap,
.gem_prime_vunmap = drm_gem_cma_prime_vunmap,
.gem_prime_mmap = drm_gem_cma_prime_mmap,
-   .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos,
 };

 static int drv_load(struct drm_device *ddev)
diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index 8b6d1a2252e3..4fe9b033de1b 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -722,6 +722,7 @@ static const struct drm_crtc_funcs ltdc_crtc_funcs = {
.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
.enable_vblank = ltdc_crtc_enable_vblank,
.disable_vblank = ltdc_crtc_disable_vblank,
+   .get_vblank_timestamp = drm_crtc_calc_vbltimestamp_from_scanoutpos,
.gamma_set = drm_atomic_helper_legacy_gamma_set,
 };



___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 08/23] drm/stm: Convert to struct drm_crtc_helper_funcs.get_scanout_position()

2020-01-14 Thread Yannick FERTRE
Thanks for the patch.

Tested-by: Yannick Fertré 

BR
Yannick Fertré


On 1/10/20 10:21 AM, Thomas Zimmermann wrote:

The callback struct drm_driver.get_scanout_position() is deprecated in
favor of struct drm_crtc_helper_funcs.get_scanout_position(). Convert stm
over.

Signed-off-by: Thomas Zimmermann 

---
 drivers/gpu/drm/stm/drv.c  |  1 -
 drivers/gpu/drm/stm/ltdc.c | 65 --
 drivers/gpu/drm/stm/ltdc.h |  5 ---
 3 files changed, 34 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c
index 5a9f9aca8bc2..486985604109 100644
--- a/drivers/gpu/drm/stm/drv.c
+++ b/drivers/gpu/drm/stm/drv.c
@@ -72,7 +72,6 @@ static struct drm_driver drv_driver = {
.gem_prime_vmap = drm_gem_cma_prime_vmap,
.gem_prime_vunmap = drm_gem_cma_prime_vunmap,
.gem_prime_mmap = drm_gem_cma_prime_mmap,
-   .get_scanout_position = ltdc_crtc_scanoutpos,
.get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos,
 };

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index c2815e8ae1da..8b6d1a2252e3 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -636,38 +636,13 @@ static void ltdc_crtc_atomic_flush(struct drm_crtc *crtc,
}
 }

-static const struct drm_crtc_helper_funcs ltdc_crtc_helper_funcs = {
-   .mode_valid = ltdc_crtc_mode_valid,
-   .mode_fixup = ltdc_crtc_mode_fixup,
-   .mode_set_nofb = ltdc_crtc_mode_set_nofb,
-   .atomic_flush = ltdc_crtc_atomic_flush,
-   .atomic_enable = ltdc_crtc_atomic_enable,
-   .atomic_disable = ltdc_crtc_atomic_disable,
-};
-
-static int ltdc_crtc_enable_vblank(struct drm_crtc *crtc)
-{
-   struct ltdc_device *ldev = crtc_to_ltdc(crtc);
-
-   DRM_DEBUG_DRIVER("\n");
-   reg_set(ldev->regs, LTDC_IER, IER_LIE);
-
-   return 0;
-}
-
-static void ltdc_crtc_disable_vblank(struct drm_crtc *crtc)
-{
-   struct ltdc_device *ldev = crtc_to_ltdc(crtc);
-
-   DRM_DEBUG_DRIVER("\n");
-   reg_clear(ldev->regs, LTDC_IER, IER_LIE);
-}
-
-bool ltdc_crtc_scanoutpos(struct drm_device *ddev, unsigned int pipe,
- bool in_vblank_irq, int *vpos, int *hpos,
- ktime_t *stime, ktime_t *etime,
- const struct drm_display_mode *mode)
+static bool ltdc_crtc_get_scanout_position(struct drm_crtc *crtc,
+  bool in_vblank_irq,
+  int *vpos, int *hpos,
+  ktime_t *stime, ktime_t *etime,
+  const struct drm_display_mode *mode)
 {
+   struct drm_device *ddev = crtc->dev;
struct ltdc_device *ldev = ddev->dev_private;
int line, vactive_start, vactive_end, vtotal;

@@ -710,6 +685,34 @@ bool ltdc_crtc_scanoutpos(struct drm_device *ddev, 
unsigned int pipe,
return true;
 }

+static const struct drm_crtc_helper_funcs ltdc_crtc_helper_funcs = {
+   .mode_valid = ltdc_crtc_mode_valid,
+   .mode_fixup = ltdc_crtc_mode_fixup,
+   .mode_set_nofb = ltdc_crtc_mode_set_nofb,
+   .atomic_flush = ltdc_crtc_atomic_flush,
+   .atomic_enable = ltdc_crtc_atomic_enable,
+   .atomic_disable = ltdc_crtc_atomic_disable,
+   .get_scanout_position = ltdc_crtc_get_scanout_position,
+};
+
+static int ltdc_crtc_enable_vblank(struct drm_crtc *crtc)
+{
+   struct ltdc_device *ldev = crtc_to_ltdc(crtc);
+
+   DRM_DEBUG_DRIVER("\n");
+   reg_set(ldev->regs, LTDC_IER, IER_LIE);
+
+   return 0;
+}
+
+static void ltdc_crtc_disable_vblank(struct drm_crtc *crtc)
+{
+   struct ltdc_device *ldev = crtc_to_ltdc(crtc);
+
+   DRM_DEBUG_DRIVER("\n");
+   reg_clear(ldev->regs, LTDC_IER, IER_LIE);
+}
+
 static const struct drm_crtc_funcs ltdc_crtc_funcs = {
.destroy = drm_crtc_cleanup,
.set_config = drm_atomic_helper_set_config,
diff --git a/drivers/gpu/drm/stm/ltdc.h b/drivers/gpu/drm/stm/ltdc.h
index a1ad0ae3b006..c5467d74e707 100644
--- a/drivers/gpu/drm/stm/ltdc.h
+++ b/drivers/gpu/drm/stm/ltdc.h
@@ -39,11 +39,6 @@ struct ltdc_device {
struct drm_atomic_state *suspend_state;
 };

-bool ltdc_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe,
- bool in_vblank_irq, int *vpos, int *hpos,
- ktime_t *stime, ktime_t *etime,
- const struct drm_display_mode *mode);
-
 int ltdc_load(struct drm_device *ddev);
 void ltdc_unload(struct drm_device *ddev);
 void ltdc_suspend(struct drm_device *ddev);


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 09/23] drm: Remove struct drm_driver.get_scanout_position()

2020-01-14 Thread Yannick FERTRE
Thanks for the patch.

Tested-by: Yannick Fertré 

BR
Yannick Fertré


On 1/10/20 10:21 AM, Thomas Zimmermann wrote:

All users of struct drm_driver.get_scanout_position() have been
covnerted to the respective CRTC helper function. Remove the callback
from struct drm_driver.

Signed-off-by: Thomas Zimmermann 

---
 drivers/gpu/drm/drm_vblank.c | 13 ++---
 include/drm/drm_drv.h| 52 
 2 files changed, 2 insertions(+), 63 deletions(-)

diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index c12f0b333e14..b84065911d69 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -633,8 +633,7 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct 
drm_device *dev,
}

/* Scanout position query not supported? Should not happen. */
-   if (!dev->driver->get_scanout_position ||
-   !crtc->helper_private->get_scanout_position) {
+   if (!crtc->helper_private->get_scanout_position) {
DRM_ERROR("Called from CRTC w/o get_scanout_position()!?\n");
return false;
}
@@ -666,17 +665,9 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct 
drm_device *dev,
 * Get vertical and horizontal scanout position vpos, hpos,
 * and bounding timestamps stime, etime, pre/post query.
 */
-   if (crtc->helper_private->get_scanout_position) {
-   vbl_status =
-   crtc->helper_private->get_scanout_position(
+   vbl_status = crtc->helper_private->get_scanout_position(
crtc, in_vblank_irq, , ,
, , mode);
-   } else {
-   vbl_status =
-   dev->driver->get_scanout_position(
-   dev, pipe, in_vblank_irq, ,
-   , , , mode);
-   }

/* Return as no-op if scanout query unsupported or failed. */
if (!vbl_status) {
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index d0049e5786fc..b704e252f3b2 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -318,58 +318,6 @@ struct drm_driver {
 */
void (*disable_vblank) (struct drm_device *dev, unsigned int pipe);

-   /**
-* @get_scanout_position:
-*
-* Called by vblank timestamping code.
-*
-* Returns the current display scanout position from a crtc, and an
-* optional accurate ktime_get() timestamp of when position was
-* measured. Note that this is a helper callback which is only used if a
-* driver uses drm_calc_vbltimestamp_from_scanoutpos() for the
-* @get_vblank_timestamp callback.
-*
-* Parameters:
-*
-* dev:
-* DRM device.
-* pipe:
-* Id of the crtc to query.
-* in_vblank_irq:
-* True when called from drm_crtc_handle_vblank().  Some drivers
-* need to apply some workarounds for gpu-specific vblank irq quirks
-* if flag is set.
-* vpos:
-* Target location for current vertical scanout position.
-* hpos:
-* Target location for current horizontal scanout position.
-* stime:
-* Target location for timestamp taken immediately before
-* scanout position query. Can be NULL to skip timestamp.
-* etime:
-* Target location for timestamp taken immediately after
-* scanout position query. Can be NULL to skip timestamp.
-* mode:
-* Current display timings.
-*
-* Returns vpos as a positive number while in active scanout area.
-* Returns vpos as a negative number inside vblank, counting the number
-* of scanlines to go until end of vblank, e.g., -1 means "one scanline
-* until start of active scanout / end of vblank."
-*
-* Returns:
-*
-* True on success, false if a reliable scanout position counter could
-* not be read out.
-*
-* This is deprecated and should not be used by new drivers.
-* Use _crtc_helper_funcs.get_scanout_position instead.
-*/
-   bool (*get_scanout_position) (struct drm_device *dev, unsigned int pipe,
- bool in_vblank_irq, int *vpos, int *hpos,
- ktime_t *stime, ktime_t *etime,
- const struct drm_display_mode *mode);
-
/**
 * @get_vblank_timestamp:
 *


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 01/23] drm: Add get_scanout_position() to struct drm_crtc_helper_funcs

2020-01-14 Thread Yannick FERTRE
Thanks for the patch.

Tested-by: Yannick Fertré 

BR
Yannick Fertré


On 1/10/20 10:21 AM, Thomas Zimmermann wrote:

The new callback get_scanout_position() reads the current location of
the scanout process. The operation is currentyl located in struct
drm_driver, but really belongs to the CRTC. Drivers will be converted
in separate patches.

Signed-off-by: Thomas Zimmermann 

---
 drivers/gpu/drm/drm_vblank.c | 24 
 include/drm/drm_drv.h|  7 +---
 include/drm/drm_modeset_helper_vtables.h | 47 
 3 files changed, 65 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 1659b13b178c..c12f0b333e14 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 

@@ -590,7 +591,7 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants);
  * Implements calculation of exact vblank timestamps from given 
drm_display_mode
  * timings and current video scanout position of a CRTC. This can be directly
  * used as the _driver.get_vblank_timestamp implementation of a kms driver
- * if _driver.get_scanout_position is implemented.
+ * if _crtc_helper_funcs.get_scanout_position is implemented.
  *
  * The current implementation only handles standard video modes. For double 
scan
  * and interlaced modes the driver is supposed to adjust the hardware mode
@@ -632,8 +633,9 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct 
drm_device *dev,
}

/* Scanout position query not supported? Should not happen. */
-   if (!dev->driver->get_scanout_position) {
-   DRM_ERROR("Called from driver w/o get_scanout_position()!?\n");
+   if (!dev->driver->get_scanout_position ||
+   !crtc->helper_private->get_scanout_position) {
+   DRM_ERROR("Called from CRTC w/o get_scanout_position()!?\n");
return false;
}

@@ -664,11 +666,17 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct 
drm_device *dev,
 * Get vertical and horizontal scanout position vpos, hpos,
 * and bounding timestamps stime, etime, pre/post query.
 */
-   vbl_status = dev->driver->get_scanout_position(dev, pipe,
-  in_vblank_irq,
-  , ,
-  , ,
-  mode);
+   if (crtc->helper_private->get_scanout_position) {
+   vbl_status =
+   crtc->helper_private->get_scanout_position(
+   crtc, in_vblank_irq, , ,
+   , , mode);
+   } else {
+   vbl_status =
+   dev->driver->get_scanout_position(
+   dev, pipe, in_vblank_irq, ,
+   , , , mode);
+   }

/* Return as no-op if scanout query unsupported or failed. */
if (!vbl_status) {
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index cf13470810a5..d0049e5786fc 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -362,11 +362,8 @@ struct drm_driver {
 * True on success, false if a reliable scanout position counter could
 * not be read out.
 *
-* FIXME:
-*
-* Since this is a helper to implement @get_vblank_timestamp, we should
-* move it to  drm_crtc_helper_funcs, like all the other
-* helper-internal hooks.
+* This is deprecated and should not be used by new drivers.
+* Use _crtc_helper_funcs.get_scanout_position instead.
 */
bool (*get_scanout_position) (struct drm_device *dev, unsigned int pipe,
  bool in_vblank_irq, int *vpos, int *hpos,
diff --git a/include/drm/drm_modeset_helper_vtables.h 
b/include/drm/drm_modeset_helper_vtables.h
index 5a87f1bd7a3f..e398512bfd5f 100644
--- a/include/drm/drm_modeset_helper_vtables.h
+++ b/include/drm/drm_modeset_helper_vtables.h
@@ -450,6 +450,53 @@ struct drm_crtc_helper_funcs {
 */
void (*atomic_disable)(struct drm_crtc *crtc,
   struct drm_crtc_state *old_crtc_state);
+
+   /**
+* @get_scanout_position:
+*
+* Called by vblank timestamping code.
+*
+* Returns the current display scanout position from a CRTC and an
+* optional accurate ktime_get() timestamp of when the position was
+* measured. Note that this is a helper callback which is only used
+* if a driver uses 

Re: [PATCH] drm/bridge/synopsys: dsi: use mipi_dsi_device to find panel or bridge

2019-12-20 Thread Yannick FERTRE
Hello Heiko,
I test with success your patch on a board stm32mp1 with a panel raydium 
rm68200.
I need more time to test with a HDMI bridge  like ad7533.

Best regards

Yannick Fertré



On 12/17/19 11:41 PM, Heiko Stuebner wrote:
> From: Heiko Stuebner 
>
> Right now the dsi driver uses drm_of_find_panel_or_bridge() to find a
> connected panel or bridge. But this requires an of-graph connection
> between the dsi-host and dsi-device, where normal bindings for regular
> panels just expect the dsi device to be a subnode of the actual dsi host
> not requiring ports.
>
> drm_of_find_panel_or_bridge is used to find panel/bridge under the actual
> device-node of the dsi device, but as this happens in the dsi_host_attach
> callback we already have the dsi-device and its device-node available and
> therefore can just call the relevant panel+bridge functions ourself,
> making it work as well in setups without port-connections.
>
> Tested on a Rockchip px30 single-dsi with panels form Leadtek and Xinpeng
> as well on Gru-Scarlet (rk3399) with dual-dsi (and thus port-connections
> to both dsi controllers) connected to the Innotek display variant.
>
> changes in v2:
> - rework commit message, rereading what I had written was just too
>cringe-worthy ;-)
>
> Signed-off-by: Heiko Stuebner 
> ---
>   drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 17 ++---
>   1 file changed, 10 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
> b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> index 981d532cdd59..4b4961e7c680 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> @@ -26,6 +26,7 @@
>   #include 
>   #include 
>   #include 
> +#include 
>   #include 
>   #include 
>   
> @@ -310,16 +311,16 @@ static int dw_mipi_dsi_host_attach(struct mipi_dsi_host 
> *host,
>   dsi->format = device->format;
>   dsi->mode_flags = device->mode_flags;
>   
> - ret = drm_of_find_panel_or_bridge(host->dev->of_node, 1, 0,
> -   , );
> - if (ret)
> - return ret;
> -
> - if (panel) {
> + panel = of_drm_find_panel(device->dev.of_node);
> + if (!IS_ERR(panel)) {
>   bridge = drm_panel_bridge_add_typed(panel,
>   DRM_MODE_CONNECTOR_DSI);
>   if (IS_ERR(bridge))
>   return PTR_ERR(bridge);
> + } else {
> + bridge = of_drm_find_bridge(device->dev.of_node);
> + if (!bridge)
> + return -EPROBE_DEFER;
>   }
>   
>   dsi->panel_bridge = bridge;
> @@ -340,6 +341,7 @@ static int dw_mipi_dsi_host_detach(struct mipi_dsi_host 
> *host,
>   {
>   struct dw_mipi_dsi *dsi = host_to_dsi(host);
>   const struct dw_mipi_dsi_plat_data *pdata = dsi->plat_data;
> + struct drm_bridge *bridge;
>   int ret;
>   
>   if (pdata->host_ops && pdata->host_ops->detach) {
> @@ -348,7 +350,8 @@ static int dw_mipi_dsi_host_detach(struct mipi_dsi_host 
> *host,
>   return ret;
>   }
>   
> - drm_of_panel_bridge_remove(host->dev->of_node, 1, 0);
> + bridge = of_drm_find_bridge(device->dev.of_node);
> + drm_panel_bridge_remove(bridge);
>   
>   drm_bridge_remove(>bridge);
>   
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] dt-bindings: display: Convert raydium, rm68200 panel to DT schema

2019-12-20 Thread Yannick Fertre
From: Yannick Fertré 

Convert the raydium,rm68200 panel binding to DT schema.

Signed-off-by: Yannick Fertre 
---
 .../bindings/display/panel/raydium,rm68200.txt | 25 -
 .../bindings/display/panel/raydium,rm68200.yaml| 61 ++
 2 files changed, 61 insertions(+), 25 deletions(-)
 delete mode 100644 
Documentation/devicetree/bindings/display/panel/raydium,rm68200.txt
 create mode 100644 
Documentation/devicetree/bindings/display/panel/raydium,rm68200.yaml

diff --git 
a/Documentation/devicetree/bindings/display/panel/raydium,rm68200.txt 
b/Documentation/devicetree/bindings/display/panel/raydium,rm68200.txt
deleted file mode 100644
index cbb79ef..000
--- a/Documentation/devicetree/bindings/display/panel/raydium,rm68200.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-Raydium Semiconductor Corporation RM68200 5.5" 720p MIPI-DSI TFT LCD panel
-
-The Raydium Semiconductor Corporation RM68200 is a 5.5" 720x1280 TFT LCD
-panel connected using a MIPI-DSI video interface.
-
-Required properties:
-  - compatible: "raydium,rm68200"
-  - reg: the virtual channel number of a DSI peripheral
-
-Optional properties:
-  - reset-gpios: a GPIO spec for the reset pin (active low).
-  - power-supply: phandle of the regulator that provides the supply voltage.
-  - backlight: phandle of the backlight device attached to the panel.
-
-Example:
- {
-   ...
-   panel@0 {
-   compatible = "raydium,rm68200";
-   reg = <0>;
-   reset-gpios = < 15 GPIO_ACTIVE_LOW>;
-   power-supply = <>;
-   backlight = <_backlight>;
-   };
-};
diff --git 
a/Documentation/devicetree/bindings/display/panel/raydium,rm68200.yaml 
b/Documentation/devicetree/bindings/display/panel/raydium,rm68200.yaml
new file mode 100644
index 000..ffe549f
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/raydium,rm68200.yaml
@@ -0,0 +1,61 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/raydium,rm68200.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Raydium RM68200 5.5" 720x1280 panel
+
+maintainers:
+  - Yannick Fertre 
+
+description:
+  The Raydium Semiconductor Corporation RM68200 is a 5.5" 720x1280 TFT LCD
+  panel connected using a MIPI-DSI video interface.
+
+properties:
+  compatible:
+const: raydium,rm68200
+
+  power-supply:
+maxItems: 1
+
+  reset-gpios:
+maxItems: 1
+
+  backlight:
+maxItems: 1
+
+  port:
+maxItems: 1
+
+  reg:
+maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - port
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+display0: display {
+  #address-cells = <1>;
+  #size-cells = <0>;
+  panel {
+compatible = "raydium,rm68200";
+reg = <0>;
+reset-gpios = < 15 GPIO_ACTIVE_LOW>;
+power-supply = <>;
+port {
+  panel_in_dsi: endpoint {
+remote-endpoint = <_out_dsi>;
+  };
+};
+  };
+};
+
+...
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] dt-bindings: display: Convert orisetech, otm8009a panel to DT schema

2019-12-20 Thread Yannick Fertre
From: Yannick Fertré 

Convert the orisetech,otm8009a panel binding to DT schema.

Signed-off-by: Yannick Fertre 
---
 .../bindings/display/panel/orisetech,otm8009a.txt  | 23 
 .../bindings/display/panel/orisetech,otm8009a.yaml | 62 ++
 2 files changed, 62 insertions(+), 23 deletions(-)
 delete mode 100644 
Documentation/devicetree/bindings/display/panel/orisetech,otm8009a.txt
 create mode 100644 
Documentation/devicetree/bindings/display/panel/orisetech,otm8009a.yaml

diff --git 
a/Documentation/devicetree/bindings/display/panel/orisetech,otm8009a.txt 
b/Documentation/devicetree/bindings/display/panel/orisetech,otm8009a.txt
deleted file mode 100644
index 203b03e..000
--- a/Documentation/devicetree/bindings/display/panel/orisetech,otm8009a.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-Orise Tech OTM8009A 3.97" 480x800 TFT LCD panel (MIPI-DSI video mode)
-
-The Orise Tech OTM8009A is a 3.97" 480x800 TFT LCD panel connected using
-a MIPI-DSI video interface. Its backlight is managed through the DSI link.
-
-Required properties:
-  - compatible: "orisetech,otm8009a"
-  - reg: the virtual channel number of a DSI peripheral
-
-Optional properties:
-  - reset-gpios: a GPIO spec for the reset pin (active low).
-  - power-supply: phandle of the regulator that provides the supply voltage.
-
-Example:
- {
-   ...
-   panel@0 {
-   compatible = "orisetech,otm8009a";
-   reg = <0>;
-   reset-gpios = < 7 GPIO_ACTIVE_LOW>;
-   power-supply = <>;
-   };
-};
diff --git 
a/Documentation/devicetree/bindings/display/panel/orisetech,otm8009a.yaml 
b/Documentation/devicetree/bindings/display/panel/orisetech,otm8009a.yaml
new file mode 100644
index 000..02bd69e
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/orisetech,otm8009a.yaml
@@ -0,0 +1,62 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/orisetech,otm8009a.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Orise Tech OTM8009A 3.97" 480x800 panel
+
+maintainers:
+  - Yannick Fertre 
+
+description:
+  The Orise Tech OTM8009A is a 3.97" 480x800 TFT LCD panel connected using
+  a MIPI-DSI video interface. Its backlight is managed through the DSI link.
+
+properties:
+  compatible:
+const: orisetech,otm8009a
+
+  power-supply:
+maxItems: 1
+
+  reset-gpios:
+maxItems: 1
+
+  backlight:
+maxItems: 1
+
+  port:
+maxItems: 1
+
+  reg:
+maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - port
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+display1: display {
+  #address-cells = <1>;
+  #size-cells = <0>;
+  panel {
+compatible = "orisetech,otm8009a";
+reg = <0>;
+reset-gpios = < 7 GPIO_ACTIVE_LOW>;
+power-supply = <>;
+
+port {
+  panel_in_dsi: endpoint {
+remote-endpoint = <_out_dsi>;
+  };
+};
+  };
+};
+
+...
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] Input: goodix - support gt9147 touchpanel

2019-11-27 Thread Yannick Fertre
From: Yannick Fertré 

Add support for it by adding compatible and supported chip data
(default settings used).
The chip data on GT9147 is similar to GT912, like
- config data register has 0x8047 address
- config data register max len is 240
- config data checksum has 8-bit

Signed-off-by: Yannick Fertre 
---
 drivers/input/touchscreen/goodix.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/input/touchscreen/goodix.c 
b/drivers/input/touchscreen/goodix.c
index fb43aa7..b470773 100644
--- a/drivers/input/touchscreen/goodix.c
+++ b/drivers/input/touchscreen/goodix.c
@@ -1045,6 +1045,7 @@ static const struct of_device_id goodix_of_match[] = {
{ .compatible = "goodix,gt9271" },
{ .compatible = "goodix,gt928" },
{ .compatible = "goodix,gt967" },
+   { .compatible = "goodix,gt9147",},
{ }
 };
 MODULE_DEVICE_TABLE(of, goodix_of_match);
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH] Input: goodix: request_irq: convert gpio to irq

2019-11-27 Thread Yannick Fertre
From: Yannick Fertré 

Convert gpio to irq if not already done by gpio lib.

Signed-off-by: Yannick Fertré 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -392,6 +393,13 @@ static void goodix_free_irq(struct goodix_ts_data *ts)
 
 static int goodix_request_irq(struct goodix_ts_data *ts)
 {
+   int gpio;
+
+   gpio = desc_to_gpio(ts->gpiod_int);
+
+   if (gpio_is_valid(gpio))
+   ts->client->irq = gpio_to_irq(gpio);
+
return devm_request_threaded_irq(>client->dev, ts->client->irq,
 NULL, goodix_ts_irq_handler,
 ts->irq_flags, ts->client->name, ts);
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH] drm/stm: ltdc: move pinctrl to encoder mode set

2019-11-27 Thread Yannick Fertre
From: Yannick Fertré 

The pin control must be set to default as soon as possible to
establish a good video link between tv & bridge hdmi
(encoder mode set is call before encoder enable).

Signed-off-by: Yannick Fertre 
---
 drivers/gpu/drm/stm/ltdc.c | 24 ++--
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index 49ef406..dba8e7f 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -435,9 +435,6 @@ static void ltdc_crtc_atomic_enable(struct drm_crtc *crtc,
/* Commit shadow registers = update planes at next vblank */
reg_set(ldev->regs, LTDC_SRCR, SRCR_VBR);
 
-   /* Enable LTDC */
-   reg_set(ldev->regs, LTDC_GCR, GCR_LTDCEN);
-
drm_crtc_vblank_on(crtc);
 }
 
@@ -451,9 +448,6 @@ static void ltdc_crtc_atomic_disable(struct drm_crtc *crtc,
 
drm_crtc_vblank_off(crtc);
 
-   /* disable LTDC */
-   reg_clear(ldev->regs, LTDC_GCR, GCR_LTDCEN);
-
/* disable IRQ */
reg_clear(ldev->regs, LTDC_IER, IER_RRIE | IER_FUIE | IER_TERRIE);
 
@@ -1042,9 +1036,13 @@ static const struct drm_encoder_funcs ltdc_encoder_funcs 
= {
 static void ltdc_encoder_disable(struct drm_encoder *encoder)
 {
struct drm_device *ddev = encoder->dev;
+   struct ltdc_device *ldev = ddev->dev_private;
 
DRM_DEBUG_DRIVER("\n");
 
+   /* Disable LTDC */
+   reg_clear(ldev->regs, LTDC_GCR, GCR_LTDCEN);
+
/* Set to sleep state the pinctrl whatever type of encoder */
pinctrl_pm_select_sleep_state(ddev->dev);
 }
@@ -1052,6 +1050,19 @@ static void ltdc_encoder_disable(struct drm_encoder 
*encoder)
 static void ltdc_encoder_enable(struct drm_encoder *encoder)
 {
struct drm_device *ddev = encoder->dev;
+   struct ltdc_device *ldev = ddev->dev_private;
+
+   DRM_DEBUG_DRIVER("\n");
+
+   /* Enable LTDC */
+   reg_set(ldev->regs, LTDC_GCR, GCR_LTDCEN);
+}
+
+static void ltdc_encoder_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+   struct drm_device *ddev = encoder->dev;
 
DRM_DEBUG_DRIVER("\n");
 
@@ -1067,6 +1078,7 @@ static void ltdc_encoder_enable(struct drm_encoder 
*encoder)
 static const struct drm_encoder_helper_funcs ltdc_encoder_helper_funcs = {
.disable = ltdc_encoder_disable,
.enable = ltdc_encoder_enable,
+   .mode_set = ltdc_encoder_mode_set,
 };
 
 static int ltdc_encoder_init(struct drm_device *ddev, struct drm_bridge 
*bridge)
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH] drm/bridge/synopsys: dsi: read status error during transfer

2019-11-27 Thread Yannick Fertre
From: Yannick Fertré 

Read the DSI_INT_ST1 status register to check if
errors occur while reading/writing a command to panel.
In case of error, the transfer is retried 3 times.

Signed-off-by: Yannick Fertre 
---
 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 99 +++
 1 file changed, 85 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index b6e793b..cc806ba 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -212,6 +212,20 @@
 
 #define DSI_INT_ST00xbc
 #define DSI_INT_ST10xc0
+#define GPRXE  BIT(12)
+#define GPRDE  BIT(11)
+#define GPTXE  BIT(10)
+#define GPWRE  BIT(9)
+#define GCWRE  BIT(8)
+#define DPIPLDWE   BIT(7)
+#define EOTPE  BIT(6)
+#define PSEBIT(5)
+#define CRCE   BIT(4)
+#define ECCME  BIT(3)
+#define ECCSE  BIT(2)
+#define TOLPRX BIT(1)
+#define TOHSTX BIT(0)
+
 #define DSI_INT_MSK0   0xc4
 #define DSI_INT_MSK1   0xc8
 
@@ -397,6 +411,42 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct 
dw_mipi_dsi *dsi, u32 hdr_val)
return 0;
 }
 
+static int dw_mipi_dsi_read_status(struct dw_mipi_dsi *dsi)
+{
+   u32 val;
+
+   val = dsi_read(dsi, DSI_INT_ST1);
+
+   if (val & GPRXE)
+   DRM_DEBUG_DRIVER("DSI Generic payload receive error\n");
+   if (val & GPRDE)
+   DRM_DEBUG_DRIVER("DSI Generic payload read error\n");
+   if (val & GPTXE)
+   DRM_DEBUG_DRIVER("DSI Generic payload transmit error\n");
+   if (val & GPWRE)
+   DRM_DEBUG_DRIVER("DSI Generic payload write error\n");
+   if (val & GCWRE)
+   DRM_DEBUG_DRIVER("DSI Generic command write error\n");
+   if (val & DPIPLDWE)
+   DRM_DEBUG_DRIVER("DSI DPI payload write error\n");
+   if (val & EOTPE)
+   DRM_DEBUG_DRIVER("DSI EoTp error\n");
+   if (val & PSE)
+   DRM_DEBUG_DRIVER("DSI Packet size error\n");
+   if (val & CRCE)
+   DRM_DEBUG_DRIVER("DSI CRC error\n");
+   if (val & ECCME)
+   DRM_DEBUG_DRIVER("DSI ECC multi-bit error\n");
+   if (val & ECCSE)
+   DRM_DEBUG_DRIVER("DSI ECC single-bit error\n");
+   if (val & TOLPRX)
+   DRM_DEBUG_DRIVER("DSI Timeout low-power reception\n");
+   if (val & TOHSTX)
+   DRM_DEBUG_DRIVER("DSI Timeout high-speed transmission\n");
+
+   return val;
+}
+
 static int dw_mipi_dsi_write(struct dw_mipi_dsi *dsi,
 const struct mipi_dsi_packet *packet)
 {
@@ -426,6 +476,12 @@ static int dw_mipi_dsi_write(struct dw_mipi_dsi *dsi,
"failed to get available write payload FIFO\n");
return ret;
}
+
+   val = dw_mipi_dsi_read_status(dsi);
+   if (val) {
+   dev_err(dsi->dev, "dsi status error 0x%0x\n", val);
+   return -EINVAL;
+   }
}
 
word = 0;
@@ -459,6 +515,12 @@ static int dw_mipi_dsi_read(struct dw_mipi_dsi *dsi,
return ret;
}
 
+   val = dw_mipi_dsi_read_status(dsi);
+   if (val) {
+   dev_err(dsi->dev, "dsi status error 0x%0x\n", val);
+   return -EINVAL;
+   }
+
val = dsi_read(dsi, DSI_GEN_PLD_DATA);
for (j = 0; j < 4 && j + i < len; j++)
buf[i + j] = val >> (8 * j);
@@ -473,6 +535,7 @@ static ssize_t dw_mipi_dsi_host_transfer(struct 
mipi_dsi_host *host,
struct dw_mipi_dsi *dsi = host_to_dsi(host);
struct mipi_dsi_packet packet;
int ret, nb_bytes;
+   int retry = 3;
 
ret = mipi_dsi_create_packet(, msg);
if (ret) {
@@ -484,24 +547,32 @@ static ssize_t dw_mipi_dsi_host_transfer(struct 
mipi_dsi_host *host,
if (dsi->slave)
dw_mipi_message_config(dsi->slave, msg);
 
-   ret = dw_mipi_dsi_write(dsi, );
-   if (ret)
-   return ret;
-   if (dsi->slave) {
-   ret = dw_mipi_dsi_write(dsi->slave, );
+   while (retry--) {
+   ret = dw_mipi_dsi_write(dsi, );
if (ret)
-   return ret;
-  

[PATCH] drm/bridge/synopsys: dsi: check post disable

2019-11-27 Thread Yannick Fertre
From: Yannick Fertré 

Some bridges did not registered the post_disable function.
To avoid a crash, check it before calling.

Signed-off-by: Yannick Fertre 
---
 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index cc806ba..1e37233 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -886,7 +886,8 @@ static void dw_mipi_dsi_bridge_post_disable(struct 
drm_bridge *bridge)
 * This needs to be fixed in the drm_bridge framework and the API
 * needs to be updated to manage our own call chains...
 */
-   dsi->panel_bridge->funcs->post_disable(dsi->panel_bridge);
+   if (dsi->panel_bridge->funcs->post_disable)
+   dsi->panel_bridge->funcs->post_disable(dsi->panel_bridge);
 
if (dsi->slave) {
dw_mipi_dsi_disable(dsi->slave);
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH] drm/bridge/synopsys: dsi: Use devm_platform_ioremap_resource() in __dw_mipi_dsi_probe()

2019-09-23 Thread Yannick FERTRE
Reviewed-by: Yannick Fertré 

Tested-by: Yannick Fertré 


Best regards

--
Yannick Fertré | TINA: 166 7152 | Tel: +33 244027152 | Mobile: +33 620600270
Microcontrollers and Digital ICs Group | Microcontrolleurs Division


On 9/21/19 8:20 PM, Markus Elfring wrote:

From: Markus Elfring 

Date: Sat, 21 Sep 2019 20:04:08 +0200

Simplify this function implementation by using a known wrapper function.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring 

---
 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index 675442bfc1bd..6ada149af9ef 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -981,7 +981,6 @@ __dw_mipi_dsi_probe(struct platform_device *pdev,
struct device *dev = >dev;
struct reset_control *apb_rst;
struct dw_mipi_dsi *dsi;
-   struct resource *res;
int ret;

dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
@@ -997,11 +996,7 @@ __dw_mipi_dsi_probe(struct platform_device *pdev,
}

if (!plat_data->base) {
-   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-   if (!res)
-   return ERR_PTR(-ENODEV);
-
-   dsi->base = devm_ioremap_resource(dev, res);
+   dsi->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(dsi->base))
return ERR_PTR(-ENODEV);

--
2.23.0



___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH v2 5/5] ARM: dts: stm32: remove phy-dsi-supply property on stm32mp157c-dk2 board

2019-08-02 Thread Yannick FERTRE
Hi Alexandre,

this patch can be abandoned.

BR

-- 
Yannick Fertré | TINA: 166 7152 | Tel: +33 244027152 | Mobile: +33 620600270
Microcontrollers and Digital ICs Group | Microcontrolleurs Division
On 5/10/19 4:20 PM, Yannick Fertré wrote:
> This property is already defined into stm32mp157c.dtsi file.
>
> Signed-off-by: Yannick Fertré 
> ---
>   arch/arm/boot/dts/stm32mp157c-dk2.dts | 1 -
>   1 file changed, 1 deletion(-)
>
> diff --git a/arch/arm/boot/dts/stm32mp157c-dk2.dts 
> b/arch/arm/boot/dts/stm32mp157c-dk2.dts
> index 020ea0f..09f6e7b 100644
> --- a/arch/arm/boot/dts/stm32mp157c-dk2.dts
> +++ b/arch/arm/boot/dts/stm32mp157c-dk2.dts
> @@ -17,7 +17,6 @@
>   #address-cells = <1>;
>   #size-cells = <0>;
>   status = "okay";
> - phy-dsi-supply = <>;
>   
>   ports {
>   #address-cells = <1>;
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH v2 4/5] ARM: dts: stm32: move fixe regulators reg11 & reg18

2019-08-02 Thread Yannick FERTRE
Hi Alexandre,

this patch can be abandoned.

BR

-- 
Yannick Fertré | TINA: 166 7152 | Tel: +33 244027152 | Mobile: +33 620600270
Microcontrollers and Digital ICs Group | Microcontrolleurs Division

On 5/10/19 4:20 PM, Yannick Fertré wrote:
> Move regulators reg11 & reg18 from device-tree files stm32mp157c-ed1.dts
> & stm32mp157c-dk2.dts to file stm32mp157c.dtsi.
>
> Signed-off-by: Yannick Fertré 
> ---
>   arch/arm/boot/dts/stm32mp157c-dk2.dts |  8 
>   arch/arm/boot/dts/stm32mp157c-ed1.dts | 16 
>   arch/arm/boot/dts/stm32mp157c.dtsi| 16 
>   3 files changed, 16 insertions(+), 24 deletions(-)
>
> diff --git a/arch/arm/boot/dts/stm32mp157c-dk2.dts 
> b/arch/arm/boot/dts/stm32mp157c-dk2.dts
> index 20ea601..020ea0f 100644
> --- a/arch/arm/boot/dts/stm32mp157c-dk2.dts
> +++ b/arch/arm/boot/dts/stm32mp157c-dk2.dts
> @@ -11,14 +11,6 @@
>   / {
>   model = "STMicroelectronics STM32MP157C-DK2 Discovery Board";
>   compatible = "st,stm32mp157c-dk2", "st,stm32mp157";
> -
> - reg18: reg18 {
> - compatible = "regulator-fixed";
> - regulator-name = "reg18";
> - regulator-min-microvolt = <180>;
> - regulator-max-microvolt = <180>;
> - regulator-always-on;
> - };
>   };
>   
>{
> diff --git a/arch/arm/boot/dts/stm32mp157c-ed1.dts 
> b/arch/arm/boot/dts/stm32mp157c-ed1.dts
> index 62a8c78..f41189c 100644
> --- a/arch/arm/boot/dts/stm32mp157c-ed1.dts
> +++ b/arch/arm/boot/dts/stm32mp157c-ed1.dts
> @@ -27,22 +27,6 @@
>   serial0 = 
>   };
>   
> - reg11: reg11 {
> - compatible = "regulator-fixed";
> - regulator-name = "reg11";
> - regulator-min-microvolt = <110>;
> - regulator-max-microvolt = <110>;
> - regulator-always-on;
> - };
> -
> - reg18: reg18 {
> - compatible = "regulator-fixed";
> - regulator-name = "reg18";
> - regulator-min-microvolt = <180>;
> - regulator-max-microvolt = <180>;
> - regulator-always-on;
> - };
> -
>   sd_switch: regulator-sd_switch {
>   compatible = "regulator-gpio";
>   regulator-name = "sd_switch";
> diff --git a/arch/arm/boot/dts/stm32mp157c.dtsi 
> b/arch/arm/boot/dts/stm32mp157c.dtsi
> index 6b14f1e..aaac51cd 100644
> --- a/arch/arm/boot/dts/stm32mp157c.dtsi
> +++ b/arch/arm/boot/dts/stm32mp157c.dtsi
> @@ -11,6 +11,22 @@
>   #address-cells = <1>;
>   #size-cells = <1>;
>   
> + reg11: reg11 {
> + compatible = "regulator-fixed";
> + regulator-name = "reg11";
> + regulator-min-microvolt = <110>;
> + regulator-max-microvolt = <110>;
> + regulator-always-on;
> + };
> +
> + reg18: reg18 {
> + compatible = "regulator-fixed";
> + regulator-name = "reg18";
> + regulator-min-microvolt = <180>;
> + regulator-max-microvolt = <180>;
> + regulator-always-on;
> + };
> +
>   cpus {
>   #address-cells = <1>;
>   #size-cells = <0>;
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH v2 3/5] ARM: dts: stm32: add phy-dsi-supply property on stm32mp157c

2019-08-02 Thread Yannick FERTRE
Hi Alexandre,

this patch can be abandoned.

BR

-- 
Yannick Fertré | TINA: 166 7152 | Tel: +33 244027152 | Mobile: +33 620600270
Microcontrollers and Digital ICs Group | Microcontrolleurs Division


On 5/10/19 4:20 PM, Yannick Fertré wrote:

> The dsi physical layer is powered by the 1v8 power controller supply.
>
> Signed-off-by: Yannick Fertré 
> ---
>   arch/arm/boot/dts/stm32mp157c.dtsi | 1 +
>   1 file changed, 1 insertion(+)
>
> diff --git a/arch/arm/boot/dts/stm32mp157c.dtsi 
> b/arch/arm/boot/dts/stm32mp157c.dtsi
> index 2afeee6..6b14f1e 100644
> --- a/arch/arm/boot/dts/stm32mp157c.dtsi
> +++ b/arch/arm/boot/dts/stm32mp157c.dtsi
> @@ -1156,6 +1156,7 @@
>   clock-names = "pclk", "ref", "px_clk";
>   resets = < DSI_R>;
>   reset-names = "apb";
> + phy-dsi-supply = <>;
>   status = "disabled";
>   };
>   
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH 1/3] drm/stm: drv: fix suspend/resume

2019-06-21 Thread Yannick FERTRE
Hi Emil,

The msm driver tests the return value & set state to NULL if no error is 
detected.

the ltdc driver tests the return value & force to suspend if an error is 
detected.

It's not exactly the same.

Best regards


-- 
Yannick Fertré | TINA: 166 7152 | Tel: +33 244027152 | Mobile: +33 620600270
Microcontrollers and Digital ICs Group | Microcontrolleurs Division

On 6/20/19 7:12 PM, Emil Velikov wrote:
> Hi Yannick,
>
> On Mon, 17 Jun 2019 at 08:18, Yannick Fertré  wrote:
>
>> @@ -155,15 +154,17 @@ static __maybe_unused int drv_resume(struct device 
>> *dev)
>>  struct ltdc_device *ldev = ddev->dev_private;
>>  int ret;
>>
>> +   if (WARN_ON(!ldev->suspend_state))
>> +   return -ENOENT;
>> +
>>  pm_runtime_force_resume(dev);
>>  ret = drm_atomic_helper_resume(ddev, ldev->suspend_state);
>> -   if (ret) {
>> +   if (ret)
> Hmm the msm driver uses !ret here. Suspecting that you want the same,
> although I haven't checked in detail.
>
> HTH
> -Emil
-- 
Yannick Fertré | TINA: 166 7152 | Tel: +33 244027152 | Mobile: +33 620600270
Microcontrollers and Digital ICs Group | Microcontrolleurs Division
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH] drm/stm: ltdc: remove clk_round_rate comment

2019-05-13 Thread Yannick FERTRE
Dear Philippe,

you're right, clk_disable() & clk_enable() are necessary with STM32F4 
SOC (not for STM32MP1).

I'll revert this part of the patch.

Many thanks


-- 
Yannick Fertré | TINA: 166 7152 | Tel: +33 244027152 | Mobile: +33 620600270
Microcontrollers and Digital ICs Group | Microcontrolleurs Division

On 5/10/19 6:40 PM, Philippe CORNU wrote:
> Dear Yannick,
> Thank you for your patch,
>
> In your patch, you have removed clk_disable() & clk_enable().
> Could you please double confirm ?
>
> thanks
> Philippe :-)
>
>
> On 5/10/19 5:03 PM, Yannick Fertré wrote:
>> Clk_round_rate returns rounded clock without changing
>> the hardware in any way.
>> This function couldn't replace set_rate/get_rate calls.
>> Todo comment has been removed & a new log inserted.
>>
>> Signed-off-by: Yannick Fertré 
>> ---
>>drivers/gpu/drm/stm/ltdc.c | 10 +++---
>>1 file changed, 3 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
>> index 97912e2..2f8aa2e 100644
>> --- a/drivers/gpu/drm/stm/ltdc.c
>> +++ b/drivers/gpu/drm/stm/ltdc.c
>> @@ -507,20 +507,16 @@ static bool ltdc_crtc_mode_fixup(struct drm_crtc *crtc,
>>  struct ltdc_device *ldev = crtc_to_ltdc(crtc);
>>  int rate = mode->clock * 1000;
>>
>> -/*
>> - * TODO clk_round_rate() does not work yet. When ready, it can
>> - * be used instead of clk_set_rate() then clk_get_rate().
>> - */
>> -
>> -clk_disable(ldev->pixel_clk);
>>  if (clk_set_rate(ldev->pixel_clk, rate) < 0) {
>>  DRM_ERROR("Cannot set rate (%dHz) for pixel clk\n", rate);
>>  return false;
>>  }
>> -clk_enable(ldev->pixel_clk);
>>
>>  adjusted_mode->clock = clk_get_rate(ldev->pixel_clk) / 1000;
>>
>> +DRM_DEBUG_DRIVER("requested clock %dkHz, adjusted clock %dkHz\n",
>> + mode->clock, adjusted_mode->clock);
>> +
>>  return true;
>>}
>>
-- 
Yannick Fertré | TINA: 166 7152 | Tel: +33 244027152 | Mobile: +33 620600270
Microcontrollers and Digital ICs Group | Microcontrolleurs Division
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH] drm/stm: fix CONFIG_FB dependency

2019-03-08 Thread Yannick FERTRE
Reviewed-by: Yannick Fertré 



Arnd,
could you merge the patch?
I think that Benjamin could also merge it.

Best regards

Yannick Fertré


On 3/7/19 4:53 PM, Arnd Bergmann wrote:

The DRM_STM driver can be built independently of the framebuffer
layer, but it causes a Kconfig warning:

WARNING: unmet direct dependencies detected for FB_PROVIDE_GET_FB_UNMAPPED_AREA
  Depends on [n]: HAS_IOMEM [=y] && FB [=n]
  Selected by [y]:
  - DRM_STM [=y] && HAS_IOMEM [=y] && DRM [=y] && (ARCH_STM32 [=n] || 
ARCH_MULTIPLATFORM [=y])

Selecting FB_PROVIDE_GET_FB_UNMAPPED_AREA actually has no effect
if CONFIG_FB is disabled, so we can make it a conditional 'select'
instead.

Signed-off-by: Arnd Bergmann 
---
 drivers/gpu/drm/stm/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/stm/Kconfig b/drivers/gpu/drm/stm/Kconfig
index 35367ada3bc1..d15b10de1da6 100644
--- a/drivers/gpu/drm/stm/Kconfig
+++ b/drivers/gpu/drm/stm/Kconfig
@@ -6,7 +6,7 @@ config DRM_STM
select DRM_KMS_CMA_HELPER
select DRM_PANEL_BRIDGE
select VIDEOMODE_HELPERS
-   select FB_PROVIDE_GET_FB_UNMAPPED_AREA
+   select FB_PROVIDE_GET_FB_UNMAPPED_AREA if FB

help
  Enable support for the on-chip display controller on


--
Yannick Fertré | TINA: 166 7152 | Tel: +33 244027152 | Mobile: +33 620600270
Microcontrollers and Digital ICs Group | Microcontrolleurs Division
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  1   2   3   >