Re: [PATCH v5 2/3] drm/panel: Add Samsung S6D7AA0 panel controller driver

2023-05-23 Thread Artur Weber
Hi,

On 23/05/2023 20:02, Nathan Chancellor wrote:
> Hi Artur,
> 
> On Fri, May 19, 2023 at 07:03:53PM +0200, Artur Weber wrote:
>> Initial driver for S6D7AA0-controlled panels. Currently, the following
>> panels are supported:
>>
>>  - S6D7AA0-LSL080AL02 (Samsung Galaxy Tab 3 8.0)
>>  - S6D7AA0-LSL080AL03 (Samsung Galaxy Tab A 8.0 2015)
>>  - S6D7AA0-LTL101AT01 (Samsung Galaxy Tab A 9.7 2015)
>>
>> It should be possible to extend this driver to work with other panels
>> using this IC.
>>
>> Tested-by: Nikita Travkin  #ltl101at01
>> Signed-off-by: Artur Weber 
> 
> 
> 
> This change as commit 6810bb390282 ("drm/panel: Add Samsung S6D7AA0
> panel controller driver") in -next causes the following build errors
> with clang and GCC older than 8.x (the kernel supports back to GCC 5.1).
> 
> With clang:
> 
>   drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c:312:14: error: initializer 
> element is not a compile-time constant
>   .drm_mode = s6d7aa0_lsl080al02_mode,
>   ^~~
>   drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c:415:14: error: initializer 
> element is not a compile-time constant
>   .drm_mode = s6d7aa0_lsl080al03_mode,
>   ^~~
>   drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c:443:14: error: initializer 
> element is not a compile-time constant
>   .drm_mode = s6d7aa0_ltl101at01_mode,
>   ^~~
>   3 errors generated.
> 
> With GCC:
> 
>   drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c:312:14: error: initializer 
> element is not constant
> .drm_mode = s6d7aa0_lsl080al02_mode,
> ^~~
>   drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c:312:14: note: (near 
> initialization for 's6d7aa0_lsl080al02_desc.drm_mode')
>   drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c:415:14: error: initializer 
> element is not constant
> .drm_mode = s6d7aa0_lsl080al03_mode,
> ^~~
>   drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c:415:14: note: (near 
> initialization for 's6d7aa0_lsl080al03_desc.drm_mode')
>   drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c:443:14: error: initializer 
> element is not constant
> .drm_mode = s6d7aa0_ltl101at01_mode,
> ^~~
>   drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c:443:14: note: (near 
> initialization for 's6d7aa0_ltl101at01_desc.drm_mode')
> 

I've submitted a patch, "drm/panel: samsung-s6d7aa0: use pointer for
drm_mode in panel desc struct"[1], which should fix this. I tested it
with GCC 13.1.1, GCC 6.4.0 and Clang 16.0.3, but I'd appreciate any
further testing and feedback.

Apologies for the error.

Best regards
Artur

[1] https://lore.kernel.org/all/20230523212050.9970-1-aweber.ker...@gmail.com/T/


Re: [PATCH v5 2/3] drm/panel: Add Samsung S6D7AA0 panel controller driver

2023-05-23 Thread Nathan Chancellor
Hi Artur,

On Fri, May 19, 2023 at 07:03:53PM +0200, Artur Weber wrote:
> Initial driver for S6D7AA0-controlled panels. Currently, the following
> panels are supported:
> 
>  - S6D7AA0-LSL080AL02 (Samsung Galaxy Tab 3 8.0)
>  - S6D7AA0-LSL080AL03 (Samsung Galaxy Tab A 8.0 2015)
>  - S6D7AA0-LTL101AT01 (Samsung Galaxy Tab A 9.7 2015)
> 
> It should be possible to extend this driver to work with other panels
> using this IC.
> 
> Tested-by: Nikita Travkin  #ltl101at01
> Signed-off-by: Artur Weber 



This change as commit 6810bb390282 ("drm/panel: Add Samsung S6D7AA0
panel controller driver") in -next causes the following build errors
with clang and GCC older than 8.x (the kernel supports back to GCC 5.1).

With clang:

  drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c:312:14: error: initializer 
element is not a compile-time constant
  .drm_mode = s6d7aa0_lsl080al02_mode,
  ^~~
  drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c:415:14: error: initializer 
element is not a compile-time constant
  .drm_mode = s6d7aa0_lsl080al03_mode,
  ^~~
  drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c:443:14: error: initializer 
element is not a compile-time constant
  .drm_mode = s6d7aa0_ltl101at01_mode,
  ^~~
  3 errors generated.

With GCC:

  drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c:312:14: error: initializer 
element is not constant
.drm_mode = s6d7aa0_lsl080al02_mode,
^~~
  drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c:312:14: note: (near 
initialization for 's6d7aa0_lsl080al02_desc.drm_mode')
  drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c:415:14: error: initializer 
element is not constant
.drm_mode = s6d7aa0_lsl080al03_mode,
^~~
  drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c:415:14: note: (near 
initialization for 's6d7aa0_lsl080al03_desc.drm_mode')
  drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c:443:14: error: initializer 
element is not constant
.drm_mode = s6d7aa0_ltl101at01_mode,
^~~
  drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c:443:14: note: (near 
initialization for 's6d7aa0_ltl101at01_desc.drm_mode')

You can find these toolchains at
https://mirrors.edge.kernel.org/pub/tools/crosstool/ and
https://mirrors.edge.kernel.org/pub/tools/llvm/ if you need help
testing.

clang may eventually match GCC's newer behavior but there appears to be
some unresolved concerns around the proposed implementation and we have
not been able to double back to it:
https://reviews.llvm.org/D76096

> +static const struct drm_display_mode s6d7aa0_lsl080al03_mode = {
> + .clock = (768 + 18 + 16 + 126) * (1024 + 8 + 2 + 6) * 60 / 1000,
> + .hdisplay = 768,
> + .hsync_start = 768 + 18,
> + .hsync_end = 768 + 18 + 16,
> + .htotal = 768 + 18 + 16 + 126,
> + .vdisplay = 1024,
> + .vsync_start = 1024 + 8,
> + .vsync_end = 1024 + 8 + 2,
> + .vtotal = 1024 + 8 + 2 + 6,
> + .width_mm = 122,
> + .height_mm = 163,
> +};
> +
> +static const struct s6d7aa0_panel_desc s6d7aa0_lsl080al03_desc = {
> + .panel_type = S6D7AA0_PANEL_LSL080AL03,
> + .init_func = s6d7aa0_lsl080al03_init,
> + .off_func = s6d7aa0_lsl080al03_off,
> + .drm_mode = s6d7aa0_lsl080al03_mode,
> + .mode_flags = MIPI_DSI_MODE_NO_EOT_PACKET,
> + .bus_flags = 0,
> +
> + .has_backlight = true,
> + .use_passwd3 = true,
> +};
> +
> +/* Initialization structures for LTL101AT01 panel */
> +
> +static const struct drm_display_mode s6d7aa0_ltl101at01_mode = {
> + .clock = (768 + 96 + 16 + 184) * (1024 + 8 + 2 + 6) * 60 / 1000,
> + .hdisplay = 768,
> + .hsync_start = 768 + 96,
> + .hsync_end = 768 + 96 + 16,
> + .htotal = 768 + 96 + 16 + 184,
> + .vdisplay = 1024,
> + .vsync_start = 1024 + 8,
> + .vsync_end = 1024 + 8 + 2,
> + .vtotal = 1024 + 8 + 2 + 6,
> + .width_mm = 148,
> + .height_mm = 197,
> +};
> +
> +static const struct s6d7aa0_panel_desc s6d7aa0_ltl101at01_desc = {
> + .panel_type = S6D7AA0_PANEL_LTL101AT01,
> + .init_func = s6d7aa0_lsl080al03_init, /* Similar init to LSL080AL03 */
> + .off_func = s6d7aa0_lsl080al03_off,
> + .drm_mode = s6d7aa0_ltl101at01_mode,
> + .mode_flags = MIPI_DSI_MODE_NO_EOT_PACKET,
> + .bus_flags = 0,
> +
> + .has_backlight = true,
> + .use_passwd3 = true,
> +};

Cheers,
Nathan


Re: [PATCH v5 2/3] drm/panel: Add Samsung S6D7AA0 panel controller driver

2023-05-22 Thread Neil Armstrong

On 19/05/2023 19:03, Artur Weber wrote:

Initial driver for S6D7AA0-controlled panels. Currently, the following
panels are supported:

  - S6D7AA0-LSL080AL02 (Samsung Galaxy Tab 3 8.0)
  - S6D7AA0-LSL080AL03 (Samsung Galaxy Tab A 8.0 2015)
  - S6D7AA0-LTL101AT01 (Samsung Galaxy Tab A 9.7 2015)

It should be possible to extend this driver to work with other panels
using this IC.

Tested-by: Nikita Travkin  #ltl101at01
Signed-off-by: Artur Weber 
---
Changed in v2:
  - Removed unused panel_name property from desc struct
Changed in v4:
  - Added LSL080AL03 and LTL101AT01 panels
  - Added DSI-controlled backlight support for panels that support it
  - Renamed command defines: CMD_* -> MCS_*
  - Dropped s6d7aa0_bl_ctl_on (not universal across panels)
  - Dropped MIPI_DSI_MODE_LPM flag
  - Added vmipi-supply, renamed enable-supply to power-supply
Changed in v5:
  - Changed compatible to avoid concatenating multiple model numbers
---
  drivers/gpu/drm/panel/Kconfig |   7 +
  drivers/gpu/drm/panel/Makefile|   1 +
  drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c | 585 ++
  3 files changed, 593 insertions(+)
  create mode 100644 drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 2b9d6db7860b..203c0ef0bbfd 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -553,6 +553,13 @@ config DRM_PANEL_SAMSUNG_S6D27A1
  This panel can be found in Samsung Galaxy Ace 2
  GT-I8160 mobile phone.
  
+config DRM_PANEL_SAMSUNG_S6D7AA0

+   tristate "Samsung S6D7AA0 MIPI-DSI video mode panel controller"
+   depends on OF
+   depends on BACKLIGHT_CLASS_DEVICE
+   select DRM_MIPI_DSI
+   select VIDEOMODE_HELPERS
+
  config DRM_PANEL_SAMSUNG_S6E3HA2
tristate "Samsung S6E3HA2 DSI video mode panel"
depends on OF
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index ff169781e82d..30cf553c8d1d 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -54,6 +54,7 @@ obj-$(CONFIG_DRM_PANEL_SAMSUNG_DB7430) += 
panel-samsung-db7430.o
  obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o
  obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6D16D0) += panel-samsung-s6d16d0.o
  obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6D27A1) += panel-samsung-s6d27a1.o
+obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6D7AA0) += panel-samsung-s6d7aa0.o
  obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2) += panel-samsung-s6e3ha2.o
  obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03) += panel-samsung-s6e63j0x03.o
  obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63M0) += panel-samsung-s6e63m0.o
diff --git a/drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c 
b/drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c
new file mode 100644
index ..f532aa018428
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c
@@ -0,0 +1,585 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Samsung S6D7AA0 MIPI-DSI TFT LCD controller drm_panel driver.
+ *
+ * Copyright (C) 2022 Artur Weber 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+/* Manufacturer command set */
+#define MCS_BL_CTL 0xc3
+#define MCS_OTP_RELOAD 0xd0
+#define MCS_PASSWD10xf0
+#define MCS_PASSWD20xf1
+#define MCS_PASSWD30xfc
+
+struct s6d7aa0 {
+   struct drm_panel panel;
+   struct mipi_dsi_device *dsi;
+   struct gpio_desc *reset_gpio;
+   struct regulator_bulk_data supplies[2];
+   const struct s6d7aa0_panel_desc *desc;
+};
+
+struct s6d7aa0_panel_desc {
+   unsigned int panel_type;
+   int (*init_func)(struct s6d7aa0 *ctx);
+   int (*off_func)(struct s6d7aa0 *ctx);
+   const struct drm_display_mode drm_mode;
+   unsigned long mode_flags;
+   u32 bus_flags;
+   bool has_backlight;
+   bool use_passwd3;
+};
+
+enum s6d7aa0_panels {
+   S6D7AA0_PANEL_LSL080AL02,
+   S6D7AA0_PANEL_LSL080AL03,
+   S6D7AA0_PANEL_LTL101AT01,
+};
+
+static inline struct s6d7aa0 *panel_to_s6d7aa0(struct drm_panel *panel)
+{
+   return container_of(panel, struct s6d7aa0, panel);
+}
+
+static void s6d7aa0_reset(struct s6d7aa0 *ctx)
+{
+   gpiod_set_value_cansleep(ctx->reset_gpio, 1);
+   msleep(50);
+   gpiod_set_value_cansleep(ctx->reset_gpio, 0);
+   msleep(50);
+}
+
+static int s6d7aa0_lock(struct s6d7aa0 *ctx, bool lock)
+{
+   struct mipi_dsi_device *dsi = ctx->dsi;
+   int ret = 0;
+
+   if (lock) {
+   mipi_dsi_dcs_write_seq(dsi, MCS_PASSWD1, 0xa5, 0xa5);
+   mipi_dsi_dcs_write_seq(dsi, MCS_PASSWD2, 0xa5, 0xa5);
+   if (ctx->desc->use_passwd3)
+   mipi_dsi_dcs_write_seq(dsi, MCS_PASSWD3, 0x5a, 0x5a);
+   } else {
+   mipi_dsi_dcs_write_seq(dsi, MCS_PASSWD1, 0x5a, 0x5a);
+   mipi_dsi_dcs_write_seq(dsi, MCS_PASSWD2, 

[PATCH v5 2/3] drm/panel: Add Samsung S6D7AA0 panel controller driver

2023-05-19 Thread Artur Weber
Initial driver for S6D7AA0-controlled panels. Currently, the following
panels are supported:

 - S6D7AA0-LSL080AL02 (Samsung Galaxy Tab 3 8.0)
 - S6D7AA0-LSL080AL03 (Samsung Galaxy Tab A 8.0 2015)
 - S6D7AA0-LTL101AT01 (Samsung Galaxy Tab A 9.7 2015)

It should be possible to extend this driver to work with other panels
using this IC.

Tested-by: Nikita Travkin  #ltl101at01
Signed-off-by: Artur Weber 
---
Changed in v2:
 - Removed unused panel_name property from desc struct
Changed in v4:
 - Added LSL080AL03 and LTL101AT01 panels
 - Added DSI-controlled backlight support for panels that support it
 - Renamed command defines: CMD_* -> MCS_*
 - Dropped s6d7aa0_bl_ctl_on (not universal across panels)
 - Dropped MIPI_DSI_MODE_LPM flag
 - Added vmipi-supply, renamed enable-supply to power-supply
Changed in v5:
 - Changed compatible to avoid concatenating multiple model numbers
---
 drivers/gpu/drm/panel/Kconfig |   7 +
 drivers/gpu/drm/panel/Makefile|   1 +
 drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c | 585 ++
 3 files changed, 593 insertions(+)
 create mode 100644 drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 2b9d6db7860b..203c0ef0bbfd 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -553,6 +553,13 @@ config DRM_PANEL_SAMSUNG_S6D27A1
  This panel can be found in Samsung Galaxy Ace 2
  GT-I8160 mobile phone.
 
+config DRM_PANEL_SAMSUNG_S6D7AA0
+   tristate "Samsung S6D7AA0 MIPI-DSI video mode panel controller"
+   depends on OF
+   depends on BACKLIGHT_CLASS_DEVICE
+   select DRM_MIPI_DSI
+   select VIDEOMODE_HELPERS
+
 config DRM_PANEL_SAMSUNG_S6E3HA2
tristate "Samsung S6E3HA2 DSI video mode panel"
depends on OF
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index ff169781e82d..30cf553c8d1d 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -54,6 +54,7 @@ obj-$(CONFIG_DRM_PANEL_SAMSUNG_DB7430) += 
panel-samsung-db7430.o
 obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o
 obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6D16D0) += panel-samsung-s6d16d0.o
 obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6D27A1) += panel-samsung-s6d27a1.o
+obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6D7AA0) += panel-samsung-s6d7aa0.o
 obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2) += panel-samsung-s6e3ha2.o
 obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03) += panel-samsung-s6e63j0x03.o
 obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63M0) += panel-samsung-s6e63m0.o
diff --git a/drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c 
b/drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c
new file mode 100644
index ..f532aa018428
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c
@@ -0,0 +1,585 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Samsung S6D7AA0 MIPI-DSI TFT LCD controller drm_panel driver.
+ *
+ * Copyright (C) 2022 Artur Weber 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+/* Manufacturer command set */
+#define MCS_BL_CTL 0xc3
+#define MCS_OTP_RELOAD 0xd0
+#define MCS_PASSWD10xf0
+#define MCS_PASSWD20xf1
+#define MCS_PASSWD30xfc
+
+struct s6d7aa0 {
+   struct drm_panel panel;
+   struct mipi_dsi_device *dsi;
+   struct gpio_desc *reset_gpio;
+   struct regulator_bulk_data supplies[2];
+   const struct s6d7aa0_panel_desc *desc;
+};
+
+struct s6d7aa0_panel_desc {
+   unsigned int panel_type;
+   int (*init_func)(struct s6d7aa0 *ctx);
+   int (*off_func)(struct s6d7aa0 *ctx);
+   const struct drm_display_mode drm_mode;
+   unsigned long mode_flags;
+   u32 bus_flags;
+   bool has_backlight;
+   bool use_passwd3;
+};
+
+enum s6d7aa0_panels {
+   S6D7AA0_PANEL_LSL080AL02,
+   S6D7AA0_PANEL_LSL080AL03,
+   S6D7AA0_PANEL_LTL101AT01,
+};
+
+static inline struct s6d7aa0 *panel_to_s6d7aa0(struct drm_panel *panel)
+{
+   return container_of(panel, struct s6d7aa0, panel);
+}
+
+static void s6d7aa0_reset(struct s6d7aa0 *ctx)
+{
+   gpiod_set_value_cansleep(ctx->reset_gpio, 1);
+   msleep(50);
+   gpiod_set_value_cansleep(ctx->reset_gpio, 0);
+   msleep(50);
+}
+
+static int s6d7aa0_lock(struct s6d7aa0 *ctx, bool lock)
+{
+   struct mipi_dsi_device *dsi = ctx->dsi;
+   int ret = 0;
+
+   if (lock) {
+   mipi_dsi_dcs_write_seq(dsi, MCS_PASSWD1, 0xa5, 0xa5);
+   mipi_dsi_dcs_write_seq(dsi, MCS_PASSWD2, 0xa5, 0xa5);
+   if (ctx->desc->use_passwd3)
+   mipi_dsi_dcs_write_seq(dsi, MCS_PASSWD3, 0x5a, 0x5a);
+   } else {
+   mipi_dsi_dcs_write_seq(dsi, MCS_PASSWD1, 0x5a, 0x5a);
+   mipi_dsi_dcs_write_seq(dsi, MCS_PASSWD2, 0x5a, 0x5a);
+   if (ctx->desc->use_passwd3)
+